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
50 changed files with 1600 additions and 319 deletions

4
.gitignore vendored
View File

@@ -6,6 +6,10 @@ obj/
.old*/ .old*/
.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>

14
.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",

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

2
cbuild

Submodule cbuild updated: ef6a3f82c4...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

@@ -44,16 +44,10 @@ 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];
IFMSC( ksprintf(errmsg,1024, "unexpected <%c> at:\n"
sprintf_s(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);
sprintf(errmsg, "unexpected <%c> at:\n"
" \"%s\"\n"
" \\___[%s:%d] %s()",
c,errBuf, srcfile,line,funcname)
);
safethrow(errmsg,;); safethrow(errmsg,;);
} }
#define safethrow_wrongchar(C, freeMem) { freeMem; return ERROR_WRONGCHAR(C, text, shared->sh_text_first, __FILE__,__LINE__,__func__); } #define safethrow_wrongchar(C, freeMem) { freeMem; return ERROR_WRONGCHAR(C, text, shared->sh_text_first, __FILE__,__LINE__,__func__); }
@@ -192,10 +186,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
char* _c=string_extract(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];
IFMSC( ksprintf(err,64,"can't parse to int: <%s>",_c);
sprintf_s(err,64,"can't parse to int: <%s>",_c),
sprintf(err,"can't parse to int: <%s>",_c)
);
safethrow(err,free(_c)); safethrow(err,free(_c));
} }
free(_c); free(_c);
@@ -208,10 +199,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
char* _c=string_extract(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];
IFMSC( ksprintf(err,64,"can't parse to int: <%s>",_c);
sprintf_s(err,64,"can't parse to int: <%s>",_c),
sprintf(err,"can't parse to int: <%s>",_c)
);
safethrow(err,free(_c)); safethrow(err,free(_c));
} }
free(_c); free(_c);

View File

@@ -36,9 +36,7 @@ Maybe dir_create(const char* path){
#endif #endif
{ {
char err[512]; char err[512];
IFWIN( ksprintf(err, 512, "can't create dicectory <%s>", path);
sprintf_s(err, 512, "can't create dicectory <%s>", path),
sprintf(err, "can't create dicectory <%s>", path));
safethrow(err,;); safethrow(err,;);
} }

View File

@@ -64,64 +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_create(); StringBuilder* sb=StringBuilder_create();
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_free(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);

View File

@@ -22,15 +22,15 @@ char* __path_concat(u32 n, ...){
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++){
memcopy(parts[k], totality, lengths[k]); memcpy(totality, parts[k], lengths[k]);
totality+=lengths[k]; totality+=lengths[k];
*totality=path_sep; *totality=path_sep;
totality++; totality++;
} }
memcopy(parts[k], totality, lengths[k]); memcpy(totality, parts[k], lengths[k]);
free(parts); free(parts);
free(lengths); free(lengths);
@@ -74,11 +74,11 @@ char* path_parentDir(char* dir){
char* path_basename(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(rezult); return string_extract(result);
} }

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

@@ -139,9 +139,6 @@ void StringBuilder_append_u64(StringBuilder* b, u64 a){
void StringBuilder_append_f64(StringBuilder* b, f64 a){ void StringBuilder_append_f64(StringBuilder* b, f64 a){
try_complete_buf(b); try_complete_buf(b);
char buf[32]; char buf[32];
IFMSC( ksprintf(buf,32,"%lf",a);
sprintf_s(buf,32,"%lf",a),
sprintf(buf,"%lf",a)
);
curr_buf_add_string(b, (string){.ptr=buf, .length=cptr_length(buf)}); curr_buf_add_string(b, (string){.ptr=buf, .length=cptr_length(buf)});
} }

View File

@@ -131,13 +131,6 @@ i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 see
return -1; return -1;
} }
void memcopy(void* from, void* to, u32 size){
if(from==NULL || to==NULL)
throw(ERR_NULLPTR);
for(u32 i=0; i<size; i++)
((char*)to)[i]=((char*)from)[i];
}
char* __cptr_concat(u32 n, ...){ char* __cptr_concat(u32 n, ...){
char** strs=(char**)malloc(n*sizeof(char*)); char** strs=(char**)malloc(n*sizeof(char*));
u32* lengths=malloc(n*sizeof(u32)); u32* lengths=malloc(n*sizeof(u32));
@@ -160,9 +153,9 @@ char* __cptr_concat(u32 n, ...){
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++){
memcopy(strs[k], totality, lengths[k]); memcpy(totality, strs[k], lengths[k]);
totality+=lengths[k]; totality+=lengths[k];
} }
@@ -212,6 +205,6 @@ char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new,
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

@@ -63,10 +63,12 @@ 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;
} }
void memcopy(void* from, void* to, u32 size); static inline bool cptr_containsChar(const char* src, char c){
return cptr_seekChar(src, c, 0, -1) != -1;
}
char* __cptr_concat(u32 n, ...); char* __cptr_concat(u32 n, ...);
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR) #define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)

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,27 +18,21 @@ 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);
IFMSC( ksprintf(result,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg);
sprintf_s(rezult,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg), return result;
sprintf(rezult,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg)
);
return rezult;
} }
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);
IFMSC( ksprintf(result,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname);
sprintf_s(rezult,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname),
sprintf(rezult,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname)
);
free(errmsg); free(errmsg);
return rezult; return result;
} }
void Maybe_free(Maybe e){ void Maybe_free(Maybe e){

View File

@@ -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,16 +73,17 @@ 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

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;

View File

@@ -70,10 +70,7 @@ char* toString_u64(u64 n, bool withPostfix, bool uppercase){
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=IFMSC( \ i32 cn = sprintf_s(str, bufsize, "%.*f", precision, n); \
sprintf_s(str, bufsize, "%.*f", precision, n), \
sprintf(str, "%.*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--; \

View File

@@ -5,6 +5,7 @@
#include "../../Hashtable/Hashtable.h" #include "../../Hashtable/Hashtable.h"
#include "../../String/StringBuilder.h" #include "../../String/StringBuilder.h"
#include "../../Filesystem/filesystem.h" #include "../../Filesystem/filesystem.h"
#include "../../Network/network.h"
#include "base_toString.h" #include "base_toString.h"
void kt_initKerepTypes(){ void kt_initKerepTypes(){
@@ -82,6 +83,13 @@ void kt_initKerepTypes(){
// StringBuilder // StringBuilder
kt_register(StringBuilder); kt_register(StringBuilder);
//File // File
kt_register(FileHandle); kt_register(FileHandle);
// Network
kt_register(knIPV4Address);
kt_register(knIPV4Endpoint);
kt_register(knSocketTCP);
kt_register(knSocketUDP);
kt_register(knSocketChanneled);
} }

View File

@@ -52,9 +52,14 @@ 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;
void kt_beginInit(bool printDebugMessages){
_printDebugMessages = printDebugMessages;
if(printDebugMessages)
kprintf("\e[94mtype descriptors initializing...\n"); kprintf("\e[94mtype descriptors initializing...\n");
__descriptorPointers=Autoarr_create(Pointer, 256, 256); __descriptorPointers=Autoarr_create(Pointer, 256, 256);
} }
@@ -65,6 +70,7 @@ void kt_endInit(){
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers); typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers);
Autoarr_free(__descriptorPointers,true); Autoarr_free(__descriptorPointers,true);
if(typeDescriptors==NULL) throw(ERR_NULLPTR); if(typeDescriptors==NULL) throw(ERR_NULLPTR);
if(_printDebugMessages)
kprintf("\e[92minitialized %u type descriptors\n", ktid_last); kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
} }
@@ -74,10 +80,9 @@ 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];
} }

View File

@@ -17,7 +17,7 @@ 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

View File

@@ -85,11 +85,11 @@ char *Unitype_toString(Unitype u, u32 fmt)
valuestr = type->toString(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("{ 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)
free(valuestr); free(valuestr);
return rezult; return result;
} }
void printuni(Unitype v) void printuni(Unitype v)

View File

@@ -39,8 +39,8 @@ Maybe __next_toString(kp_fmt f, void* object){
} }
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;
} }
@@ -53,8 +53,8 @@ Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
StringBuilder_append_cptr(strb, mStr.value.VoidPtr); StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
Unitype_free(mStr.value); Unitype_free(mStr.value);
} }
char* rezult=StringBuilder_build(strb).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){
@@ -90,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;
@@ -113,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;
@@ -199,12 +197,12 @@ static const char* _kp_colorNames[16]={
"white" "white"
}; };
char* kp_bgColor_toString(kp_fmt 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(kp_fmt 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

@@ -4,6 +4,8 @@
extern "C" { extern "C" {
#endif #endif
#include "../base/type_system/typedef_macros.h"
// 10000000 00000000 00000000 00000000 // 10000000 00000000 00000000 00000000
// ^ ^^^^ // ^ ^^^^
// | color num // | color num

View File

@@ -45,91 +45,90 @@ 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;
for(char c=format[i++]; c!=0; c=format[i++]){ i32 args_left = args_count;
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( 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( 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(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(&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(&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(&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=malloc(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); free(argstr);
} }
} }
// escape sequences // escape sequences
else if(c=='\e'){ else if(c == '\e'){
IFWIN( //////////////////// 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;
@@ -138,11 +137,12 @@ void kprintf(const char* format, ...){
} }
} }
} }
}), ////////////////////// UNIX //////////////////////
/* UNIX */ #else
putc(c,stdout); putc(c,stdout);
); #endif
} }
// common characters // common characters
else { else {
putc(c,stdout); putc(c,stdout);
@@ -152,4 +152,112 @@ void kprintf(const char* format, ...){
#endif #endif
} }
va_end(vl); va_end(vl);
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,8 +6,63 @@ 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
} }

View File

@@ -57,8 +57,8 @@ static inline i32 krand_next32(krand_statePtr state, i32 from, i32 to) __krand_n
static inline i64 krand_next64(krand_statePtr state, i64 from, i64 to) __krand_next_definition(64) static inline i64 krand_next64(krand_statePtr state, i64 from, i64 to) __krand_next_definition(64)
// divides random number by 2^64 to return a value between 0 and 1 // divides random number by 2^64 to return a value between 0 and 1
static inline f32 krand_nextFloat32(krand_statePtr state) {return (u32)KRAND_ALG32_next(state)/0xffffffff; } static inline f32 krand_nextFloat32(krand_statePtr state) {return (f32)KRAND_ALG32_next(state) / (u32)(-1); }
static inline f64 krand_nextFloat64(krand_statePtr state) {return KRAND_ALG64_next(state)/0xffffffff; } static inline f64 krand_nextFloat64(krand_statePtr state) {return (f64)KRAND_ALG64_next(state) / (u64)(-1); }
///@param chance (0-1.0) is probability of success ///@param chance (0-1.0) is probability of success

48
src/time/time.c Normal file
View File

@@ -0,0 +1,48 @@
// posix version definition to use clock_gettime
#ifndef _XOPEN_SOURCE
#if __STDC_VERSION__ >= 199901L
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE 500
#endif
#endif
#include "time.h"
#include <time.h>
#define K 1000
#define M 1000000
#define G 1000000000
nsec_t getTimeNsec(){
struct timespec t;
if(clock_gettime(CLOCK_REALTIME, &t) != 0)
throw(ERR_UNEXPECTEDVAL);
u64 n = t.tv_sec * G + t.tv_nsec;
return n;
}
usec_t getTimeUsec(){
struct timespec t;
if(clock_gettime(CLOCK_REALTIME, &t) != 0)
throw(ERR_UNEXPECTEDVAL);
u64 n = t.tv_sec * M + t.tv_nsec / K;
return n;
}
void sleepNsec(nsec_t time){
struct timespec t = {
.tv_sec = time / G,
.tv_nsec = time % G
};
if(nanosleep(&t, NULL) != 0)
throw(ERR_UNEXPECTEDVAL);
}
void sleepUsec(usec_t time){
sleepNsec(time * K);
}
void sleepMsec(msec_t time){
sleepNsec(time * M);
}

30
src/time/time.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
/// nanoseconds
typedef u64 nsec_t;
/// microseconds
typedef u64 usec_t;
/// miliseconds
typedef u64 msec_t;
/// system time now in nanoseconds
///@return u64 will overflow in 13 years
nsec_t getTimeNsec();
/// system time now in microseconds
///@return u64 will overflow in 58494 years
usec_t getTimeUsec();
void sleepNsec(nsec_t time);
void sleepUsec(usec_t time);
void sleepMsec(msec_t time);
#if __cplusplus
}
#endif

View File

@@ -3,11 +3,11 @@
i32 main(){ i32 main(){
if(setlocale(LC_CTYPE, "C.UTF-8")!=0) if(setlocale(LC_CTYPE, "C.UTF-8")!=0)
kprintf("\e[93msetlocale failed\n"); kprintf("\e[93msetlocale failed\n");
kt_beginInit(); kt_beginInit(true);
kt_initKerepTypes(); kt_initKerepTypes();
kt_endInit(); kt_endInit();
test_all(); test_all();
kt_free(); kt_free();
kprintf("\e[0m\n"); kprintf("\e[37m\n");
return 0; return 0;
} }

View File

@@ -38,10 +38,7 @@ void printrowgraph(Hashtable* ht){
char* genkey(u32 i){ char* genkey(u32 i){
char* key=malloc(12); char* key=malloc(12);
IFMSC( ksprintf(key,12,"key_%u",i);
sprintf_s(key,12,"key_%u",i),
sprintf(key,"key_%u",i)
);
return key; return key;
} }

View File

@@ -5,7 +5,7 @@ void test_kprint(){
//int //int
kprint(kp_fgCyan| kprint(kp_fgCyan|
kp_i,-8888, kp_c,' ', kp_i,0, kp_c,' ', kp_i,1234567890987654321LL,kp_s,"\n"); kp_i,-8888, kp_c,' ', kp_i,0, kp_c,' ', kp_i,1234567890987654321LL,kp_s,"\n");
//u //uint
kprint(kp_fgGreen| kprint(kp_fgGreen|
kp_u|kp_post,-8888, kp_c|kp_post|kp_upper,' ', kp_u,0, kp_c,' ', kp_u|kp_post,-8888, kp_c|kp_post|kp_upper,' ', kp_u,0, kp_c,' ',
kp_u,1234567890987654321LL, kp_c,'\n'); kp_u,1234567890987654321LL, kp_c,'\n');
@@ -15,7 +15,7 @@ void test_kprint(){
kp_f,-1.0f, kp_c,' ', kp_f,0.0f, kp_c,' ', kp_f,1.0f, kp_c,'\n', kp_f,-1.0f, kp_c,' ', kp_f,0.0f, kp_c,' ', kp_f,1.0f, kp_c,'\n',
kp_f|kp_post,0.000020004f, kp_c,' ', kp_f|kp_post,0.000020004f, kp_c,' ',
kp_f|kp_post|kp_upper,4000.0109f, kp_c,'\n'); kp_f|kp_post|kp_upper,4000.0109f, kp_c,'\n');
//f64 //double
kprint(kp_fgYellowD| kprint(kp_fgYellowD|
kp_f,-4000.0109, kp_c,' ', kp_f,-0.000020004, kp_c,'\n', kp_f,-4000.0109, kp_c,' ', kp_f,-0.000020004, kp_c,'\n',
kp_f,-1.0, kp_c,' ', kp_f,0.0, kp_c,' ', kp_f,1.0, kp_c,'\n', kp_f,-1.0, kp_c,' ', kp_f,0.0, kp_c,' ', kp_f,1.0, kp_c,'\n',

240
tests/test_network.c Normal file
View File

@@ -0,0 +1,240 @@
#include "tests.h"
#include "../src/Network/network.h"
#include <pthread.h>
static void __test_knIPV4Address_fromStr(char* addrStr, u8 a, u8 b, u8 c, u8 d){
knIPV4Address addr;
tryLast(knIPV4Address_fromStr(addrStr, &addr), maybeAddr, ;)
kprintf("\e[92mknIPV4Address_fromStr(\e[96m%s\e[92m) -> ", addrStr);
if(addr.UintBigEndian != knIPV4Address_fromBytes(a,b,c,d).UintBigEndian){
kprintf("\e[91m%u.%u.%u.%u\n",
(u8)addr.bytes[0], (u8)addr.bytes[1], (u8)addr.bytes[2], (u8)addr.bytes[3]);
throw("knIPV4Address_fromStr returned wrong value");
}
else {
kprintf("\e[94m%u.%u.%u.%u\n",
(u8)addr.bytes[0], (u8)addr.bytes[1], (u8)addr.bytes[2], (u8)addr.bytes[3]);
}
}
#define test_knIPV4Address_fromStr(a,b,c,d) __test_knIPV4Address_fromStr(#a"."#b"."#c"."#d, a,b,c,d)
static void test_network_types(){
PRINT_SIZEOF(knIPV4Address);
PRINT_SIZEOF(knPort);
PRINT_SIZEOF(knIPV4Endpoint);
PRINT_SIZEOF(knSocketTCP);
PRINT_SIZEOF(knSocketUDP);
PRINT_SIZEOF(knPackage);
PRINT_SIZEOF(knChannel);
test_knIPV4Address_fromStr(127,0,0,1);
test_knIPV4Address_fromStr(34,255,45,0);
test_knIPV4Address_fromStr(3,3,3,128);
fflush(stdout);
}
static pthread_mutex_t stdout_mutex = {0};
// thread-safe print
#define kprintf_safe(ARGS...) pthread_mutex_lock(&stdout_mutex); kprintf(ARGS); fflush(stdout); pthread_mutex_unlock(&stdout_mutex);
typedef struct {
knSocketTCP* socket_client;
knIPV4Endpoint serverEnd;
} tcp_client_connect_async_data;
void* tcp_client_connect_async(void* _data){
tcp_client_connect_async_data* data = _data;
tryLast(knSocketTCP_connect(data->socket_client, data->serverEnd), _m8531,;);
kprintf_safe("\e[92mclient socket connected to server\n");
char* adrstr = knIPV4Endpoint_toString(data->socket_client->localEndpoint);
kprintf("\e[92mclient socket was implicitely bound to %s\n\e[94m", adrstr);
free(adrstr);
free(data);
return NULL;
}
static void test_tcp(){
kprintf("\e[96m----------[test_network/tcp]----------\n");
knIPV4Endpoint serverEnd = knIPV4Endpoint_create(knIPV4Address_LOOPBACK, 4444);
knSocketTCP *socket_server, *clientConnection, *socket_client;
// server
{
tryLast(knSocketTCP_open(true), m_socketS, ;);
socket_server=m_socketS.value.VoidPtr;
kprintf("\e[92mTCP server socket created\n");
tryLast(knSocketTCP_bind(socket_server, serverEnd), _m81775, ;)
tryLast(knSocketTCP_listen(socket_server), _m88775, ;)
kprintf("\e[92mserver socket is listening\n");
}
// client
{
tryLast(knSocketTCP_open(false), m_socketC, ;);
socket_client=m_socketC.value.VoidPtr;
kprintf("\e[92mTCP client socket created\n");
tcp_client_connect_async_data* client_connection_data = malloc(sizeof(tcp_client_connect_async_data));
client_connection_data->serverEnd = serverEnd;
client_connection_data->socket_client = socket_client;
pthread_t client_connection_thread;
fflush(stdout);
if(pthread_create(&client_connection_thread, NULL, tcp_client_connect_async, client_connection_data) != 0)
throw("can't create client connection thread");
if(pthread_detach(client_connection_thread) != 0)
throw("can't detatch client connection thread");
}
// server
{
tryLast(knSocketTCP_accept(socket_server), m_connection, ;);
clientConnection = m_connection.value.VoidPtr;
kprintf_safe("\e[92mserver accepted client connection\n");
}
// client
{
const char client_msg[] = "ping";
tryLast(knSocketTCP_send(socket_client, client_msg, sizeof(client_msg)), _mu75q2, ;);
kprintf("\e[92mmessage sent to server\n\e[94m");
}
// server
{
char received_client_msg[32];
tryLast(knSocketTCP_receive(clientConnection, received_client_msg, sizeof(received_client_msg)), m_recCount, ;);
u64 recCount = m_recCount.value.UInt64;
fwrite(received_client_msg, sizeof(char), recCount, stdout);
fputc('\n', stdout);
if(!cptr_equals(received_client_msg, "ping"))
throw("received_client_msg != \"ping\"");
kprintf("\e[92mmessage received by server\n");
const char server_msg[] = "pong";
tryLast(knSocketTCP_send(clientConnection, server_msg, sizeof(server_msg)), _mu75q2, ;);
kprintf("\e[92mmessage sent to client\n\e[94m");
fflush(stdout);
}
// client
{
char received_server_msg[32];
tryLast(knSocketTCP_receive(socket_client, received_server_msg, sizeof(received_server_msg)), m_recCount, ;);
u64 recCount = m_recCount.value.UInt64;
fwrite(received_server_msg, sizeof(char), recCount, stdout);
fputc('\n', stdout);
if(!cptr_equals(received_server_msg, "pong"))
throw("received_server_msg != \"pong\"");
kprintf("\e[92mmessage received by client\n");
fflush(stdout);
}
// server
{
tryLast(knSocketTCP_shutdown(clientConnection, knShutdownType_Both), _m2351, ;);
tryLast(knSocketTCP_close(clientConnection), _m9776, ;);
kprintf("\e[92mclient connection closed\n");
tryLast(knSocketTCP_close(socket_server), _m676, ;);
kprintf("\e[92mTCP server socket closed\n");
}
// client
{
tryLast(knSocketTCP_close(socket_client), _m964, ;);
kprintf("\e[92mTCP client socket closed\n");
}
fflush(stdout);
}
void test_udp(){
kprintf("\e[96m----------[test_network/udp]----------\n");
knIPV4Endpoint serverEnd = knIPV4Endpoint_create(knIPV4Address_LOOPBACK, 4444);
knSocketUDP *socket_server, *socket_client;
// server
{
tryLast(knSocketUDP_open(true), m_socketS, ;);
socket_server=m_socketS.value.VoidPtr;
kprintf("\e[92mUDP server socket created\n");
tryLast(knSocketUDP_bind(socket_server, serverEnd), _m81775, ;)
kprintf("\e[92mserver socket is bound\n");
}
// client
{
tryLast(knSocketUDP_open(false), m_socketC, ;);
socket_client=m_socketC.value.VoidPtr;
kprintf("\e[92mUDP client socket created\n");
const char client_msg[] = "ping";
tryLast(knSocketUDP_sendTo(socket_client, client_msg, sizeof(client_msg), serverEnd), _mu75q2, ;);
kprintf("\e[92mmessage sent to server\n\e[94m");
char* adrstr = knIPV4Endpoint_toString(socket_client->localEndpoint);
kprintf("\e[92mclient socket was implicitely bound to %s\n\e[94m", adrstr);
free(adrstr);
}
// server
{
char received_client_msg[32];
knIPV4Endpoint clientEnd = knIPV4Endpoint_INVALID;
tryLast(knSocketUDP_receiveAny(socket_server, received_client_msg, sizeof(received_client_msg), &clientEnd), m_recCount, ;);
u64 recCount = m_recCount.value.UInt64;
fwrite(received_client_msg, sizeof(char), recCount, stdout);
fputc('\n', stdout);
if(!cptr_equals(received_client_msg, "ping"))
throw("received_client_msg != \"ping\"");
kprintf("\e[92mmessage received by server\n");
const char server_msg[] = "pong";
tryLast(knSocketUDP_sendTo(socket_server, server_msg, sizeof(server_msg), clientEnd), _mu75q2, ;);
char* adrstr = knIPV4Endpoint_toString(clientEnd);
kprintf("\e[92mmessage sent to client (%s)\n\e[94m", adrstr);
free(adrstr);
fflush(stdout);
}
// client
{
char received_server_msg[32];
knIPV4Endpoint senderEnd = knIPV4Endpoint_INVALID;
tryLast(knSocketUDP_receiveAny(socket_client, received_server_msg, sizeof(received_server_msg), &senderEnd), m_recCount, ;);
u64 recCount = m_recCount.value.UInt64;
fwrite(received_server_msg, sizeof(char), recCount, stdout);
fputc('\n', stdout);
if(!cptr_equals(received_server_msg, "pong"))
throw("received_server_msg != \"pong\"");
char* adrstr = knIPV4Endpoint_toString(serverEnd);
kprintf("\e[92mmessage received by client (%s)\n", adrstr);
free(adrstr);
fflush(stdout);
}
// server
{
tryLast(knSocketUDP_close(socket_server), _m676, ;);
kprintf("\e[92mUDP server socket closed\n");
}
// client
{
tryLast(knSocketUDP_close(socket_client), _m964, ;);
kprintf("\e[92mUDP client socket closed\n");
}
fflush(stdout);
}
void test_network(){
optime(__func__,1,({
kprintf("\e[96m------------[test_network]------------\n");
tryLast(kn_tryInit(), _mjj64g, ;);
kprintf("\e[92mkerepNetwork initialized\n");
if(pthread_mutex_init(&stdout_mutex, NULL) != 0)
throw("can't init mutex");
test_network_types();
test_tcp();
test_udp();
if(pthread_mutex_destroy(&stdout_mutex) != 0)
throw("can't destroy mutex");
tryLast(kt_tryDispose(), _m88ag, ;);
kprintf("\e[92mkerepNetwork disposed\n");
}));
}

View File

@@ -19,6 +19,7 @@ void test_rng_algorithms();
void test_kprint_colors(); void test_kprint_colors();
void test_kprint(); void test_kprint();
void test_type_system(); void test_type_system();
void test_network();
inline void test_all(){ inline void test_all(){
kprintf("\e[97mkerep tests are starting!\n"); kprintf("\e[97mkerep tests are starting!\n");
@@ -36,6 +37,7 @@ inline void test_all(){
test_hash_functions(); test_hash_functions();
test_hashtable(); test_hashtable();
test_dtsod(); test_dtsod();
test_network();
kprintf("\e[96m--------------------------------------\e[0m\n"); kprintf("\e[96m--------------------------------------\e[0m\n");
); );
} }