Compare commits

..

35 Commits

Author SHA1 Message Date
c30a23669b some small fixes 2024-05-06 17:22:38 +05:00
3329837974 knIPV4Endpoint_toString 2024-04-12 21:42:18 +05:00
c4e102b14c TCP and UDP sockets localEndpoint 2024-04-12 21:32:09 +05:00
f2847a819d clion files update 2024-04-10 15:59:49 +05:00
235889604e src/time/ 2024-04-09 04:16:59 +05:00
da504dfcf5 knSocketTCP_receiveN 2024-04-09 04:12:43 +05:00
0e370b31ba kprintf args count check 2024-03-23 01:42:15 +05:00
9bc2a8587b ksprintf 2024-03-23 01:17:46 +05:00
dd5788f72a cbuild update 2024-02-22 01:10:04 +06:00
95a9fcfd5e bufgixes 2024-01-04 00:58:10 +06:00
918588e0e4 fixed warning 2024-01-04 00:41:18 +06:00
6ba06dcc0c knIPV4Endpoint_fromStr 2024-01-04 00:29:55 +06:00
b430846a0e network types *_isINVALID 2024-01-03 23:58:11 +06:00
7ba15b208f kt_beginInit(bool) 2024-01-03 16:58:20 +06:00
791ffe8633 printf color code macros 2024-01-03 15:33:09 +06:00
0756b51950 removed -lpthread for linux 2024-01-03 12:56:57 +06:00
fd30713d29 network types registered 2024-01-03 12:21:12 +06:00
930b35575c test_udp 2024-01-03 10:58:16 +06:00
59b3772d5a udp implementation 2024-01-02 23:30:25 +06:00
9d2f5ddc2a some fixes in sockets and complete tcp client/server test 2024-01-02 21:59:10 +06:00
336bde5fb0 finished tcp functions 2024-01-02 16:08:11 +06:00
550175fa92 fixed typos 2024-01-02 12:28:20 +06:00
1b93c0ca22 fixed typos 2024-01-02 12:16:28 +06:00
6135f3030f config and kprintf 2024-01-01 20:04:21 +06:00
c9969a1d96 Merge branch 'main' into 'network' 2024-01-01 19:46:52 +06:00
53cf9875e6 cbuild 2023-10-12 13:59:25 +06:00
ccac9536e8 cbuild update 2023-02-07 12:26:00 +06:00
f64a8368ac linking to winsock 2023-01-20 04:26:35 +06:00
3d15cb35af Merge branch 'main' into network 2023-01-20 01:24:41 +06:00
85d6ba2216 different socket structs instead of universal 2023-01-15 21:34:04 +06:00
288c73104c fixed errors 2022-11-25 10:36:38 +06:00
Timerix22
2efcf08ebe Merge pull request #13 from Timerix22/main
merge changes from 'main'
2022-11-15 12:25:47 +06:00
c2b3e3997d knNetwork file structure changed 2022-11-14 10:02:28 +06:00
a55b2245bd Merge branch 'main' into network 2022-10-30 19:57:05 +06:00
abfbc7eaa2 some small changes 2022-10-30 19:47:13 +06:00
141 changed files with 3285 additions and 1966 deletions

8
.gitignore vendored
View File

@@ -4,12 +4,12 @@ obj/
# user files # user files
.old*/ .old*/
[Tt]mp/
[Tt]emp/
.[Tt]mp/
.[Tt]emp/
.vs/ .vs/
.vshistory/ .vshistory/
tmp/
temp/
*.tmp
*.temp
.editorconfig .editorconfig
*.user *.user
*.vcxproj.filters *.vcxproj.filters

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

7
.idea/discord.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
<option name="description" value="" />
</component>
</project>

102
.idea/editor.xml generated Normal file
View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BackendCodeEditorSettings">
<option name="/Default/CodeStyle/CodeFormatting/CppClangFormat/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_BINARY_EXPRESSIONS_CHAIN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXPRESSION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_FOR_STMT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTIPLE_DECLARATION/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_TERNARY/@EntryValue" value="ALIGN_ALL" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_CLASS_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue" value="2" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/KEEP_USER_LINEBREAKS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CASE_FROM_SWITCH/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_COMMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INT_ALIGN_EQ/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SIMPLE_BLOCK_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COMMA_IN_TEMPLATE_PARAMS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_SEMICOLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_SEMICOLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_UNARY_OPERATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_ARRAY_ACCESS_BRACKETS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_METHOD_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_INITIALIZER_BRACES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPECIAL_ELSE_IF_TREATMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_CAST_EXPRESSION_PARENTHESES/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_BINARY_OPSIGN/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_TERNARY_OPSIGNS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TYPE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/OTHER_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CASE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DECLARATION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_FUNCTION_DEFINITION/@EntryValue" value="1" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_WHILE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_ELSE_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_CATCH_ON_NEW_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_INDENTATION/@EntryValue" value="All" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_ARGUMENT/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_PARAMETER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_ARGUMENT/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ALIGN_MULTILINE_TYPE_PARAMETER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BLANK_LINES_AROUND_DECLARATIONS/@EntryValue" value="0" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_ACCESS_SPECIFIERS_FROM_CLASS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_CLASS_MEMBERS_FROM_ACCESS_SPECIFIERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/LINE_BREAK_AFTER_COLON_IN_MEMBER_INITIALIZER_LISTS/@EntryValue" value="ON_SINGLE_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/MEMBER_INITIALIZER_LIST_STYLE/@EntryValue" value="DO_NOT_CHANGE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/PLACE_NAMESPACE_DEFINITIONS_ON_SAME_LINE/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_COLON_IN_BITFIELD_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_EXTENDS_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_FOR_COLON/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_FOR_COLON/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_PTR_IN_NESTED_DECLARATOR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBER/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_DATA_MEMBERS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_AFTER_REF_IN_METHOD/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_PTR_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_ABSTRACT_DECL/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBER/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_DATA_MEMBERS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_REF_IN_METHOD/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BEFORE_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_BETWEEN_CLOSING_ANGLE_BRACKETS_IN_TEMPLATE_ARGS/@EntryValue" value="true" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_ARGS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_TEMPLATE_PARAMS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_DECLARATION_PARENTHESES/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/SPACE_WITHIN_EMPTY_BLOCKS/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_INVOCATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_INVOCATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_AFTER_DECLARATION_LPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_BEFORE_DECLARATION_RPAR/@EntryValue" value="false" type="bool" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_ARGUMENTS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/WRAP_PARAMETERS_STYLE/@EntryValue" value="WRAP_IF_LONG" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/BREAK_TEMPLATE_DECLARATION/@EntryValue" value="LINE_BREAK" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/NAMESPACE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/FREE_BLOCK_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INVOCABLE_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/ANONYMOUS_METHOD_DECLARATION_BRACES/@EntryValue" value="END_OF_LINE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INITIALIZER_BRACES/@EntryValue" value="END_OF_LINE_NO_SPACE" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_STYLE/@EntryValue" value="Space" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/INDENT_SIZE/@EntryValue" value="4" type="int" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/CONTINUOUS_LINE_INDENT/@EntryValue" value="Double" type="string" />
<option name="/Default/CodeStyle/CodeFormatting/CppFormatting/TAB_WIDTH/@EntryValue" value="4" type="int" />
</component>
</project>

View File

@@ -1,29 +1,6 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="ClangTidy" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="CodeBlock2Expr" enabled="true" level="TEXT ATTRIBUTES" enabled_by_default="true" editorAttributes="CONSIDERATION_ATTRIBUTES" />
<option name="clangTidyCheckOptions">
<list>
<ClangTidyCheckOption />
</list>
</option>
<option name="clangTidyChecks" value="-*,bugprone-argument-comment,bugprone-assert-side-effect,bugprone-bad-signal-to-kill-thread,bugprone-branch-clone,bugprone-copy-constructor-init,bugprone-dangling-handle,bugprone-dynamic-static-initializers,bugprone-fold-init-type,bugprone-forward-declaration-namespace,bugprone-forwarding-reference-overload,bugprone-inaccurate-erase,bugprone-incorrect-roundings,bugprone-integer-division,bugprone-lambda-function-name,bugprone-macro-repeated-side-effects,bugprone-misplaced-operator-in-strlen-in-alloc,bugprone-misplaced-pointer-arithmetic-in-alloc,bugprone-misplaced-widening-cast,bugprone-move-forwarding-reference,bugprone-multiple-statement-macro,bugprone-no-escape,bugprone-not-null-terminated-result,bugprone-parent-virtual-call,bugprone-posix-return,bugprone-sizeof-container,bugprone-sizeof-expression,bugprone-spuriously-wake-up-functions,bugprone-string-constructor,bugprone-string-integer-assignment,bugprone-string-literal-with-embedded-nul,bugprone-suspicious-enum-usage,bugprone-suspicious-include,bugprone-suspicious-memory-comparison,bugprone-suspicious-memset-usage,bugprone-suspicious-missing-comma,bugprone-suspicious-semicolon,bugprone-suspicious-string-compare,bugprone-swapped-arguments,bugprone-terminating-continue,bugprone-throw-keyword-missing,bugprone-too-small-loop-variable,bugprone-undefined-memory-manipulation,bugprone-undelegated-constructor,bugprone-unhandled-self-assignment,bugprone-unused-raii,bugprone-unused-return-value,bugprone-use-after-move,bugprone-virtual-near-miss,cert-dcl21-cpp,cert-dcl58-cpp,cert-err34-c,cert-err52-cpp,cert-err58-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,cert-str34-c,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-member-init,cppcoreguidelines-pro-type-static-cast-downcast,cppcoreguidelines-slicing,google-default-arguments,google-explicit-constructor,google-runtime-operator,hicpp-exception-baseclass,hicpp-multiway-paths-covered,misc-misplaced-const,misc-new-delete-overloads,misc-no-recursion,misc-non-copyable-objects,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,modernize-avoid-bind,modernize-concat-nested-namespaces,modernize-deprecated-headers,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-disallow-copy-and-assign-macro,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,mpi-buffer-deref,mpi-type-mismatch,openmp-use-default-none,performance-faster-string-find,performance-for-range-copy,performance-implicit-conversion-in-loop,performance-inefficient-algorithm,performance-inefficient-string-concatenation,performance-inefficient-vector-operation,performance-move-const-arg,performance-move-constructor-init,performance-no-automatic-move,performance-noexcept-move-constructor,performance-trivially-destructible,performance-type-promotion-in-math-fn,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,portability-simd-intrinsics,readability-avoid-const-params-in-decls,readability-const-return-type,readability-container-size-empty,readability-convert-member-functions-to-static,readability-delete-null-pointer,readability-deleted-default,readability-inconsistent-declaration-parameter-name,readability-make-member-function-const,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-use-anyofallof" />
</inspection_tool>
<inspection_tool class="ClangdErrorsAndWarnings" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="EmptyDeclOrStmt" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GrazieInspection" enabled="false" level="TYPO" enabled_by_default="false" />
<inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Misra" enabled="false" level="WARNING" enabled_by_default="false">
<option name="myMisraCPPChecks" value="clion-misra-cpp2008-*,-clion-misra-cpp2008-11-0-1" />
</inspection_tool>
<inspection_tool class="OCUnusedGlobalDeclaration" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ShellCheck" enabled="false" level="ERROR" enabled_by_default="false">
<shellcheck_settings value="SC2034,SC2035,SC2059,SC2061,SC2091,SC2155" />
</inspection_tool>
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />
<option name="processLiterals" value="true" />
<option name="processComments" value="true" />
</inspection_tool>
</profile> </profile>
</component> </component>

1
.idea/vcs.xml generated
View File

@@ -2,5 +2,6 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/cbuild" vcs="Git" />
</component> </component>
</project> </project>

24
.vscode/launch.json vendored
View File

@@ -11,19 +11,7 @@
"stopAtEntry": false, "stopAtEntry": false,
"externalConsole": false, "externalConsole": false,
"MIMode": "gdb", "MIMode": "gdb",
"miDebuggerPath": "gdb", "miDebuggerPath": "gdb"
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}, },
{ {
"name": "(gdb-pipe) Debug", "name": "(gdb-pipe) Debug",
@@ -42,6 +30,16 @@
"pipeArgs": ["-c"], "pipeArgs": ["-c"],
"pipeCwd": "${workspaceFolder}" "pipeCwd": "${workspaceFolder}"
} }
},
{
"name": "(msvc) Debug",
"type": "cppvsdbg",
"request": "launch",
"preLaunchTask": "build_dbg",
"program": "${workspaceFolder}\\bin\\kerep",
"cwd": "${workspaceFolder}\\bin",
"stopAtEntry": false,
"console": "integratedTerminal"
} }
] ]
} }

3
.vscode/tasks.json vendored
View File

@@ -23,7 +23,8 @@
"reveal": "always", "reveal": "always",
"focus": true, "focus": true,
"panel": "shared", "panel": "shared",
"showReuseMessage": false "showReuseMessage": false,
"clean": true
} }
} }
] ]

View File

@@ -57,7 +57,7 @@ gprof:
# compiles program and runs it with callgrind (part of valgrind) # compiles program and runs it with callgrind (part of valgrind)
# uses gprof2dot python script to generate function call tree (pip install gprof2dot) # uses gprof2dot python script to generate function call tree (pip install gprof2dot)
# requires graphviz (https://www.graphviz.org/download/source/) # requires graphviz (https://www.graphviz.org/download/source/)
# P.S. detailed rezults can be viewed in KCacheGrind # P.S. detailed results can be viewed in KCacheGrind
callgrind: callgrind:
@cbuild/call_task.sh callgrind 2>&1 | tee make_raw.log @cbuild/call_task.sh callgrind 2>&1 | tee make_raw.log

29
TODO.md
View File

@@ -1,29 +0,0 @@
## Allocators
- replace all malloc() and free() with allocator_alloc() and allocator_free()
- replace allocating constructors with Type_construct(var_ptr, ...)
- replace Struct_free functions with Struct_destruct which will not call free() on the struct ptr
- store in resizable structs their buffer allocators and free them with Struct_destruct()
- check allocator_free call order
- deal with StackingAllocator_free not freing memory sometimes
- replace LinearAllocator with StackingAllocator when possible (in DtsodV24_deserialize)
- use LinkedList instead of complicated LinearAllocator logic
- configurable LinearAllocator chunk size (static/growing)
## Autoarr
- store length and max_length inside the struct instead of calculating them by macro
- keep Autoarr_length() and Autoarr_maxLength() to old code compatibility
- toString()
## Hashtable
- store hash in KVPair
- don't use Autoarr in Hashtable
- make Hashtable generic struct
## Unitype
- replace UniPtrHeap with UniPtrStack
- do something with VoidPtr ownership
## String
- add `bool zero_terminated`
- rewrite all code to use `string` instead of `char*`
- rewrite `StringBuilder`

2
cbuild

Submodule cbuild updated: 60fa8c11c2...574ce6eab3

View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
CBUILD_VERSION=7 CBUILD_VERSION=7
CONFIG_VERSION=7 CONFIG_VERSION=8
PROJECT="kerep" PROJECT="kerep"
CMP_C="gcc" CMP_C="gcc"
@@ -37,10 +37,12 @@ case "$OS" in
WINDOWS) WINDOWS)
EXEC_FILE="$PROJECT.exe" EXEC_FILE="$PROJECT.exe"
SHARED_LIB_FILE="$PROJECT.dll" SHARED_LIB_FILE="$PROJECT.dll"
LINKER_LIBS="-lpthread -lws2_32"
;; ;;
LINUX) LINUX)
EXEC_FILE="$PROJECT" EXEC_FILE="$PROJECT"
SHARED_LIB_FILE="$PROJECT.so" SHARED_LIB_FILE="$PROJECT.so"
LINKER_LIBS=""
;; ;;
*) *)
error "operating system $OS has no configuration variants" error "operating system $OS has no configuration variants"
@@ -59,7 +61,7 @@ case "$TASK" in
# -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code # -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections" C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@@ -68,7 +70,7 @@ case "$TASK" in
build_exec_dbg) build_exec_dbg)
C_ARGS="-O0 -g3" C_ARGS="-O0 -g3"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@@ -77,7 +79,7 @@ case "$TASK" in
build_shared_lib) build_shared_lib)
C_ARGS="-O2 -fpic -flto -shared" C_ARGS="-O2 -fpic -flto -shared"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE" LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE $LINKER_LIBS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@@ -86,7 +88,7 @@ case "$TASK" in
build_shared_lib_dbg) build_shared_lib_dbg)
C_ARGS="-O0 -g3 -fpic -shared" C_ARGS="-O0 -g3 -fpic -shared"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE" LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE $LINKER_LIBS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@@ -127,7 +129,7 @@ case "$TASK" in
# -fprofile-prefix-path sets path where profiling info about objects will be saved # -fprofile-prefix-path sets path where profiling info about objects will be saved
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects" C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/profile.sh TASK_SCRIPT=cbuild/default_tasks/profile.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@@ -140,7 +142,7 @@ case "$TASK" in
# -pg adds code to executable, that generates file containing function call info (gmon.out) # -pg adds code to executable, that generates file containing function call info (gmon.out)
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg" C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/gprof.sh TASK_SCRIPT=cbuild/default_tasks/gprof.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=
@@ -148,13 +150,13 @@ case "$TASK" in
# compiles program and runs it with callgrind (part of valgrind) # compiles program and runs it with callgrind (part of valgrind)
# uses gprof2dot python script to generate function call tree (pip install gprof2dot) # uses gprof2dot python script to generate function call tree (pip install gprof2dot)
# requires graphviz (https://www.graphviz.org/download/source/) # requires graphviz (https://www.graphviz.org/download/source/)
# P.S. detailed rezults can be viewed in KCacheGrind # P.S. detailed results can be viewed in KCacheGrind
callgrind) callgrind)
OUTDIR="$OUTDIR/callgrind" OUTDIR="$OUTDIR/callgrind"
# -pg adds code to executable, that generates file containing function call info (gmon.out) # -pg adds code to executable, that generates file containing function call info (gmon.out)
C_ARGS="-O2 -flto=auto -fuse-linker-plugin" C_ARGS="-O2 -flto=auto -fuse-linker-plugin"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=tasks/pre_build.sh PRE_TASK_SCRIPT=tasks/pre_build.sh
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
POST_TASK_SCRIPT=cbuild/default_tasks/callgrind.sh POST_TASK_SCRIPT=cbuild/default_tasks/callgrind.sh
@@ -164,7 +166,7 @@ case "$TASK" in
OUTDIR="$OUTDIR/sanitize" OUTDIR="$OUTDIR/sanitize"
C_ARGS="-O0 -g3 -fsanitize=undefined,address" C_ARGS="-O0 -g3 -fsanitize=undefined,address"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS $LINKER_LIBS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/exec.sh TASK_SCRIPT=cbuild/default_tasks/exec.sh
POST_TASK_SCRIPT= POST_TASK_SCRIPT=

View File

@@ -1,31 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.2.32317.152 VisualStudioVersion = 17.2.32317.152
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kerep", "kerep.vcxproj", "{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kerep", "kerep.vcxproj", "{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Release|x64 = Release|x64 Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.ActiveCfg = Debug|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.ActiveCfg = Debug|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.Build.0 = Debug|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.Build.0 = Debug|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.ActiveCfg = Debug|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.ActiveCfg = Debug|Win32
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.Build.0 = Debug|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.Build.0 = Debug|Win32
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.ActiveCfg = Release|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.ActiveCfg = Release|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.Build.0 = Release|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.Build.0 = Release|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.ActiveCfg = Release|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.ActiveCfg = Release|Win32
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.Build.0 = Release|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {22F8C351-9A96-4F37-94E6-37E6AB5BA058} SolutionGuid = {22F8C351-9A96-4F37-94E6-37E6AB5BA058}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@@ -1,297 +1,297 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64"> <ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|x64"> <ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Array\Array.c" /> <ClCompile Include="src\Array\Array.c" />
<ClCompile Include="src\Autoarr\Autoarr.c" /> <ClCompile Include="src\Autoarr\Autoarr.c" />
<ClCompile Include="src\Autoarr\Autoarr_KVPair_exported.c" /> <ClCompile Include="src\Autoarr\Autoarr_KVPair_exported.c" />
<ClCompile Include="src\Autoarr\Autoarr_Unitype.c" /> <ClCompile Include="src\Autoarr\Autoarr_Unitype.c" />
<ClCompile Include="src\Autoarr\Autoarr_Unitype_exported.c" /> <ClCompile Include="src\Autoarr\Autoarr_Unitype_exported.c" />
<ClCompile Include="src\base\cptr.c" /> <ClCompile Include="src\base\cptr.c" />
<ClCompile Include="src\base\endian.c" /> <ClCompile Include="src\base\endian.c" />
<ClCompile Include="src\base\errors.c" /> <ClCompile Include="src\base\errors.c" />
<ClCompile Include="src\base\type_system\base_toString.c" /> <ClCompile Include="src\base\type_system\base_toString.c" />
<ClCompile Include="src\base\type_system\init.c" /> <ClCompile Include="src\base\type_system\init.c" />
<ClCompile Include="src\base\type_system\kt_functions.c" /> <ClCompile Include="src\base\type_system\kt_functions.c" />
<ClCompile Include="src\base\type_system\unitype.c" /> <ClCompile Include="src\base\type_system\unitype.c" />
<ClCompile Include="src\DtsodParser\DtsodV24.c" /> <ClCompile Include="src\DtsodParser\DtsodV24.c" />
<ClCompile Include="src\DtsodParser\DtsodV24_deserialize.c" /> <ClCompile Include="src\DtsodParser\DtsodV24_deserialize.c" />
<ClCompile Include="src\DtsodParser\DtsodV24_exported.c" /> <ClCompile Include="src\DtsodParser\DtsodV24_exported.c" />
<ClCompile Include="src\DtsodParser\DtsodV24_serialize.c" /> <ClCompile Include="src\DtsodParser\DtsodV24_serialize.c" />
<ClCompile Include="src\Filesystem\dir.c" /> <ClCompile Include="src\Filesystem\dir.c" />
<ClCompile Include="src\Filesystem\file.c" /> <ClCompile Include="src\Filesystem\file.c" />
<ClCompile Include="src\Filesystem\path.c" /> <ClCompile Include="src\Filesystem\path.c" />
<ClCompile Include="src\HashFunctions\hash.c" /> <ClCompile Include="src\HashFunctions\hash.c" />
<ClCompile Include="src\Hashtable\Hashtable.c" /> <ClCompile Include="src\Hashtable\Hashtable.c" />
<ClCompile Include="src\Hashtable\KeyValuePair.c" /> <ClCompile Include="src\Hashtable\KeyValuePair.c" />
<ClCompile Include="src\kprint\kprint.c" /> <ClCompile Include="src\kprint\kprint.c" />
<ClCompile Include="src\kprint\kprintf.c" /> <ClCompile Include="src\kprint\kprintf.c" />
<ClCompile Include="src\random\splitmix64\splitmix64.c" /> <ClCompile Include="src\random\splitmix64\splitmix64.c" />
<ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64star.c" /> <ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64star.c" />
<ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64starstar.c" /> <ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64starstar.c" />
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plus.c" /> <ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plus.c" />
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plusplus.c" /> <ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plusplus.c" />
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128starstar.c" /> <ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128starstar.c" />
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plus.c" /> <ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plus.c" />
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plusplus.c" /> <ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plusplus.c" />
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128starstar.c" /> <ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128starstar.c" />
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plus.c" /> <ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plus.c" />
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plusplus.c" /> <ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plusplus.c" />
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256starstar.c" /> <ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256starstar.c" />
<ClCompile Include="src\SearchTree\SearchTree.c" /> <ClCompile Include="src\SearchTree\SearchTree.c" />
<ClCompile Include="src\String\string.c" /> <ClCompile Include="src\String\string.c" />
<ClCompile Include="src\String\StringBuilder.c" /> <ClCompile Include="src\String\StringBuilder.c" />
<ClCompile Include="tests\test_marshalling.c" /> <ClCompile Include="tests\test_marshalling.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\Array\Array.h" /> <ClInclude Include="src\Array\Array.h" />
<ClInclude Include="src\Array\Array_declare.h" /> <ClInclude Include="src\Array\Array_declare.h" />
<ClInclude Include="src\Array\Array_define.h" /> <ClInclude Include="src\Array\Array_define.h" />
<ClInclude Include="src\Autoarr\Autoarr.h" /> <ClInclude Include="src\Autoarr\Autoarr.h" />
<ClInclude Include="src\Autoarr\Autoarr_declare.h" /> <ClInclude Include="src\Autoarr\Autoarr_declare.h" />
<ClInclude Include="src\Autoarr\Autoarr_define.h" /> <ClInclude Include="src\Autoarr\Autoarr_define.h" />
<ClInclude Include="src\Autoarr\Autoarr_Unitype.h" /> <ClInclude Include="src\Autoarr\Autoarr_Unitype.h" />
<ClInclude Include="src\base\base.h" /> <ClInclude Include="src\base\base.h" />
<ClInclude Include="src\base\cptr.h" /> <ClInclude Include="src\base\cptr.h" />
<ClInclude Include="src\base\endian.h" /> <ClInclude Include="src\base\endian.h" />
<ClInclude Include="src\base\errors.h" /> <ClInclude Include="src\base\errors.h" />
<ClInclude Include="src\base\optime.h" /> <ClInclude Include="src\base\optime.h" />
<ClInclude Include="src\base\std.h" /> <ClInclude Include="src\base\std.h" />
<ClInclude Include="src\base\type_system\base_toString.h" /> <ClInclude Include="src\base\type_system\base_toString.h" />
<ClInclude Include="src\base\type_system\init.h" /> <ClInclude Include="src\base\type_system\init.h" />
<ClInclude Include="src\base\type_system\ktDescriptor.h" /> <ClInclude Include="src\base\type_system\ktDescriptor.h" />
<ClInclude Include="src\base\type_system\ktid.h" /> <ClInclude Include="src\base\type_system\ktid.h" />
<ClInclude Include="src\base\type_system\kt_functions.h" /> <ClInclude Include="src\base\type_system\kt_functions.h" />
<ClInclude Include="src\base\type_system\type_system.h" /> <ClInclude Include="src\base\type_system\type_system.h" />
<ClInclude Include="src\base\type_system\unitype.h" /> <ClInclude Include="src\base\type_system\unitype.h" />
<ClInclude Include="src\DtsodParser\DtsodV24.h" /> <ClInclude Include="src\DtsodParser\DtsodV24.h" />
<ClInclude Include="src\Filesystem\dir.h" /> <ClInclude Include="src\Filesystem\dir.h" />
<ClInclude Include="src\Filesystem\file.h" /> <ClInclude Include="src\Filesystem\file.h" />
<ClInclude Include="src\Filesystem\filesystem.h" /> <ClInclude Include="src\Filesystem\filesystem.h" />
<ClInclude Include="src\Filesystem\path.h" /> <ClInclude Include="src\Filesystem\path.h" />
<ClInclude Include="src\HashFunctions\hash.h" /> <ClInclude Include="src\HashFunctions\hash.h" />
<ClInclude Include="src\Hashtable\Hashtable.h" /> <ClInclude Include="src\Hashtable\Hashtable.h" />
<ClInclude Include="src\Hashtable\KeyValuePair.h" /> <ClInclude Include="src\Hashtable\KeyValuePair.h" />
<ClInclude Include="src\kprint\kprint.h" /> <ClInclude Include="src\kprint\kprint.h" />
<ClInclude Include="src\kprint\kprintf.h" /> <ClInclude Include="src\kprint\kprintf.h" />
<ClInclude Include="src\kprint\kprint_colors.h" /> <ClInclude Include="src\kprint\kprint_colors.h" />
<ClInclude Include="src\kprint\kprint_format.h" /> <ClInclude Include="src\kprint\kprint_format.h" />
<ClInclude Include="src\random\krandom.h" /> <ClInclude Include="src\random\krandom.h" />
<ClInclude Include="src\random\splitmix64\splitmix64.h" /> <ClInclude Include="src\random\splitmix64\splitmix64.h" />
<ClInclude Include="src\random\xoroshiro\32bitValue\xoroshiro64.h" /> <ClInclude Include="src\random\xoroshiro\32bitValue\xoroshiro64.h" />
<ClInclude Include="src\random\xoroshiro\64bitValue\xoroshiro128.h" /> <ClInclude Include="src\random\xoroshiro\64bitValue\xoroshiro128.h" />
<ClInclude Include="src\random\xoroshiro\xoroshiro.h" /> <ClInclude Include="src\random\xoroshiro\xoroshiro.h" />
<ClInclude Include="src\random\xoshiro\32bitValue\xoshiro128.h" /> <ClInclude Include="src\random\xoshiro\32bitValue\xoshiro128.h" />
<ClInclude Include="src\random\xoshiro\64bitValue\xoshiro256.h" /> <ClInclude Include="src\random\xoshiro\64bitValue\xoshiro256.h" />
<ClInclude Include="src\random\xoshiro\xoshiro.h" /> <ClInclude Include="src\random\xoshiro\xoshiro.h" />
<ClInclude Include="src\SearchTree\SearchTree.h" /> <ClInclude Include="src\SearchTree\SearchTree.h" />
<ClInclude Include="src\String\string.h" /> <ClInclude Include="src\String\string.h" />
<ClInclude Include="src\String\StringBuilder.h" /> <ClInclude Include="src\String\StringBuilder.h" />
<ClInclude Include="tests\tests.h" /> <ClInclude Include="tests\tests.h" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{52f0bd29-a3cb-47ce-b25d-ceaf5dfb2d73}</ProjectGuid> <ProjectGuid>{52f0bd29-a3cb-47ce-b25d-ceaf5dfb2d73}</ProjectGuid>
<RootNamespace>kerep</RootNamespace> <RootNamespace>kerep</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
<ImportGroup Label="Shared"> <ImportGroup Label="Shared">
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>bin\$(Configuration)-$(Platform)\</OutDir> <OutDir>bin\$(Configuration)-$(Platform)\</OutDir>
<IntDir>obj\$(Configuration)-$(Platform)\</IntDir> <IntDir>obj\$(Configuration)-$(Platform)\</IntDir>
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>bin\x86\</OutDir> <OutDir>bin\x86\</OutDir>
<IntDir>obj\x86\</IntDir> <IntDir>obj\x86\</IntDir>
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<OutDir>bin\$(Configuration)-$(Platform)\</OutDir> <OutDir>bin\$(Configuration)-$(Platform)\</OutDir>
<IntDir>obj\$(Configuration)-$(Platform)\</IntDir> <IntDir>obj\$(Configuration)-$(Platform)\</IntDir>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<OutDir>bin\x64\</OutDir> <OutDir>bin\x64\</OutDir>
<IntDir>obj\x64\</IntDir> <IntDir>obj\x64\</IntDir>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
<TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal> <TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal>
<DisableAnalyzeExternal>true</DisableAnalyzeExternal> <DisableAnalyzeExternal>true</DisableAnalyzeExternal>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

27
src/Array/Array.c Normal file
View File

@@ -0,0 +1,27 @@
#include "Array.h"
Array_define(char)
Array_define(bool)
Array_define(f32)
Array_define(f64)
Array_define(i8)
Array_define(u8)
Array_define(i16)
Array_define(u16)
Array_define(i32)
Array_define(u32)
Array_define(i64)
Array_define(u64)
Array_define(Pointer)
Array_define(Unitype)
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers){
if(freeMembers) for (u32 i=0; i<array->length; i++)
Unitype_free(array->values[i]);
if(array->allocatedOnHeap)
free(array->values);
}
void __Array_Unitype_free_(void* ar)
{ Array_Unitype_free_(ar, true); }

32
src/Array/Array.h Normal file
View File

@@ -0,0 +1,32 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "Array_declare.h"
#include "Array_define.h"
Array_declare(char)
Array_declare(bool)
Array_declare(f32)
Array_declare(f64)
Array_declare(i8)
Array_declare(u8)
Array_declare(i16)
Array_declare(u16)
Array_declare(i32)
Array_declare(u32)
Array_declare(i64)
Array_declare(u64)
Array_declare(Pointer)
Array_declare(Unitype)
/// use this function instead of auto generated
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers);
void __Array_Unitype_free_(void* ar);
#if __cplusplus
}
#endif

39
src/Array/Array_declare.h Normal file
View File

@@ -0,0 +1,39 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#define Array_declare(type) \
STRUCT(Array_##type, \
type* values; \
u32 length; \
bool allocatedOnHeap; \
) \
\
static inline Array_##type Array_##type##_allocValues(u32 length){ \
return (Array_##type) { \
.values=(type*)malloc(sizeof(type)*length), \
.length=length, \
.allocatedOnHeap=true \
}; \
} \
\
static inline Array_##type Array_##type##_fromBuffer(type* buffer, u32 bufferLength, bool allocatedOnHeap){ \
return (Array_##type) { \
.values=buffer, \
.length=bufferLength, \
.allocatedOnHeap=allocatedOnHeap \
}; \
} \
\
static inline void Array_##type##_free(Array_##type* array){ \
if(array->allocatedOnHeap) \
free(array->values); \
}
#if __cplusplus
}
#endif

14
src/Array/Array_define.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#define Array_define(type) \
kt_define(Array_##type, (freeMembers_t)Array_##type##_free, NULL);
#if __cplusplus
}
#endif

2
src/Array/README.md Normal file
View File

@@ -0,0 +1,2 @@
# Array struct
This struct stores array pointer and length. If you want to use `Array` of some type, it should be declared in header file by macro `Array_declare` and defined in source file by `Array_define`.

View File

@@ -1,17 +1,17 @@
#include "Autoarr.h" #include "Autoarr.h"
Autoarr_define(Pointer) Autoarr_define(Pointer, true)
Autoarr_define(char) Autoarr_define(char, false)
Autoarr_define(bool) Autoarr_define(bool, false)
Autoarr_define(f32) Autoarr_define(f32, false)
Autoarr_define(f64) Autoarr_define(f64, false)
Autoarr_define(u8) Autoarr_define(u8, false)
Autoarr_define(i8) Autoarr_define(i8, false)
Autoarr_define(u16) Autoarr_define(u16, false)
Autoarr_define(i16) Autoarr_define(i16, false)
Autoarr_define(u32) Autoarr_define(u32, false)
Autoarr_define(i32) Autoarr_define(i32, false)
Autoarr_define(u64) Autoarr_define(u64, false)
Autoarr_define(i64) Autoarr_define(i64, false)
Autoarr_define(Unitype) Autoarr_define(Unitype, false)

View File

@@ -23,6 +23,21 @@ Autoarr_declare(u64)
Autoarr_declare(Unitype) Autoarr_declare(Unitype)
#define Autoarr_foreach(ar, elem, codeblock...) { \
if(ar->blocks_count>0) { \
typeof(**ar->values) elem; \
for(u16 blockI=0;blockI<ar->blocks_count-1;blockI++) \
for(u32 elemI=0;elemI<ar->max_block_length;elemI++){ \
elem=ar->values[blockI][elemI]; \
{ codeblock; } \
} \
for(u16 elemI=0;elemI<ar->block_length;elemI++){ \
elem=ar->values[ar->blocks_count-1][elemI]; \
{ codeblock; } \
} \
} \
}
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -0,0 +1,38 @@
#if __cplusplus
extern "C" {
#endif
#include "Autoarr.h"
#include "../Hashtable/KeyValuePair.h"
EXPORT void CALL kerep_Autoarr_KVPair_create(u16 max_blocks_count, u16 max_block_length, Autoarr_KVPair** output){
*output=Autoarr_create(KVPair, max_blocks_count, max_block_length);
}
EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){
Autoarr_free(ar, true);
}
EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, u32 index, KVPair* output){
*output=Autoarr_get(ar, index);
}
EXPORT void CALL kerep_Autoarr_KVPair_add(Autoarr_KVPair* ar, KVPair element){
Autoarr_add(ar, element);
}
EXPORT void CALL kerep_Autoarr_KVPair_set(Autoarr_KVPair* ar, u32 index, KVPair element){
Autoarr_set(ar, index, element);
}
EXPORT void CALL kerep_Autoarr_KVPair_length(Autoarr_KVPair* ar, u32* output){
*output=Autoarr_length(ar);
}
EXPORT void CALL kerep_Autoarr_KVPair_max_length(Autoarr_KVPair* ar, u32* output){
*output=Autoarr_max_length(ar);
}
#if __cplusplus
}
#endif

View File

@@ -4,12 +4,12 @@ extern "C" {
#include "Autoarr.h" #include "Autoarr.h"
EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_chunks_count, u16 max_chunk_length, Autoarr_Unitype** output){ EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_blocks_count, u16 max_block_length, Autoarr_Unitype** output){
*output=Autoarr_construct(Unitype, max_chunks_count, max_chunk_length); *output=Autoarr_create(Unitype, max_blocks_count, max_block_length);
} }
EXPORT void CALL kerep_Autoarr_Unitype_destruct(Autoarr_Unitype* ar){ EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){
Autoarr_destruct(ar, true); Autoarr_free(ar, true);
} }
EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, u32 index, Unitype* output){ EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, u32 index, Unitype* output){
@@ -34,4 +34,4 @@ EXPORT void CALL kerep_Autoarr_Unitype_max_length(Autoarr_Unitype* ar, u32* outp
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -6,62 +6,69 @@ extern "C" {
#include "../base/base.h" #include "../base/base.h"
#define Autoarr_declare(TYPE) \ #define Autoarr_declare(type) \
\ \
typedef struct Autoarr_##TYPE Autoarr_##TYPE; \ struct Autoarr_##type; \
\ \
typedef struct __Autoarr_##TYPE##_functions_list_t { \ typedef struct __Autoarr_##type##_functions_list_t { \
void (*add)(Autoarr_##TYPE* ar, TYPE element); \ void (*add)(struct Autoarr_##type* ar, type element); \
TYPE (*get)(Autoarr_##TYPE* ar, u32 index); \ type (*get)(struct Autoarr_##type* ar, u32 index); \
TYPE* (*getPtr)(Autoarr_##TYPE* ar, u32 index); \ type* (*getPtr)(struct Autoarr_##type* ar, u32 index); \
void (*set)(Autoarr_##TYPE* ar, u32 index, TYPE element); \ void (*set)(struct Autoarr_##type* ar, u32 index, type element); \
TYPE* (*toArray)(Autoarr_##TYPE* ar, allocator_ptr array_holder); \ void (*freeWithMembers)(struct Autoarr_##type* ar, bool freePtr); \
} __Autoarr_##TYPE##_functions_list_t; \ void (*freeWithoutMembers)(struct Autoarr_##type* ar, bool freePtr); \
type* (*toArray)(struct Autoarr_##type* ar); \
} __Autoarr_##type##_functions_list_t; \
\ \
STRUCT(Autoarr_##TYPE, \ extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \
InternalAllocator_declare(LinearAllocator); \ \
__Autoarr_##TYPE##_functions_list_t* functions; \ STRUCT(Autoarr_##type, \
ktDescriptor* type; \ u16 blocks_count; \
u32 length; \ u16 max_blocks_count; \
TYPE* _typeof_target; \ u16 block_length; \
u16 max_block_length; \
type** values; \
__Autoarr_##type##_functions_list_t* functions; \
) \ ) \
\ \
void __Autoarr_##TYPE##_construct(Autoarr_##TYPE* ar, alloc_size_t starting_size, allocator_ptr external_al); \ Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length); \
void __Autoarr_##TYPE##_destruct(Autoarr_##TYPE* ar); \ void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr); \
void ____Autoarr_##type##_freeWithMembers(void* ar);
#define Autoarr(TYPE) Autoarr_##TYPE #define Autoarr(type) Autoarr_##type
#define Autoarr_construct(ptr, TYPE, starting_size, data_allocator) \ #define Autoarr_create(type, max_blocks_count, max_block_length) \
__Autoarr_##TYPE##_construct(ptr, starting_size, data_allocator) __Autoarr_##type##_create(max_blocks_count, max_block_length)
#define Autoarr_destruct(autoarr) (autoarr)->type->destruct(autoarr) #define Autoarr_add(autoarr, element) \
#define Autoarr_add(autoarr, element) (autoarr)->functions->add(autoarr, element) autoarr->functions->add(autoarr, element)
#define Autoarr_get(autoarr, index) (autoarr)->functions->get(autoarr,index) #define Autoarr_get(autoarr, index) \
#define Autoarr_getPtr(autoarr, index) (autoarr)->functions->getPtr(autoarr,index) autoarr->functions->get(autoarr,index)
#define Autoarr_set(autoarr, index, element) (autoarr)->functions->set(autoarr, index, element) #define Autoarr_getPtr(autoarr, index) \
#define Autoarr_toArray(autoarr, array_alloctr) (autoarr)->functions->toArray(autoarr, array_alloctr) autoarr->functions->getPtr(autoarr,index)
#define Autoarr_length(autoarr) (autoarr)->length #define Autoarr_set(autoarr, index, element) \
#define Autoarr_pop(autoarr) { \ autoarr->functions->set(autoarr, index, element)
u32 new_len=(autoarr)->length-1; \ #define Autoarr_free(autoarr, freePtr) \
allocator_free(InternalAllocator_getPtr((autoarr)), Autoarr_getPtr((autoarr), new_len)); \ autoarr->functions->freeWithMembers(autoarr, freePtr)
(autoarr)->length=new_len; \ #define Autoarr_freeWithoutMembers(autoarr, freePtr) \
} autoarr->functions->freeWithoutMembers(autoarr, freePtr)
#define Autoarr_toArray(autoarr) \
autoarr->functions->toArray(autoarr)
#define Autoarr_foreach(ar, elem, codeblock...) { \ #define Autoarr_length(autoarr) \
if((ar)->length > 0) { \ (u32)(!autoarr->blocks_count ? 0 : \
typeof(*((ar)->_typeof_target)) elem; \ autoarr->max_block_length*(autoarr->blocks_count-1)+autoarr->block_length)
LinearAllocator* al=(LinearAllocator*)InternalAllocator_getPtr(ar); \ #define Autoarr_max_length(autoarr) \
for(u16 chunk_i=0; chunk_i <= al->curr_chunk_i; chunk_i++) { \ (u32)(autoarr->max_block_length*autoarr->max_blocks_count)
MemoryChunk chunk = al->chunks[chunk_i]; \
alloc_size_t chunk_elem_count = chunk.occupied_size/sizeof(elem); \ #define Autoarr_pop(AR){ \
typeof((ar)->_typeof_target) chunk_data = (void*)chunk.data; \ if(AR->block_length==1){ \
for(u32 elem##_i=0; elem##_i < chunk_elem_count; elem##_i++) { \ AR->blocks_count--; \
elem = chunk_data[elem##_i]; \ AR->block_length=AR->max_block_length; \
{ codeblock; } \ free(AR->values[AR->blocks_count]); \
} \
} \
} \ } \
else AR->block_length--; \
} }
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -6,73 +6,95 @@ extern "C" {
#include "../base/base.h" #include "../base/base.h"
#define Autoarr_define(TYPE) \ #define Autoarr_define(type, TYPE_IS_PTR) \
\ \
void __Autoarr_##TYPE##_add(Autoarr_##TYPE* ar, TYPE element){ \ kt_define(Autoarr_##type, ____Autoarr_##type##_freeWithMembers, NULL); \
TYPE* ptr = allocator_alloc(InternalAllocator_getPtr(ar), sizeof(element)); \
*ptr=element; \
ar->length++; \
} \
\ \
TYPE* __Autoarr_##TYPE##_getPtr(Autoarr_##TYPE* ar, u32 index){ \ void __Autoarr_##type##_add(Autoarr_##type* ar, type element){ \
if(index >= Autoarr_length(ar)) \ if(!ar->values){ \
throw(ERR_WRONGINDEX); \ ar->values=malloc(ar->max_blocks_count*sizeof(type*)); \
u32 elem_count_sum=0; \ goto create_block; \
LinearAllocator* al=(LinearAllocator*)InternalAllocator_getPtr(ar); \
for(u16 chunk_i=0; chunk_i <= al->curr_chunk_i; chunk_i++) { \
MemoryChunk chunk = al->chunks[chunk_i]; \
alloc_size_t chunk_elem_count = chunk.occupied_size/sizeof(TYPE); \
alloc_size_t chunk_elem_i = index - elem_count_sum; \
if(chunk_elem_i < chunk_elem_count){ \
return chunk.data + chunk_elem_i*sizeof(TYPE); \
} \
elem_count_sum += chunk_elem_count; \
} \ } \
return NULL; \ if(ar->block_length==ar->max_block_length){ \
if (ar->blocks_count>=ar->max_blocks_count) throw(ERR_MAXLENGTH); \
ar->block_length=0; \
create_block: \
ar->values[ar->blocks_count]=malloc(ar->max_block_length*sizeof(type)); \
ar->blocks_count++; \
} \
ar->values[ar->blocks_count-1][ar->block_length]=element; \
ar->block_length++; \
} \ } \
\ \
TYPE __Autoarr_##TYPE##_get(Autoarr_##TYPE* ar, u32 index){ \ type __Autoarr_##type##_get(Autoarr_##type* ar, u32 index){ \
TYPE* ptr=__Autoarr_##TYPE##_getPtr(ar, index); \ if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
return *ptr; \ return ar->values[index/ar->max_block_length][index%ar->max_block_length]; \
} \ } \
\ \
void __Autoarr_##TYPE##_set(Autoarr_##TYPE* ar, u32 index, TYPE value){ \ type* __Autoarr_##type##_getPtr(Autoarr_##type* ar, u32 index){ \
TYPE* ptr=__Autoarr_##TYPE##_getPtr(ar, index); \ if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
*ptr=value; \ return ar->values[index/ar->max_block_length]+(index%ar->max_block_length); \
} \ } \
\ \
void __Autoarr_##TYPE##_destruct(Autoarr_##TYPE* ar){ \ void __Autoarr_##type##_set(Autoarr_##type* ar, u32 index, type element){ \
InternalAllocator_destructIfInternal(LinearAllocator, ar); \ if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
ar->values[index/ar->max_block_length][index%ar->max_block_length]=element; \
} \ } \
\ \
TYPE* __Autoarr_##TYPE##_toArray(Autoarr_##TYPE* ar, allocator_ptr array_alloctr){ \ void __Autoarr_##type##_freeWithoutMembers(Autoarr_##type* ar, bool freePtr){ \
for(u16 i=0; i<ar->blocks_count;i++) \
free(ar->values[i]); \
free(ar->values); \
if(freePtr) free(ar); \
} \
\
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr){ \
if(ktDescriptor_##type.freeMembers!=NULL) { \
Autoarr_foreach(ar, el, \
void* members_ptr=&el; \
if(TYPE_IS_PTR) members_ptr=*(type**)members_ptr; \
ktDescriptor_##type.freeMembers(members_ptr); \
); \
} \
__Autoarr_##type##_freeWithoutMembers(ar, freePtr);\
} \
void ____Autoarr_##type##_freeWithMembers(void* ar){ \
__Autoarr_##type##_freeWithMembers((Autoarr_##type*)ar, false); \
} \
\
type* __Autoarr_##type##_toArray(Autoarr_##type* ar){ \
u32 length=Autoarr_length(ar); \ u32 length=Autoarr_length(ar); \
if(length==0) \ if(length==0) \
return NULL; \ return NULL; \
TYPE* array=allocator_alloc(array_alloctr, length); \ type* array=malloc(length * sizeof(type)); \
Autoarr_foreach(ar, el, { \ for(u32 i=0; i<length; i++) \
array[el_i]=el; \ array[i]=__Autoarr_##type##_get(ar, i); \
}); \
return array; \ return array; \
} \ } \
\ \
__Autoarr_##TYPE##_functions_list_t __Autoarr_##TYPE##_functions_list={ \ __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list={ \
&__Autoarr_##TYPE##_add, \ &__Autoarr_##type##_add, \
&__Autoarr_##TYPE##_get, \ &__Autoarr_##type##_get, \
&__Autoarr_##TYPE##_getPtr, \ &__Autoarr_##type##_getPtr, \
&__Autoarr_##TYPE##_set, \ &__Autoarr_##type##_set, \
&__Autoarr_##TYPE##_toArray \ &__Autoarr_##type##_freeWithMembers, \
&__Autoarr_##type##_freeWithoutMembers, \
&__Autoarr_##type##_toArray \
}; \ }; \
\ \
void __Autoarr_##TYPE##_construct(Autoarr_##TYPE* ar, alloc_size_t starting_size, allocator_ptr data_allocator){ \ Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length){ \
InternalAllocator_setExternalOrConstruct(ar, data_allocator, LinearAllocator, starting_size); \ Autoarr_##type* ar=malloc(sizeof(Autoarr_##type)); \
ar->functions=&__Autoarr_##TYPE##_functions_list; \ *ar=(Autoarr_##type){ \
ar->type = &ktDescriptor_name(TYPE); \ .max_blocks_count=max_blocks_count, \
ar->length=0; \ .blocks_count=0, \
} \ .max_block_length=max_block_length, \
\ .block_length=0, \
kt_define(Autoarr_##TYPE, (destruct_t)__Autoarr_##TYPE##_destruct, NULL); .values=NULL, \
.functions=&__Autoarr_##type##_functions_list \
}; \
return ar; \
}
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -25,6 +25,6 @@ bool DtsodV24_remove(Hashtable* dtsod, char* key){
} }
// frees memory including memory of elements (hashtables, autoarrs, etc.) // frees memory including memory of elements (hashtables, autoarrs, etc.)
void DtsodV24_destruct(Hashtable* dtsod){ void DtsodV24_free(Hashtable* dtsod){
Hashtable_destruct(dtsod); Hashtable_free(dtsod);
} }

View File

@@ -25,8 +25,8 @@ bool DtsodV24_contains(Hashtable* dtsod, char* key);
bool DtsodV24_remove(Hashtable* dtsod, char* key); bool DtsodV24_remove(Hashtable* dtsod, char* key);
// frees memory including memory of elements (hashtables, autoarrs, etc.) // frees memory including memory of elements (hashtables, autoarrs, etc.)
void DtsodV24_destruct(Hashtable* dtsod); void DtsodV24_free(Hashtable* dtsod);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,7 +1,8 @@
#include "DtsodV24.h" #include "DtsodV24.h"
#include "../String/StringBuilder.h" #include "../String/StringBuilder.h"
#define ARR_SZ_START 64 #define ARR_BC 64
#define ARR_BL 1024
typedef struct DeserializeSharedData{ typedef struct DeserializeSharedData{
@@ -9,13 +10,11 @@ typedef struct DeserializeSharedData{
char* sh_text; char* sh_text;
bool sh_partOfDollarList; bool sh_partOfDollarList;
bool sh_calledRecursively; bool sh_calledRecursively;
allocator_ptr sh_tmp_al;
} DeserializeSharedData; } DeserializeSharedData;
#define text shared->sh_text #define text shared->sh_text
#define partOfDollarList shared->sh_partOfDollarList #define partOfDollarList shared->sh_partOfDollarList
#define calledRecursively shared->sh_calledRecursively #define calledRecursively shared->sh_calledRecursively
#define tmp_al shared->sh_tmp_al
// special func for throwing error messages about wrong characters in deserializing text // special func for throwing error messages about wrong characters in deserializing text
@@ -45,9 +44,9 @@ Maybe ERROR_WRONGCHAR(const char c, char* _text, char* text_first, const char* s
if(!_c) break; if(!_c) break;
} }
char errmsg[1024]; char errmsg[1024];
sprintf_s(errmsg, sizeof(errmsg), "unexpected <%c> at:\n" ksprintf(errmsg,1024, "unexpected <%c> at:\n"
" \"%s\"\n" " \"%s\"\n"
"\\___[%s:%d] %s()", "\\___[%s:%d] %s()",
c,errBuf, srcfile,line,funcname); c,errBuf, srcfile,line,funcname);
safethrow(errmsg,;); safethrow(errmsg,;);
} }
@@ -91,11 +90,11 @@ Maybe __ReadName(DeserializeSharedData* shared){
nameStr.ptr=text+1; // skips '\n' nameStr.ptr=text+1; // skips '\n'
break; break;
case '}': case '}':
if(!calledRecursively || nameStr.length!=0) if(!calledRecursively || nameStr.length!=0)
safethrow_wrongchar(c,;); safethrow_wrongchar(c,;);
return SUCCESS(UniHeapPtr(char,NULL)); return SUCCESS(UniHeapPtr(char,NULL));
case ':': case ':':
return SUCCESS(UniHeapPtr(char,string_extract(tmp_al, nameStr))); return SUCCESS(UniHeapPtr(char,string_extract(nameStr)));
case '$': case '$':
if(nameStr.length!=0) if(nameStr.length!=0)
safethrow_wrongchar(c,;); safethrow_wrongchar(c,;);
@@ -112,7 +111,7 @@ Maybe __ReadName(DeserializeSharedData* shared){
} }
#define ReadName() __ReadName(shared) #define ReadName() __ReadName(shared)
Maybe __deserialize(char** _text, bool _calledRecursively, allocator_ptr _tmp_al); Maybe __deserialize(char** _text, bool _calledRecursively);
Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList); Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList);
#define ReadValue(rL) __ReadValue(shared, rL) #define ReadValue(rL) __ReadValue(shared, rL)
@@ -120,15 +119,13 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList);
Maybe __ReadString(DeserializeSharedData* shared){ Maybe __ReadString(DeserializeSharedData* shared){
char c; char c;
bool prevIsBackslash=false; bool prevIsBackslash=false;
StringBuilder _sb; StringBuilder* b=StringBuilder_create();
StringBuilder* b=&_sb;
StringBuilder_construct(b, tmp_al);
while ((c=*++text)){ while ((c=*++text)){
if(c=='"') { if(c=='"') {
if(prevIsBackslash) { if(prevIsBackslash) {
// replacing <\"> with <"> // replacing <\"> with <">
StringBuilder_rmchar(b); StringBuilder_rmchar(b);
StringBuilder_append_char(b,c); StringBuilder_append_char(b,c);
prevIsBackslash=false; prevIsBackslash=false;
} }
@@ -136,32 +133,31 @@ Maybe __ReadString(DeserializeSharedData* shared){
char* str=StringBuilder_build(b).ptr; char* str=StringBuilder_build(b).ptr;
return SUCCESS(UniHeapPtr(char,str)); return SUCCESS(UniHeapPtr(char,str));
} }
} }
else { else {
prevIsBackslash= c=='\\' && !prevIsBackslash; prevIsBackslash= c=='\\' && !prevIsBackslash;
StringBuilder_append_char(b,c); StringBuilder_append_char(b,c);
} }
} }
safethrow(ERR_ENDOFSTR, StringBuilder_destruct(b)); safethrow(ERR_ENDOFSTR, StringBuilder_free(b));
} }
#define ReadString() __ReadString(shared) #define ReadString() __ReadString(shared)
Maybe __ReadList(DeserializeSharedData* shared){ Maybe __ReadList(DeserializeSharedData* shared){
Autoarr(Unitype) list; Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
Autoarr_construct(&list, Unitype, ARR_SZ_START, NULL);
bool readingList=true; bool readingList=true;
while (true){ while (true){
try(ReadValue((&readingList)), m_val, Autoarr_destruct(&list)) try(ReadValue((&readingList)), m_val, Autoarr_free(list, true))
Autoarr_add(&list, m_val.value); Autoarr_add(list,m_val.value);
if (!readingList){ if (!readingList){
if(Unitype_isUniNull(m_val.value)) if(Unitype_isUniNull(m_val.value))
Autoarr_pop(&list); Autoarr_pop(list);
break; break;
} }
} }
return SUCCESS(UniHeapPtr(Autoarr_Unitype, &list)); return SUCCESS(UniHeapPtr(Autoarr_Unitype,list));
}; };
#define ReadList() __ReadList(shared) #define ReadList() __ReadList(shared)
@@ -179,34 +175,34 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
else safethrow_wrongchar(*str.ptr,;); else safethrow_wrongchar(*str.ptr,;);
// Float64 // Float64
case 'f': { case 'f': {
char* _c=string_extract(tmp_al, str); char* _c=string_extract(str);
Unitype rez=UniFloat64(strtod(_c,NULL)); Unitype rez=UniFloat64(strtod(_c,NULL));
// allocator_free(tmp_al,_c); free(_c);
return SUCCESS(rez); return SUCCESS(rez);
} }
// UInt64 // UInt64
case 'u': { case 'u': {
u64 lu=0; u64 lu=0;
char* _c=string_extract(tmp_al, str); char* _c=string_extract(str);
if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){ if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){
char err[64]; char err[64];
sprintf_s(err, sizeof(err), "can't parse to int: <%s>", _c); ksprintf(err,64,"can't parse to int: <%s>",_c);
safethrow(err, /*allocator_free(tmp_al, _c)*/); safethrow(err,free(_c));
} }
// allocator_free(tmp_al, _c); free(_c);
return SUCCESS(UniUInt64(lu)); return SUCCESS(UniUInt64(lu));
} }
// Int64 // Int64
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': { case '5': case '6': case '7': case '8': case '9': {
i64 li=0; i64 li=0;
char* _c=string_extract(tmp_al, str); char* _c=string_extract(str);
if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){ if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){
char err[64]; char err[64];
sprintf_s(err, sizeof(err),"can't parse to int: <%s>",_c); ksprintf(err,64,"can't parse to int: <%s>",_c);
// safethrow(err,allocator_free(tmp_al, _c)); safethrow(err,free(_c));
} }
// allocator_free(tmp_al, _c); free(_c);
return SUCCESS(UniInt64(li)); return SUCCESS(UniInt64(li));
} }
// wrong type // wrong type
@@ -231,53 +227,53 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
spaceAfterVal=true; spaceAfterVal=true;
else valueStr.ptr++; else valueStr.ptr++;
break; break;
case '=': case ':': case '=': case ':':
case '}': case '$': case '}': case '$':
case '\'': case '\'':
safethrow_wrongchar(c,Unitype_destruct(&value)); safethrow_wrongchar(c,Unitype_free(value));
case '#':; case '#':;
char _c=c; char _c=c;
char* _text=text; char* _text=text;
try(SkipComment(),_,;); try(SkipComment(),_,;);
if(valueStr.length!=0){ if(valueStr.length!=0){
text=_text; text=_text;
safethrow_wrongchar(_c,Unitype_destruct(&value)); safethrow_wrongchar(_c,Unitype_free(value));
} }
valueStr.ptr=text+1; // skips '\n' valueStr.ptr=text+1; // skips '\n'
break; break;
case '"': case '"':
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_destruct(&value)); if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value));
try(ReadString(),maybeString,;) try(ReadString(),maybeString,;)
value=maybeString.value; value=maybeString.value;
break; break;
case '{': case '{':
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_destruct(&value)); if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value));
++text; // skips '{' ++text; // skips '{'
try(__deserialize(&text,true,tmp_al), val, Unitype_destruct(&value)) try(__deserialize(&text,true), val,Unitype_free(value))
value=val.value; value=val.value;
break; break;
case '[': case '[':
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_destruct(&value)); if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value));
try(ReadList(),maybeList,Unitype_destruct(&value)) try(ReadList(),maybeList,Unitype_free(value))
value=maybeList.value; value=maybeList.value;
break; break;
case ']': case ']':
if(!readingList) safethrow_wrongchar(c,Unitype_destruct(&value)); if(!readingList) safethrow_wrongchar(c,Unitype_free(value));
*readingList=false; *readingList=false;
goto return_value; goto return_value;
case ';': case ';':
case ',': case ',':
return_value: return_value:
if(valueStr.length!=0){ if(valueStr.length!=0){
if(!Unitype_isUniNull(value)) if(!Unitype_isUniNull(value))
safethrow_wrongchar(c,Unitype_destruct(&value)); safethrow_wrongchar(c,Unitype_free(value));
try(ParseValue(valueStr),maybeParsed,;) try(ParseValue(valueStr),maybeParsed,;)
value=maybeParsed.value; value=maybeParsed.value;
} }
return SUCCESS(value); return SUCCESS(value);
default: default:
if(spaceAfterVal) if(spaceAfterVal)
safethrow_wrongchar(c,Unitype_destruct(&value)); safethrow_wrongchar(c,Unitype_free(value));
valueStr.length++; valueStr.length++;
break; break;
} }
@@ -286,29 +282,25 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
} }
Maybe __deserialize(char** _text, bool _calledRecursively, allocator_ptr _tmp_al) { Maybe __deserialize(char** _text, bool _calledRecursively) {
DeserializeSharedData _shared={ DeserializeSharedData _shared={
.sh_text_first=*_text, .sh_text_first=*_text,
.sh_text=*_text, .sh_text=*_text,
.sh_partOfDollarList=false, .sh_partOfDollarList=false,
.sh_calledRecursively=_calledRecursively, .sh_calledRecursively=_calledRecursively
.sh_tmp_al=_tmp_al
}; };
DeserializeSharedData* shared=&_shared; DeserializeSharedData* shared=&_shared;
Hashtable _dict; Hashtable* dict=Hashtable_create();
Hashtable* dict = &_dict;
Hashtable_construct(dict, _tmp_al);
text--; text--;
while(true){ while(true){
try(ReadName(), maybeName, Hashtable_destruct(dict)) try(ReadName(), maybeName, Hashtable_free(dict))
if(!maybeName.value.VoidPtr) // end of file or '}' in recursive call if(!maybeName.value.VoidPtr) // end of file or '}' in recursive call
goto END; goto END;
char* nameCPtr=maybeName.value.VoidPtr; char* nameCPtr=maybeName.value.VoidPtr;
try(ReadValue(NULL), val, { try(ReadValue(NULL), val, {
Hashtable_destruct(dict); Hashtable_free(dict);
// do not use, free call order is incorrect free(nameCPtr);
// allocator_free(tmp_al, nameCPtr);
}) { }) {
if(partOfDollarList){ if(partOfDollarList){
partOfDollarList=false; partOfDollarList=false;
@@ -318,12 +310,10 @@ Maybe __deserialize(char** _text, bool _calledRecursively, allocator_ptr _tmp_al
list=(Autoarr(Unitype)*)lu.VoidPtr; list=(Autoarr(Unitype)*)lu.VoidPtr;
// Key is not used in that case, because it is already added // Key is not used in that case, because it is already added
// to the table with the first dollar list item. // to the table with the first dollar list item.
// do not use, free call order is incorrect free(nameCPtr);
// allocator_free(tmp_al, nameCPtr);
} }
else{ else{
list=allocator_alloc(tmp_al, sizeof(*list)); list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
Autoarr_construct(list, Unitype, ARR_SZ_START, NULL);
Hashtable_add(dict,nameCPtr,UniHeapPtr(Autoarr_Unitype,list)); Hashtable_add(dict,nameCPtr,UniHeapPtr(Autoarr_Unitype,list));
} }
Autoarr_add(list,val.value); Autoarr_add(list,val.value);
@@ -338,9 +328,5 @@ Maybe __deserialize(char** _text, bool _calledRecursively, allocator_ptr _tmp_al
} }
Maybe DtsodV24_deserialize(char* _text) { Maybe DtsodV24_deserialize(char* _text) {
LinearAllocator _tmp_al; return __deserialize(&_text, false);
LinearAllocator_construct(&_tmp_al, 1024);
Maybe m=__deserialize(&_text, false, (allocator_ptr)&_tmp_al);
LinearAllocator_destruct(&_tmp_al);
return m;
} }

View File

@@ -0,0 +1,62 @@
//
// I planned to export functions from DtsodV24.h,
// but C# P/Invoke can't get returned values for some reason.
// Following functions return values by pointer, which looks in C# like out parameter
//
#if __cplusplus
extern "C" {
#endif
#include "DtsodV24.h"
// parses text to binary values
EXPORT void CALL kerep_DtsodV24_deserialize(char* text, Hashtable** output, char** errmsg){
Maybe r=DtsodV24_deserialize(text);
*errmsg=r.errmsg;
*output=r.value.VoidPtr;
}
// creates text representation of dtsod
EXPORT void CALL kerep_DtsodV24_serialize(Hashtable* dtsod, char** output, char** errmsg){
Maybe r=DtsodV24_serialize(dtsod);
*errmsg=r.errmsg;
*output=r.value.VoidPtr;
}
// returns value or UniNull if key not found
EXPORT void CALL kerep_DtsodV24_get(Hashtable* dtsod, char* key, Unitype* output){
*output=DtsodV24_get(dtsod, key);
}
// adds or sets the value
EXPORT void CALL kerep_DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value){
DtsodV24_addOrSet(dtsod, key, value);
}
// checks for dtsod contains value or dont
EXPORT void CALL kerep_DtsodV24_contains(Hashtable* dtsod, char* key, bool* output){
*output=DtsodV24_contains(dtsod, key);
}
// replaces value with UniNull if key exists in dtsod
EXPORT void CALL kerep_DtsodV24_remove(Hashtable* dtsod, char* key, bool* output){
*output=DtsodV24_remove(dtsod, key);
}
// replaces value with UniNull if key exists in dtsod
EXPORT void CALL kerep_DtsodV24_free(Hashtable* dtsod){
DtsodV24_free(dtsod);
}
EXPORT void CALL kerep_DtsodV24_height(Hashtable* dtsod, u16* heigth){
*heigth=Hashtable_height(dtsod);
}
EXPORT void CALL kerep_DtsodV24_getrow(Hashtable* dtsod, u16 h, Autoarr_KVPair** row){
*row=dtsod->rows[h];
}
#if __cplusplus
}
#endif

View File

@@ -3,7 +3,7 @@
STRUCT(SerializeSharedData, STRUCT(SerializeSharedData,
StringBuilder* sh_builder; StringBuilder* sh_builder;
u8 sh_tabs; u8 sh_tabs;
) )
#define b shared->sh_builder #define b shared->sh_builder
@@ -55,7 +55,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
AppendTabs(); AppendTabs();
addc('['); addc('[');
tabs++; tabs++;
Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e,
addc('\n'); addc('\n');
AppendTabs(); AppendTabs();
try(AppendValue(e),__,;); try(AppendValue(e),__,;);
@@ -75,7 +75,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
else if(u.typeId==ktid_ptrName(Hashtable)){ else if(u.typeId==ktid_ptrName(Hashtable)){
// check hashtable is blank // check hashtable is blank
bool hashtableNotBlank=false; bool hashtableNotBlank=false;
Hashtable_foreach(((Hashtable*)u.VoidPtr), __, Hashtable_foreach(((Hashtable*)u.VoidPtr), __,
hashtableNotBlank=true; hashtableNotBlank=true;
if(__.key) {} // weird way to disable warning if(__.key) {} // weird way to disable warning
break; break;
@@ -96,7 +96,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
} }
} }
else { else {
dbg((u.typeId)); dbg((u.typeId));
safethrow(ERR_WRONGTYPE,;); safethrow(ERR_WRONGTYPE,;);
} }
return MaybeNull; return MaybeNull;
@@ -109,7 +109,7 @@ Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod){
}; };
SerializeSharedData* shared=&_shared; SerializeSharedData* shared=&_shared;
Hashtable_foreach(dtsod, p, Hashtable_foreach(dtsod, p,
AppendTabs(); AppendTabs();
StringBuilder_append_cptr(b,p.key); StringBuilder_append_cptr(b,p.key);
addc(':'); addc(':');
@@ -123,13 +123,8 @@ Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod){
} }
Maybe DtsodV24_serialize(Hashtable* dtsod){ Maybe DtsodV24_serialize(Hashtable* dtsod){
LinearAllocator _al; allocator_ptr al=(allocator_ptr)&_al; StringBuilder* sb=StringBuilder_create();
LinearAllocator_construct(&_al, 512); try(__serialize(sb,0,dtsod),__, StringBuilder_free(sb));
StringBuilder _sb;
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, al);
try(__serialize(sb,0,dtsod),__, StringBuilder_destruct(sb); LinearAllocator_destruct(&_al););
char* str=StringBuilder_build(sb).ptr; char* str=StringBuilder_build(sb).ptr;
LinearAllocator_destruct(&_al);
return SUCCESS(UniHeapPtr(char, str)); return SUCCESS(UniHeapPtr(char, str));
} }

View File

@@ -4,7 +4,7 @@
bool dir_exists(const char* path){ bool dir_exists(const char* path){
if(path[0]=='.'){ if(path[0]=='.'){
if(path[1]==0 || (path[1]==path_sep && path[1]==0)) if(path[1]==0 || (path[1]==path_sep && path[1]==0))
return true; // dir . or ./ always exists return true; // dir . or ./ always exists
// else if(path[1]=='.' && path[2]==path_sep) // else if(path[1]=='.' && path[2]==path_sep)
//TODO path_resolve because windows doesnt recognize .\ pattern //TODO path_resolve because windows doesnt recognize .\ pattern
@@ -26,10 +26,9 @@ bool dir_exists(const char* path){
Maybe dir_create(const char* path){ Maybe dir_create(const char* path){
if (dir_exists(path)) if (dir_exists(path))
return MaybeNull; return MaybeNull;
LinearAllocator _al; LinearAllocator_construct(&_al, 128); char* parentDir=path_parentDir(path);
allocator_ptr al=&_al.base;
char* parentDir=path_parentDir(al, path);
dir_create(parentDir); dir_create(parentDir);
free(parentDir);
#if KFS_USE_WINDOWS_H #if KFS_USE_WINDOWS_H
if(!CreateDirectory(path, NULL)) if(!CreateDirectory(path, NULL))
#else #else
@@ -37,10 +36,10 @@ Maybe dir_create(const char* path){
#endif #endif
{ {
char err[512]; char err[512];
sprintf_s(err, sizeof(err), "can't create dicectory <%s>", path); ksprintf(err, 512, "can't create dicectory <%s>", path);
safethrow(err, LinearAllocator_destruct(&_al)); safethrow(err,;);
} }
LinearAllocator_destruct(&_al);
return MaybeNull; return MaybeNull;
} }

View File

@@ -25,4 +25,4 @@ Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -2,9 +2,9 @@
#include "../String/StringBuilder.h" #include "../String/StringBuilder.h"
#include "io_includes.h" #include "io_includes.h"
void __file_destructMembers(void* _f){ fclose((FileHandle)_f); } void __file_freeMembers(void* _f){ fclose((FileHandle)_f); }
kt_define(FileHandle, __file_destructMembers, NULL) kt_define(FileHandle, __file_freeMembers, NULL)
bool file_exists(const char* path){ bool file_exists(const char* path){
if(path[0]=='.'){ if(path[0]=='.'){
@@ -50,11 +50,8 @@ char* FileOpenMode_toStr(FileOpenMode m){
Maybe file_open(const char* path, FileOpenMode mode){ Maybe file_open(const char* path, FileOpenMode mode){
FileHandle file=fopen(path, FileOpenMode_toStr(mode)); FileHandle file=fopen(path, FileOpenMode_toStr(mode));
LinearAllocator _al; LinearAllocator_construct(&_al, 128);
allocator_ptr al=&_al.base;
if(!file) if(!file)
safethrow(cptr_concat(al, "can't open file ", (char*)path), LinearAllocator_destruct(&_al)); safethrow(cptr_concat("can't open file ", (char*)path),;);
LinearAllocator_destruct(&_al);
return SUCCESS(UniHeapPtr(FileHandle,file)); return SUCCESS(UniHeapPtr(FileHandle,file));
} }
@@ -67,66 +64,64 @@ Maybe file_close(FileHandle file){
} }
#define ioWriteCheck() \ #define ioWriteCheck() \
if(rezult==EOF) \ if(result==EOF) \
safethrow(ERR_IO_EOF,;); \ safethrow(ERR_IO_EOF,;); \
if(rezult!=0) \ if(result!=0) \
safethrow(ERR_IO,;); safethrow(ERR_IO,;);
Maybe file_writeChar(FileHandle file, char byte){ Maybe file_writeChar(FileHandle file, char byte){
i32 rezult=fputc(byte, file); i32 result=fputc(byte, file);
ioWriteCheck(); ioWriteCheck();
return MaybeNull; return MaybeNull;
} }
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length){ Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length){
i32 rezult=0; i32 result=0;
for(u64 i=0; i<length && !rezult; i++) for(u64 i=0; i<length && !result; i++)
rezult=fputc(buffer[i], file); result=fputc(buffer[i], file);
ioWriteCheck(); ioWriteCheck();
return MaybeNull; return MaybeNull;
} }
Maybe file_writeCptr(FileHandle file, char* cptr){ Maybe file_writeCptr(FileHandle file, char* cptr){
i32 rezult=fputs(cptr, file); i32 result=fputs(cptr, file);
ioWriteCheck(); ioWriteCheck();
return MaybeNull; return MaybeNull;
} }
Maybe file_readChar(FileHandle file){ Maybe file_readChar(FileHandle file){
i32 rezult=fgetc(file); i32 result=fgetc(file);
if(feof(file)) safethrow(ERR_IO_EOF,;); if(feof(file)) safethrow(ERR_IO_EOF,;);
if(ferror(file)) safethrow(ERR_IO,;); if(ferror(file)) safethrow(ERR_IO,;);
return SUCCESS(UniUInt64(rezult)); return SUCCESS(UniUInt64(result));
} }
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length){ Maybe file_readBuffer(FileHandle file, char* buffer, u64 length){
i32 rezult=0; i32 result=0;
u64 i=0; u64 i=0;
for(; i<length && rezult!=EOF; i++){ for(; i<length && result!=EOF; i++){
rezult=fgetc(file); result=fgetc(file);
buffer[i]=(char)rezult; buffer[i]=(char)result;
} }
if(ferror(file)) safethrow(ERR_IO,;); if(ferror(file)) safethrow(ERR_IO,;);
return SUCCESS(UniUInt64(i)); return SUCCESS(UniUInt64(i));
} }
Maybe file_readAll(FileHandle file, char** allBytes){ Maybe file_readAll(FileHandle file, char** allBytes){
i32 rezult=0; i32 result=0;
char buffer[256]; char buffer[256];
string bufStr={.ptr=buffer, .length=sizeof(buffer)}; string bufStr={.ptr=buffer, .length=sizeof(buffer)};
StringBuilder _sb; StringBuilder* sb=StringBuilder_create();
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, NULL);
u64 i=0; u64 i=0;
while(true){ while(true){
rezult=fgetc(file); result=fgetc(file);
if(rezult==EOF){ if(result==EOF){
if(ferror(file)) if(ferror(file))
safethrow(ERR_IO, StringBuilder_destruct(sb)); safethrow(ERR_IO, StringBuilder_free(sb));
break; break;
} }
buffer[i%sizeof(buffer)]=(char)rezult; buffer[i%sizeof(buffer)]=(char)result;
i++; i++;
if(!(i%sizeof(buffer))) if(!(i%sizeof(buffer)))
StringBuilder_append_string(sb,bufStr); StringBuilder_append_string(sb,bufStr);
@@ -137,7 +132,7 @@ Maybe file_readAll(FileHandle file, char** allBytes){
string str=StringBuilder_build(sb); string str=StringBuilder_build(sb);
*allBytes=str.ptr; *allBytes=str.ptr;
// i dont know how can it happen, but if it will have, it will be very dangerous // i dont know how can it happen, but if it will have, it will be very dangerous
if(i!=str.length) if(i!=str.length)
throw(ERR_UNEXPECTEDVAL); throw(ERR_UNEXPECTEDVAL);
return SUCCESS(UniUInt64(i)); return SUCCESS(UniUInt64(i));
} }

View File

@@ -5,6 +5,7 @@ extern "C" {
#endif #endif
#include "../base/base.h" #include "../base/base.h"
#include "../Array/Array.h"
#include "../String/string.h" #include "../String/string.h"
typedef FILE* FileHandle; typedef FILE* FileHandle;
@@ -16,15 +17,15 @@ bool file_exists(const char* path);
Maybe file_delete(const char* path, bool recursive); Maybe file_delete(const char* path, bool recursive);
PACKED_ENUM(FileOpenMode, PACKED_ENUM(FileOpenMode,
// open a file for reading // open a file for reading
FileOpenMode_Read=1, FileOpenMode_Read=1,
// (re)create a file for writing // (re)create a file for writing
FileOpenMode_Write=2, FileOpenMode_Write=2,
// opens file for writing additional data to the end / creates new file // opens file for writing additional data to the end / creates new file
FileOpenMode_Append=4, FileOpenMode_Append=4,
// (re)creates file for reading/writing // (re)creates file for reading/writing
FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write, FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write,
// opens file for readng/writing additional data to the end / creates new file // opens file for readng/writing additional data to the end / creates new file
FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append
) )
@@ -66,10 +67,10 @@ Maybe file_readChar(FileHandle file);
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length); Maybe file_readBuffer(FileHandle file, char* buffer, u64 length);
/// @brief reads all bytes from file /// @brief reads all bytes from file
/// @param allBytes ptr to the file's content will be pushed there /// @param allBytes ptr to the file's content will be pushed there
/// @return Maybe<u64> total number of successfully read bytes /// @return Maybe<u64> total number of successfully read bytes
Maybe file_readAll(FileHandle file, char** allBytes); Maybe file_readAll(FileHandle file, char** allBytes);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -2,7 +2,7 @@
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)
#define KFS_USE_WINDOWS_H 1 #define KFS_USE_WINDOWS_H 1
#else #else
#define KFS_USE_WINDOWS_H 0 #define KFS_USE_WINDOWS_H 0
#endif #endif

View File

@@ -1,8 +1,8 @@
#include "filesystem.h" #include "filesystem.h"
char* __path_concat(allocator_ptr al, u32 n, ...){ char* __path_concat(u32 n, ...){
char** parts=(char**)allocator_alloc(al, n*sizeof(char*)); char** parts=(char**)malloc(n*sizeof(char*));
u32* lengths=allocator_alloc(al, n*sizeof(u32)); u32* lengths=malloc(n*sizeof(u32));
u32 totalLength=0; u32 totalLength=0;
// reading args from va_list // reading args from va_list
@@ -18,11 +18,11 @@ char* __path_concat(allocator_ptr al, u32 n, ...){
va_end(vl); va_end(vl);
// allocating memory for output value // allocating memory for output value
char* totality=allocator_alloc(al, totalLength+1); char* totality=malloc(totalLength+1);
const char* output=totality; const char* output=totality;
totality[totalLength]=0; totality[totalLength]=0;
// copying content of all strings to rezult // copying content of all strings to result
u16 k=0; u16 k=0;
for(; k<n-1; k++){ for(; k<n-1; k++){
memcpy(totality, parts[k], lengths[k]); memcpy(totality, parts[k], lengths[k]);
@@ -32,13 +32,13 @@ char* __path_concat(allocator_ptr al, u32 n, ...){
} }
memcpy(totality, parts[k], lengths[k]); memcpy(totality, parts[k], lengths[k]);
allocator_free(al, lengths); free(parts);
allocator_free(al, parts); free(lengths);
return output; return output;
} }
char* path_fixSeparators(allocator_ptr al, const char* path){ char* path_fixSeparators(const char* path){
char* pathCopy=cptr_copy(al, path); char* pathCopy=cptr_copy(path);
char c; char c;
while((c=*pathCopy)){ while((c=*pathCopy)){
if(c==path_notSep) if(c==path_notSep)
@@ -49,17 +49,13 @@ char* path_fixSeparators(allocator_ptr al, const char* path){
} }
Maybe path_throwIfEscapes(const char* path){ Maybe path_throwIfEscapes(const char* path){
LinearAllocator _al; LinearAllocator_construct(&_al, 128);
allocator_ptr al=&_al.base;
if(cptr_contains(path,"..")) if(cptr_contains(path,".."))
safethrow(cptr_concat(al, "path <",path,"> uses <..>, that's not allowed"), safethrow(cptr_concat("path <",path,"> uses <..>, that's not allowed"),);
LinearAllocator_destruct(&_al));
LinearAllocator_destruct(&_al);
return MaybeNull; return MaybeNull;
} }
char* path_parentDir(allocator_ptr al, char* dir){ char* path_parentDir(char* dir){
char* copy=cptr_copy(al, dir); char* copy=cptr_copy(dir);
i32 length=cptr_length(copy); i32 length=cptr_length(copy);
i32 i=cptr_lastIndexOfChar(copy,path_sep); i32 i=cptr_lastIndexOfChar(copy,path_sep);
if(i!=-1 && i==length-1){ if(i!=-1 && i==length-1){
@@ -67,8 +63,8 @@ char* path_parentDir(allocator_ptr al, char* dir){
i=cptr_lastIndexOfChar(copy,path_sep); i=cptr_lastIndexOfChar(copy,path_sep);
} }
if(i==-1){ if(i==-1){
allocator_free(al, copy); free(copy);
copy=allocator_alloc(al, 2); copy=malloc(2);
copy[0]='.'; copy[0]='.';
copy[1]=0; copy[1]=0;
} }
@@ -76,13 +72,13 @@ char* path_parentDir(allocator_ptr al, char* dir){
} }
char* path_basename(allocator_ptr al, char* path, bool with_extension){ char* path_basename(char* path, bool with_extension){
i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1; i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1;
string rezult=string_fromCptr(path+nameIndex); string result=string_fromCptr(path+nameIndex);
if(!with_extension){ if(!with_extension){
i32 extIndex=cptr_lastIndexOfChar(rezult.ptr, '.'); i32 extIndex=cptr_lastIndexOfChar(result.ptr, '.');
if(extIndex!=0 && extIndex!=-1) if(extIndex!=0 && extIndex!=-1)
rezult.length=extIndex; result.length=extIndex;
} }
return string_extract(al, rezult); return string_extract(result);
} }

View File

@@ -14,17 +14,17 @@ static const char path_sep='/';
static const char path_notSep='\\'; static const char path_notSep='\\';
#endif #endif
char* __path_concat(allocator_ptr al, u32 n, ...); char* __path_concat(u32 n, ...);
/// @brief merges path parts together and puts <path_sep> between them /// @brief merges path parts together and puts <path_sep> between them
/// @return new cstr /// @return new cstr
#define path_concat(ALLOCATOR, PATH_PARTS...) __path_concat(ALLOCATOR, count_args(PATH_PARTS), PATH_PARTS) #define path_concat(PATH_PARTS...) __path_concat(count_args(PATH_PARTS), PATH_PARTS)
/// @brief fixes path separators /// @brief fixes path separators
/// @param cstr where can be <path_notSep> /// @param cstr where can be <path_notSep>
/// @return new cstr with correct separators /// @return new cstr with correct separators
char* path_fixSeparators(allocator_ptr al, const char* path); char* path_fixSeparators(const char* path);
#define path_resolve(ALLOCATOR, PATH_PARTS...) path_fixSeparators(ALLOCATOR, path_concat(ALLOCATOR, PATH_PARTS)) #define path_resolve(PATH_PARTS...) path_fixSeparators(path_concat(PATH_PARTS))
/// @brief calls safethrow() if finds escape sequense in path /// @brief calls safethrow() if finds escape sequense in path
/// @param path cstr where can be <..> /// @param path cstr where can be <..>
@@ -32,11 +32,11 @@ char* path_fixSeparators(allocator_ptr al, const char* path);
Maybe path_throwIfEscapes(const char* path); Maybe path_throwIfEscapes(const char* path);
///@return path of parent dir ///@return path of parent dir
char* path_parentDir(allocator_ptr al, char* path); char* path_parentDir(char* path);
///@return file name ///@return file name
char* path_basename(allocator_ptr al, char* path, bool with_extension); char* path_basename(char* path, bool with_extension);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -9,68 +9,68 @@ u32 hash_sdbm32(u32 oldhash, void* buf, u32 len){
} }
static const u32 crc_32_tab[]={ static const u32 crc_32_tab[]={
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
}; };

View File

@@ -14,4 +14,4 @@ u32 hash_crc32(u32 oldhash, void* buf, u32 len);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,70 +1,74 @@
#include "Hashtable.h" #include "Hashtable.h"
kt_define(Hashtable, __Hashtable_destruct, NULL); kt_define(Hashtable, __Hashtable_free, NULL);
// amount of rows // amount of rows
static const u16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521}; static const u16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
#define HT_HEIN_MIN 0 #define HT_HEIN_MIN 0
#define HT_HEIN_MAX 6 #define HT_HEIN_MAX 6
#define ARR_SIZE_MAX 16 #define ARR_BC 2
#define ARR_BL 8
void Hashtable_construct(Hashtable* ht, allocator_ptr external_al){ Hashtable* Hashtable_create(){
InternalAllocator_setExternalOrConstruct(ht, external_al, LinearAllocator, 1024); Hashtable* ht=malloc(sizeof(Hashtable));
ht->hein=HT_HEIN_MIN; ht->hein=HT_HEIN_MIN;
ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*)); ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*));
allocator_ptr internal_al = InternalAllocator_getPtr(ht); for(u16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
for(u16 i=0; i<HT_HEIGHTS[HT_HEIN_MIN]; i++) ht->rows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
Autoarr_construct(&ht->rows[i], KVPair, 16, internal_al); return ht;
} }
u16 __Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; } void __Hashtable_free(void* _ht){
void __Hashtable_destruct(void* _ht){
Hashtable* ht=_ht; Hashtable* ht=_ht;
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++) for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
Autoarr_destruct(&ht->rows[i]); Autoarr_free(ht->rows[i], true);
allocator_free(InternalAllocator_getPtr(ht), ht->rows); free(ht->rows);
InternalAllocator_destructIfInternal(LinearAllocator, ht);
} }
void Hashtable_destruct(Hashtable* ht){ void Hashtable_free(Hashtable* ht){
__Hashtable_destruct(ht); __Hashtable_free(ht);
free(ht);
} }
u16 Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; }
void Hashtable_expand(Hashtable* ht){ void Hashtable_expand(Hashtable* ht){
if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH); if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH);
Autoarr(KVPair)* newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*)); Autoarr(KVPair)** newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*));
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++) for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
Autoarr_construct(&newrows[i], KVPair, ARR_SIZE_MAX, InternalAllocator_getPtr(ht)); newrows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
for(u16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){ for(u16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
Autoarr(KVPair)* ar=&ht->rows[i]; Autoarr(KVPair)* ar=ht->rows[i];
u32 arlen=Autoarr_length(ar); u32 arlen=Autoarr_length(ar);
for(u32 k=0;k<arlen;k++){ for(u32 k=0;k<arlen;k++){
KVPair p=Autoarr_get(ar,k); KVPair p=Autoarr_get(ar,k);
u16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein]; u16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein];
Autoarr(KVPair)* newar=&newrows[newrown]; Autoarr(KVPair)* newar=newrows[newrown];
Autoarr_add(newar,p); Autoarr_add(newar,p);
} }
Autoarr_destruct(ar); // there is no need to free array values, because they are copied into new array
// so dont replace this incorrect auto-generated function
Autoarr_freeWithoutMembers(ar, true);
} }
free(ht->rows); free(ht->rows);
ht->rows = newrows; ht->rows=newrows;
} }
Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){ Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
u32 hash=hashs(hash_sdbm32, key); u32 hash=hashs(hash_sdbm32, key);
Autoarr(KVPair)* ar=&ht->rows[hash%HT_HEIGHTS[ht->hein]]; Autoarr(KVPair)* ar=ht->rows[hash%HT_HEIGHTS[ht->hein]];
if(can_expand && Autoarr_length(ar) == ARR_SIZE_MAX) if(can_expand && Autoarr_length(ar)==Autoarr_max_length(ar))
Hashtable_expand(ht); Hashtable_expand(ht);
ar=&ht->rows[hash%HT_HEIGHTS[ht->hein]]; ar=ht->rows[hash%HT_HEIGHTS[ht->hein]];
return ar; return ar;
} }
/// @param key must be heap allocated /// @param key must be heap allocated
/// Hashtable_destruct will free this pointer /// Hashtable_free will free this pointer
void Hashtable_add(Hashtable* ht, char* key, Unitype u){ void Hashtable_add(Hashtable* ht, char* key, Unitype u){
KVPair p={ .key=key, .value=u }; KVPair p={ .key=key, .value=u };
Autoarr_add(getrow(ht,key,true),p); Autoarr_add(getrow(ht,key,true),p);
@@ -82,8 +86,7 @@ Unitype* Hashtable_getPtr(Hashtable* ht, char* key){
u32 arlen=Autoarr_length(ar); u32 arlen=Autoarr_length(ar);
for(u32 i=0;i<arlen;i++){ for(u32 i=0;i<arlen;i++){
KVPair* p=Autoarr_getPtr(ar,i); KVPair* p=Autoarr_getPtr(ar,i);
if(cptr_equals(key,p->key)) if(cptr_equals(key,p->key)) return &p->value;
return &p->value;
} }
return NULL; return NULL;
} }
@@ -93,8 +96,7 @@ Unitype Hashtable_get(Hashtable* ht, char* key){
u32 arlen=Autoarr_length(ar); u32 arlen=Autoarr_length(ar);
for(u32 i=0;i<arlen;i++){ for(u32 i=0;i<arlen;i++){
KVPair p=Autoarr_get(ar,i); KVPair p=Autoarr_get(ar,i);
if(cptr_equals(key,p.key)) if(cptr_equals(key,p.key)) return p.value;
return p.value;
} }
return UniNull; return UniNull;
} }

View File

@@ -9,14 +9,16 @@ extern "C" {
#include "KeyValuePair.h" #include "KeyValuePair.h"
STRUCT(Hashtable, STRUCT(Hashtable,
InternalAllocator_declare(LinearAllocator); u8 hein; // height=HT_HEIGHTS[hein]
u8 hein; // height=HT_HEIGHTS[hein] Autoarr(KVPair)** rows; // Autoarr[height]
Autoarr(KVPair)* rows; // Autoarr[height]
) )
void Hashtable_construct(Hashtable* ht, allocator_ptr external_al); Hashtable* Hashtable_create();
void Hashtable_destruct(Hashtable* ht); void Hashtable_free(Hashtable* ht);
void __Hashtable_destruct(void* ht); void __Hashtable_free(void* ht);
// amount of rows
u16 Hashtable_height(Hashtable* ht);
// don't add pairs with the same keys, // don't add pairs with the same keys,
// or something weird will happen // or something weird will happen
@@ -34,16 +36,14 @@ Unitype* Hashtable_getPtr(Hashtable* ht, char* key);
Unitype Hashtable_get(Hashtable* ht, char* key); Unitype Hashtable_get(Hashtable* ht, char* key);
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output); bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output);
u16 __Hashtable_height(Hashtable* ht);
#define Hashtable_foreach(HT, EL, codeblock...) { \ #define Hashtable_foreach(HT, EL, codeblock...) { \
u16 hmax=__Hashtable_height(HT); \ u16 hmax=Hashtable_height(HT); \
for(u16 h=0; h<hmax; h++){ \ for(u16 h=0; h<hmax; h++){ \
Autoarr(KVPair)* row=&HT->rows[h]; \ Autoarr(KVPair)* AR=HT->rows[h]; \
Autoarr_foreach(row, EL, codeblock); \ Autoarr_foreach(AR, EL, codeblock); \
} \ } \
} }
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,8 +1,15 @@
#include "KeyValuePair.h" #include "KeyValuePair.h"
kt_define(KVPair, NULL, NULL); kt_define(KVPair, __KVPair_free, NULL);
Autoarr_define(KVPair) Autoarr_define(KVPair, false)
// proper way to clean a KVP
void KVPair_free(KVPair p){
free(p.key);
Unitype_free(p.value);
}
void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); }
void printkvp(KVPair p){ void printkvp(KVPair p){
kprintf("{\"%s\", ",p.key); kprintf("{\"%s\", ",p.key);

View File

@@ -14,10 +14,12 @@ STRUCT(KVPair,
Autoarr_declare(KVPair) Autoarr_declare(KVPair)
void __KVPair_destruct(void* p); // proper way to clean a KVP
void KVPair_free(KVPair p);
void __KVPair_free(void* p);
void printkvp(KVPair p); void printkvp(KVPair p);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -34,7 +34,7 @@ void LinkedList_addToEnd(void* _llist, void* _new_node) {
llist->last_node=new_node; llist->last_node=new_node;
} }
static inline void _insertNode(LinkedList(Pointer)* llist, static inline void _insertNode(LinkedList(Pointer)* llist,
LLNode(Pointer)* prev_node, LLNode(Pointer)* new_node, LLNode(Pointer)* next_node){ LLNode(Pointer)* prev_node, LLNode(Pointer)* new_node, LLNode(Pointer)* next_node){
if(prev_node==NULL){ if(prev_node==NULL){
if(next_node==llist->first_node) if(next_node==llist->first_node)

View File

@@ -16,7 +16,7 @@ extern "C" {
#define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE) #define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE)
#define LinkedList_create(TYPE) LinkedList_##TYPE##_create() #define LinkedList_create(TYPE) LinkedList_##TYPE##_create()
#define LinkedList_destruct(LLIST) ({ LLIST->_functions->destruct(LLIST); free(LLIST); }) #define LinkedList_free(LLIST) ({ LLIST->_functions->freeMembers(LLIST); free(LLIST); })
void LinkedList_addToBeginning(void* _llist, void* _new_node); void LinkedList_addToBeginning(void* _llist, void* _new_node);

View File

@@ -12,7 +12,7 @@ STRUCT(LLNode(TYPE), \
) \ ) \
\ \
LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \ LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \
void LLNode_##TYPE##_destruct(LLNode(TYPE)* node, bool free_value); void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value);
#define LinkedList_declare(TYPE)\ #define LinkedList_declare(TYPE)\
@@ -27,7 +27,7 @@ STRUCT(LinkedList(TYPE), \
) \ ) \
\ \
typedef struct LinkedList_##TYPE##_functions_t { \ typedef struct LinkedList_##TYPE##_functions_t { \
destruct_t destruct; \ freeMembers_t freeMembers; \
void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \ void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \
void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \ void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \
} LinkedList_##TYPE##_functions_t; \ } LinkedList_##TYPE##_functions_t; \

View File

@@ -14,19 +14,19 @@ LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value){ \
return node; \ return node; \
} \ } \
\ \
void LLNode_##TYPE##_destructMembers(void* _node){ \ void LLNode_##TYPE##_freeMembers(void* _node){ \
LLNode(TYPE)* node=(LLNode(TYPE)*)_node; \ LLNode(TYPE)* node=(LLNode(TYPE)*)_node; \
void* value_ptr=&node->value; \ void* value_ptr=&node->value; \
if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \ if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \
ktDescriptor_##TYPE.destruct(value_ptr); \ ktDescriptor_##TYPE.freeMembers(value_ptr); \
} \ } \
\ \
void LLNode_##TYPE##_destruct(LLNode(TYPE)* node, bool free_value){ \ void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value){ \
if(free_value) LLNode_##TYPE##_destructMembers(node); \ if(free_value) LLNode_##TYPE##_freeMembers(node); \
free(node); \ free(node); \
} \ } \
\ \
kt_define(LLNode_##TYPE, LLNode_##TYPE##_destructMembers, NULL) kt_define(LLNode_##TYPE, LLNode_##TYPE##_freeMembers, NULL)
#define LinkedList_define(TYPE, VALUE_IS_PTR)\ #define LinkedList_define(TYPE, VALUE_IS_PTR)\
@@ -41,10 +41,10 @@ LinkedList(TYPE)* LinkedList_##TYPE##_create(){ \
return l; \ return l; \
} \ } \
\ \
void LinkedList_##TYPE##_destructMembers(void* _l){ \ void LinkedList_##TYPE##_freeMembers(void* _l){ \
LinkedList(TYPE)* l=(LinkedList(TYPE)*)_l; \ LinkedList(TYPE)* l=(LinkedList(TYPE)*)_l; \
if(l->first_node!=NULL) \ if(l->first_node!=NULL) \
LinkedList_foreach(l, node, LLNode_##TYPE##_destruct(node, true)); \ LinkedList_foreach(l, node, LLNode_##TYPE##_free(node, true)); \
l->first_node=NULL; l->last_node=NULL; l->count=0; \ l->first_node=NULL; l->last_node=NULL; l->count=0; \
} \ } \
\ \
@@ -55,7 +55,7 @@ void LinkedList_##TYPE##_removePrev(LinkedList(TYPE)* llist, LLNode(TYPE)* nextN
nextNode->prev=prevNode; \ nextNode->prev=prevNode; \
prevNode->next=nextNode; \ prevNode->next=nextNode; \
if(freeRemoved) \ if(freeRemoved) \
LLNode_##TYPE##_destruct(removedNode, true); \ LLNode_##TYPE##_free(removedNode, true); \
} \ } \
\ \
void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved){ \ void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved){ \
@@ -65,16 +65,16 @@ void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevN
prevNode->next=nextNode; \ prevNode->next=nextNode; \
nextNode->prev=prevNode; \ nextNode->prev=prevNode; \
if(freeRemoved) \ if(freeRemoved) \
LLNode_##TYPE##_destruct(removedNode, true); \ LLNode_##TYPE##_free(removedNode, true); \
} \ } \
\ \
LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \ LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \
.destruct=LinkedList_##TYPE##_destructMembers, \ .freeMembers=LinkedList_##TYPE##_freeMembers, \
.removePrev=LinkedList_##TYPE##_removePrev, \ .removePrev=LinkedList_##TYPE##_removePrev, \
.removeNext=LinkedList_##TYPE##_removeNext \ .removeNext=LinkedList_##TYPE##_removeNext \
}; \ }; \
\ \
kt_define(LinkedList_##TYPE, LinkedList_##TYPE##_destructMembers, NULL) kt_define(LinkedList_##TYPE, LinkedList_##TYPE##_freeMembers, NULL)
#if __cplusplus #if __cplusplus

4
src/Network/README.md Normal file
View File

@@ -0,0 +1,4 @@
# kerep network
Don't forget to call `kn_tryInit()` before doint anything with network.

44
src/Network/network.c Normal file
View File

@@ -0,0 +1,44 @@
#include "network_internal.h"
Maybe kn_tryInit(){
#if _WIN32
// Initialize Winsock
WSADATA wsaData = {0};
int startupResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (startupResult != 0) {
char* errcode = toString_hex(&startupResult, sizeof(int), 0 , 1, 1);
safethrow(cptr_concat("WSAStartup failed with error: ", errcode), ;);
}
#endif
return SUCCESS(UniNull);
}
Maybe kt_tryDispose(){
#if _WIN32
// Deinitialize Winsock
int cleanupResult = WSACleanup();
if (cleanupResult != 0) {
char* errcode = toString_hex(&cleanupResult, sizeof(int), 0, 1, 1);
safethrow(cptr_concat("WSAStartup failed with error: ", errcode), ;);
}
#endif
return SUCCESS(UniNull);
}
Maybe __kn_StdSocket_shutdown(i64 socketfd, knShutdownType direction){
if(shutdown(socketfd, (int)direction) == -1)
safethrow("can't shutdown socket", ;);
return MaybeNull;
}
Maybe __kn_StdSocket_close(i64 socketfd){
#if KN_USE_WINSOCK
if(closesocket(socketfd) == -1)
#else
if(close(socketfd) == -1)
#endif
safethrow("can't close socket", ;);
return MaybeNull;
}

19
src/Network/network.h Normal file
View File

@@ -0,0 +1,19 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "network_types.h"
#include "sockets/knSocketTCP.h"
#include "sockets/knSocketUDP.h"
#include "sockets/knSocketChanneled.h"
Maybe kn_tryInit();
Maybe kt_tryDispose();
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,32 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "network.h"
#include "socket_impl_includes.h"
/// shutdown TCP/UDP/other std socket
Maybe __kn_StdSocket_shutdown(i64 socketfd, knShutdownType direction);
/// close TCP/UDP/other std socket
Maybe __kn_StdSocket_close(i64 socketfd);
static inline struct sockaddr_in knIPV4Endpoint_toSockaddr(knIPV4Endpoint end){
struct sockaddr_in saddr = {0};
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = end.address.UintBigEndian;
saddr.sin_port = htons(end.port); /* transforms port number to big endian (network order) */
return saddr;
}
static inline knIPV4Endpoint knIPV4Endpoint_fromSockaddr(struct sockaddr_in saddr_ptr){
knIPV4Address ipv4 = knIPV4Address_fromU32(saddr_ptr.sin_addr.s_addr);
u16 port = ntohs(saddr_ptr.sin_port); /* transforms port number to little endian (normal order) */
return knIPV4Endpoint_create(ipv4, port);
}
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,95 @@
#include "network_types.h"
char* __knIPV4Address_toString(void* p, u32 f){ return knIPV4Address_toString(*(knIPV4Address*)p); }
char* __knIPV4Endpoint_toString(void* p, u32 f){ return knIPV4Endpoint_toString(*(knIPV4Endpoint*)p); }
kt_define(knIPV4Address, NULL, __knIPV4Address_toString);
kt_define(knIPV4Endpoint, NULL, __knIPV4Endpoint_toString);
Maybe knIPV4Address_fromStr(char* addrStr, knIPV4Address* addrVal){
char* addrStr_src=addrStr;
char* errmsg_extra="wrong char";
u8 c;
knIPV4Address addr;
addr.UintBigEndian=0;
u16 n=0;
for(u8 i=0; i<4; ){
c=*addrStr++;
switch (c){
case '\0':
if(i<3){
errmsg_extra="end of string";
goto default_case;
}
addr.bytes[i++]=n;
n=0;
break;
case '.':
addr.bytes[i++]=n;
n=0;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n=n*10+c-'0';
if(n>255) {
errmsg_extra="one part of address > 255";
goto default_case;
}
break;
default_case:
default:
u32 errmsgL=cptr_length(addrStr) + 80;
char* errmsg=malloc(errmsgL);
ksprintf(errmsg, errmsgL, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra);
safethrow(errmsg,;);
break;
}
}
*addrVal=addr;
return MaybeNull;
}
char* knIPV4Address_toString(knIPV4Address address) {
char* a = toString_u64(address.bytes[0], 0, 0);
char* b = toString_u64(address.bytes[1], 0, 0);
char* c = toString_u64(address.bytes[2], 0, 0);
char* d = toString_u64(address.bytes[3], 0, 0);
char* s = cptr_concat(a,".",b,".",c,".",d);
free(a);
free(b);
free(c);
free(d);
return s;
}
Maybe knIPV4Endpoint_fromStr(char* endStr, knIPV4Endpoint* endVal){
i32 sep_i = cptr_seekChar(endStr, ':', 0, 48);
if(sep_i < 7)
safethrow(cptr_concat("can't find ':' in '", endStr, "'"), ;);
const char* portBegin = endStr+sep_i+1;
u64 port = knPort_INVALID;
if(sscanf(portBegin, IFWIN("%llu", "%lu"), &port)!=1)
safethrow(cptr_concat("can't recognise port number in '", portBegin, "'"), ;)
knIPV4Address addr = knIPV4Address_INVALID;
char* addrStr = cptr_copy(endStr);
addrStr[sep_i] = 0;
try(knIPV4Address_fromStr(addrStr, &addr), _m865, ;);
free(addrStr);
*endVal = knIPV4Endpoint_create(addr, port);
return MaybeNull;
}
char* knIPV4Endpoint_toString(knIPV4Endpoint end) {
char* a = knIPV4Address_toString(end.address);
char* p = toString_u64(end.port, 0, 0);
char* s = cptr_concat(a,":",p);
free(a);
free(p);
return s;
}

View File

@@ -0,0 +1,58 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
typedef u16 knPort;
#define knPort_INVALID ((knPort)~0)
#define knPort_isINVALID(PORT) (PORT == knPort_INVALID)
typedef union knIPV4Address {
u32 UintBigEndian;
u8 bytes[4];
} knIPV4Address;
kt_declare(knIPV4Address);
#define knIPV4Address_fromBytes(A, B, C, D) ((knIPV4Address){.bytes={A,B,C,D}})
#define knIPV4Address_fromU32(N) ((knIPV4Address){.UintBigEndian=N})
#define knIPV4Address_ANY knIPV4Address_fromBytes(0,0,0,0)
#define knIPV4Address_LOOPBACK knIPV4Address_fromBytes(127,0,0,1)
#define knIPV4Address_INVALID knIPV4Address_fromBytes(255,255,255,255)
#define knIPV4Address_isINVALID(ADDR) (ADDR.UintBigEndian == (u32)~0)
///@return Maybe<null>
Maybe knIPV4Address_fromStr(char* addrStr, knIPV4Address* addrPtr);
char* knIPV4Address_toString(knIPV4Address address);
STRUCT(knIPV4Endpoint,
knIPV4Address address;
knPort port;
)
#define knIPV4Endpoint_create(ADDR, PORT) ((knIPV4Endpoint){ADDR, PORT})
#define knIPV4Endpoint_INVALID knIPV4Endpoint_create(knIPV4Address_INVALID, knPort_INVALID)
#define knIPV4Endpoint_isINVALID(ENDP) (knIPV4Address_isINVALID(ENDP.address) || knPort_isINVALID(ENDP.port))
///@return Maybe<null>
Maybe knIPV4Endpoint_fromStr(char* endStr, knIPV4Endpoint* endVal);
char* knIPV4Endpoint_toString(knIPV4Endpoint end);
typedef enum knShutdownType {
knShutdownType_Receive = 0,
knShutdownType_Send = 1,
knShutdownType_Both = 2,
} knShutdownType;
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,27 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#if defined(_WIN64) || defined(_WIN32)
#define KN_USE_WINSOCK 1
#else
#define KN_USE_WINSOCK 0
#endif
#if KN_USE_WINSOCK
#include <winsock2.h>
// #include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,52 @@
#include "../network_internal.h"
void __knSocketChanneled_close(void* p){ knSocketChanneled_close(p); }
kt_define(knPackage, NULL, NULL);
kt_define(knPackageQueueElem, NULL, NULL);
kt_define(knChannel, NULL, NULL);
kt_define(knSocketChanneled, __knSocketChanneled_close, NULL);
Maybe knSocketChanneled_open(){
knSocketChanneled* newSocket=malloc(sizeof(knSocketChanneled));
newSocket->localEndpoint=knIPV4Endpoint_INVALID;
newSocket->remoteEndpoint=knIPV4Endpoint_INVALID;
newSocket->channels=NULL;
newSocket->channelsAmount=0;
return SUCCESS(UniHeapPtr(knSocketChanneled, newSocket));
}
Maybe knSocketChanneled_close(knSocketChanneled* socket){
try(__kn_StdSocket_close(socket->socketfd), _m762, ;);
free(socket);
return MaybeNull;
}
knChannel* __createChannel(){
knChannel* ch=malloc(sizeof(knChannel));
ch->queueStart=NULL;
return ch;
}
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){
if(socket->channelsAmount == 65535)
safethrow("max amount of channels",;);
u16 channelsAmountPrev=socket->channelsAmount;
socket->channelsAmount++;
if(channelsAmountPrev==0)
socket->channels=malloc(sizeof(knChannel*));
else
socket->channels=realloc(socket->channels, socket->channelsAmount*sizeof(knChannel*));
socket->channels[channelsAmountPrev]=__createChannel();
return SUCCESS(UniUInt64(channelsAmountPrev));
}
Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp);
Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remoteEndp);
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
Maybe knSocketChanneled_receive(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);

View File

@@ -0,0 +1,77 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../network_types.h"
#define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(u8*))
typedef enum __attribute__((__packed__)) knPacVersion {
knPac_V1=1
} knPacVersion;
static const char knPacHeader[5]={'k','n','p','a','c'};
STRUCT(knPackage,
char header[5]; /* knpac */
knPacVersion version; /* protocol version */
u16 data_size; /* size of data block in bytes (1-KNPAC_MAX_DATA_SIZE) */
u32 channel_id; /* id of knChannel in socket */
u32 package_num; /* number in sequence of sent packages */
u64 data_hash; /* hash64 of data */
u8* data; /* ptr to data */
)
STRUCT(knPackageQueueElem,
knPackage package;
knPackageQueueElem* previousElem;
knPackageQueueElem* nextElem;
)
STRUCT(knChannel,
knPackageQueueElem* queueStart;
)
STRUCT(knSocketChanneled,
i64 socketfd;
knIPV4Endpoint localEndpoint;
knIPV4Endpoint remoteEndpoint;
u16 channelsAmount;
knChannel** channels;
)
///@return Maybe<knSocketChanneled*> new socket
Maybe knSocketChanneled_open();
///@return Maybe<void> error or nothing
Maybe knSocketChanneled_close(knSocketChanneled* socket);
///@return Maybe<u64> channel index
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket);
///start listening at local endpoint
///@return Maybe<void> error or nothing
Maybe knSocketChanneled_listen(knSocketChanneled* socket, knIPV4Endpoint localEndp);
///sets socket remote endpoint
///@return Maybe<void> error or nothing
Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remoteEndp);
///@return Maybe<knSocketChanneled*> new socket connected to client
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
///@param buffer buffer for receiving data
///@param bufferLength 0-4294967295
///@return Maybe<u64> received bytes amount
Maybe knSocketChanneled_receive(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,129 @@
#include "../network_internal.h"
void __knSocketTCP_close(void* p){ knSocketTCP_close(p); }
kt_define(knSocketTCP, __knSocketTCP_close, NULL);
Maybe knSocketTCP_open(bool allowReuse){
knSocketTCP* newSocket=malloc(sizeof(knSocketTCP));
newSocket->localEndpoint=knIPV4Endpoint_INVALID;
newSocket->remoteEndpoint=knIPV4Endpoint_INVALID;
newSocket->socketfd=socket(AF_INET, SOCK_STREAM, 0);
if(newSocket->socketfd==-1 || newSocket->socketfd == ~0)
safethrow("can't create socket", free(newSocket));
// set value of REUSEADDR socket option
int opt_val = allowReuse;
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
safethrow("can't set socket options", knSocketTCP_close(newSocket));
return SUCCESS(UniHeapPtr(knSocketTCP, newSocket));
}
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction){
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
return MaybeNull;
}
Maybe knSocketTCP_close(knSocketTCP* socket){
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
free(socket);
return MaybeNull;
}
Maybe knSocketTCP_bind(knSocketTCP* socket, knIPV4Endpoint localEndp){
struct sockaddr_in servaddr = knIPV4Endpoint_toSockaddr(localEndp);
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
safethrow("socket bind failed", ;);
socket->localEndpoint = localEndp;
return MaybeNull;
}
Maybe knSocketTCP_listen(knSocketTCP* socket){
if(listen(socket->socketfd, 1024) != 0)
safethrow("socket listen failed", ;);
return MaybeNull;
}
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd){
struct sockaddr_in localAddr = {0};
struct sockaddr_in remoteAddr = knIPV4Endpoint_toSockaddr(remoteEnd);
u64 sockaddr_size = sizeof(localAddr);
if(connect(socket->socketfd, (struct sockaddr*)&remoteAddr, sizeof(remoteAddr)) != 0)
safethrow("socket connect failed", ;);
if(getsockname(socket->socketfd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get connected socket local address", ;);
socket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
socket->remoteEndpoint = remoteEnd;
return MaybeNull;
}
Maybe knSocketTCP_accept(knSocketTCP* socket){
struct sockaddr_in localAddr = {0};
struct sockaddr_in remoteAddr = {0};
u64 sockaddr_size = sizeof(localAddr);
i64 client_fd = accept(socket->socketfd, (struct sockaddr*)&remoteAddr, (void*)&sockaddr_size);
if(client_fd == -1 || client_fd == ~0)
safethrow("can't accept client connection", ;);
if(getsockname(client_fd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get accepted socket local address", __kn_StdSocket_close(client_fd));
// if accept() didn't set remoteAddr for some reason
if(remoteAddr.sin_addr.s_addr == 0 && remoteAddr.sin_port == 0 && remoteAddr.sin_family == 0){
if(getpeername(client_fd, (struct sockaddr*)&remoteAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get accepted socket remote address", __kn_StdSocket_close(client_fd));
}
knSocketTCP* clientSocket = malloc(sizeof(knSocketTCP));
clientSocket->socketfd = client_fd;
clientSocket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
clientSocket->remoteEndpoint = knIPV4Endpoint_fromSockaddr(remoteAddr);
return SUCCESS(UniHeapPtr(knSocketTCP, clientSocket));
}
Maybe knSocketTCP_send(knSocketTCP* socket, void* _buf, u32 dataLength){
char* buf = _buf;
u32 sentTotal = 0;
while(sentTotal < dataLength){
int sentCount = send(socket->socketfd, buf+sentTotal, dataLength-sentTotal, 0);
if(sentCount == -1){
safethrow(
cptr_concat("can't send ", toString_u64(dataLength-sentTotal,0,0),
" bytes out of ", toString_u64(dataLength,0,0),
" at index ", toString_u64(sentTotal,0,0)
),
;);
}
sentTotal += sentCount;
}
return MaybeNull;
}
Maybe knSocketTCP_receive(knSocketTCP* socket, void* _buf, u32 bufferLength){
char* buf = _buf;
int receivedCount = recv(socket->socketfd, buf, bufferLength, 0);
if(receivedCount == -1 || receivedCount == 0)
safethrow("can't receive data from socket", ;)
return SUCCESS(UniUInt64(receivedCount));
}
Maybe knSocketTCP_receiveN(knSocketTCP* socket, void* _buf, u32 bufsize, u32 n){
char* buf = _buf;
if(bufsize < n)
safethrow(ERR_UNEXPECTEDVAL, ;);
u32 receivedTotal = 0;
while(receivedTotal < n) {
try(knSocketTCP_receive(socket, buf+receivedTotal, n-receivedTotal), m_receivedCount, ;);
receivedTotal += m_receivedCount.value.UInt64;
}
return MaybeNull;
}

View File

@@ -0,0 +1,64 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../network_types.h"
STRUCT(knSocketTCP,
i64 socketfd;
knIPV4Endpoint localEndpoint;
knIPV4Endpoint remoteEndpoint;
/* TODO socket status enum */
)
///@note EXAMPLE 1: socket = open(false); bind(socket, localhost:8080); close(socket); - the socket on port 8080 still unavaliable for several minutes
///@note EXAMPLE 2: socket = open(true); bind(socket, localhost:8080); close(socket); - the socket on port 8080 can be opened again
///@param allowReuse enables binding multiple sockets to single port. Set to TRUE on a listening socket if you want to bind it to the same port after close.
///@return Maybe<knSocketTCP*> new socket
Maybe knSocketTCP_open(bool allowReuse);
///@param direction receive/send/both
///@return Maybe<void> error or nothing
Maybe knSocketTCP_shutdown(knSocketTCP* socket, knShutdownType direction);
/// closes file descriptor and frees socket pointer
///@return Maybe<void> error or nothing
Maybe knSocketTCP_close(knSocketTCP* socket);
/// binds socket to a local endpoint
///@return Maybe<void> error or nothing
Maybe knSocketTCP_bind(knSocketTCP* socket, knIPV4Endpoint localEndp);
/// begins listening for incoming TCP connections
Maybe knSocketTCP_listen(knSocketTCP* socket);
///@return Maybe<void> error or nothing
/// establishes TCP connection with a remote endpoint
///@return Maybe<void> error or nothing
Maybe knSocketTCP_connect(knSocketTCP* socket, knIPV4Endpoint remoteEnd);
///@return Maybe<knSocketTCP*> new socket connected to client
Maybe knSocketTCP_accept(knSocketTCP* socket);
/// sends <dataLength> bytes from buffer
///@param buffer buffer for receiving data
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketTCP_send(knSocketTCP* socket, void* buffer, u32 dataLength);
/// receives a package of any size
/// (by TCP 32 bytes han be sent as 32x1byte, 4x8byte, 32x1byte or in any other combination)
///@param buffer buffer for receiving data
///@param bufferLength 0-4294967295
///@return Maybe<u64> received bytes amount
Maybe knSocketTCP_receive(knSocketTCP* socket, void* buffer, u32 bufferLength);
/// receives a package of size n
///@return Maybe<void>
Maybe knSocketTCP_receiveN(knSocketTCP* socket, void* buf, u32 bufsize, u32 n);
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,94 @@
#include "../network_internal.h"
void __knSocketUDP_close(void* p){ knSocketUDP_close(p); }
kt_define(knSocketUDP, __knSocketUDP_close, NULL);
Maybe knSocketUDP_open(bool allowReuse){
knSocketUDP* newSocket=malloc(sizeof(knSocketUDP));
newSocket->localEndpoint=knIPV4Endpoint_INVALID;
newSocket->socketfd=socket(AF_INET, SOCK_DGRAM, 0);
if(newSocket->socketfd==-1 || newSocket->socketfd == ~0)
safethrow("can't create socket", free(newSocket));
// set value of REUSEADDR socket option
int opt_val = allowReuse;
if(setsockopt(newSocket->socketfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt_val, sizeof(opt_val)) != 0)
safethrow("can't set socket options", knSocketUDP_close(newSocket));
return SUCCESS(UniHeapPtr(knSocketUDP, newSocket));
}
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction){
try(__kn_StdSocket_shutdown(socket->socketfd, direction), _m875, ;);
return MaybeNull;
}
Maybe knSocketUDP_close(knSocketUDP* socket){
try(__kn_StdSocket_close(socket->socketfd), _m875, ;);
free(socket);
return MaybeNull;
}
Maybe knSocketUDP_bind(knSocketUDP* socket, knIPV4Endpoint localEndp){
struct sockaddr_in servaddr = {
.sin_family = AF_INET,
.sin_addr.s_addr = localEndp.address.UintBigEndian,
.sin_port = htons(localEndp.port) /* transforms port to big endian */
};
if(bind(socket->socketfd, (void*)&servaddr, sizeof(servaddr)) != 0)
safethrow("socket bind failed", ;);
socket->localEndpoint = localEndp;
return MaybeNull;
}
Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIPV4Endpoint destEnd){
struct sockaddr_in dest_saddr = knIPV4Endpoint_toSockaddr(destEnd);
u32 sentCount = sendto(
socket->socketfd,
buffer,
dataLength,
0,
(struct sockaddr*)&dest_saddr,
sizeof(struct sockaddr_in)
);
if(sentCount != dataLength) {
safethrow(
cptr_concat("can't send ", toString_u64(dataLength-sentCount,0,0),
" bytes out of ", toString_u64(dataLength,0,0)
),
;);
}
struct sockaddr_in localAddr = {0};
u64 sockaddr_size = sizeof(localAddr);
if(getsockname(socket->socketfd, (struct sockaddr*)&localAddr, (void*)&sockaddr_size) != 0)
safethrow("can't get implicitely bound socket local address", ;);
socket->localEndpoint = knIPV4Endpoint_fromSockaddr(localAddr);
return MaybeNull;
}
Maybe knSocketUDP_receiveAny(knSocketUDP* socket, char* buffer, u32 bufferLength, knIPV4Endpoint* senderEnd){
struct sockaddr_in remote_saddr = {0};
u64 remote_saddr_size = sizeof(remote_saddr);
int receivedCount = recvfrom(
socket->socketfd,
buffer,
bufferLength,
0,
(struct sockaddr*)&remote_saddr,
(void*)&remote_saddr_size
);
if(receivedCount == -1 || receivedCount == 0)
safethrow("can't receive data from socket", ;)
*senderEnd = knIPV4Endpoint_fromSockaddr(remote_saddr);
return SUCCESS(UniUInt64(receivedCount));
}

View File

@@ -0,0 +1,49 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../network_types.h"
STRUCT(knSocketUDP,
i64 socketfd;
knIPV4Endpoint localEndpoint;
/* TODO socket status enum */
)
///@note EXAMPLE 1: socket = open(false); bind(socket, localhost:8080); close(socket); - the socket on port 8080 still unavaliable for several minutes
///@note EXAMPLE 2: socket = open(true); bind(socket, localhost:8080); close(socket); - the socket on port 8080 can be opened again
///@param allowReuse enables binding multiple sockets to single port. Set to TRUE on a listening socket if you want to bind it to the same port after close.
///@return Maybe<knSocketUDP*> new socket
Maybe knSocketUDP_open(bool allowReuse);
///@param direction receive/send/both
///@return Maybe<void> error or nothing
Maybe knSocketUDP_shutdown(knSocketUDP* socket, knShutdownType direction);
/// closes file descriptor and frees socket pointer
///@return Maybe<void> error or nothing
Maybe knSocketUDP_close(knSocketUDP* socket);
/// binds socket to a local endpoint
///@return Maybe<void> error or nothing
Maybe knSocketUDP_bind(knSocketUDP* socket, knIPV4Endpoint localEndp);
/// sends one package to destination endpoint
///@param buffer buffer for receiving data
///@param dataLength 0-64k
///@param destEnd destination endpoint
///@return Maybe<void>
Maybe knSocketUDP_sendTo(knSocketUDP* socket, char* buffer, u32 dataLength, knIPV4Endpoint destEnd);
/// receives one package from anywhere
///@param buffer buffer for receiving data
///@param bufferLength 0-64k
///@param senderEnd [OUT] endpoint UPD package was sent from
///@return Maybe<u64> received bytes amount
Maybe knSocketUDP_receiveAny(knSocketUDP* socket, char* buffer, u32 bufferLength, knIPV4Endpoint* senderEnd);
#if __cplusplus
}
#endif

View File

@@ -1,6 +1,6 @@
#include "SearchTree.h" #include "SearchTree.h"
kt_define(STNode, __STNode_destruct, NULL); kt_define(STNode, __STNode_free, NULL);
STNode* STNode_create(){ STNode* STNode_create(){
STNode* node=malloc(sizeof(STNode)); STNode* node=malloc(sizeof(STNode));
@@ -9,20 +9,20 @@ STNode* STNode_create(){
return node; return node;
} }
void __STNode_destruct(void* _node){ void __STNode_free(void* _node){
STNode* node=_node; STNode* node=_node;
if (!node) throw(ERR_NULLPTR); if (!node) throw(ERR_NULLPTR);
if(node->branches){ if(node->branches){
for(u8 n32 = 0;n32<8;n32++){ for(u8 n32 = 0;n32<8;n32++){
STNode*** ptrn32=(STNode***)node->branches[n32]; STNode*** ptrn32=(STNode***)node->branches[n32];
if(ptrn32){ if(ptrn32){
for(u8 n4 = 0;n4<8;n4++){ for(u8 n4 = 0;n4<8;n4++){
STNode** ptrn4=ptrn32[n4]; STNode** ptrn4=ptrn32[n4];
if (ptrn4){ if (ptrn4){
for(u8 rem=0;rem<4;rem++){ for(u8 rem=0;rem<4;rem++){
STNode* ptrrem=ptrn4[rem]; STNode* ptrrem=ptrn4[rem];
if(ptrrem) if(ptrrem)
STNode_destruct(ptrrem); STNode_free(ptrrem);
} }
free(ptrn4); free(ptrn4);
} }
@@ -32,11 +32,11 @@ void __STNode_destruct(void* _node){
} }
free(node->branches); free(node->branches);
} }
if(node->value.VoidPtr) if(node->value.VoidPtr)
Unitype_destruct(&node->value); Unitype_free(node->value);
} }
void STNode_destruct(STNode* node){ void STNode_free(STNode* node){
__STNode_destruct(node); __STNode_free(node);
free(node); free(node);
} }

View File

@@ -13,8 +13,8 @@ STRUCT(STNode,
) )
STNode* STNode_create(); STNode* STNode_create();
void STNode_destruct(STNode* node); void STNode_free(STNode* node);
void __STNode_destruct(void* node); void __STNode_free(void* node);
void ST_push(STNode* node, char* key, Unitype value); void ST_push(STNode* node, char* key, Unitype value);
void ST_pushString(STNode* node, string key, Unitype value); void ST_pushString(STNode* node, string key, Unitype value);
@@ -23,4 +23,4 @@ Unitype ST_pullString(STNode* node, string key);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -22,4 +22,4 @@ STNode.branches byte
┗━[7]━┳━[0] 252 ┗━[7]━┳━[0] 252
┣━... ┣━...
┗━[3] 255 ┗━[3] 255
``` ```

View File

@@ -1,90 +1,144 @@
#include "StringBuilder.h" #include "StringBuilder.h"
kt_define(StringBuilder, (destruct_t)StringBuilder_destruct, NULL); kt_define(StringBuilder, __StringBuilder_free, NULL);
#define BL_C 32 #define BL_C 32
#define BL_L 1024 #define BL_L 1024
#define createBuffer() (MemoryChunk){.data = allocator_alloc(InternalAllocator_getPtr(b), 512), .size=512, .occupied_size=0}
void complete_buf(StringBuilder* b){ void complete_buf(StringBuilder* b){
if(b->curr_buf.occupied_size == 0) if(!b->compl_bufs)
return; b->compl_bufs=Autoarr_create(string,BL_C,BL_L);
string str={ .length=b->curr_buf.occupied_size, .ptr= b->curr_buf.data }; u32 len=Autoarr_length(b->curr_buf);
Autoarr_add(&b->compl_bufs,str); if(!len) return;
b->curr_buf = createBuffer(); string str={.length=len, .ptr=malloc(len)};
u32 i=0;
Autoarr_foreach(b->curr_buf, c,
str.ptr[i++]=c;
);
Autoarr_add(b->compl_bufs,str);
Autoarr_free(b->curr_buf, true);
b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
}
void try_complete_buf(StringBuilder* b){
if(b->curr_buf->blocks_count==BL_C)
complete_buf(b);
} }
void StringBuilder_construct(StringBuilder* b, allocator_ptr external_al){ StringBuilder* StringBuilder_create(){
InternalAllocator_setExternalOrConstruct(b, external_al, LinearAllocator, 1024); StringBuilder* b=malloc(sizeof(StringBuilder));
Autoarr_construct(&b->compl_bufs, string, 0, InternalAllocator_getPtr(b)); b->compl_bufs=NULL;
b->curr_buf = createBuffer(); b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
b->total_length = 0; return b;
} }
void StringBuilder_destruct(StringBuilder* b){ void __StringBuilder_free(void* _b){
Autoarr_destruct(&b->compl_bufs); StringBuilder* b=_b;
allocator_free(InternalAllocator_getPtr(b), b->curr_buf.data); if(b->compl_bufs) Autoarr_free(b->compl_bufs, true);
InternalAllocator_destructIfInternal(LinearAllocator, b); Autoarr_free(b->curr_buf, true);
}
void StringBuilder_free(StringBuilder* b){
__StringBuilder_free(b);
free(b);
} }
string StringBuilder_build(StringBuilder* b){ string StringBuilder_build(StringBuilder* b){
complete_buf(b); complete_buf(b);
string str= { u32 len=0;
.length = b->total_length, Autoarr_foreach(b->compl_bufs, cs,
.ptr = allocator_alloc(InternalAllocator_getPtr(b), b->total_length+1) len+=cs.length;
};
str.ptr[b->total_length]='\0';
char* free_space_ptr = str.ptr;
Autoarr_foreach(&b->compl_bufs, buf,
memcpy(free_space_ptr, buf.ptr, buf.length);
free_space_ptr += buf.length;
); );
StringBuilder_destruct(b); string str= { .length=len, .ptr=malloc(len+1) };
str.ptr[len]='\0';
u32 i=0;
Autoarr_foreach(b->compl_bufs, cs,
for(u32 n=0;n<cs.length;n++)
str.ptr[i++]=cs.ptr[n];
free(cs.ptr);
);
StringBuilder_free(b);
return str; return str;
} }
void StringBuilder_rmchar(StringBuilder* b){ void StringBuilder_rmchar(StringBuilder* b){
if(b->curr_buf.occupied_size != 0) if(b->curr_buf->block_length!=0)
b->curr_buf.occupied_size--; Autoarr_pop(b->curr_buf)
else { else {
for(u32 buf_i = Autoarr_length(&b->compl_bufs) - 1; buf_i != (u32)-1; buf_i--){ if(!b->compl_bufs) throw(ERR_NULLPTR);
string* lastcb = Autoarr_getPtr(&b->compl_bufs, buf_i); string* lastcb=Autoarr_getPtr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1));
if(lastcb->length != 0){ lastcb->length--;
lastcb->length--;
break;
}
}
} }
} }
void StringBuilder_append_char(StringBuilder* b, char c){ void StringBuilder_append_char(StringBuilder* b, char c){
if(b->curr_buf.occupied_size==b->curr_buf.size) try_complete_buf(b);
complete_buf(b); Autoarr_add(b->curr_buf,c);
((char*)b->curr_buf.data)[b->curr_buf.occupied_size] = c;
} }
void StringBuilder_append_string(StringBuilder* b, string s){ void StringBuilder_append_string(StringBuilder* b, string s){
complete_buf(b); complete_buf(b);
Autoarr_add(&b->compl_bufs, s); Autoarr_add(b->compl_bufs, string_copy(s));
} }
void StringBuilder_append_cptr(StringBuilder* b, char* s){ void StringBuilder_append_cptr(StringBuilder* b, char* s){
string str={ .ptr=s, .length=cptr_length(s) }; string str={
StringBuilder_append_string(b, str); .ptr=s,
.length=cptr_length(s)
};
StringBuilder_append_string(b,str);
}
void curr_buf_add_string(StringBuilder* b, string s){
for(u32 i=0; i<s.length; i++)
Autoarr_add(b->curr_buf,s.ptr[i]);
} }
void StringBuilder_append_i64(StringBuilder* b, i64 a){ void StringBuilder_append_i64(StringBuilder* b, i64 a){
StringBuilder_append_cptr(b, toString_i64(InternalAllocator_getPtr(b), a)); try_complete_buf(b);
u8 i=0;
if(a==0){
Autoarr_add(b->curr_buf,'0');
return;
}
else if(a<0){
Autoarr_add(b->curr_buf,'-');
a=-a;
}
char buf[24];
while(a!=0){
buf[i++]='0'+a%10;
a/=10;
}
string rev=string_reverse((string){buf,i});
curr_buf_add_string(b,rev);
free(rev.ptr);
} }
void StringBuilder_append_u64(StringBuilder* b, u64 a){ void StringBuilder_append_u64(StringBuilder* b, u64 a){
StringBuilder_append_cptr(b, toString_u64(InternalAllocator_getPtr(b), a, 0, 0)); try_complete_buf(b);
u8 i=0;
if(a==0){
Autoarr_add(b->curr_buf,'0');
return;
}
char buf[24];
while(a!=0){
buf[i++]='0'+a%10;
a/=10;
}
string rev=string_reverse((string){buf,i});
curr_buf_add_string(b,rev);
free(rev.ptr);
} }
void StringBuilder_append_f64(StringBuilder* b, f64 a){ void StringBuilder_append_f64(StringBuilder* b, f64 a){
StringBuilder_append_cptr(b, toString_f64(InternalAllocator_getPtr(b), a, toString_f64_max_precision, 0, 0)); try_complete_buf(b);
char buf[32];
ksprintf(buf,32,"%lf",a);
curr_buf_add_string(b, (string){.ptr=buf, .length=cptr_length(buf)});
} }

View File

@@ -8,25 +8,20 @@ extern "C" {
#include "string.h" #include "string.h"
STRUCT(StringBuilder, STRUCT(StringBuilder,
InternalAllocator_declare(LinearAllocator); Autoarr(string)* compl_bufs;
Autoarr(string) compl_bufs; Autoarr(i8)* curr_buf;
MemoryChunk curr_buf;
u64 total_length;
) )
///@param external_al if null, creates internal allocator StringBuilder* StringBuilder_create(void);
void StringBuilder_construct(StringBuilder* b, allocator_ptr external_al); void StringBuilder_free(StringBuilder* b);
void StringBuilder_destruct(StringBuilder* b); void __StringBuilder_free(void* b);
// Joins all strings from compl_bufs. // Joins all strings from compl_bufs.
// Returns zero-terminated string. // Returns zero-terminated string.
// No need to call string_extract! // No need to call string_extract()!
// Destructs StringBuilder. // Frees StringBuilder.
string StringBuilder_build(StringBuilder* b); string StringBuilder_build(StringBuilder* b);
// removes last char
/// OBSOLETE! Will be removed later
void StringBuilder_rmchar(StringBuilder* b); void StringBuilder_rmchar(StringBuilder* b);
void StringBuilder_append_char(StringBuilder* b, char c); void StringBuilder_append_char(StringBuilder* b, char c);
void StringBuilder_append_cptr(StringBuilder* b, char* s); void StringBuilder_append_cptr(StringBuilder* b, char* s);
void StringBuilder_append_string(StringBuilder* b, string s); void StringBuilder_append_string(StringBuilder* b, string s);
@@ -36,4 +31,4 @@ void StringBuilder_append_f64(StringBuilder* b, f64 a);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,49 +1,47 @@
#include "string.h" #include "string.h"
kt_define(string, NULL, NULL); kt_define(string, NULL, NULL);
Autoarr_define(string); Array_define(string)
Autoarr_define(string, false)
// copies str content to new char pointer value (adding '\0' at the end) // copies str content to new char pointer value (adding '\0' at the end)
char* string_extract(allocator_ptr al, string str){ char* string_extract(string str){
if(str.length==0) return NULL; if(str.length==0) return NULL;
char* cptr=allocator_alloc(al, str.length+1); char* cptr=malloc(str.length*sizeof(char)+1);
memcpy(cptr, str.ptr, str.length);
cptr[str.length]=0; cptr[str.length]=0;
while(str.length-->0)
cptr[str.length]=str.ptr[str.length];
return cptr; return cptr;
} }
// copies src.ptr content to new string and adds \0 at the end // copies src.ptr content to new string and adds \0 at the end
string string_copy(allocator_ptr al, string src){ string string_copy(string src){
if(!src.ptr) if(!src.ptr)
throw(ERR_NULLPTR); return src;
string nstr; string nstr;
nstr.length=src.length; nstr.length=src.length;
nstr.ptr=allocator_alloc(al, nstr.length+1); nstr.ptr=malloc(nstr.length+1);
memcpy(nstr.ptr, src.ptr, nstr.length); for(u32 i=0;i<nstr.length;i++)
nstr.ptr[i]=src.ptr[i];
nstr.ptr[nstr.length]='\0'; nstr.ptr[nstr.length]='\0';
return nstr; return nstr;
} }
// compares two strings, NullPtr-friendly // compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1){ bool string_compare(string str0, string str1){
if(str0.length!=str1.length) if(str0.length!=str1.length) return false;
return false; if(!str0.ptr) return str1.ptr ? false : true;
if(!str0.ptr)
return str1.ptr ? false : true;
else if(!str1.ptr) return false; else if(!str1.ptr) return false;
while(str0.length-->0) while(str0.length-->0)
if(*str0.ptr++ != *str1.ptr++) if(*str0.ptr++ != *str1.ptr++)
return false; return false;
return true; return true;
} }
// creates new string which is reversed variant of <s> // creates new string which is reversed variant of <s>
string string_reverse(allocator_ptr al, string s){ string string_reverse(string s){
if(s.length==0) if(s.length==0) return s;
return s; string r={malloc(s.length), s.length};
string r;
r.ptr=allocator_alloc(al, s.length);
r.length=s.length;
for(u32 i=0; i<s.length; i++) for(u32 i=0; i<s.length; i++)
r.ptr[i]=s.ptr[s.length-i-1]; r.ptr[i]=s.ptr[s.length-i-1];
return r; return r;

View File

@@ -5,6 +5,7 @@ extern "C" {
#endif #endif
#include "../base/base.h" #include "../base/base.h"
#include "../Array/Array.h"
#include "../Autoarr/Autoarr.h" #include "../Autoarr/Autoarr.h"
// my fixed length string struct // my fixed length string struct
@@ -14,6 +15,7 @@ STRUCT(string,
u64 length; // amount of chars in ptr value u64 length; // amount of chars in ptr value
) )
Array_declare(string)
Autoarr_declare(string) Autoarr_declare(string)
static const string stringNull={NULL,0}; static const string stringNull={NULL,0};
@@ -22,17 +24,17 @@ static const string stringNull={NULL,0};
#define string_fromCptr(CPTR) (string){ .ptr=CPTR, .length=cptr_length(CPTR) } #define string_fromCptr(CPTR) (string){ .ptr=CPTR, .length=cptr_length(CPTR) }
// copies str content to new char pointer value (adding '\0' at the end) // copies str content to new char pointer value (adding '\0' at the end)
char* string_extract(allocator_ptr al, string str); char* string_extract(string str);
// copies src.ptr content to new string and adds \0 at the end // copies src.ptr content to new string and adds \0 at the end
string string_copy(allocator_ptr al, string src); string string_copy(string src);
// compares two strings, NullPtr-friendly // compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1); bool string_compare(string str0, string str1);
// creates new string which is reversed variant of <s> // creates new string which is reversed variant of <s>
string string_reverse(allocator_ptr al, string s); string string_reverse(string s);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -11,8 +11,7 @@ extern "C" {
#include "type_system/type_system.h" #include "type_system/type_system.h"
#include "../kprint/kprintf.h" #include "../kprint/kprintf.h"
#include "endian.h" #include "endian.h"
#include "memory/memory.h"
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -11,16 +11,17 @@ u32 cptr_length(const char* str){
} }
// allocates new char[] and copies src there // allocates new char[] and copies src there
char* cptr_copy(allocator_ptr al, const char* src){ char* cptr_copy(const char* src){
u32 len=cptr_length(src)+1; u32 len=cptr_length(src)+1;
char* dst=allocator_alloc(al, len); char* dst=malloc(len);
memcpy(dst, src, len); while(len--!=0)
dst[len]=src[len];
return dst; return dst;
} }
// multiplies char n times // multiplies char n times
char* char_multiply(allocator_ptr al, char c, u32 n){ char* char_multiply(char c, u32 n){
char* rez=allocator_alloc(al, n+1); char* rez=malloc(n+1);
rez[n]=0; rez[n]=0;
while(n--!=0) while(n--!=0)
rez[n]=c; rez[n]=c;
@@ -130,9 +131,9 @@ i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 see
return -1; return -1;
} }
char* __cptr_concat(allocator_ptr al, u32 n, ...){ char* __cptr_concat(u32 n, ...){
char** strs=(char**)allocator_alloc(al, n*sizeof(char*)); char** strs=(char**)malloc(n*sizeof(char*));
u32* lengths=allocator_alloc(al, n*sizeof(u32)); u32* lengths=malloc(n*sizeof(u32));
u32 totalLength=0; u32 totalLength=0;
// reading args from va_list // reading args from va_list
@@ -148,41 +149,41 @@ char* __cptr_concat(allocator_ptr al, u32 n, ...){
va_end(vl); va_end(vl);
// allocating memory for output value // allocating memory for output value
char* totality=allocator_alloc(al, totalLength+1); char* totality=malloc(totalLength+1);
char* output=totality; char* output=totality;
totality[totalLength]=0; totality[totalLength]=0;
// copying content of all strings to rezult // copying content of all strings to result
for(u16 k=0; k<n; k++){ for(u16 k=0; k<n; k++){
memcpy(totality, strs[k], lengths[k]); memcpy(totality, strs[k], lengths[k]);
totality+=lengths[k]; totality+=lengths[k];
} }
allocator_free(al, lengths); free(strs);
allocator_free(al, strs); free(lengths);
return output; return output;
} }
char* cptr_toLower(allocator_ptr al, const char* src) { char* cptr_toLower(const char* src) {
u32 length=cptr_length(src); u32 length=cptr_length(src);
char *p=allocator_alloc(al, length+1); char *p=malloc(length+1);
p[length]=0; p[length]=0;
for(u32 i=0; i<length; i++) for(u32 i=0; i<length; i++)
p[i]=tolower(src[i]); p[i]=tolower(src[i]);
return p; return p;
} }
char* cptr_toUpper(allocator_ptr al, const char* src) { char* cptr_toUpper(const char* src) {
u32 length=cptr_length(src); u32 length=cptr_length(src);
char *p=allocator_alloc(al, length+1); char *p=malloc(length+1);
p[length]=0; p[length]=0;
for(u32 i=0; i<length; i++) for(u32 i=0; i<length; i++)
p[i]=toupper(src[i]); p[i]=toupper(src[i]);
return p; return p;
} }
char* cptr_replaceCharIn(allocator_ptr al, const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength){ char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength){
char* rzlt=cptr_copy(al, src); char* rzlt=cptr_copy(src);
for(u32 i=startIndex; i!=seekLength && src[i]!=0; i++){ for(u32 i=startIndex; i!=seekLength && src[i]!=0; i++){
if(src[i]==c_old) if(src[i]==c_old)
rzlt[i]=c_new; rzlt[i]=c_new;
@@ -190,10 +191,8 @@ char* cptr_replaceCharIn(allocator_ptr al, const char* src, char c_old, char c_n
return rzlt; return rzlt;
} }
char* cptr_replaceIn(allocator_ptr al, const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength){ char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength){
StringBuilder _sb; StringBuilder* sb=StringBuilder_create();
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, al);
const u32 str_old_len=cptr_length(str_old); const u32 str_old_len=cptr_length(str_old);
const u32 str_new_len=cptr_length(str_new); const u32 str_new_len=cptr_length(str_new);
i32 i=startIndex; i32 i=startIndex;
@@ -206,6 +205,6 @@ char* cptr_replaceIn(allocator_ptr al, const char* src, const char* str_old, con
u32 src_remains_len=cptr_length(src); u32 src_remains_len=cptr_length(src);
if(src_remains_len>0) if(src_remains_len>0)
StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=src_remains_len}); StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=src_remains_len});
string rezult=StringBuilder_build(sb); string result=StringBuilder_build(sb);
return rezult.ptr; return result.ptr;
} }

View File

@@ -5,13 +5,12 @@ extern "C" {
#endif #endif
#include "std.h" #include "std.h"
#include "memory/allocator_base.h"
// returns length of char buffer (without \0) // returns length of char buffer (without \0)
u32 cptr_length(const char* str); u32 cptr_length(const char* str);
// allocates new char[] and copies src there // allocates new char[] and copies src there
char* cptr_copy(allocator_ptr al, const char* src); char* cptr_copy(const char* src);
bool cptr_equals(const char* key0, const char* key1); bool cptr_equals(const char* key0, const char* key1);
@@ -20,9 +19,9 @@ bool cptr_startsWith(const char* src, const char* fragment);
bool cptr_endsWith(const char* src, const char* fragment); bool cptr_endsWith(const char* src, const char* fragment);
// multiplies char n times // multiplies char n times
char* char_multiply(allocator_ptr al, char c, u32 n); char* char_multiply(char c, u32 n);
/// @param startIndex 0 ... src length /// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1 /// @param seekLength 0 ... -1
/// @return pos of first <fragment> inclusion in <src> or -1 if not found /// @return pos of first <fragment> inclusion in <src> or -1 if not found
i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength); i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength);
@@ -64,30 +63,34 @@ static inline i32 cptr_lastIndexOfChar(const char* src, char fragment)
static inline bool cptr_contains(const char* src, const char* fragment){ static inline bool cptr_contains(const char* src, const char* fragment){
return cptr_seek(src, fragment, 0, -1) +1; return cptr_seek(src, fragment, 0, -1) != -1;
} }
char* __cptr_concat(allocator_ptr al, u32 n, ...); static inline bool cptr_containsChar(const char* src, char c){
#define cptr_concat(ALLOCATOR, STR...) __cptr_concat(ALLOCATOR, count_args(STR), STR) return cptr_seekChar(src, c, 0, -1) != -1;
}
char* cptr_toLower(allocator_ptr al, const char* src); char* __cptr_concat(u32 n, ...);
char* cptr_toUpper(allocator_ptr al, const char* src); #define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)
char* cptr_toLower(const char* src);
char* cptr_toUpper(const char* src);
/// @param startIndex 0 ... src length /// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1 /// @param seekLength 0 ... -1
/// @return <src> with <str_old> replaced by <str_new> or empty cstring if <str_old> not found /// @return <src> with <str_old> replaced by <str_new> or empty cstring if <str_old> not found
char* cptr_replaceIn(allocator_ptr al, const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength); char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength);
/// @param startIndex 0 ... src length /// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1 /// @param seekLength 0 ... -1
/// @return <src> with <c_old> replaced by <c_new> or empty cstring if <str_old> not found /// @return <src> with <c_old> replaced by <c_new> or empty cstring if <str_old> not found
char* cptr_replaceCharIn(allocator_ptr al, const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength); char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength);
static inline char* cptr_replace(allocator_ptr al, const char* src, const char* str_old, const char* str_new) static inline char* cptr_replace(const char* src, const char* str_old, const char* str_new)
{ return cptr_replaceIn(al, src, str_old, str_new, 0, -1); } { return cptr_replaceIn(src, str_old, str_new, 0, -1); }
static inline char* cptr_replaceChar(allocator_ptr al, const char* src, char c_old, char c_new) static inline char* cptr_replaceChar(const char* src, char c_old, char c_new)
{ return cptr_replaceCharIn(al, src, c_old, c_new, 0, -1); } { return cptr_replaceCharIn(src, c_old, c_new, 0, -1); }
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,7 +1,4 @@
#include "std.h" #include "base.h"
#include "errors.h"
#include "cptr.h"
#include "../kprint/kprintf.h"
char* errname(ErrorId err){ char* errname(ErrorId err){
switch(err){ switch(err){
@@ -21,26 +18,26 @@ char* errname(ErrorId err){
} }
} }
#define ERRMSG_MAXLENGTH 1024 #define ERRMSG_MAXLENGTH 4096
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){ char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
size_t bufsize=ERRMSG_MAXLENGTH; size_t bufsize=ERRMSG_MAXLENGTH;
char* rezult=malloc(bufsize); char* result=malloc(bufsize);
sprintf_s(rezult,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg); ksprintf(result,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg);
return rezult; return result;
} }
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){ char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH; size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH;
char* rezult=malloc(bufsize); char* result=malloc(bufsize);
sprintf_s(rezult,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname); ksprintf(result,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname);
free(errmsg); free(errmsg);
return rezult; return result;
} }
void Maybe_destruct(Maybe e){ void Maybe_free(Maybe e){
free(e.errmsg); free(e.errmsg);
Unitype_destruct(&e.value); Unitype_free(e.value);
} }
void printMaybe(Maybe e){ void printMaybe(Maybe e){

View File

@@ -29,7 +29,7 @@ STRUCT(Maybe,
// .value .errmsg // .value .errmsg
#define MaybeNull (Maybe){UniNull, NULL} #define MaybeNull (Maybe){UniNull, NULL}
void Maybe_destruct(Maybe e); void Maybe_free(Maybe e);
void printMaybe(Maybe e); void printMaybe(Maybe e);
@@ -60,10 +60,10 @@ char* __unknownErr( );
__RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__))); \ __RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__))); \
} }
#define try_cpp(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \ #define try_cpp(_funcCall, _result, freeMem) Maybe _result=_funcCall; if(_result.errmsg){ \
freeMem; \ freeMem; \
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \ _result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
return _rezult; \ return _result; \
} }
#else #else
@@ -73,18 +73,19 @@ char* __unknownErr( );
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \ __RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \
} }
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \ #define try(_funcCall, _result, freeMem) Maybe _result=_funcCall; if(_result.errmsg){ \
freeMem; \ freeMem; \
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \ _result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
return _rezult; \ return _result; \
} }
#endif #endif
#define tryLast(_funcCall, _rezult, ON_EXIT) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \ #define tryLast(_funcCall, _result, ON_EXIT) Maybe _result=_funcCall; if(_result.errmsg){ \
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \ ON_EXIT; \
__EXIT(_rezult.errmsg); \ _result.errmsg=__extendErrMsg(_result.errmsg, __FILE__,__LINE__,__func__); \
__EXIT(_result.errmsg); \
} }
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,15 +0,0 @@
#include "allocators_internal.h"
void* CstdAllocator_alloc(allocator_ptr self, alloc_size_t size){
// assert(size>0);
return malloc(size);
}
void CstdAllocator_free(allocator_ptr self, void* ptr){
// assert(ptr!=NULL);
free(ptr);
}
kt_define(CstdAllocator, NULL, NULL);
CstdAllocator CstdAllocator_instance=(CstdAllocator){.base.alloc_f=CstdAllocator_alloc, .base.free_f=CstdAllocator_free};

View File

@@ -1,102 +0,0 @@
#include "allocators_internal.h"
#include <stdio.h>
#define default_chunks_per_allocation 16
// growing chunk array size
#define new_max_chunks_count ( default_chunks_per_allocation*(self->chunks_count/16 == 0) + \
default_chunks_per_allocation*add_padding(self->chunks_count/2)/4 )
#define default_chunk_size 1024
// growing chunk size
#define new_chunk_size ( default_chunk_size*(self->chunks_count/16 == 0) + \
default_chunk_size*add_padding(self->chunks_count/8) )
#define chunk_alloc(SZ, OCCUPIED) (MemoryChunk){ .data=malloc(SZ), .size=SZ, .occupied_size=OCCUPIED }
#define curr_chunk (self->chunks+self->curr_chunk_i)
__attribute__ ((noinline)) void* ___alloc_realloc_chunk(LinearAllocator* self, alloc_size_t alloc_size){
free(curr_chunk->data);
*curr_chunk=chunk_alloc(alloc_size, alloc_size);
return curr_chunk->data;
}
__attribute__ ((noinline)) void* __alloc_new_chunk(LinearAllocator* self, alloc_size_t alloc_size){
self->curr_chunk_i++;
// next chunk has been already allocated
if(self->curr_chunk_i < self->chunks_count)
return curr_chunk->data;
// self->chunks array is full
if(self->chunks_count == self->max_chunks_count){
self->max_chunks_count = new_max_chunks_count;
self->chunks = realloc(self->chunks, sizeof(MemoryChunk) * self->max_chunks_count);
}
// new chunk allocation
self->chunks_count++;
alloc_size_t _new_chunk_size= alloc_size > new_chunk_size ? alloc_size : new_chunk_size;
*curr_chunk=chunk_alloc(_new_chunk_size, alloc_size);
return curr_chunk->data;
}
void* LinearAllocator_alloc(allocator_ptr _self, alloc_size_t alloc_size){
// assert(_self!=NULL);
// assert(alloc_size>0);
LinearAllocator* self = (LinearAllocator*)_self;
alloc_size=add_padding(alloc_size);
// aligned alloc_size can fit into the current chunk
if(curr_chunk->occupied_size + alloc_size <= curr_chunk->size){
void* data_ptr=curr_chunk->data + curr_chunk->occupied_size;
curr_chunk->occupied_size += alloc_size;
return data_ptr;
}
// reallocation of current chunk because it is clean
if(curr_chunk->occupied_size == 0){
// It is very unefficient operation.
// If it happens not only in the first chunk, code have to be refactored
assert(self->curr_chunk_i==0);
return ___alloc_realloc_chunk(self, alloc_size);
}
// creation of a new chunk
else {
return __alloc_new_chunk(self, alloc_size);
}
}
void LinearAllocator_free(allocator_ptr _self, void* ptr){
// LinearAllocator can't free pointers
}
void LinearAllocator_destruct(LinearAllocator* self){
// assert(_self!=NULL);
u32 size=0;
u32 oc_size=0;
for(u32 chunk_i=0; chunk_i < self->chunks_count; chunk_i++){
free(self->chunks[chunk_i].data);
size+=self->chunks[chunk_i].size;
oc_size+=self->chunks[chunk_i].occupied_size;
}
printf("\e[35m%u/%u\n",oc_size,size);
free(self->chunks);
self->chunks=NULL;
self->chunks_count=0;
self->curr_chunk_i=0;
self->max_chunks_count=0;
}
void LinearAllocator_construct(LinearAllocator* self, alloc_size_t starting_size){
assert(self!=NULL);
assert(starting_size>0);
self->base.alloc_f=LinearAllocator_alloc;
self->base.free_f=LinearAllocator_free;
self->curr_chunk_i=0;
self->chunks_count=1;
self->max_chunks_count=new_max_chunks_count;
self->chunks=malloc(sizeof(MemoryChunk) * new_max_chunks_count);
self->chunks[0]=chunk_alloc(starting_size, 0);
}
kt_define(LinearAllocator, (destruct_t)LinearAllocator_destruct, NULL)

View File

@@ -1,58 +0,0 @@
#include "allocators_internal.h"
#define chunk_alloc(SZ) (MemoryChunk){ .data=malloc(SZ), .size=SZ, .occupied_size=0 }
#define linear self->base
#define curr_chunk (linear.chunks+linear.curr_chunk_i)
typedef struct {
alloc_size_t data_size;
} AllocationHeader;
void* StackingAllocator_alloc(allocator_ptr _self, alloc_size_t size){
assert(_self!=NULL);
assert(size>0);
StackingAllocator* self = (StackingAllocator*)_self;
size=add_padding(size);
// allocates memory with header struct before data
AllocationHeader* header_ptr=LinearAllocator_alloc(_self, sizeof(AllocationHeader) + size);
void* data_ptr = (void*)header_ptr + sizeof(AllocationHeader);
header_ptr->data_size = size;
self->allocations_count++;
return data_ptr;
}
void StackingAllocator_free(allocator_ptr _self, void* data_ptr){
assert(_self!=NULL);
assert(data_ptr!=NULL);
StackingAllocator* self = (StackingAllocator*)_self;
AllocationHeader* header_ptr = data_ptr - sizeof(AllocationHeader);
// TODO check is data_ptr pointer to the last allocation
// chunk is empty
if(curr_chunk->occupied_size==0){
// isn't the first chunk
assert(linear.curr_chunk_i>0);
linear.curr_chunk_i--;
}
alloc_size_t allocation_size=header_ptr->data_size+sizeof(*header_ptr);
// data must fit in chunk
assert(allocation_size <= curr_chunk->occupied_size);
curr_chunk->occupied_size -= allocation_size;
}
void StackingAllocator_destruct(StackingAllocator* self){
LinearAllocator_destruct(&self->base);
}
void StackingAllocator_construct(StackingAllocator* self, alloc_size_t starting_size){
assert(self!=NULL);
assert(starting_size>0);
LinearAllocator_construct(&linear, starting_size);
linear.base.alloc_f=StackingAllocator_alloc;
linear.base.free_f=StackingAllocator_free;
self->allocations_count=0;
}
kt_define(StackingAllocator, (destruct_t)StackingAllocator_destruct, NULL)

View File

@@ -1,36 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "../std.h"
///////////////////////////////////////////
// MemoryAllocator interface //
///////////////////////////////////////////
typedef u32 alloc_size_t;
typedef struct MemoryAllocator MemoryAllocator;
typedef MemoryAllocator* allocator_ptr;
typedef void* (*alloc_t)(allocator_ptr, alloc_size_t size);
typedef void (*free_t)(allocator_ptr, void* ptr);
typedef struct MemoryAllocator {
alloc_t alloc_f;
free_t free_f;
} MemoryAllocator;
#define allocator_alloc(ALLOCATOR, SIZE) \
((allocator_ptr)ALLOCATOR)->alloc_f(ALLOCATOR, SIZE)
#define allocator_free(ALLOCATOR, PTR) \
((allocator_ptr)ALLOCATOR)->free_f(ALLOCATOR, PTR)
#define allocator_destruct(ALLOCATOR) \
((allocator_ptr)ALLOCATOR)->destruct_f(ALLOCATOR)
void* allocator_transfer(allocator_ptr src, allocator_ptr dest, void* data, alloc_size_t data_size);
#ifdef __cplusplus
}
#endif

View File

@@ -1,9 +0,0 @@
#include "memory.h"
void* allocator_transfer(allocator_ptr src, allocator_ptr dest, void* data, alloc_size_t data_size)
{
void* transfered=allocator_alloc(dest, data_size);
memcpy(transfered, data, data_size);
allocator_free(src, data);
return transfered;
}

View File

@@ -1,69 +0,0 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../std.h"
#include "../type_system/ktDescriptor.h"
#include "allocator_base.h"
///////////////////////////////////////////
// CstdAllocator //
///////////////////////////////////////////
// Just wrapper for malloc() and free() //
///////////////////////////////////////////
STRUCT(CstdAllocator,
MemoryAllocator base;
);
extern CstdAllocator CstdAllocator_instance;
#define CstdAllocator_instPtr (allocator_ptr)(&CstdAllocator_instance)
///////////////////////////////////////////
// LinearAllocator //
///////////////////////////////////////////
// Can't free allocated memory. //
// Allocates new memory chunk when the //
// current is full. //
///////////////////////////////////////////
typedef struct MemoryChunk {
void* data;
alloc_size_t size;
alloc_size_t occupied_size; /* free memory position in the current chunk. */
} MemoryChunk;
STRUCT(LinearAllocator,
MemoryAllocator base;
MemoryChunk* chunks; /* MemoryChunk[max_chunks_count] */
u32 chunks_count; /* allocated chunks */
u32 max_chunks_count; /* chunks that can be allocated without reallocating .chunks */
u32 curr_chunk_i; /* index of current chunk in .chunks, can be < .chunks_count */
);
void LinearAllocator_construct(LinearAllocator* self, alloc_size_t starting_size);
void LinearAllocator_destruct(LinearAllocator* self);
///////////////////////////////////////////
// StackingAllocator //
///////////////////////////////////////////
// The same as Linear, but can free //
// allocations in reverse order //
///////////////////////////////////////////
STRUCT(StackingAllocator,
LinearAllocator base;
u32 allocations_count;
);
void StackingAllocator_construct(StackingAllocator* self, alloc_size_t starting_size);
void StackingAllocator_destruct(StackingAllocator* self);
#if __cplusplus
}
#endif

View File

@@ -1,4 +0,0 @@
#include <assert.h>
#include "memory.h"
void* LinearAllocator_alloc(allocator_ptr _self, alloc_size_t size);

View File

@@ -1,44 +0,0 @@
#include "allocators.h"
// addresses must be aligned to this value
#define memory_align sizeof(void*)
// adds padding if memory_align if N isn't a multiple of memory_aligh
#define add_padding(N) (N + (N%memory_align != 0)*(memory_align - N%memory_align))
///////////////////////////////////////////
// NOT AN ALLOCATOR //
///////////////////////////////////////////
// Macros to embed internal allocator //
// into some collection struct. //
///////////////////////////////////////////
/// call this macro inside struct declaration
#define InternalAllocator_declare(AL_TYPE) \
AL_TYPE _internal_al; \
allocator_ptr _internal_al_ptr;
/// get pointer to allocator
#define InternalAllocator_getPtr(STRUCT_PTR) ((STRUCT_PTR)->_internal_al_ptr)
/// true if allocator is stored inside the struct, otherwise false
#define InternalAllocator_isInternal(STRUCT_PTR) (bool)((STRUCT_PTR)->_internal_al_ptr == (allocator_ptr)&(STRUCT_PTR)->_internal_al)
/// set ptr to external allocator
#define InternalAllocator_setExternal(STRUCT_PTR, EXT_AL_PTR) ((STRUCT_PTR)->_internal_al_ptr = EXT_AL_PTR);
/// create internal allocator and set ptr to it
#define InternalAllocator_construct(STRUCT_PTR, TYPE, CTOR_ARGS...) { \
TYPE##_construct(&(STRUCT_PTR)->_internal_al, CTOR_ARGS); \
(STRUCT_PTR)->_internal_al_ptr = (allocator_ptr)&(STRUCT_PTR)->_internal_al; \
}
/// if EXT_AL_PTR isn't null, set external allocator, otherwise create new
#define InternalAllocator_setExternalOrConstruct(STRUCT_PTR, EXT_AL_PTR, TYPE, CTOR_ARGS...) \
if(EXT_AL_PTR!=NULL) InternalAllocator_setExternal(STRUCT_PTR, EXT_AL_PTR) \
else InternalAllocator_construct(STRUCT_PTR, TYPE, CTOR_ARGS)
#define InternalAllocator_destructIfInternal(TYPE, STRUCT_PTR) {\
if(InternalAllocator_isInternal(STRUCT_PTR)) \
TYPE##_destruct((TYPE*)InternalAllocator_getPtr(STRUCT_PTR)); \
}

View File

@@ -13,10 +13,9 @@
tni=1; \ tni=1; \
} else tni=2; \ } else tni=2; \
kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n", \ kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n", \
opname, t, tnames[tni]); \ opname, t, tnames[tni]);
fflush(stdout);
#ifdef CLOCK_REALTIME #ifdef CLOCK_REALTIME
/// executes codeblock and prints execution time /// executes codeblock and prints execution time
/// u64 op_i is counter of the internal loop /// u64 op_i is counter of the internal loop
/// uses non-standard high-precision clock /// uses non-standard high-precision clock
@@ -29,7 +28,7 @@
f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000; \ f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000; \
__optime_print(opname,t); \ __optime_print(opname,t); \
} }
#else #else
/// uses standard low precision clock /// uses standard low precision clock
#define optime(opname, repeats, codeblock...) { \ #define optime(opname, repeats, codeblock...) { \
clock_t start=clock(); \ clock_t start=clock(); \

View File

@@ -14,6 +14,7 @@ extern "C" {
#include <setjmp.h> #include <setjmp.h>
#include <signal.h> #include <signal.h>
#include <math.h> #include <math.h>
#include <string.h>
typedef int8_t i8; typedef int8_t i8;
typedef uint8_t u8; typedef uint8_t u8;
@@ -25,10 +26,10 @@ typedef int64_t i64;
typedef uint64_t u64; typedef uint64_t u64;
typedef float f32; typedef float f32;
typedef double f64; typedef double f64;
/// anonymous pointer without specified destruct() func /// anonymous pointer without specified freeMembers() func
typedef void* Pointer; typedef void* Pointer;
// Usually bool from stdbool.h is defined as macro, // Usually bool from stdbool.h is defined as macro,
// so in other macros like ktid_##TYPE it will be replaced by _Bool. // so in other macros like ktid_##TYPE it will be replaced by _Bool.
// ktid__Bool will be created instead of ktid_bool // ktid__Bool will be created instead of ktid_bool
// In C++ bool is a keyword, so there is no need to redefine it. // In C++ bool is a keyword, so there is no need to redefine it.
@@ -38,14 +39,6 @@ typedef u8 bool;
#define false 0 #define false 0
#endif #endif
#ifndef memcpy
extern void* memcpy(void *dest, const void * src, size_t n);
#endif
#ifndef typeof
#define typeof __typeof__
#endif
#define dbg(N) kprintf("\e[95m%d\n",N) #define dbg(N) kprintf("\e[95m%d\n",N)
#define nameof(V) #V #define nameof(V) #V
@@ -140,4 +133,4 @@ You can even embed it into macro in header (see kprint.h)
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -22,7 +22,7 @@ and register it.
## type descriptors ## type descriptors
Every registered type should have it's own descriptor (`ktDescriptor`). It's a struct, which contains some information about type and pointers to some specific functions for this type (`toString`, `destruct`). Every registered type should have it's own descriptor (`ktDescriptor`). It's a struct, which contains some information about type and pointers to some specific functions for this type (`toString`, `freeMembers`).
## type registration ## type registration

View File

@@ -5,14 +5,14 @@
// accepts char* (ptr to char) and char* (ptr to string) // accepts char* (ptr to char) and char* (ptr to string)
// uses format kp_s and kp_c to determine what type is <c> argument // uses format kp_s and kp_c to determine what type is <c> argument
char* __toString_char(allocator_ptr al, void* c, u32 fmt) { char* __toString_char(void* c, u32 fmt) {
// *c=char* // *c=char*
if(kp_fmt_dataFormat(fmt)==kp_s){ if(kp_fmt_dataFormat(fmt)==kp_s){
return cptr_copy(al, (char*)c); // to avoid segmentation fault on free() when *c allocalet on stack return cptr_copy((char*)c); // to avoid segmentation fault on free() when *c allocalet on stack
} }
// *c=char // *c=char
if(kp_fmt_dataFormat(fmt)==kp_c){ if(kp_fmt_dataFormat(fmt)==kp_c){
char* cc=allocator_alloc(al, 2); char* cc=malloc(2);
cc[0]=*(char*)c; cc[0]=*(char*)c;
cc[1]=0; cc[1]=0;
return cc; return cc;
@@ -20,10 +20,10 @@ char* __toString_char(allocator_ptr al, void* c, u32 fmt) {
else throw(ERR_FORMAT); else throw(ERR_FORMAT);
} }
char* __toString_bool(allocator_ptr al, void* c, u32 fmt) { char* __toString_bool(void* c, u32 fmt) {
static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" }; static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" };
u8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2; u8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2;
char* rez=allocator_alloc(al, 6); char* rez=malloc(6);
rez[0]=_strbool[strind][0]; rez[0]=_strbool[strind][0];
rez[1]=_strbool[strind][1]; rez[1]=_strbool[strind][1];
rez[2]=_strbool[strind][2]; rez[2]=_strbool[strind][2];
@@ -33,7 +33,7 @@ char* __toString_bool(allocator_ptr al, void* c, u32 fmt) {
return rez; return rez;
} }
char* toString_i64(allocator_ptr al, i64 n){ char* toString_i64(i64 n){
i64 d=n<0 ? -1*n : n; i64 d=n<0 ? -1*n : n;
char str[32]; char str[32];
u8 i=sizeof(str); u8 i=sizeof(str);
@@ -46,10 +46,10 @@ char* toString_i64(allocator_ptr al, i64 n){
} }
if(n<0) if(n<0)
str[--i]='-'; str[--i]='-';
return cptr_copy(al, (char*)str+i); return cptr_copy((char*)str+i);
} }
char* toString_u64(allocator_ptr al, u64 n, bool withPostfix, bool uppercase){ char* toString_u64(u64 n, bool withPostfix, bool uppercase){
char str[32]; char str[32];
u8 i=sizeof(str); u8 i=sizeof(str);
str[--i]=0; str[--i]=0;
@@ -61,30 +61,30 @@ char* toString_u64(allocator_ptr al, u64 n, bool withPostfix, bool uppercase){
str[--i]='0' + n%10; str[--i]='0' + n%10;
n/=10; n/=10;
} }
return cptr_copy(al, (char*)str+i); return cptr_copy((char*)str+i);
} }
#define _toString_float_impl(al, bufsize, maxPrecision) { \ #define _toString_float_impl(bufsize, maxPrecision) { \
char str[bufsize]; \ char str[bufsize]; \
if(precision>maxPrecision) \ if(precision>maxPrecision) \
throw("too big precision"); \ throw("too big precision"); \
if(precision==0) \ if(precision==0) \
precision=toString_float_default_precision; \ precision=toString_float_default_precision; \
i32 cn=sprintf_s(str, bufsize, "%.*f", precision, n); \ i32 cn = sprintf_s(str, bufsize, "%.*f", precision, n); \
/* remove trailing zeroes except .0*/ \ /* remove trailing zeroes except .0*/ \
while(str[cn-1]=='0' && str[cn-2]!='.') \ while(str[cn-1]=='0' && str[cn-2]!='.') \
cn--; \ cn--; \
if(withPostfix) \ if(withPostfix) \
str[cn++]= uppercase ? 'F' : 'f'; \ str[cn++]= uppercase ? 'F' : 'f'; \
str[cn]='\0'; \ str[cn]='\0'; \
return cptr_copy(al, str); \ return cptr_copy(str); \
} }
char* toString_f32(allocator_ptr al, f32 n, u8 precision, bool withPostfix, bool uppercase) char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(al, 48, toString_f32_max_precision) _toString_float_impl(48, toString_f32_max_precision)
char* toString_f64(allocator_ptr al, f64 n, u8 precision, bool withPostfix, bool uppercase) char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(al, 512, toString_f64_max_precision) _toString_float_impl(512, toString_f64_max_precision)
#define byte_to_bits(byte) { \ #define byte_to_bits(byte) { \
str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */ \ str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */ \
@@ -97,9 +97,9 @@ char* toString_f64(allocator_ptr al, f64 n, u8 precision, bool withPostfix, bool
str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */ \ str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */ \
} }
char* toString_bin(allocator_ptr al, void* _bytes, u32 size, bool inverse, bool withPrefix){ char* toString_bin(void* _bytes, u32 size, bool inverse, bool withPrefix){
char* bytes=_bytes; char* bytes=_bytes;
char* str=allocator_alloc(al, size*8 + (withPrefix?2:0) +1); char* str=malloc(size*8 + (withPrefix?2:0) +1);
u32 cn=0; // char number u32 cn=0; // char number
if(withPrefix){ if(withPrefix){
str[cn++]='0'; str[cn++]='0';
@@ -123,19 +123,19 @@ char _4bitsHex(u8 u, bool uppercase){
case 0: case 1: case 2: case 3: case 4: case 0: case 1: case 2: case 3: case 4:
case 5: case 6: case 7: case 8: case 9: case 5: case 6: case 7: case 8: case 9:
return '0'+u; return '0'+u;
case 0xA: case 0xB: case 0xC: case 0xA: case 0xB: case 0xC:
case 0xD: case 0xE: case 0xF: case 0xD: case 0xE: case 0xF:
return (uppercase ? 'A' : 'a') + u -10; return (uppercase ? 'A' : 'a') + u -10;
default: default:
dbg(u); dbg(u);
throw("incorrect number"); throw("incorrect number");
return (char)219; return 219;
} }
} }
char* toString_hex(allocator_ptr al, void* _bytes, u32 size, bool inverse, bool withPrefix, bool uppercase){ char* toString_hex(void* _bytes, u32 size, bool inverse, bool withPrefix, bool uppercase){
char* bytes=_bytes; char* bytes=_bytes;
char* str=allocator_alloc(al, size*2 + (withPrefix?2:0) + 1); char* str=malloc(size*2 + (withPrefix?2:0) + 1);
u32 cn=0; // char number u32 cn=0; // char number
if(withPrefix){ if(withPrefix){
str[cn++]='0'; str[cn++]='0';
@@ -144,7 +144,7 @@ char* toString_hex(allocator_ptr al, void* _bytes, u32 size, bool inverse, bool
// left to right // left to right
if(inverse){ if(inverse){
// byte number // byte number
for(i32 bn=size-1; bn>=0; bn--){ for(i32 bn=size-1; bn>=0; bn--){
unsigned char byte=bytes[bn]; unsigned char byte=bytes[bn];
str[cn++]=_4bitsHex(byte/16, uppercase); str[cn++]=_4bitsHex(byte/16, uppercase);
str[cn++]=_4bitsHex(byte%16, uppercase); str[cn++]=_4bitsHex(byte%16, uppercase);
@@ -163,58 +163,67 @@ char* toString_hex(allocator_ptr al, void* _bytes, u32 size, bool inverse, bool
} }
#define __toString_i_def(BITS) char* __toString_i##BITS(allocator_ptr al, void* _n, u32 f){ \ #define __toString_i32_def(BITS) char* __toString_i##BITS(void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \ switch(kp_fmt_dataFormat(f)){ \
case kp_i: ; \ case kp_i: ; \
i##BITS n=*(i##BITS*)_n; \ i##BITS n=*(i##BITS*)_n; \
return toString_i64(al,n); \ return toString_i64(n); \
case kp_b: \ case kp_b: \
return toString_bin(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \ return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \ case kp_h: \
return toString_hex(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \ return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \ default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \ kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \ throw(ERR_FORMAT); \
return NULL; \ return NULL; \
} \ } \
} }
__toString_i32_def(8)
__toString_i32_def(16)
__toString_i32_def(32)
__toString_i32_def(64)
__toString_i_def(8) #define __toString_u_def(BITS) char* __toString_u##BITS(void* _n, u32 f){ \
__toString_i_def(16)
__toString_i_def(32)
__toString_i_def(64)
#define __toString_u_def(BITS) char* __toString_u##BITS(allocator_ptr al, void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \ switch(kp_fmt_dataFormat(f)){ \
case kp_u: ; \ case kp_u: ; \
u##BITS n=*(u##BITS*)_n; \ u##BITS n=*(u##BITS*)_n; \
return toString_u64(al, n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \ return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
case kp_b: \ case kp_b: \
return toString_bin(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \ return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \ case kp_h: \
return toString_hex(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \ return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \ default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \ kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \ throw(ERR_FORMAT); \
return NULL; \ return NULL; \
} \ } \
} }
__toString_u_def(8) __toString_u_def(8)
__toString_u_def(16) __toString_u_def(16)
__toString_u_def(32) __toString_u_def(32)
__toString_u_def(64) // __toString_u_def(64)
char* __toString_u64(void* _n, u32 f){
switch(kp_fmt_dataFormat(f)){
case kp_u: ;
u64 n=*(u64*)_n;
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));
case kp_b:
return toString_bin(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));
case kp_h:
return toString_hex(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));
default:
kprintf("\n%u\n", kp_fmt_dataFormat(f)); throw(ERR_FORMAT); return NULL; }
}
#define __toString_float_def(BITS) char* __toString_f##BITS(void* _n, u32 f){ \
#define __toString_f_def(BITS) char* __toString_f##BITS(allocator_ptr al, void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \ switch(kp_fmt_dataFormat(f)){ \
case kp_f: ; \ case kp_f: ; \
f##BITS n=*(f##BITS*)_n; \ f##BITS n=*(f##BITS*)_n; \
return toString_f64(al, n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \ return toString_f64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
case kp_b: \ case kp_b: \
return toString_bin(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \ return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \ case kp_h: \
return toString_hex(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \ return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \ default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \ kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \ throw(ERR_FORMAT); \
@@ -222,5 +231,5 @@ __toString_u_def(64)
} \ } \
} }
__toString_f_def(32) __toString_float_def(32)
__toString_f_def(64) __toString_float_def(64)

View File

@@ -5,44 +5,43 @@ extern "C" {
#endif #endif
#include "../errors.h" #include "../errors.h"
#include "../memory/allocator_base.h"
// accepts char* (ptr to char) and char* (ptr to string) // accepts char* (ptr to char) and char* (ptr to string)
// uses format kp_s and kp_c to determine what type is <c> argument // uses format kp_s and kp_c to determine what type is <c> argument
char* __toString_char(allocator_ptr al, void* c, u32 fmt); char* __toString_char(void* c, u32 fmt);
// bool // bool
char* __toString_bool(allocator_ptr al, void* c, u32 fmt); char* __toString_bool(void* c, u32 fmt);
// signed int // signed int
char* toString_i64(allocator_ptr al, i64 n); char* toString_i64(i64 n);
char* __toString_i8(allocator_ptr al, void* n, u32 fmt); char* __toString_i8(void* n, u32 fmt);
char* __toString_i16(allocator_ptr al, void* n, u32 fmt); char* __toString_i16(void* n, u32 fmt);
char* __toString_i32(allocator_ptr al, void* n, u32 fmt); char* __toString_i32(void* n, u32 fmt);
char* __toString_i64(allocator_ptr al, void* n, u32 fmt); char* __toString_i64(void* n, u32 fmt);
// unsigned int // unsigned int
char* toString_u64(allocator_ptr al, u64 n, bool withPostfix, bool uppercase); char* toString_u64(u64 n, bool withPostfix, bool uppercase);
char* __toString_u8(allocator_ptr al, void* n, u32 fmt); char* __toString_u8(void* n, u32 fmt);
char* __toString_u16(allocator_ptr al, void* n, u32 fmt); char* __toString_u16(void* n, u32 fmt);
char* __toString_u32(allocator_ptr al, void* n, u32 fmt); char* __toString_u32(void* n, u32 fmt);
char* __toString_u64(allocator_ptr al, void* n, u32 fmt); char* __toString_u64(void* n, u32 fmt);
// float // float
#define toString_f32_max_precision 6 #define toString_f32_max_precision 6
#define toString_f64_max_precision 15 #define toString_f64_max_precision 15
#define toString_float_default_precision 6 #define toString_float_default_precision 6
char* toString_f32(allocator_ptr al, f32 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* toString_f64(allocator_ptr al, f64 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* __toString_f32(allocator_ptr al, void* n, u32 fmt); char* __toString_f32(void* n, u32 fmt);
char* __toString_f64(allocator_ptr al, void* n, u32 fmt); char* __toString_f64(void* n, u32 fmt);
///@param inverse set to true for little endian numbers (their bytes are in reverse order) ///@param inverse set to true for little endian numbers (their bytes are in reverse order)
char* toString_bin(allocator_ptr al, void* bytes, u32 size, bool inverse, bool withPrefix); char* toString_bin(void* bytes, u32 size, bool inverse, bool withPrefix);
///@param inverse set to true for little endian numbers (their bytes are in reverse order) ///@param inverse set to true for little endian numbers (their bytes are in reverse order)
char* toString_hex(allocator_ptr al, void* bytes, u32 size, bool inverse, bool withPrefix, bool uppercase); char* toString_hex(void* bytes, u32 size, bool inverse, bool withPrefix, bool uppercase);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,74 +1,95 @@
#include "../base.h" #include "../base.h"
#include "../../Autoarr/Autoarr.h" #include "../../Array/Array.h"
#include "../../SearchTree/SearchTree.h" #include "../../Autoarr/Autoarr.h"
#include "../../Hashtable/Hashtable.h" #include "../../SearchTree/SearchTree.h"
#include "../../String/StringBuilder.h" #include "../../Hashtable/Hashtable.h"
#include "../../Filesystem/filesystem.h" #include "../../String/StringBuilder.h"
#include "base_toString.h" #include "../../Filesystem/filesystem.h"
#include "../../Network/network.h"
void kt_initKerepTypes(){ #include "base_toString.h"
// base types
kt_register(Pointer); void kt_initKerepTypes(){
if(ktid_Pointer!=0) // this can break UnitypeNull // base types
throw("ktid_Pointer!=0, you must init kerep types before any other types"); kt_register(Pointer);
if(ktid_Pointer!=0) // this can break UnitypeNull
kt_register(char); throw("ktid_Pointer!=0, you must init kerep types before any other types");
kt_register(bool);
kt_register(f32); kt_register(char);
kt_register(f64); kt_register(bool);
kt_register(i8); kt_register(f32);
kt_register(u8); kt_register(f64);
kt_register(i16); kt_register(i8);
kt_register(u16); kt_register(u8);
kt_register(i32); kt_register(i16);
kt_register(u32); kt_register(u16);
kt_register(i64); kt_register(i32);
kt_register(u64); kt_register(u32);
kt_register(i64);
// ktDescriptor kt_register(u64);
kt_register(ktDescriptor);
// ktDescriptor
// base type autoarrs kt_register(ktDescriptor);
kt_register(Autoarr_Pointer);
kt_register(Autoarr_char); // base type arrays
kt_register(Autoarr_bool); kt_register(Array_char);
kt_register(Autoarr_f32); kt_register(Array_bool);
kt_register(Autoarr_f64); kt_register(Array_f32);
kt_register(Autoarr_i8); kt_register(Array_f64);
kt_register(Autoarr_u8); kt_register(Array_i8);
kt_register(Autoarr_i16); kt_register(Array_u8);
kt_register(Autoarr_u16); kt_register(Array_i16);
kt_register(Autoarr_i32); kt_register(Array_u16);
kt_register(Autoarr_u32); kt_register(Array_i32);
kt_register(Autoarr_i64); kt_register(Array_u32);
kt_register(Autoarr_u64); kt_register(Array_i64);
kt_register(Array_u64);
// Unitype kt_register(Array_Pointer);
kt_register(Unitype);
kt_register(Autoarr_Unitype); // base type autoarrs
kt_register(Autoarr_Pointer);
// STNode kt_register(Autoarr_char);
kt_register(STNode); kt_register(Autoarr_bool);
kt_register(Autoarr_f32);
// KeyValuePair kt_register(Autoarr_f64);
kt_register(KVPair); kt_register(Autoarr_i8);
kt_register(Autoarr_KVPair); kt_register(Autoarr_u8);
kt_register(Autoarr_i16);
// Hashtable kt_register(Autoarr_u16);
kt_register(Hashtable); kt_register(Autoarr_i32);
kt_register(Autoarr_u32);
// string kt_register(Autoarr_i64);
kt_register(string); kt_register(Autoarr_u64);
kt_register(Autoarr_string);
// Unitype
// StringBuilder kt_register(Unitype);
kt_register(StringBuilder); kt_register(Array_Unitype);
kt_register(Autoarr_Unitype);
// File
kt_register(FileHandle); // STNode
kt_register(STNode);
// Allocators
kt_register(CstdAllocator); // KeyValuePair
kt_register(LinearAllocator); kt_register(KVPair);
kt_register(StackingAllocator); kt_register(Autoarr_KVPair);
}
// Hashtable
kt_register(Hashtable);
// string
kt_register(string);
kt_register(Array_string);
kt_register(Autoarr_string);
// StringBuilder
kt_register(StringBuilder);
// File
kt_register(FileHandle);
// Network
kt_register(knIPV4Address);
kt_register(knIPV4Endpoint);
kt_register(knSocketTCP);
kt_register(knSocketUDP);
kt_register(knSocketChanneled);
}

View File

@@ -9,4 +9,4 @@ void kt_initKerepTypes();
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -7,7 +7,6 @@ extern "C" {
#include "../std.h" #include "../std.h"
#include "ktid.h" #include "ktid.h"
#include "typedef_macros.h" #include "typedef_macros.h"
#include "../memory/allocator_base.h"
#define kt_declare(TYPE)\ #define kt_declare(TYPE)\
ktid_declare(TYPE);\ ktid_declare(TYPE);\
@@ -20,25 +19,25 @@ extern "C" {
.name=#TYPE, \ .name=#TYPE, \
.id=ktid_undefined, \ .id=ktid_undefined, \
.size=sizeof(TYPE), \ .size=sizeof(TYPE), \
.destruct=FREE_MEMBERS_F, \ .freeMembers=FREE_MEMBERS_F, \
.toString=TOSTRING_F \ .toString=TOSTRING_F \
}; \ }; \
ktDescriptor ktDescriptor_##TYPE##_Ptr={\ ktDescriptor ktDescriptor_##TYPE##_Ptr={\
.name=#TYPE "_Ptr", \ .name=#TYPE "_Ptr", \
.id=ktid_undefined, \ .id=ktid_undefined, \
.size=sizeof(TYPE), \ .size=sizeof(TYPE), \
.destruct=FREE_MEMBERS_F, \ .freeMembers=FREE_MEMBERS_F, \
.toString=TOSTRING_F \ .toString=TOSTRING_F \
}; };
typedef void (*destruct_t)(void*); typedef void (*freeMembers_t)(void*);
typedef char* (*toString_t)(allocator_ptr al, void* obj, u32 fmt); typedef char* (*toString_t)(void* obj, u32 fmt);
STRUCT(ktDescriptor, STRUCT(ktDescriptor,
char* name; char* name;
ktid id; ktid id;
u16 size; u16 size;
destruct_t destruct; // NULL or function which frees all struct members freeMembers_t freeMembers; // NULL or function which frees all struct members
toString_t toString; // NULL or function which generates string representaion of object toString_t toString; // NULL or function which generates string representaion of object
) )
@@ -49,4 +48,4 @@ STRUCT(ktDescriptor,
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -17,33 +17,33 @@ kt_define(i64, NULL, __toString_i64);
kt_define(u64, NULL, __toString_u64); kt_define(u64, NULL, __toString_u64);
char* ktDescriptor_toString(allocator_ptr al, ktDescriptor* d){ char* ktDescriptor_toString(ktDescriptor* d){
const char* n="null"; const char* n="null";
char *s0 = toString_u64(al, d->id, 0,0); char *s0 = toString_u64(d->id, 0,0);
char *s1 = toString_u64(al, d->size, 0,0); char *s1 = toString_u64(d->size, 0,0);
char *s2 = d->toString ? toString_hex(al, d->toString, sizeof(void*), 0,1,0) : n; char *s2 = d->toString ? toString_hex(d->toString, sizeof(void*), 0,1,0) : n;
char *s3 = d->destruct ? toString_hex(al, d->destruct, sizeof(void*), 0,1,0) : n; char *s3 = d->freeMembers ? toString_hex(d->freeMembers, sizeof(void*), 0,1,0) : n;
char *rez=cptr_concat(al, "ktDescriptor {" char *rez=cptr_concat("ktDescriptor {"
" name:", d->name, " name:", d->name,
" id:",s0, " id:",s0,
" size:",s1, " size:",s1,
" toString:",s2, " toString:",s2,
" destruct:",s3, " freeMembers:",s3,
" }"); " }");
if(s3!=n) allocator_free(al, s3); free(s0);
if(s2!=n) allocator_free(al, s2); free(s1);
allocator_free(al, s1); if(s2!=n) free(s2);
allocator_free(al, s0); if(s3!=n) free(s3);
return rez; return rez;
} }
char* _ktDescriptor_toString(allocator_ptr al, void* _d, u32 fmt) { return ktDescriptor_toString(al, _d); } char* _ktDescriptor_toString(void* _d, u32 fmt) { return ktDescriptor_toString(_d); }
kt_define(ktDescriptor, NULL, _ktDescriptor_toString); kt_define(ktDescriptor, NULL, _ktDescriptor_toString);
typedef ktDescriptor* ktDescriptor_Ptr; typedef ktDescriptor* ktDescriptor_Ptr;
// type descriptors are stored here during initialization // type descriptors are stored here during initialization
Autoarr(Pointer)* __descriptorPointers=NULL; Autoarr(Pointer)* __descriptorPointers=NULL;
// here type descriptors are stored when initialization is complited // here type descriptors are stored when initialization is complited
ktDescriptor** typeDescriptors=NULL; ktDescriptor** typeDescriptors=NULL;
@@ -52,21 +52,26 @@ ktid ktid_last=-1;
ENUM(ktDescriptorsState, ENUM(ktDescriptorsState,
NotInitialized, Initializing, Initialized NotInitialized, Initializing, Initialized
) )
ktDescriptorsState initState=NotInitialized; ktDescriptorsState initState=NotInitialized;
void kt_beginInit(){ bool _printDebugMessages = false;
kprintf("\e[94mtype descriptors initializing...\n");
Autoarr_construct(__descriptorPointers, Pointer, 256, NULL); void kt_beginInit(bool printDebugMessages){
_printDebugMessages = printDebugMessages;
if(printDebugMessages)
kprintf("\e[94mtype descriptors initializing...\n");
__descriptorPointers=Autoarr_create(Pointer, 256, 256);
} }
void kt_endInit(){ void kt_endInit(){
if(__descriptorPointers==NULL) if(__descriptorPointers==NULL)
throw(ERR_NULLPTR); throw(ERR_NULLPTR);
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers, CstdAllocator_instPtr); typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers);
Autoarr_destruct(__descriptorPointers); Autoarr_free(__descriptorPointers,true);
if(typeDescriptors==NULL) if(typeDescriptors==NULL) throw(ERR_NULLPTR);
throw(ERR_NULLPTR); if(_printDebugMessages)
kprintf("\e[92minitialized %u type descriptors\n", ktid_last); kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
} }
void __kt_register(ktDescriptor* descriptor){ void __kt_register(ktDescriptor* descriptor){
@@ -75,13 +80,12 @@ void __kt_register(ktDescriptor* descriptor){
} }
ktDescriptor* ktDescriptor_get(ktid id){ ktDescriptor* ktDescriptor_get(ktid id){
if(id>ktid_last || id==ktid_undefined) { if(id>ktid_last || id==ktid_undefined)
kprintf("\ntype id: %u\n",id); throw(cptr_concat("invalid type id ", toString_i64(id)));
throw("invalid type id");
}
return typeDescriptors[id]; return typeDescriptors[id];
} }
void kt_deinit(){ void kt_free(){
free(typeDescriptors); free(typeDescriptors);
} }

View File

@@ -17,16 +17,16 @@ void __kt_register(ktDescriptor* descriptor);
__kt_register(&ktDescriptor_##TYPE##_Ptr); \ __kt_register(&ktDescriptor_##TYPE##_Ptr); \
ktid_##TYPE##_Ptr=ktid_last; ktid_##TYPE##_Ptr=ktid_last;
void kt_beginInit(); void kt_beginInit(bool printDebugMessages);
void kt_endInit(); void kt_endInit();
/// @param id id of registered type /// @param id id of registered type
ktDescriptor* ktDescriptor_get(ktid id); ktDescriptor* ktDescriptor_get(ktid id);
char* ktDescriptor_toString(allocator_ptr al, ktDescriptor* d); char* ktDescriptor_toString(ktDescriptor* d);
// call it to free heap-allocated ktDescriptors array // call it to free heap-allocated ktDescriptors array
void kt_deinit(); void kt_free();
kt_declare(Pointer); kt_declare(Pointer);
kt_declare(char); kt_declare(char);
@@ -46,4 +46,4 @@ kt_declare(ktDescriptor);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -25,4 +25,4 @@ static const ktid ktid_undefined=-1;
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -8,10 +8,6 @@
ENUM_MEMBERS \ ENUM_MEMBERS \
} __attribute__((__packed__)) ENUM_NAME; } __attribute__((__packed__)) ENUM_NAME;
#define PACKED_STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME { \
STRUCT_MEMBERS \
} __attribute__((__packed__)) STRUCT_NAME;
#define STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME STRUCT_NAME; \ #define STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME STRUCT_NAME; \
typedef struct STRUCT_NAME { \ typedef struct STRUCT_NAME { \
STRUCT_MEMBERS \ STRUCT_MEMBERS \

View File

@@ -1,36 +1,40 @@
#include "../../kprint/kprint_format.h" #include "../../kprint/kprint_format.h"
#include "../base.h" #include "../base.h"
char *__Unitype_toString(allocator_ptr al, void *_u, u32 fmt) char *__Unitype_toString(void *_u, u32 fmt)
{ {
return Unitype_toString(al, *(Unitype *)_u, fmt); return Unitype_toString(*(Unitype *)_u, fmt);
} }
kt_define(Unitype, (destruct_t)Unitype_destruct, __Unitype_toString); kt_define(Unitype, __UnitypePtr_free, __Unitype_toString);
void Unitype_destruct(Unitype* u) void Unitype_free(Unitype u)
{
if (u->typeId == ktid_undefined)
{
if (u->VoidPtr != NULL)
throw("unitype with undefined typeId has value");
return;
}
ktDescriptor *type = ktDescriptor_get(u->typeId);
if (type->destruct)
type->destruct(u->VoidPtr);
if (u->allocatedInHeap)
free(u->VoidPtr);
}
char *Unitype_toString(allocator_ptr al, Unitype u, u32 fmt)
{ {
if (u.typeId == ktid_undefined) if (u.typeId == ktid_undefined)
{ {
if (u.VoidPtr != NULL) if (u.VoidPtr != NULL)
throw("unitype with undefined typeId has value"); throw("unitype with undefined typeId has value");
return cptr_copy(al, "{ERROR_TYPE}"); return;
}
ktDescriptor *type = ktDescriptor_get(u.typeId);
if (type->freeMembers)
type->freeMembers(u.VoidPtr);
if (u.allocatedInHeap)
free(u.VoidPtr);
}
void __UnitypePtr_free(void *u)
{
Unitype_free(*(Unitype *)u);
}
char *Unitype_toString(Unitype u, u32 fmt)
{
if (u.typeId == ktid_undefined)
{
if (u.VoidPtr != NULL)
throw("unitype with undefined typeId has value");
return cptr_copy("{ERROR_TYPE}");
} }
if (fmt == 0) if (fmt == 0)
@@ -70,7 +74,7 @@ char *Unitype_toString(allocator_ptr al, Unitype u, u32 fmt)
else if (u.typeId == ktid_name(Pointer)) else if (u.typeId == ktid_name(Pointer))
{ {
if (u.VoidPtr == NULL) if (u.VoidPtr == NULL)
return cptr_copy(al, "{ UniNull }"); return cptr_copy("{ UniNull }");
fmt = kp_h; fmt = kp_h;
} }
} }
@@ -78,22 +82,19 @@ char *Unitype_toString(allocator_ptr al, Unitype u, u32 fmt)
ktDescriptor *type = ktDescriptor_get(u.typeId); ktDescriptor *type = ktDescriptor_get(u.typeId);
char *valuestr; char *valuestr;
if (type->toString) if (type->toString)
valuestr = type->toString(al, u.VoidPtr, fmt); valuestr = type->toString(u.VoidPtr, fmt);
else else
valuestr = "ERR_NO_TOSTRING_FUNC"; valuestr = "ERR_NO_TOSTRING_FUNC";
char *rezult = cptr_concat(al, "{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"), char *result = cptr_concat("{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"),
", value:", valuestr, " }"); ", value:", valuestr, " }");
if (type->toString) if (type->toString)
allocator_free(al, valuestr); free(valuestr);
return rezult; return result;
} }
void printuni(Unitype v) void printuni(Unitype v)
{ {
LinearAllocator _al; char *s = Unitype_toString(v, 0);
LinearAllocator_construct(&_al, 128);
allocator_ptr al=&_al.base;
char *s = Unitype_toString(al, v, 0);
fputs(s, stdout); fputs(s, stdout);
LinearAllocator_destruct(&_al); free(s);
} }

View File

@@ -17,7 +17,7 @@ STRUCT(Unitype,
char Bytes[8]; char Bytes[8];
}; };
ktid typeId; ktid typeId;
bool allocatedInHeap; // should Unitype_destruct call free() to VoidPtr* bool allocatedInHeap; // should Unitype_free call free() to VoidPtr*
) )
@@ -45,10 +45,11 @@ STRUCT(Unitype,
#define UniCheckTypePtr(UNI, TYPE) UniCheckTypeId(UNI, ktid_ptrName(TYPE)) #define UniCheckTypePtr(UNI, TYPE) UniCheckTypeId(UNI, ktid_ptrName(TYPE))
// frees VoidPtr value or does nothing if type isn't pointer // frees VoidPtr value or does nothing if type isn't pointer
void Unitype_destruct(Unitype* u); void Unitype_free(Unitype u);
char* Unitype_toString(allocator_ptr al, Unitype v, u32 fmt); void __UnitypePtr_free(void* u);
char* Unitype_toString(Unitype v, u32 fmt);
void printuni(Unitype v); void printuni(Unitype v);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -3,27 +3,27 @@
ktid __typeFromFormat(kp_fmt f){ ktid __typeFromFormat(kp_fmt f){
ktid typeId=kp_fmt_ktid(f); ktid typeId=kp_fmt_ktid(f);
if(typeId) if(typeId)
return typeId; return typeId;
switch(kp_fmt_dataFormat(f)){ switch(kp_fmt_dataFormat(f)){
case kp_i: case kp_i:
case kp_h: case kp_h:
case kp_b: case kp_b:
return ktid_name(i64); return ktid_name(i64);
case kp_u: case kp_u:
return ktid_name(u64); return ktid_name(u64);
case kp_f: case kp_f:
return ktid_name(f64); return ktid_name(f64);
case kp_c: case kp_c:
return ktid_name(char); return ktid_name(char);
case kp_s: case kp_s:
return ktid_ptrName(char); return ktid_ptrName(char);
default: default:
return ktid_undefined; return ktid_undefined;
} }
} }
Maybe __next_toString(allocator_ptr al, kp_fmt f, void* object){ Maybe __next_toString(kp_fmt f, void* object){
// detecting type // detecting type
ktid typeId=__typeFromFormat(f); ktid typeId=__typeFromFormat(f);
if(typeId==ktid_undefined) if(typeId==ktid_undefined)
@@ -35,62 +35,54 @@ Maybe __next_toString(allocator_ptr al, kp_fmt f, void* object){
ktDescriptor* type=ktDescriptor_get(typeId); ktDescriptor* type=ktDescriptor_get(typeId);
if(!type->toString) if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;); safethrow("type descriptor doesnt have toString() func",;);
return SUCCESS(UniHeapPtr(char, type->toString(al, object, f))); return SUCCESS(UniHeapPtr(char, type->toString(object, f)));
} }
Maybe check_argsN(u8 n){ Maybe check_argsN(u8 n){
if(n%2 != 0) safethrow("kprint recieved non-even number of arguments",;); if(n%2 != 0) safethrow("kprint received non-even number of arguments",;);
if(n > 32) safethrow("kprint recieved >32 number of arguments",;); if(n > 32) safethrow("kprint received >32 number of arguments",;);
return MaybeNull; return MaybeNull;
} }
Maybe __ksprint(allocator_ptr al, u8 n, kp_fmt* formats, __kp_value_union* objects){ Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;); try(check_argsN(n), _,;);
n/=2; n/=2;
StringBuilder _sb; StringBuilder* strb=StringBuilder_create();
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, al);
for(u8 i=0; i<n; i++){ for(u8 i=0; i<n; i++){
try(__next_toString(al, formats[i], &objects[i]),mStr,;); try(__next_toString(formats[i], &objects[i]),mStr,;);
StringBuilder_append_cptr(sb, mStr.value.VoidPtr); StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
allocator_free(al, mStr.value.VoidPtr); Unitype_free(mStr.value);
} }
char* rezult=StringBuilder_build(sb).ptr; char* result=StringBuilder_build(strb).ptr;
return SUCCESS(UniHeapPtr(char, rezult)); return SUCCESS(UniHeapPtr(char, result));
} }
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){ Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;); try(check_argsN(n), _,;);
n/=2; n/=2;
LinearAllocator _al;
LinearAllocator_construct(&_al, 256);
allocator_ptr al=&_al.base;
for(u8 i=0; i<n; i++){ for(u8 i=0; i<n; i++){
try(__next_toString(al, formats[i], &objects[i]),maybeStr, LinearAllocator_destruct(&_al)); try(__next_toString(formats[i], &objects[i]),maybeStr,;);
if(fputs(maybeStr.value.VoidPtr, file)==EOF) if(fputs(maybeStr.value.VoidPtr, file)==EOF)
safethrow("can't write string to file", LinearAllocator_destruct(&_al)); safethrow("can't write string to file", Unitype_free(maybeStr.value));
Unitype_free(maybeStr.value);
} }
fflush(file); fflush(file);
LinearAllocator_destruct(&_al);
return MaybeNull; return MaybeNull;
} }
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){ void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
tryLast(check_argsN(n), _,;); tryLast(check_argsN(n), _,;);
n/=2; n/=2;
LinearAllocator _al;
LinearAllocator_construct(&_al, 256);
allocator_ptr al=&_al.base;
for(u8 i=0; i<n; i++){ for(u8 i=0; i<n; i++){
kp_fmt fmt=formats[i]; kp_fmt fmt=formats[i];
kprint_setColor(fmt); kprint_setColor(fmt);
tryLast(__next_toString(al, fmt, &objects[i]), maybeStr, tryLast(__next_toString(fmt, &objects[i]),maybeStr, kprint_setColor(kp_bgBlack|kp_fgGray));
kprint_setColor(kp_bgBlack|kp_fgGray);); if(fputs(maybeStr.value.VoidPtr, stdout)==EOF) \
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF)
throw("can't write string to stdout"); throw("can't write string to stdout");
//, Unitype_free(maybeStr.value)
Unitype_free(maybeStr.value);
} }
fflush(stdout); fflush(stdout);
LinearAllocator_destruct(&_al);
} }
#if defined(_WIN32)|| defined(_WIN64) #if defined(_WIN32)|| defined(_WIN64)
@@ -98,7 +90,6 @@ void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
#define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED #define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
DWORD kp_fgColor_toWin(kp_fgColor f){ DWORD kp_fgColor_toWin(kp_fgColor f){
//kprintf("fg: %x\n", f);
switch(f){ switch(f){
case kp_fgBlack: return 0; case kp_fgBlack: return 0;
case kp_fgRedD: return FOREGROUND_RED; case kp_fgRedD: return FOREGROUND_RED;
@@ -121,7 +112,6 @@ DWORD kp_fgColor_toWin(kp_fgColor f){
} }
DWORD kp_bgColor_toWin(kp_bgColor f){ DWORD kp_bgColor_toWin(kp_bgColor f){
//kprintf("bg: %x\n", f);
switch(f){ switch(f){
case kp_bgBlack: return 0; case kp_bgBlack: return 0;
case kp_bgRedD: return BACKGROUND_RED; case kp_bgRedD: return BACKGROUND_RED;
@@ -175,19 +165,17 @@ void kprint_setColor(kp_fmt f){
ktDescriptor* type=ktDescriptor_get(format.typeId); ktDescriptor* type=ktDescriptor_get(format.typeId);
if(!type->toString) if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;); safethrow("type descriptor doesnt have toString() func",;);
StringBuilder _sb; StringBuilder* strb=StringBuilder_create();
StringBuilder* sb=&_sb; StringBuilder_append_char(strb, '[');
StringBuilder_construct(sb, al);
StringBuilder_append_char(sb, '[');
for (u16 e=1; e<count; e++){ for (u16 e=1; e<count; e++){
StringBuilder_append_char(sb, ' '); StringBuilder_append_char(strb, ' ');
char* elStr=type->toString(array+type->size*e, &format); char* elStr=type->toString(array+type->size*e, &format);
StringBuilder_append_cptr(sb, elStr); StringBuilder_append_cptr(strb, elStr);
StringBuilder_append_char(sb, ','); StringBuilder_append_char(strb, ',');
} }
StringBuilder_rmchar(sb); StringBuilder_rmchar(strb);
StringBuilder_append_char(sb, ' '); StringBuilder_append_char(strb, ' ');
StringBuilder_append_char(sb, ']'); StringBuilder_append_char(strb, ']');
} */ } */
static const char* _kp_colorNames[16]={ static const char* _kp_colorNames[16]={
@@ -209,12 +197,12 @@ static const char* _kp_colorNames[16]={
"white" "white"
}; };
char* kp_bgColor_toString(allocator_ptr al, kp_bgColor c){ char* kp_bgColor_toString(kp_bgColor c){
u32 color_index=(c&0x00f00000)>>20; u32 color_index=(c&0x00f00000)>>20;
if(color_index>15) throw(ERR_WRONGINDEX); if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index]; return _kp_colorNames[color_index];
} }
char* kp_fgColor_toString(allocator_ptr al, kp_fgColor c){ char* kp_fgColor_toString(kp_fgColor c){
u32 color_index=(c&0x00f00000)>>24; u32 color_index=(c&0x00f00000)>>24;
if(color_index>15) throw(ERR_WRONGINDEX); if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index]; return _kp_colorNames[color_index];

View File

@@ -9,7 +9,7 @@ extern "C" {
/* /*
This file looks like a mess, but all cotnent here just solves the problem of putting variadic arguments to array of formats and array of objects. This file looks like a mess, but all cotnent here just solves the problem of putting variadic arguments to array of formats and array of objects.
*/ */
@@ -18,11 +18,11 @@ typedef union {
u64 u64; u64 u64;
f64 f64; f64 f64;
void* ptr; void* ptr;
} __kp_value_union; } __kp_value_union;
static inline __kp_value_union __kpVU_f(f64 f) { return (__kp_value_union){ .f64=f }; } static inline __kp_value_union __kpVU_f(f64 f) { return (__kp_value_union){ .f64=f }; }
static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64=f }; } static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64=f }; }
#define __kpVU_selectType(V) _Generic(V, float: __kpVU_f, f64: __kpVU_f, default: __kpVU_i)(V) #define __kpVU_selectType(V) _Generic(V, float: __kpVU_f, f64: __kpVU_f, default: __kpVU_i)(V)
@@ -70,18 +70,18 @@ static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64
__kp_argsToObjs32(ARGS)) __kp_argsToObjs32(ARGS))
Maybe __ksprint(allocator_ptr al, u8 n, kp_fmt* formats, __kp_value_union* objects); Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects);
/// @param ARGS kp_fmt, value, kp_fmt, value... /// @param ARGS kp_fmt, value, kp_fmt, value...
///@returns Maybe<char*> ///@returns Maybe<char*>
#define ksprint(ALLOCATOR, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \ #define ksprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
__ksprint(ALLOCATOR, count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \ __ksprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
) )
/*-Wint-conversion warning was produced during value to __kp_value_union conversion*/ /*-Wint-conversion warning was produced during value to __kp_value_union conversion*/
Maybe __kfprint(FILE* fd, u8 n, kp_fmt* formats, __kp_value_union* objects); Maybe __kfprint(FILE* fd, u8 n, kp_fmt* formats, __kp_value_union* objects);
/// @param FD FILE* /// @param FD FILE*
/// @param ARGS kp_fmt, value, kp_fmt, value... /// @param ARGS kp_fmt, value, kp_fmt, value...
///@returns Maybe<void> ///@returns Maybe<void>
#define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \ #define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
@@ -99,4 +99,4 @@ void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -4,12 +4,12 @@
extern "C" { extern "C" {
#endif #endif
#include "../base/memory/allocator_base.h" #include "../base/type_system/typedef_macros.h"
// 10000000 00000000 00000000 00000000 // 10000000 00000000 00000000 00000000
// ^ ^^^^ // ^ ^^^^
// | color num // | color num
// fgColorSet flag // fgColorSet flag
PACKED_ENUM(kp_fgColor, PACKED_ENUM(kp_fgColor,
/// black foreground /// black foreground
kp_fgBlack = 0x80000000, kp_fgBlack = 0x80000000,
@@ -42,7 +42,7 @@ PACKED_ENUM(kp_fgColor,
/// cyan foreground /// cyan foreground
kp_fgCyan = 0x8e000000, kp_fgCyan = 0x8e000000,
/// white foreground /// white foreground
kp_fgWhite = 0x8f000000 kp_fgWhite = 0x8f000000
) )
// 01000000 00000000 00000000 00000000 // 01000000 00000000 00000000 00000000
@@ -83,9 +83,9 @@ PACKED_ENUM(kp_bgColor,
kp_bgWhite = 0x40f00000 kp_bgWhite = 0x40f00000
) )
char* kp_bgColor_toString(allocator_ptr al, kp_bgColor c); char* kp_bgColor_toString(kp_bgColor c);
char* kp_fgColor_toString(allocator_ptr al, kp_fgColor c); char* kp_fgColor_toString(kp_fgColor c);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -45,9 +45,9 @@ PACKED_ENUM(kp_dataFmt,
#define kp_fmt_dataFormat(FMT) (kp_dataFmt)(FMT&0x000f0000) #define kp_fmt_dataFormat(FMT) (kp_dataFmt)(FMT&0x000f0000)
#define kp_fmt_ktid(FMT) (ktid)(FMT&0x0000ffff) #define kp_fmt_ktid(FMT) (ktid)(FMT&0x0000ffff)
///@param f bgColor | fgColor ///@param f bgColor | fgColor
void kprint_setColor(kp_fmt f); void kprint_setColor(kp_fmt f);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -45,114 +45,219 @@ WORD unixColorToWin(u8 c){
} }
#endif #endif
void kprintf(const char* format, ...){ i32 _kprintf(const char* format, const i32 args_count, ...){
va_list vl; va_list vl;
va_start(vl, format); va_start(vl, args_count);
u32 i=0; i32 i = 0;
LinearAllocator _al; i32 args_left = args_count;
LinearAllocator_construct(&_al, 128); for(char c = format[i++]; c != 0; c = format[i++]){
allocator_ptr al=(allocator_ptr)&_al;
for(char c=format[i++]; c!=0; c=format[i++]){
// value format specifiers // value format specifiers
if(c=='%'){ if(c == '%'){
char* argstr=NULL; if(args_left-- == 0)
bool l=false; return kprintf_NOT_ENOUGH_ARGUMENTS;
c=format[i++];
char* argstr = NULL;
bool l = false;
c = format[i++];
format_escape_seq: format_escape_seq:
switch (c) { switch (c) {
case 'u': case 'u':
argstr=toString_u64(al, argstr = toString_u64(
l ? va_arg(vl, u64) : va_arg(vl, u32) l ? va_arg(vl, u64) : va_arg(vl, u32)
,0,0); ,0,0);
break; break;
case 'i': case 'd': case 'i': case 'd':
argstr=toString_i64(al, argstr = toString_i64(
l ? va_arg(vl, i64) : va_arg(vl, i32) l ? va_arg(vl, i64) : va_arg(vl, i32)
); );
break; break;
case 'f': case 'f':
// f32 is promoted to f64 when passed through '...' // f32 is promoted to f64 when passed through '...'
argstr=toString_f64(al, va_arg(vl, f64), toString_float_default_precision,0,0); argstr = toString_f64(va_arg(vl, f64), toString_float_default_precision,0,0);
break; break;
case 'l': case 'l':
l=true; l = true;
if((c=format[i++])) if((c = format[i++]))
goto format_escape_seq; goto format_escape_seq;
break; break;
case 'p': ; case 'p': ;
void* phex=va_arg(vl, void*); void* phex = va_arg(vl, void*);
argstr=toString_hex(al, &phex,getEndian()==LittleEndian,sizeof(phex),1,0); argstr = toString_hex(&phex,getEndian() == LittleEndian,sizeof(phex),1,0);
break; break;
case 'x': ; case 'x': ;
if(l){ if(l){
u64 xhex=va_arg(vl, u64); u64 xhex = va_arg(vl, u64);
argstr=toString_hex(al, &xhex,getEndian()==LittleEndian,sizeof(xhex),0,1); argstr = toString_hex(&xhex,getEndian() == LittleEndian,sizeof(xhex),0,1);
} }
else { else {
u32 xhex=va_arg(vl, u32); u32 xhex = va_arg(vl, u32);
argstr=toString_hex(al, &xhex,getEndian()==LittleEndian,sizeof(xhex),0,1); argstr = toString_hex(&xhex,getEndian() == LittleEndian,sizeof(xhex),0,1);
} }
break; break;
case 's': ; case 's': ;
char* cptr=va_arg(vl,char*); char* cptr = va_arg(vl,char*);
if(!cptr) if(!cptr)
cptr="<nullstr>"; cptr = "<nullstr>";
if(*cptr) if(*cptr)
fputs(cptr, stdout); fputs(cptr, stdout);
break; break;
case 'c': case 'c':
argstr=allocator_alloc(al, 2); putc((char)va_arg(vl,int), stdout);
argstr[0]=(char)va_arg(vl,int);
argstr[1]=0;
break; break;
default: default:
putc('\n',stdout); fputs("<INCORRECT FORMAT STRING>", stdout);
putc('<',stdout); return kprintf_INVALID_FORMAT;
putc(c,stdout);
putc('>',stdout);
throw(ERR_FORMAT);
} }
if(argstr){ if(argstr){
fputs(argstr, stdout); fputs(argstr, stdout);
free(argstr);
} }
} }
// escape sequences
else if(c=='\e'){ // escape sequences
IFWIN( else if(c == '\e'){
/* WINDOWS */ //////////////////// WINDOWS ////////////////////
({ #if defined(_WIN64) || defined(_WIN32)
if((c=format[i++])=='['){ if((c = format[i++]) == '['){
u8 colorUnix=0; u8 colorUnix = 0;
for(i8 n=0; n<6 && c!=0; n++){ for(i8 n = 0; n<6 && c != 0; n++){
c=format[i++]; c = format[i++];
switch (c){ switch (c){
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
colorUnix=colorUnix*10+c-'0'; colorUnix = colorUnix*10+c-'0';
break; break;
case 'm': ; case 'm': ;
WORD colorWin=unixColorToWin(colorUnix); WORD colorWin = unixColorToWin(colorUnix);
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, colorWin); SetConsoleTextAttribute(hConsole, colorWin);
goto end_iteration; goto end_iteration;
default: default:
goto end_iteration; goto end_iteration;
}
} }
} }
}), }
/* UNIX */ ////////////////////// UNIX //////////////////////
#else
putc(c,stdout); putc(c,stdout);
); #endif
} }
// common characters
// common characters
else { else {
putc(c,stdout); putc(c,stdout);
} }
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)
end_iteration:; end_iteration:;
#endif #endif
} }
va_end(vl); va_end(vl);
LinearAllocator_destruct(&_al); return i;
}
i32 _ksprintf(char* buffer, i32 buffer_size, const char* format, const i32 args_count, ...){
if(buffer == NULL)
return kprintf_BUFFER_IS_NULL;
va_list vl;
va_start(vl, args_count);
i32 i = 0;
i32 written = 0;
i32 args_left = args_count;
for(char c = format[i++]; c != 0; c = format[i++]){
// value format specifiers
if(c == '%'){
if(args_left-- == 0)
return kprintf_NOT_ENOUGH_ARGUMENTS;
char* argstr = NULL;
bool l = false;
c = format[i++];
format_escape_seq:
switch (c) {
case 'u':
argstr = toString_u64(
l ? va_arg(vl, u64) : va_arg(vl, u32)
,0,0);
break;
case 'i': case 'd':
argstr = toString_i64(
l ? va_arg(vl, i64) : va_arg(vl, i32)
);
break;
case 'f':
// f32 is promoted to f64 when passed through '...'
argstr = toString_f64(va_arg(vl, f64), toString_float_default_precision,0,0);
break;
case 'l':
l = true;
if((c = format[i++]))
goto format_escape_seq;
break;
case 'p': ;
void* phex = va_arg(vl, void*);
argstr = toString_hex(&phex,getEndian() == LittleEndian,sizeof(phex),1,0);
break;
case 'x': ;
if(l){
u64 xhex = va_arg(vl, u64);
argstr = toString_hex(&xhex,getEndian() == LittleEndian,sizeof(xhex),0,1);
}
else {
u32 xhex = va_arg(vl, u32);
argstr = toString_hex(&xhex,getEndian() == LittleEndian,sizeof(xhex),0,1);
}
break;
case 's': ;
char* cptr = va_arg(vl,char*);
if(!cptr)
cptr = "<nullstr>";
if(*cptr){
i32 str_length = cptr_length(cptr);
if(written + str_length > buffer_size)
return kprintf_BUFFER_IS_TOO_SMALL;
memcpy(buffer + written, cptr, str_length);
written += str_length;
}
break;
case 'c': ;
char ch = (char)va_arg(vl,int);
if(written > buffer_size)
return kprintf_BUFFER_IS_TOO_SMALL;
buffer[written++] = ch;
break;
default:
const char errformat_str[] = "<INCORRECT FORMAT STRING>";
if(written + (i32)sizeof(errformat_str) <= buffer_size)
memcpy(buffer + written, errformat_str, sizeof(errformat_str));
return kprintf_INVALID_FORMAT;
}
if(argstr){
i32 str_length = cptr_length(argstr);
if(written + str_length > buffer_size)
return kprintf_BUFFER_IS_TOO_SMALL;
memcpy(buffer + written, argstr, str_length);
written += str_length;
free(argstr);
}
}
// common characters
else {
if(written > buffer_size)
return kprintf_BUFFER_IS_TOO_SMALL;
buffer[written++] = c;
}
}
va_end(vl);
if(written > buffer_size)
return kprintf_BUFFER_IS_TOO_SMALL;
buffer[written] = '\0';
return i;
} }

View File

@@ -6,9 +6,64 @@ extern "C" {
#include "../base/type_system/base_toString.h" #include "../base/type_system/base_toString.h"
// cross-platform printf analog #define kprintf_INVALID_FORMAT -1
void kprintf(const char* format, ...); #define kprintf_NOT_ENOUGH_ARGUMENTS -2
#define kprintf_BUFFER_IS_TOO_SMALL -3
#define kprintf_BUFFER_IS_NULL -4
/// cross-platform printf analog
///@return number of processed format string characters or error code
i32 _kprintf(const char* format, const i32 args_count, ...);
#define kprintf(FORMAT, ARGS... ) _kprintf(FORMAT, count_args(ARGS) ,##ARGS)
/// @return number of processed format string characters or error code
i32 _ksprintf(char* buffer, i32 buffer_size, const char* format, const i32 args_count, ...);
#define ksprintf(BUFFER, BUFFER_SIZE, FORMAT, ARGS... ) _ksprintf(BUFFER, BUFFER_SIZE, FORMAT, count_args(ARGS) ,##ARGS)
// printf format terminal color sequence
#define _PRINTF_COLOR(N) "\e["#N"m"
// foreground dark color codes
#define FBLK _PRINTF_COLOR(30)
#define FREDD _PRINTF_COLOR(31)
#define FGRND _PRINTF_COLOR(32)
#define FYELD _PRINTF_COLOR(33)
#define FBLUD _PRINTF_COLOR(34)
#define FMAGD _PRINTF_COLOR(35)
#define FCYND _PRINTF_COLOR(36)
#define FGRY _PRINTF_COLOR(37)
// foreground bright color codes
#define FGRYD _PRINTF_COLOR(90)
#define FRED _PRINTF_COLOR(91)
#define FGRN _PRINTF_COLOR(92)
#define FYEL _PRINTF_COLOR(93)
#define FBLU _PRINTF_COLOR(94)
#define FMAG _PRINTF_COLOR(95)
#define FCYN _PRINTF_COLOR(96)
#define FWHI _PRINTF_COLOR(97)
// background dark color codes
#define BBLK _PRINTF_COLOR(40)
#define BREDD _PRINTF_COLOR(41)
#define BGRND _PRINTF_COLOR(42)
#define BYELD _PRINTF_COLOR(43)
#define BBLUD _PRINTF_COLOR(44)
#define BMAGD _PRINTF_COLOR(45)
#define BCYND _PRINTF_COLOR(46)
#define BGRY _PRINTF_COLOR(47)
// background bright color codes
#define BGRYD _PRINTF_COLOR(100)
#define BRED _PRINTF_COLOR(101)
#define BGRN _PRINTF_COLOR(102)
#define BYEL _PRINTF_COLOR(103)
#define BBLU _PRINTF_COLOR(104)
#define BMAG _PRINTF_COLOR(105)
#define BCYN _PRINTF_COLOR(106)
#define BWHI _PRINTF_COLOR(107)
#if __cplusplus #if __cplusplus
} }
#endif #endif

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