// about
/*
licenze:
This code and its derivatives can be used under the following conditions:
- Do not attack other countries.
- Jerk off on public at least 1 time per day.
- Observe hygiene.
- check my other projects https://chiselapp.com/user/sergey6661313
about:
ScalpiEditor - ansi-only text editor for terminals.
killer features: no. its just editor.
Compile:
this file is just part of zig version (for now)
current version used zig compiller for compile zig file. (unstructions inside zig file)
in future you can use any C compiller, but not now.
nevest C compillers is DUMB!
they insert thousands of checks of what I did not ask them to insert. Here is how you can avoid it:
-fno-stack-protector -fno-sanitize=undefined
also for debug use:
-Og -g
todo. alse try next keys for optimize size
-ffunction-sections -fdata-sections -Wl,--gc-sections
-nostdlib -Oz -Qn -m32 -static -s -N -Wl,--build-id=none -fno-asynchronous-unwind-tables
to support me
with boosty:
https://boosty.to/cutloosedev
with monero:
87T7 qGbA TrM3 a6Br
DyeC jQQf NWtU u3iZ
bHVB MC6W mEbN NE13
Qrrt KhBb e4vF 58NR
8PTF dYk2 Sozc HexX
4Q69 jbdQ Asrs P7B
why i cancel use zig:
gabarages in output code.
zig perfecly crash without printing stack trace in non standart situations.
Zig does not try fix console flags before print stack trace.
zig can crash to segfault like c.
tagged enum does not sense.
c: tagged_enum.tag = ANOTHER_TAG;
zig: tagged_enum = .{.ANOTHER_TAG = tagged_enum.LAST_USED_TAG.data};
operator ".?" does not sense:
c: while(link) { i++; link = link->next; }
zig: while(link) |_| { i += 1; link = link.?.next; }
zig idiomatic: while(link) |unwrapped_link|{ i += 1; link = unwrapped_link.next; }
nullable types are inconvenient.
c: if (link) i++;
zig idiomatic: if (link) |_| i += 1;
zig but C pointer: if (@intFromPtr(link) != @intFromPtr(c.NULL)) i += 1;
*/
// TODO
/*
remove name buffer_len. use buffer_max_size and buffer_used instead.
fix bold in folding mode. why one upper line is skipped?
update OsConsoleInput_Handle // remove C variant.
*/
// enums and constants
// compilation target
// os
#define __TargetOs_windows__ 1
#define __TargetOs_linux__ 2
// memory type
#define __TargetMemoryType_endiansLittle__ 1
#define __TargetMemoryType_endiansBig__ 2
// time
#define __Time_msPerS__ 1000
// OsNetwork
#define __OsNetworkTcp_maxAllowedListenPort__ 49151
#define __OsNetworkTcpSocketConnectResult_error__ -1
#define __OsNetworkTcpSocketConnectResult_inProgress__ 0
#define __OsNetworkTcpSocketConnectResult_success__ 1
// scalpi
#define __TextCharsDecFromU64_lenMax__ __CText_len__("18446744073709551615")
// __LoggerWriters__
#define __LoggerWriter_toFallback__ 0
#define __LoggerWriter_toFile__ 1
#define __LoggerWriter_toConsole__ 2
#define __LoggerWriter_toTerminal__ 3
// Scalpi_Console_ansi_input_Key
// ascii
#define __ConsoleAnsiInputKey_ascii_ctrl__ (-'a' + 1) /* do not use externally */
#define __ConsoleAnsiInputKey_ctrl_bs__ 8 /* also ctrl_h */
#define __ConsoleAnsiInputKey_tab__ 9 /* also ctrl_i */
#define __ConsoleAnsiInputKey_enter__ 13 /* also ctrl_m */
#define __ConsoleAnsiInputKey_escape__ 27
#define __ConsoleAnsiInputKey_back_space__ 127 /* sometime delete */
#define __ConsoleAnsiInputKey_ctrl_a__ ('a' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 1 start_of_heading */
#define __ConsoleAnsiInputKey_ctrl_b__ ('b' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 2 */
#define __ConsoleAnsiInputKey_ctrl_c__ ('c' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 3 */
#define __ConsoleAnsiInputKey_ctrl_d__ ('d' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 4 */
#define __ConsoleAnsiInputKey_ctrl_e__ ('e' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 5 */
#define __ConsoleAnsiInputKey_ctrl_f__ ('f' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 6 */
#define __ConsoleAnsiInputKey_ctrl_g__ ('g' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 7 */
#define __ConsoleAnsiInputKey_ctrl_h__ ('h' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 8 also */ ctrl_bs */
#define __ConsoleAnsiInputKey_ctrl_i__ ('i' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 9 also */ tab */
#define __ConsoleAnsiInputKey_ctrl_j__ ('j' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 10 */
#define __ConsoleAnsiInputKey_ctrl_k__ ('k' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 11 vertical_tab */ */
#define __ConsoleAnsiInputKey_ctrl_l__ ('l' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 12 formFeed */ */
#define __ConsoleAnsiInputKey_ctrl_m__ ('m' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 13 also */ enter */
#define __ConsoleAnsiInputKey_ctrl_n__ ('n' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 14 */
#define __ConsoleAnsiInputKey_ctrl_o__ ('o' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 15 */
#define __ConsoleAnsiInputKey_ctrl_p__ ('p' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 16 */
#define __ConsoleAnsiInputKey_ctrl_q__ ('q' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 17 */
#define __ConsoleAnsiInputKey_ctrl_r__ ('r' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 18 */
#define __ConsoleAnsiInputKey_ctrl_s__ ('s' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 19 */
#define __ConsoleAnsiInputKey_ctrl_t__ ('t' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 20 */
#define __ConsoleAnsiInputKey_ctrl_u__ ('u' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 21 */
#define __ConsoleAnsiInputKey_ctrl_v__ ('v' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 22 */
#define __ConsoleAnsiInputKey_ctrl_w__ ('w' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 23 */
#define __ConsoleAnsiInputKey_ctrl_x__ ('x' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 24 */
#define __ConsoleAnsiInputKey_ctrl_y__ ('y' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 25 */
#define __ConsoleAnsiInputKey_ctrl_z__ ('z' + __ConsoleAnsiInputKey_ascii_ctrl__) /* 26 */
// __ConsoleAnsiInputKey_non_ascii__
#define __ConsoleAnsiInputKey_special__ (1 << 8)
#define __ConsoleAnsiInputKey_functional__ (1 << 9)
#define __ConsoleAnsiInputKey_ctrl__ (1 << 10)
#define __ConsoleAnsiInputKey_alt__ (1 << 11)
#define __ConsoleAnsiInputKey_shift__ (1 << 12)
#define __ConsoleAnsiInputKey_mouse__ (1 << 13)
// FN
#define __ConsoleAnsiInputKey_f1__ (1 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f2__ (2 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f3__ (3 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f4__ (4 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f5__ (5 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f6__ (6 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f7__ (7 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f8__ (8 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f9__ (9 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f10__ (10 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f11__ (11 + __ConsoleAnsiInputKey_functional__)
#define __ConsoleAnsiInputKey_f12__ (12 + __ConsoleAnsiInputKey_functional__)
// arrows
// left
#define __ConsoleAnsiInputKey_left__ (1 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_ctrl_left__ (__ConsoleAnsiInputKey_left__ + __ConsoleAnsiInputKey_ctrl__)
#define __ConsoleAnsiInputKey_alt_left__ (__ConsoleAnsiInputKey_left__ + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_shift_left__ (__ConsoleAnsiInputKey_left__ + __ConsoleAnsiInputKey_shift__)
#define __ConsoleAnsiInputKey_ctrl_shift_left__ (__ConsoleAnsiInputKey_left__ + __ConsoleAnsiInputKey_ctrl__ + __ConsoleAnsiInputKey_shift__)
// right
#define __ConsoleAnsiInputKey_right__ (2 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_ctrl_right__ (__ConsoleAnsiInputKey_right__ + __ConsoleAnsiInputKey_ctrl__)
#define __ConsoleAnsiInputKey_alt_right__ (__ConsoleAnsiInputKey_right__ + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_shift_right__ (__ConsoleAnsiInputKey_right__ + __ConsoleAnsiInputKey_shift__)
#define __ConsoleAnsiInputKey_ctrl_shift_right__ (__ConsoleAnsiInputKey_right__ + __ConsoleAnsiInputKey_ctrl__ + __ConsoleAnsiInputKey_shift__)
// up
#define __ConsoleAnsiInputKey_up__ (3 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_ctrl_up__ (__ConsoleAnsiInputKey_up__ + __ConsoleAnsiInputKey_ctrl__)
#define __ConsoleAnsiInputKey_alt_up__ (__ConsoleAnsiInputKey_up__ + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_shift_up__ (__ConsoleAnsiInputKey_up__ + __ConsoleAnsiInputKey_shift__)
// down
#define __ConsoleAnsiInputKey_down__ (4 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_ctrl_down__ (__ConsoleAnsiInputKey_down__ + __ConsoleAnsiInputKey_ctrl__)
#define __ConsoleAnsiInputKey_alt_down__ (__ConsoleAnsiInputKey_down__ + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_shift_down__ (__ConsoleAnsiInputKey_down__ + __ConsoleAnsiInputKey_shift__)
// spec keys
#define __ConsoleAnsiInputKey_delete__ (5 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_shift_delete__ (__ConsoleAnsiInputKey_delete__ + __ConsoleAnsiInputKey_shift__)
#define __ConsoleAnsiInputKey_page_up__ (6 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_page_down__ (7 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_end__ (8 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_home__ (9 + __ConsoleAnsiInputKey_special__)
#define __ConsoleAnsiInputKey_ctrl_enter__ (__ConsoleAnsiInputKey_enter__ + __ConsoleAnsiInputKey_special__ + __ConsoleAnsiInputKey_ctrl__)
#define __ConsoleAnsiInputKey_ctrl_triangular_open_quotation_mark__ ('<' + __ConsoleAnsiInputKey_special__ + __ConsoleAnsiInputKey_ctrl__)
#define __ConsoleAnsiInputKey_ctrl_triangular_close_quotation_mark__ ('>' + __ConsoleAnsiInputKey_special__ + __ConsoleAnsiInputKey_ctrl__)
#define __ConsoleAnsiInputKey_ctrl_alt_v__ ('v' + __ConsoleAnsiInputKey_alt__ + __ConsoleAnsiInputKey_ctrl__)
// altX
#define __ConsoleAnsiInputKey_alt_a__ ('a' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_b__ ('b' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_c__ ('c' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_d__ ('d' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_e__ ('e' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_f__ ('f' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_g__ ('g' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_h__ ('h' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_i__ ('i' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_j__ ('j' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_k__ ('k' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_l__ ('l' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_m__ ('m' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_n__ ('n' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_o__ ('o' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_p__ ('p' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_q__ ('q' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_r__ ('r' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_s__ ('s' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_t__ ('t' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_u__ ('u' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_v__ ('v' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_w__ ('w' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_x__ ('x' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_y__ ('y' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_z__ ('z' + __ConsoleAnsiInputKey_alt__)
// alt_shiftX,
#define __ConsoleAnsiInputKey_alt_M__ ('M' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_N__ ('N' + __ConsoleAnsiInputKey_alt__)
// altN
#define __ConsoleAnsiInputKey_alt_0__ ('0' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_1__ ('1' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_2__ ('2' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_3__ ('3' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_4__ ('4' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_5__ ('5' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_6__ ('6' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_7__ ('7' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_8__ ('8' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_9__ ('9' + __ConsoleAnsiInputKey_alt__)
// alt_spec
#define __ConsoleAnsiInputKey_alt_comma__ (',' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_dot__ ('.' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_open_bracket__ ('[' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_close_bracket__ (']' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_semicolon__ (';' + __ConsoleAnsiInputKey_alt__)
#define __ConsoleAnsiInputKey_alt_apostrophe__ ('`' + __ConsoleAnsiInputKey_alt__)
// websocket
#define __NetworkTcpHttpWebSocketHandShake_encoded_len__ 28
// settings
// platform
// #define __target_os__ __TargetOs_
#ifndef __target_os__
#ifdef _WIN32
#define __target_os__ __TargetOs_windows__
#elif defined(__linux__)
#define __target_os__ __TargetOs_linux__
#endif
#endif
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
#else
#error "__target_os__ not implemented"
#endif
#define __target_memory_type__ __TargetMemoryType_endiansLittle__
#define __with_network__ 0
#define __OsFilePathLen_max__ 1024
#define __OsNetworkTcp_maxClientCount__ 8
#define __OsNetworkTcpHttp_maxHeaders__ 48
#define __TerminalInput_size__ 32
// App
#define __App_expectedFps__ 30
#define __AppEditorLineLen_max__ (1024 * 8)
// imports
// libC
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fenv.h>
#include <float.h>
#include <inttypes.h>
#include <iso646.h>
#include <limits.h>
#include <locale.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <string.h>
#include <tgmath.h>
#include <time.h>
#include <uchar.h>
#include <wchar.h>
#include <wctype.h>
#if __target_os__ == __TargetOs_windows__
// posix
#include <fcntl.h>
// Windows
#if __with_network__
#include <ws2tcpip.h> // include before windows.h
#include <winsock2.h>
#endif
#include <windef.h>
#include <windows.h>
#include <winuser.h>
#include <commctrl.h>
#include <io.h>
#include <conio.h>
#ifdef __COMPILED_FROM_ZIG_FILE__
#define INVALID_HANDLE_VALUE (HANDLE)0xFFFFFFFF
#endif
#elif __target_os__ == __TargetOs_linux__
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#include <time.h>
#if __with_network__
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <sys/socket.h>
#endif
#endif
// strings
#define __NetworkWsQuery_expected__ "GET /ws"
#define __TextCharsDecFromU64_lenMax__ __CText_len__("18446744073709551615")
// Scalpi_Console_ansi
#define Scalpi_Console_ansi_esc "\x1B"
#define __ConsoleAnsi_control__ Scalpi_Console_ansi_esc "["
// clear_output
#define Scalpi_Console_ansi_output_clear_to_end_line __ConsoleAnsi_control__ "0K"
#define Scalpi_Console_ansi_output_clear_to_start_line __ConsoleAnsi_control__ "1K"
#define Scalpi_Console_ansi_output_clear_line __ConsoleAnsi_control__ "2K"
// cursor
#define Scalpi_Console_ansi_output_cursor_hide __ConsoleAnsi_control__ "?25l"
#define Scalpi_Console_ansi_output_cursor_show __ConsoleAnsi_control__ "?25h"
#define __ConsoleAnsiOutputCursorStyle_reset__ __ConsoleAnsi_control__ "0 q"
#define Scalpi_Console_ansi_output_cursor_style_blinking_block __ConsoleAnsi_control__ "1 q"
#define Scalpi_Console_ansi_output_cursor_style_steady_block __ConsoleAnsi_control__ "2 q"
#define Scalpi_Console_ansi_output_cursor_style_blinking_underline __ConsoleAnsi_control__ "3 q"
#define Scalpi_Console_ansi_output_cursor_style_steady_underline __ConsoleAnsi_control__ "4 q"
#define Scalpi_Console_ansi_output_cursor_style_blinking_I_beam __ConsoleAnsi_control__ "5 q"
#define Scalpi_Console_ansi_output_cursor_style_steady_I_beam __ConsoleAnsi_control__ "6 q"
// color
#define Scalpi_Console_ansi_output_FontStyle_color_zero "39"
#define Scalpi_Console_ansi_output_FontStyle_color_black "30"
#define Scalpi_Console_ansi_output_FontStyle_color_red "31"
#define Scalpi_Console_ansi_output_FontStyle_color_green "32"
#define Scalpi_Console_ansi_output_FontStyle_color_gold "33"
#define Scalpi_Console_ansi_output_FontStyle_color_blue "34"
#define Scalpi_Console_ansi_output_FontStyle_color_magenta "35"
#define Scalpi_Console_ansi_output_FontStyle_color_cyan "36"
#define Scalpi_Console_ansi_output_FontStyle_color_light_gray "37"
#define Scalpi_Console_ansi_output_FontStyle_color_gray "90"
#define Scalpi_Console_ansi_output_FontStyle_color_pink "91"
#define Scalpi_Console_ansi_output_FontStyle_color_light_green "92"
#define Scalpi_Console_ansi_output_FontStyle_color_yellow "93"
#define Scalpi_Console_ansi_output_FontStyle_color_light_blue "94"
#define Scalpi_Console_ansi_output_FontStyle_color_light_magenta "95"
#define Scalpi_Console_ansi_output_FontStyle_color_light_cyan "96"
#define Scalpi_Console_ansi_output_FontStyle_color_white "97"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_zero "49"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_black "40"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_red "41"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_green "42"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_gold "43"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_blue "44"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_magenta "45"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_cyan "46"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_gray "47"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_gray "100"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_pink "101"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_green "102"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_yellow "103"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_blue "104"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_magenta "105"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_cyan "106"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_white "107"
#define Scalpi_Console_ansi_output_FontStyle_sep ";"
#define Scalpi_Console_ansi_output_FontStyle_end "m"
#define Scalpi_Console_ansi_output_FontStyle_reset "0"
#define Scalpi_Console_ansi_output_FontStyle_bold "1"
#define Scalpi_Console_ansi_output_FontStyle_dim "2"
#define Scalpi_Console_ansi_output_FontStyle_italic "3"
#define Scalpi_Console_ansi_output_FontStyle_underline "4"
#define Scalpi_Console_ansi_output_FontStyle_conceal "8"
#define Scalpi_Console_ansi_output_FontStyle_fraktur "20"
#define Scalpi_Console_ansi_output_FontStyle_unbold "21;24"
#define Scalpi_Console_ansi_output_FontStyle_set_color "38"
#define Scalpi_Console_ansi_output_FontStyle_set_bg_color "48"
#define Scalpi_Console_ansi_output_FontStyle_start __ConsoleAnsi_control__
#define __ConsoleAnsiOutputFontStyle_reset__ Scalpi_Console_ansi_output_FontStyle_start Scalpi_Console_ansi_output_FontStyle_reset Scalpi_Console_ansi_output_FontStyle_end
// mouse
#define Scalpi_ansi_input_mouse_release __ConsoleAnsi_control__ "?1000l"
#define Scalpi_ansi_input_mouse_grab __ConsoleAnsi_control__ "?1000h"
// settings
#define __ConsoleAnsiOutputSettings_enableLineWrap__ __ConsoleAnsi_control__ "?7h"
#define __ConsoleAnsiOutputSettings_disableLineWrap__ __ConsoleAnsi_control__ "?7l"
// # __OsFilePath_separator__
#if __target_os__ == __TargetOs_windows__
#define __OsFilePath_separator__ "\\"
#elif __target_os__ == __TargetOs_linux__
#define __OsFilePath_separator__ "/"
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
#define Base64_standard_alphabet_chars "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
// basic types
// scalpi
// # __ConsoleAnsiInputKey__
typedef
uint64_t
__ConsoleAnsiInputKey__
;
// # __WriteFnPtr__
typedef
size_t
(*__WriteFnPtr__)
(void* context, const char* bytes, size_t bytes_len)
;
// # __WriteFnPtrVoid__
typedef
void
(*__WriteFnPtrVoid__)
(void* context, const char* bytes, size_t bytes_len)
;
// OS
// # __OsFileHandle__
#if __target_os__ == __TargetOs_windows__
typedef HANDLE __OsFileHandle__;
#elif __target_os__ == __TargetOs_linux__
typedef int __OsFileHandle__;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
// # __OsConsoleInputHandle__
#if __target_os__ == __TargetOs_windows__
typedef void* __OsConsoleInputHandle__;
#elif __target_os__ == __TargetOs_linux__
typedef FILE* __OsConsoleInputHandle__;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
// # __OsConsoleOutputHandle__
#if __target_os__ == __TargetOs_windows__
typedef HANDLE __OsConsoleOutputHandle__;
#elif __target_os__ == __TargetOs_linux__
typedef int __OsConsoleOutputHandle__;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
// # __OsNetworkTcpHandle__
#if __target_os__ == __TargetOs_windows__
typedef SOCKET __OsNetworkTcpHandle__;
#elif __target_os__ == __TargetOs_linux__
typedef int __OsNetworkTcpHandle__;
#else
#error "__target_os__ not implemented"
#endif
// macroses
// c
#define or ||
#define and &&
#define __addrFromPtr__(ptr) ((uintptr_t)(ptr))
#define __ptrFromInt__(type, number) ((type*)number)
#define __getFieldPtr__(obj, field) (&((obj)->field))
#define __getField__(ptr, offset, type) (* (*type) ( __addrFromPtr__(ptr) + offset ) )
#define __alignOf__(type) (offsetof(struct { char c; type member; }, member))
#define __fieldParentPtr__(type, field, instance) ((type *)(__addrFromPtr__(instance) - offsetof(type, field)))
#define __arrayLen__(array) (sizeof(array) / sizeof(array[0]))
// text
#define __CText_len__(str) (__arrayLen__(str) - 1)
#define __CTextPtr_fromCText__(text) ((char(*)[__CText_len__(text)]) text)
#define __CTextPtr_lvalue__(name, text) (char(*name)[__CText_len__(text)])
#define __CTextPtr_declare__(name, text) __CTextPtr_lvalue__(name, text) = __CTextPtr_fromCText__(text)
// slice
#define __len_and_text__(str) __CText_len__(str), str
#define __text_and_len__(str) str, __CText_len__(str)
#define __Slice_fromCText__(text) {.ptr=text, .len=__CText_len__(text)}
// crypto
#define Sha1_block_size 64
#define Sha1_digest_length 20
// Network
#if __target_os__ == __TargetOs_windows__
#define WSA_SUCCESS 0
#elif __target_os__ == __TargetOs_linux__
#else
#error "__target_os__ not implemented"
#endif
// Scalpi_network_tcp_http_WebSocket_Header
#define Scalpi_network_tcp_http_WebSocket_Header_Mask_size 4
// Scalpi_network_tcp_http_WebSocket_Header_Opcode
#define Scalpi_network_tcp_http_WebSocket_Header_Opcode_continuation 0
#define Scalpi_network_tcp_http_WebSocket_Header_Opcode_text 1
#define Scalpi_network_tcp_http_WebSocket_Header_Opcode_binary 2
#define Scalpi_network_tcp_http_WebSocket_Header_Opcode_close 8
#define Scalpi_network_tcp_http_WebSocket_Header_Opcode_ping 9
#define Scalpi_network_tcp_http_WebSocket_Header_Opcode_pong 10
// 2 bytes header for sizes 1 ... 125
#define Scalpi_network_tcp_http_WebSocket_Header_Size_small 0
#define Scalpi_network_tcp_http_WebSocket_Header_Size_small_header 2
#define Scalpi_network_tcp_http_WebSocket_Header_Size_small_extended_payload_len_size 0
// 4 bytes header for sizes 126 ... 65535
#define Scalpi_network_tcp_http_WebSocket_Header_Size_medium 1
#define Scalpi_network_tcp_http_WebSocket_Header_Size_medium_flag 126
#define Scalpi_network_tcp_http_WebSocket_Header_Size_medium_extended_payload_len_size 2
#define Scalpi_network_tcp_http_WebSocket_Header_Size_medium_header (Scalpi_network_tcp_http_WebSocket_Header_Size_small_header + Scalpi_network_tcp_http_WebSocket_Header_Size_medium_extended_payload_len_size)
// 10 bytes header for sizes more than 65535
#define Scalpi_network_tcp_http_WebSocket_Header_Size_long 2
#define Scalpi_network_tcp_http_WebSocket_Header_Size_long_flag 127
#define Scalpi_network_tcp_http_WebSocket_Header_Size_long_extended_payload_len_size 8
#define Scalpi_network_tcp_http_WebSocket_Header_Size_long_header (Scalpi_network_tcp_http_WebSocket_Header_Size_small_header + Scalpi_network_tcp_http_WebSocket_Header_Size_long_extended_payload_len_size)
// auto unwrap CText to text and len
// # __OsConsoleOutput_writeCText__
#define __OsConsoleOutput_writeCText__( ctx, text) \
__OsConsoleOutput_write__( ctx, text, __CText_len__(text))
// auto casting
// # __Mem_fillAny__
#define __Mem_fillAny__( dest, symbol, len) \
__Mem_fill__( (char*)dest, symbol, len)
// # __OsFile_readToAny__
#define __OsFile_readToAny__( file, buffer, buffer_len, offset ) \
__OsFile_readToBuffer__( file, (char*) (buffer), buffer_len, offset )
// # __OsMem_allocAny__
#define __OsMem_allocAny__( ret_data_addr, size) \
__OsMem_alloc__( (uintptr_t*) (ret_data_addr), size)
// # __OsMem_freeAny__
#define __OsMem_freeAny__( ret_data_addr) \
__OsMem_free__( (uintptr_t) (ret_data_addr))
// # __AlignedPtr_allocAny__
#define __AlignedPtr_allocAny__( ret_data_addr, mem_align, size) \
__AlignedPtr_alloc__( (uintptr_t*) (ret_data_addr), mem_align, size)
// # __AlignedPtr_freeAny__
#define __AlignedPtr_freeAny__( ret_data_addr, size) \
__AlignedPtr_free__( (uintptr_t) (ret_data_addr), size)
// # __FileComplete_readToAny__
#define __FileComplete_readToAny__( ret_data_ptr, ret_file_data_size, file_name, file_name_len, align ) \
__FileComplete_read__( (uintptr_t*)ret_data_ptr, ret_file_data_size, file_name, file_name_len, align )
// structs
// core
// # __Trace__
struct __Trace__ {
struct __Trace__ *__Trace_prevTrace__;
size_t __Trace_line__;
};
// memory
// # __AlignedPtr__
/* its a virtual struct becouse C not have "anytype" type.
struct __AlignedPtr__ {
char gap[gap_size] // padding for aligning data. gap_size can be 0.
anytype your_data // <- the pointer that the alloc function returns will be pointed here.
uint8_t gap_size
}
*/
// # __MemListLink__
struct __MemListLink__ {
struct __MemListLink__* prev;
struct __MemListLink__* next;
struct __MemList__* list;
};
// # __MemList__
struct __MemList__ {
struct __MemListLink__* first;
struct __MemListLink__* last;
size_t count;
};
// # Slice
struct Slice {
char* ptr;
size_t len;
};
// # Finder
struct Finder {
struct Slice text;
struct Slice desired;
size_t pos;
};
// Os
// system specifics
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
// # __OsLinux_timespec__
struct __OsLinux_timespec__ {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
#else
#error "__target_os__ not implemented"
#endif
// OsConsole
// # __OsConsoleFlags__
struct __OsConsoleFlags__ {
bool inited;
#if __target_os__ == __TargetOs_windows__
DWORD input_mode;
DWORD output_mode;
#elif __target_os__ == __TargetOs_linux__
struct termios termios;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
};
// # __OsConsoleInput__
struct __OsConsoleInput__ {
__OsConsoleInputHandle__ handle;
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
int fileno;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
};
// # __OsConsoleOutput__
struct __OsConsoleOutput__ {
__OsConsoleOutputHandle__ __OsConsoleOutput_handle__;
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
};
// # __OsHelper__
struct __OsHelper__ {
#if __target_os__ == __TargetOs_windows__
HINSTANCE instance;
void* console_input_handle;
__OsConsoleOutputHandle__ console_output_handle;
#if __with_network__
bool network_inited;
WSADATA wsdata;
#endif
#elif __target_os__ == __TargetOs_linux__
FILE* console_input_handle;
__OsConsoleOutputHandle__ console_output_handle;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
};
// Scalpi
// mem
// # __Writer__
struct __Writer__ {
void* context;
__WriteFnPtr__ write;
};
struct __MemTree__ {
struct __MemTree__* parent; // todo remove me. create func __MemTree_getParentByListLink__
struct __MemList__ childs;
struct __MemListLink__ link;
size_t count; // recurse. for get non recurse use childs.count
size_t nested;
};
// math
struct __math_d2_U_Pos__ {
size_t x;
size_t y;
};
// text
// # __TextFormatU64__
struct __TextFormatU64__ {
char buffer [__TextCharsDecFromU64_lenMax__];
char *ptr;
size_t len;
};
// # Scalpi_Text_Splitter
struct Scalpi_Text_Splitter {
struct Finder finder;
bool stop;
size_t last_pos;
};
// # __Logger__
struct __Logger__ {
// write to terminal, console, file or to all together, but no real check "bytes is writen"
struct __Writer__ writers[4]; // __LoggerWriters__
};
// Console
// __ConsoleAnsiInputKey_SequenceParser__
struct __ConsoleAnsiInputKey_SequenceParser__ {
__ConsoleAnsiInputKey__ sequence;
size_t used;
};
struct Scalpi_Console_ansi_input_Key_SequenceParser_fromBytes_SequenceInfo {
const char* text;
size_t len;
__ConsoleAnsiInputKey__ key;
};
struct __Console__ {
struct __OsConsoleInput__ input;
struct __OsConsoleOutput__ output;
};
// Terminal
typedef struct __math_d2_U_Pos__ __TerminalOutput_CursorPos__;
struct __TerminalOutput__ {
__TerminalOutput_CursorPos__ cursor_pos;
const char* font_style;
struct __math_d2_U_Pos__ size;
bool convert_n_to_rn;
bool apply_r;
bool apply_n;
};
struct __TerminalInput__ {
// usage:
// call __TerminalInput_updateBuffer__ for update unreaded
// use __TerminalInput_grab__ in loop for get keys
size_t ungrabed;
char buffer[__TerminalInput_size__];
};
struct __Terminal__ {
struct __Console__ *console;
struct __OsConsoleFlags__ system_flags;
struct __TerminalInput__ input;
struct __TerminalOutput__ output;
};
// crypto
// Sha1_Streaming
struct Sha1_Streaming {
uint32_t state[5];
char block[Sha1_block_size];
size_t buf_len; // current? filling level of block
uint64_t total_len;
};
struct RoundParam {uint32_t a; uint32_t b; uint32_t c; uint32_t d; uint32_t e; uint32_t i;};
// network
// Scalpi_network_tcp_Ip
// ip
struct Scalpi_network_tcp_Ip {
uint8_t address[4];
uint16_t port;
};
struct Scalpi_network_tcp_Ip_ToText {
/// 255.255.255.255:65535
/// 127. 0. 0. 1:27015
/// 0. 0. 0. 1: 0
char buffer[25];
size_t len;
};
#if __with_network__
struct Scalpi_network_tcp_Visitor {
__OsNetworkTcpHandle__ socket_handle;
struct Scalpi_network_tcp_Ip ip;
struct sockaddr_in addr;
};
#endif
struct Scalpi_network_tcp_Server {
bool ready;
__OsNetworkTcpHandle__ socket_handle;
size_t max_waiting_clients;
uint16_t port;
};
// Scalpi_network_tcp_http_WebSocket
// real struct of web socket header:
// fin_flag: u1 = 1,
// rsv: [3]u1 = .{0,0,0},
// opcode: Opcode = .binary, // may be text
// mask_flag: u1 = 0,
// payload_len: u7 = 0,
// extended_payload_len: u16 or u64 or void (optional)
// masking_key: u64 or void (optional)
struct Scalpi_network_tcp_http_WebSocket_Parser {
size_t frame_len;
size_t header_len;
char* message; // no null
size_t message_len;
};
// App
// # __AppEditorLine__
struct __AppEditorLine__ {
struct __MemListLink__ link; // used in Views.Flat.lines for iterating
struct __MemTree__ tree; // used in Views.Fold.lines
char text[__AppEditorLineLen_max__]; // todo use ptr to allocated data
size_t text_len;
};
// # __AppEditorHistoryNote__
struct __AppEditorHistoryNote__ {
__ConsoleAnsiInputKey__ key;
struct __MemListLink__ link;
};
// # App
struct App {
struct __OsHelper__ __App_osHelper__;
struct __Logger__ logger;
uint64_t tick;
};
// function prototypes
void __OsFile_truncate__( __OsFileHandle__ file);
void __OsFile_setPos__( __OsFileHandle__ file, size_t pos);
bool __OsMem_alloc__( uintptr_t *ret_data_addr, size_t size);
void __OsMem_free__( uintptr_t ret_data_addr);
bool __OsFile_exist__( const char* file_name, size_t file_name_len);
size_t __OsFallbackConsole_write__( void* unused_ctx, char* data, size_t len);
// globals
struct App global_app;
// functions
// CScpecific
// core
// TRACE
// # __Trace_init__
void __Trace_init__(
struct __Trace__ *trace,
struct __Trace__ *prev_trace // can be null
) {
trace->__Trace_prevTrace__ = prev_trace;
trace->__Trace_line__ = 0; // не треубется знать где был создан трейс. т.к. трейсы нужны для того чтобы хранить номер строки вызывающего кода (устанавливается в prev_trace макросом TC()), но если мы будем смотреть программу в отладчике - было бы полезно проинициализировать нулём для того чтобы видеть что значение ещё не изменялось.
}
// # __Trace_print__
void __Trace_print__(struct __Trace__ *trace) {
if (trace) {
printf("%zu", trace->__Trace_line__);
trace = trace->__Trace_prevTrace__;
while (trace) {
printf("|%zu", trace->__Trace_line__);
trace = trace->__Trace_prevTrace__;
}
} else {
printf("nil");
}
}
// # print_trace_example
void print_trace_example(
int anyarg,
struct __Trace__* prev_trace
) {
struct __Trace__ trace; __Trace_init__(&trace, prev_trace);
trace.__Trace_line__ = __LINE__; __Trace_print__(&trace);
}
// # call_other_trace_example
void call_other_trace_example(
struct __Trace__* prev_trace // can be null
) {
struct __Trace__ trace; __Trace_init__(&trace, prev_trace);
trace.__Trace_line__ = __LINE__; print_trace_example(0, &trace);
}
// mem
// bits operations
uint8_t bits_rotl8(uint8_t value, unsigned int shift) {
shift %= 8;
return (value << shift) | (value >> (8 - shift));
}
uint16_t bits_rotl16(uint16_t value, unsigned int shift) {
shift %= 16;
return (value << shift) | (value >> (16 - shift));
}
uint32_t bits_rotl32(uint32_t value, unsigned int shift) {
shift %= 32;
return (value << shift) | (value >> (32 - shift));
}
uint64_t bits_rotl64(uint64_t value, unsigned int shift) {
shift %= 64;
return (value << shift) | (value >> (64 - shift));
}
// bytes operations
// # __Mem_fill__
void __Mem_fill__(
char *dest,
char symbol,
size_t len
) {
for (size_t pos = 0; pos < len; pos++) {
dest[pos] = symbol;
}
}
// # __Mem_copy__
void __Mem_copy__( // todo create macros __Mem_copyAny__
char *dest,
const char *src,
size_t size
) {
// i use this instead memcpy becouse clang-in-zig just replace memcpy to crash-zig-bloated-version code
size_t pos = 0;
while(pos < size) {
dest[pos] = src[pos];
pos++;
}
}
// # __Mem_copyBackward__
void __Mem_copyBackward__(char* dest, const char* src, size_t size) {
size_t pos = size;
while(pos > 0) {
pos-=1;
dest[pos] = src[pos];
}
}
// # __Mem_reverse__
void __Mem_reverse__(
char *dest,
const char *src,
size_t len
) {
src = &src[len - 1];
size_t iter = 0;
for(; iter < len; iter++, dest++, src--) {
*dest = *src;
}
}
// # __Mem_findDiffOrLen__
size_t __Mem_findDiffOrLen__(const char a[], const char b[], size_t len) {
size_t pos = 0;
while(pos < len) {
if (a[pos] != b[pos]) break;
pos++;
}
return pos;
}
// # __Mem_isEql__
bool __Mem_isEql__(const char a[], const char b[], size_t len) {
return __Mem_findDiffOrLen__(a, b, len) == len;
}
// # __Mem_isEql_test_
bool __Mem_isEql_test_() {
return true
and (__Mem_isEql__("abcd", "abcd", 4))
and (__Mem_isEql__("abcd", "abce", 4) == false)
and (__Mem_isEql__("abcdasdasd", "asd", 3) == false)
;
}
// # writeWithOffset
void writeWithOffset(char* dest, size_t* writed, char* data, size_t data_len) {
__Mem_copy__(&dest[*writed], data, data_len);
*writed += data_len;
}
// __AlignedPtr__
// # __AlignedPtr_alloc__
bool __AlignedPtr_alloc__(
uintptr_t *ret_data_addr,
uint8_t data_align, // expected >= 1
size_t data_size // expected >= 1
) {
bool ok = true;
uint8_t gap_size = 0;
size_t allocated_size = data_size + (data_align - 1) + sizeof(gap_size);
uintptr_t allocated_addr;
if (__OsMem_allocAny__(&allocated_addr, allocated_size)) {
// calc size of gap
uint8_t nodled = allocated_addr % data_align;
if (nodled) {
gap_size = data_align - nodled;
}
// write ret_data_addr
uintptr_t data_addr = allocated_addr + gap_size;
*ret_data_addr = data_addr;
// save gap size
* (uint8_t*) (data_addr + data_size) = gap_size;
if (!ok) __OsMem_freeAny__(allocated_addr);
} else {
ok = false;
}
return ok;
}
// # __AlignedPtr_free__
void __AlignedPtr_free__(
uintptr_t data_addr,
size_t data_size
) {
uint8_t gap_size = * (uint8_t*) (data_addr + data_size);
__OsMem_freeAny__(data_addr - gap_size);
}
// format_number
bool cpu_checkNumberFormat() {
char current_endians = 0;
int n = 1;
if (* (char *) &n == 1) {
current_endians = __TargetMemoryType_endiansLittle__;
} else {
current_endians = __TargetMemoryType_endiansBig__;
}
if (__target_memory_type__ == current_endians) {
return true;
} else {
printf("%d wrong MEMORY_TYPE !\r\n", __LINE__);
}
return false;
}
#if __target_memory_type__ == __TargetMemoryType_endiansBig__
#define nativeToBig(dest, src, size) __Mem_copy__(dest, src, size)
#define nativeToLittle(dest, src, size) __Mem_reverse__(dest, src, size)
#elif __target_memory_type__ == __TargetMemoryType_endiansLittle__
#define nativeToBig(dest, src, size) __Mem_reverse__(dest, src, size)
#define nativeToLittle(dest, src, size) __Mem_copy__(dest, src, size)
#else
#error "please define __target_memory_type__ with __TargetMemoryType_ (you can test endings with cpu_checkNumberFormat function)"
#endif
// read unaligned memory
// big
uint16_t readBig16(char* src) {
uint16_t ret;
nativeToBig( (char*) &ret, src, 2);
return ret;
}
uint32_t readBig32(char* src) {
uint32_t ret;
nativeToBig( (char*) &ret, src, 4);
return ret;
}
uint64_t readBig64(char* src) {
uint64_t ret;
nativeToBig( (char*) &ret, src, 8);
return ret;
}
// little
uint16_t readLittle16(char* src) {
uint16_t ret;
nativeToLittle( (char*) &ret, src, 2);
return ret;
}
uint32_t readLittle32(char* src) {
uint32_t ret;
nativeToLittle( (char*) &ret, src, 4);
return ret;
}
uint64_t readLittle64(char* src) {
uint64_t ret;
nativeToLittle( (char*) &ret, src, 8);
return ret;
}
// write unaligned memory
// big
// # writeBig16
void writeBig16(
char *dest,
uint16_t value
) {
nativeToBig( dest, (char*)&value, 2);
}
// # writeBig32
void writeBig32(
char *dest,
uint32_t value
) {
nativeToBig(dest, (char*)&value, 4);
}
// # writeBig64
void writeBig64(
char *dest,
uint64_t value
) {
nativeToBig(dest, (char*)&value, 8);
}
// little
// # writeLittle16
void writeLittle16(
char *dest,
uint16_t value
) {
nativeToLittle(dest, (char*)&value, 2);
}
// # writeLittle32
void writeLittle32(
char *dest,
uint32_t value
) {
nativeToLittle(dest, (char*)&value, 4);
}
// # writeLittle64
void writeLittle64(
char *dest,
uint64_t value
) {
nativeToLittle(dest, (char*)&value, 8);
}
// Slice
// # Slice_debug
void Slice_debug(struct Slice* slice, char* name, size_t line) {
if (slice->len == 0) {
printf("%zu: %s is NULL. \r\n", line, name);
} else {
printf("%zu: %s (%zu): \"%.*s", line, name, slice->len, (int)slice->len, slice->ptr);
}
}
// # Scalpi_mem_find
bool Scalpi_mem_find(struct Slice* slice, struct Slice* desired, uintptr_t* out_pos) {
// not fast
if (slice->len >= desired->len) {
uintptr_t last_pos = slice->len - desired->len;
for (uintptr_t pos = 0; pos <= last_pos; pos++) {
size_t slice_len = slice->len - pos;
if (slice_len >= desired->len) {
if (__Mem_isEql__(&slice->ptr[pos], desired->ptr, desired->len)) {
*out_pos = pos;
return true;
}
} else {
break;
}
}
} else {
// printf("%d desired is too long\r\n", __LINE__);
}
return false;
}
// # isStartWith
bool isStartWith(struct Slice* a, struct Slice* b) {
return (a->len >= b->len) && __Mem_isEql__(a->ptr, b->ptr, b->len);
}
// Finder
void Finder_init(struct Finder* t, char* text, size_t text_len, char* desired, size_t desired_len) {
t->pos = 0;
t->text.ptr = text;
t->text.len = text_len;
t->desired.ptr = desired;
t->desired.len = desired_len;
}
bool Finder_next(struct Finder* t, size_t* out_pos) {
if (t->pos != t->text.len) {
struct Slice slice; // = t->text[->.pos..];
slice.ptr = &t->text.ptr[t->pos];
slice.len = t->text.len - t->pos;
size_t finded;
if (Scalpi_mem_find(&slice, &t->desired, &finded)) {
size_t new_pos = t->pos + finded;
t->pos = new_pos + t->desired.len;
*out_pos = new_pos;
return true;
}
}
return false;
}
// text Splitter
void Scalpi_Text_Splitter_init(struct Scalpi_Text_Splitter* t, char* text, size_t text_len, char* delim, size_t delim_len) {
t->stop = false;
t->last_pos = 0;
Finder_init(&t->finder, text, text_len, delim, delim_len);
}
bool Scalpi_Text_Splitter_next(struct Scalpi_Text_Splitter* t, struct Slice* out_slice) {
if (t->stop == false) {
size_t finded;
if (Finder_next(&t->finder, &finded)) {
out_slice->ptr = &t->finder.text.ptr[t->last_pos]; // slice = t->finder.text[t->last_pos..finded];
out_slice->len = finded - t->last_pos;
t->last_pos = t->finder.pos;
return true;
} else {
t->stop = true;
out_slice->ptr = &t->finder.text.ptr[t->last_pos]; // slice = t->finder.text[t->last_pos..];
out_slice->len = t->finder.text.len - t->last_pos;
t->last_pos = t->finder.pos;
return true;
}
}
return false;
}
// math
uint32_t ceilDiv32(uint32_t a, uint32_t b) {
return (a + b - 1) / b;
}
// __TextFormatU64__ (utoa utos)
// # __TextFormatU64_do__
void __TextFormatU64_do__(
struct __TextFormatU64__ *t,
uint64_t number,
size_t min_width
) {
size_t len = 0;
uintptr_t buffer_start = (uintptr_t) &t->buffer[0];
uintptr_t buffer_end = buffer_start + __TextCharsDecFromU64_lenMax__;
// write utoa
uintptr_t addr = buffer_end;
for (uint64_t num = number; num > 0; num = num / 10) {
uint8_t remainder = num % 10;
addr = addr - 1;
*(char*) addr = '0' + (char) remainder;
}
len = buffer_end - addr;
// fill zeroes to min_width
if (min_width > len) {
size_t fill_len = min_width - len;
addr = addr - fill_len;
__Mem_fillAny__(addr, '0', fill_len);
len = len + fill_len;
}
t->ptr = (char*) addr;
t->len = len;
}
// # __Text_formatU64ToBuffer__
size_t __Text_formatU64ToBuffer__(
char *buffer, // expected len >= __TextCharsDecFromU64_lenMax__
uint64_t number,
size_t min_width
) {
struct __TextFormatU64__ format;
__TextFormatU64_do__(&format, number, min_width);
if (format.len > 0) {
__Mem_copy__(buffer, format.ptr, format.len);
}
return format.len;
}
// # __Text_formatU64__
size_t __Text_formatU64__(__WriteFnPtrVoid__ fn_write, void* context, uint64_t number, size_t min_width) {
struct __TextFormatU64__ format;
__TextFormatU64_do__(&format, number, min_width);
fn_write(context, format.ptr, format.len);
return format.len;
}
// ZText - zero ended text
// # __ZText_fromBytes__
void __ZText_fromBytes__(char* buffer, const char bytes[], size_t bytes_len) {
// expected buffer_len >= bytes_len + 1
__Mem_copy__(buffer, bytes, bytes_len);
buffer[bytes_len] = 0;
}
// # __ZText_countLen__
size_t __ZText_countLen__(const char text[]) {
size_t len = 0;
while(text[len] != 0) len++;
return len;
}
// # __ZText_writeToBuffer__
size_t __ZText_writeToBuffer__(char buffer[], const char data[]) {
const size_t len = __ZText_countLen__(data);
__Mem_copy__(buffer, data, len);
return len;
}
// # __ZText_writeToWriteFn__
size_t __ZText_writeToWriteFn__(__WriteFnPtr__ fn_write, void* context, const char text[]) {
const size_t len = __ZText_countLen__(text);
fn_write(context, text, len);
return len;
}
// Os
// mem
// # __OsMem_alloc__
bool __OsMem_alloc__( // TODO use real system alloc?
uintptr_t *ret,
size_t size
) {
bool ok = true;
char* ptr = malloc(size);
if (ptr) {
*ret = (uintptr_t) ptr;
} else {
ok = false;
// TODO print debug
}
return ok;
}
// # __OsMem_free__
void __OsMem_free__(uintptr_t ptr) {
free((void*) ptr);
}
// enviroment
// # __OsEnvHome_getLen__
size_t __OsEnvHome_getLen__() {
size_t len = 0;
#if __target_os__ == __TargetOs_windows__
char* home_drive = getenv("HOMEDRIVE");
len += __ZText_countLen__(home_drive);
char* home_path = getenv("HOMEPATH");
len += __ZText_countLen__(home_path);
#elif __target_os__ == __TargetOs_linux__
char* home = getenv("HOME");
len += __ZText_countLen__(home);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return len;
}
// # __OsEnvHome_write__
void __OsEnvHome_write__(
char* buffer // expected len >= __OsEnvHome_getLen__()
) {
#if __target_os__ == __TargetOs_windows__
size_t writed = 0;
// write HOMEDRIVE
char* home_drive = getenv("HOMEDRIVE");
size_t home_drive_len = __ZText_countLen__(home_drive);
__Mem_copy__(&buffer[writed], home_drive, home_drive_len);
writed += home_drive_len;
// write HOMEPATH
char* home_path = getenv("HOMEPATH");
size_t home_path_len = __ZText_countLen__(home_path);
__Mem_copy__(&buffer[writed], home_path, home_path_len);
writed += home_path_len;
#elif __target_os__ == __TargetOs_linux__
char* home = getenv("HOME");
size_t len = __ZText_countLen__(home);
__Mem_copy__(buffer, home, len);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// file
// # __OsFile_clear__
void __OsFile_clear__(
__OsFileHandle__ file
) {
__OsFile_setPos__(file, 0);
__OsFile_truncate__(file);
}
// # __OsFile_exist__
bool __OsFile_exist__(
const char* file_name,
size_t file_name_len // expected < __OsFilePathLen_max__
) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
char file_name_z[__OsFilePathLen_max__ + 1]; // create null terminated string
__Mem_copy__(file_name_z, file_name, file_name_len);
file_name_z[file_name_len] = 0;
DWORD attrs = GetFileAttributesA(file_name_z);
if (true
and (attrs != INVALID_FILE_ATTRIBUTES)
and (!(attrs & FILE_ATTRIBUTE_DIRECTORY))
) {
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
char file_name_z[__OsFilePathLen_max__ + 1]; // create null terminated string
__Mem_copy__(file_name_z, file_name, file_name_len);
file_name_z[file_name_len] = 0;
struct stat buffer;
if (stat(file_name_z, &buffer) == 0) {
} else {
ok = false;
}
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return ok;
}
// # __OsFile_create__
bool __OsFile_create__(
__OsFileHandle__ *ret,
const char file_name[],
size_t file_name_len // expected < __OsFilePathLen_max__
) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
char file_name_z[__OsFilePathLen_max__ + 1]; // null terminated string
__Mem_copy__(file_name_z, file_name, file_name_len);
file_name_z[file_name_len] = 0;
HANDLE file = CreateFile( // open
file_name_z, // [in] LPCSTR lpFileName,
GENERIC_WRITE | GENERIC_READ, // [in] DWORD dwDesiredAccess,
0, // [in] DWORD dwShareMode, // TODO also try FILE_SHARE_WRITE
NULL, // [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
OPEN_ALWAYS, // [in] DWORD dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL, // [in] DWORD dwFlagsAndAttributes,
NULL // [in, optional] HANDLE hTemplateFile
);
if (file != INVALID_HANDLE_VALUE) {
*ret = file;
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
char file_name_z[__OsFilePathLen_max__ + 1]; // create null terminated string
__Mem_copy__(file_name_z, file_name, file_name_len);
file_name_z[file_name_len] = 0;
int file = creat(file_name_z, 0777);
if (file != -1) {
*ret = file;
} else {
ok = false;
}
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return ok;
}
// # __OsFile_open__
bool __OsFile_open__(
__OsFileHandle__ *ret,
const char file_name[],
size_t file_name_len // expected < __OsFilePathLen_max__
) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
char file_name_z[__OsFilePathLen_max__ + 1]; // null terminated string
__Mem_copy__(file_name_z, file_name, file_name_len);
file_name_z[file_name_len] = 0;
HANDLE file = CreateFile( // open
file_name_z, // [in] LPCSTR lpFileName,
GENERIC_WRITE | GENERIC_READ, // [in] DWORD dwDesiredAccess,
0, // [in] DWORD dwShareMode, // TODO also try FILE_SHARE_WRITE
NULL, // [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
OPEN_EXISTING, // [in] DWORD dwCreationDisposition,
FILE_ATTRIBUTE_NORMAL, // [in] DWORD dwFlagsAndAttributes,
NULL // [in, optional] HANDLE hTemplateFile
);
if (file != INVALID_HANDLE_VALUE) {
*ret = file;
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
char file_name_z[__OsFilePathLen_max__ + 1]; // null terminated string
__Mem_copy__(file_name_z, file_name, file_name_len);
file_name_z[file_name_len] = 0;
// open
int file = open(file_name_z, O_RDWR);
if (file != -1) {
*ret = file;
} else {
ok = false;
}
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return ok;
}
// # __OsFile_openOrCreate__
bool __OsFile_openOrCreate__(
__OsFileHandle__ *ret,
const char file_name[],
size_t file_name_len // expected < __OsFilePathLen_max__
) {
if (__OsFile_exist__(file_name, file_name_len)) {
return __OsFile_open__(ret, file_name, file_name_len);
} else {
return __OsFile_create__(ret, file_name, file_name_len);
}
}
// # __OsFile_close__
void __OsFile_close__(
__OsFileHandle__ file
) {
#if __target_os__ == __TargetOs_windows__
CloseHandle(file);
#elif __target_os__ == __TargetOs_linux__
close(file);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// # __OsFile_getPos__
size_t __OsFile_getPos__(
__OsFileHandle__ file
) {
#if __target_os__ == __TargetOs_windows__
LARGE_INTEGER liPosition = {0};
LARGE_INTEGER liNewPosition = {0};
BOOL sfp_result = SetFilePointerEx (
file,
liPosition,
&liNewPosition,
FILE_CURRENT
);
if (sfp_result == FALSE) {
// unexpected
int err = GetLastError();
printf("%d SetFilePointerEx error: %d", __LINE__, err);
}
return liNewPosition.QuadPart;
#elif __target_os__ == __TargetOs_linux__
return lseek(file, 0, SEEK_CUR);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// # __OsFile_setPos__
void __OsFile_setPos__(
__OsFileHandle__ file,
size_t pos
) {
#if __target_os__ == __TargetOs_windows__
LARGE_INTEGER liPosition = {0};
liPosition.QuadPart = pos;
BOOL sfp_result = SetFilePointerEx(file, liPosition, NULL, FILE_BEGIN);
if (sfp_result == FALSE) {
// unexpeced
printf("%d, unexpected SetFilePointer result", __LINE__);
}
#elif __target_os__ == __TargetOs_linux__
lseek(file, pos, SEEK_SET);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// # __OsFile_readToBuffer__
bool __OsFile_readToBuffer__(
__OsFileHandle__ file,
char *buffer,
size_t buffer_len,
size_t offset
) {
bool ok = true;
size_t readed = 0;
while (ok and (readed < buffer_len)) {
__OsFile_setPos__(file, offset + readed);
#if __target_os__ == __TargetOs_windows__
__OsFile_setPos__(file, offset + readed);
size_t readed_atom = 0;
if (ReadFile(file, &buffer[readed], buffer_len - readed, &readed_atom, NULL)) {
readed += readed_atom;
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
__OsFile_setPos__(file, offset + readed);
ssize_t read_result = read(file, &buffer[readed], buffer_len - readed);
if (read_result >= 0) {
readed += read_result;
} else {
ok = false;
}
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
return ok;
}
// # __OsFile_write__
bool __OsFile_write__(
__OsFileHandle__ file,
const char* data,
size_t data_len,
size_t offset
) {
bool ok = true;
size_t writed = 0;
while (ok and (writed < data_len)) {
__OsFile_setPos__(file, offset + writed);
#if __target_os__ == __TargetOs_windows__
DWORD atom_writed = 0;
if ( WriteFile(file, &data[writed], data_len - writed, &atom_writed, NULL) ) {
writed += atom_writed;
ok = FlushFileBuffers(file);
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
ssize_t atom_write = write(file, &data[writed], data_len - writed);
if (atom_write != -1) {
writed += atom_write;
} else {
ok = false;
}
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
return ok;
}
// # __OsFile_getSize__
size_t __OsFile_getSize__(
__OsFileHandle__ file
) {
#if __target_os__ == __TargetOs_windows__
LARGE_INTEGER size;
if (GetFileSizeEx(file, &size)) {
return size.QuadPart;
} else {
// unexpected
return 0;
}
#elif __target_os__ == __TargetOs_linux__
struct stat st;
fstat(file, &st);
return st.st_size;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// # __OsFile_truncate__
void __OsFile_truncate__(
__OsFileHandle__ file
) {
#if __target_os__ == __TargetOs_windows__
bool ok = true;
if (FlushFileBuffers(file)) {
if (SetEndOfFile(file)) {
if (FlushFileBuffers(file)) {
} else { // unexpected
ok = false;
printf("%d unexpected retusult of FlushFileBuffers", __LINE__);
}
} else { // unexpected
ok = false;
printf("%d unexpected retusult of SetEndOfFile", __LINE__);
}
} else { // unexpected
ok = false;
printf("%d unexpected retusult of FlushFileBuffers", __LINE__);
}
if (!ok) printf("%d failue", __LINE__);
// return ok; not needed to real return ok state becouse expected posibly truncate any file without errors.
#elif __target_os__ == __TargetOs_linux__
size_t current_pos = __OsFile_getPos__(file);
ftruncate(file, current_pos);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// time
uint64_t __os_getTick__() {
#if __target_os__ == __TargetOs_windows__
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
uint64_t ft64;
__Mem_copy__((char*) &ft64, (char*) &ft, 8);
return ft64 / 10000; // in ft is intervals * 100 ns. to ms need * 100 / 1000000
#elif __target_os__ == __TargetOs_linux__
// NOT TESTED
struct timespec ts;
clock_gettime(CLOCK_REALTIME, (void*)&ts);
uint64_t ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
return ms;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
void Os_sleep(uint64_t ms) {
#if __target_os__ == __TargetOs_windows__
Sleep(ms);
#elif __target_os__ == __TargetOs_linux__
// NOT TESTED
struct timespec delay;
delay.tv_sec = ms / 1000;
delay.tv_nsec = (ms % 1000) * 1000000;
nanosleep(&delay, NULL);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// Console
// ConsoleOutput
// # __OsConsoleOutput_getSize__
void __OsConsoleOutput_getSize__ (
struct __OsConsoleOutput__ *t,
struct __math_d2_U_Pos__ *ret_pos
) {
#if __target_os__ == __TargetOs_windows__
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(t->__OsConsoleOutput_handle__, &csbi);
int x = csbi.srWindow.Right - csbi.srWindow.Left + 1;
int y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
ret_pos->x = x;
ret_pos->y = y;
// printf("%d, %d x %d\n", __LINE__, x, y);
#elif __target_os__ == __TargetOs_linux__
struct winsize w;
ioctl(t->__OsConsoleOutput_handle__, TIOCGWINSZ, &w);
ret_pos->x = w.ws_col;
ret_pos->y = w.ws_row;
#else
#error "__target_os__ not implemented"
#endif
}
// # __OsConsoleOutput_init__
void __OsConsoleOutput_init__(struct __OsConsoleOutput__* output, __OsConsoleOutputHandle__ handle) {
output->__OsConsoleOutput_handle__ = handle;
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
}
// # __OsConsoleOutput_write__
bool __OsConsoleOutput_write__(
struct __OsConsoleOutput__* os_console_output,
const char* data,
size_t _len
) {
bool ok = true;
// support null-string // todo remove me
size_t len = _len;
if (len == 0) {
while(data[len] != 0) len += 1;
}
#if __target_os__ == __TargetOs_windows__
unsigned long writed = 0;
WriteConsoleA(os_console_output->__OsConsoleOutput_handle__, data, len, &writed, NULL);
len = writed;
#elif __target_os__ == __TargetOs_linux__
// stdin = 0
// stdout = 1
// stderr = 2
if (write(1, data, len) == len) {
} else {
ok = false;
}
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return ok;
}
// ConsoleInput
// # __OsConsoleInput_readByte__
bool __OsConsoleInput_readByte__(struct __OsConsoleInput__* t, char* byte) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
INPUT_RECORD key;
DWORD picked = 0;
if ( ReadConsoleInputA(t->handle, &key, 1, &picked) ) {
if (picked != 0) {
if (key.EventType == KEY_EVENT) {
KEY_EVENT_RECORD *event = &key.Event.KeyEvent;
if (event->bKeyDown != 0) {
if (event->uChar.AsciiChar != 0) {
*byte = event->uChar.AsciiChar;
} else {ok = false;}
} else {ok = false;}
} else {ok = false;}
} else {ok = false;}
} else {ok = false;}
#elif __target_os__ == __TargetOs_linux__
ssize_t result = read(t->fileno, byte, 1);
if (result != 1) {ok = false;}
#else
#error "__target_os__ not implemented"
#endif
return ok;
}
// # __OsConsoleInput_getCountOfUnreaded__
bool __OsConsoleInput_getCountOfUnreaded__(struct __OsConsoleInput__* t, size_t *ret_unreaded) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
DWORD unreaded = 0;
if ( GetNumberOfConsoleInputEvents(t->handle, &unreaded) ) {
*ret_unreaded += unreaded;
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
int unreaded = 0;
int result = ioctl(t->fileno, FIONREAD, &unreaded);
*ret_unreaded += unreaded;
#else
#error "__target_os__ not implemented"
#endif
return ok;
}
// # __OsConsoleInput_init__
void __OsConsoleInput_init__(
struct __OsConsoleInput__* t,
__OsConsoleInputHandle__ input_hanle
) {
#if __target_os__ == __TargetOs_windows__
t->handle = input_hanle;
#elif __target_os__ == __TargetOs_linux__
t->handle = input_hanle;
t->fileno = fileno(t->handle);
#else
#error "__target_os__ not implemented"
#endif
}
// Flags
uint32_t __BitsU32_enable__(uint32_t value, uint32_t mask) {
return value | mask;
}
uint32_t __BitsU32_disable__(uint32_t value, uint32_t mask) {
return value & (~mask);
}
uint32_t __BitsU32_toggle__(uint32_t value, uint32_t mask, bool new_state) {
if (new_state) {
return __BitsU32_enable__(value, mask);
} else {
return __BitsU32_disable__(value, mask);
}
}
bool __OsConsoleFlags_setNonCanonicalMode__(struct __OsConsoleFlags__ *t) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
uint32_t input = t->input_mode;
input = __BitsU32_toggle__(input, ENABLE_EXTENDED_FLAGS, true);
input = __BitsU32_toggle__(input, ENABLE_ECHO_INPUT, false); // print pressed keys
input = __BitsU32_toggle__(input, ENABLE_LINE_INPUT, false); // wait '\n' (buffering on enter)
input = __BitsU32_toggle__(input, ENABLE_VIRTUAL_TERMINAL_INPUT, true);
input = __BitsU32_toggle__(input, ENABLE_PROCESSED_INPUT, false); // CTRL+C
input = __BitsU32_toggle__(input, ENABLE_MOUSE_INPUT, false);
input = __BitsU32_toggle__(input, ENABLE_QUICK_EDIT_MODE, true); // enable mouse select and copy
input = __BitsU32_toggle__(input, ENABLE_WINDOW_INPUT, false); // reported of change size of the console screen buffer
input = __BitsU32_toggle__(input, ENABLE_INSERT_MODE, true); // When enabled, text entered in a console window will be inserted at the current cursor location and all text following that location will not be overwritten. When disabled, all following text will be overwritten.
t->input_mode = input;
uint32_t output = t->output_mode;
output = __BitsU32_toggle__(output, ENABLE_LVB_GRID_WORLDWIDE, true); // enable colors
output = __BitsU32_toggle__(output, ENABLE_VIRTUAL_TERMINAL_PROCESSING, true); // emulate VT100
output = __BitsU32_toggle__(output, ENABLE_PROCESSED_OUTPUT, true); // Backspace, tab, bell, carriage return, and line feed characters are processed
output = __BitsU32_toggle__(output, ENABLE_WRAP_AT_EOL_OUTPUT, false); // disable line wrap
output = __BitsU32_toggle__(output, DISABLE_NEWLINE_AUTO_RETURN, true);
t->output_mode = output;
#elif __target_os__ == __TargetOs_linux__
// clear c_cc
cc_t* cc = &t->termios.c_cc[0]; // cc_t c_cc[NCCS]
for (int i = 0; i < NCCS ; i++) {
cc[i] = 0;
}
// timers off
cc = &t->termios.c_cc[0];
cc[VTIME] = 0;
cc[VMIN] = 1;
uint32_t cflag = t->termios.c_cflag;
cflag = __BitsU32_toggle__(cflag, CS8, true); // use 8 bit
cflag = __BitsU32_toggle__(cflag, CSTOPB, false); // two stops bits
cflag = __BitsU32_toggle__(cflag, PARENB, false); // parity check
cflag = __BitsU32_toggle__(cflag, PARODD, false); // parity check
t->termios.c_cflag = cflag;
uint32_t lflag = t->termios.c_lflag;
lflag = __BitsU32_toggle__(lflag, ISIG, false); // disable react to Ctrl+C
lflag = __BitsU32_toggle__(lflag, ICANON, false); // no wait '\n'
lflag = __BitsU32_toggle__(lflag, ECHO, false); // print pressed keys
lflag = __BitsU32_toggle__(lflag, ECHOE, false); // mashing
lflag = __BitsU32_toggle__(lflag, ECHONL, false); // print NL
lflag = __BitsU32_toggle__(lflag, ECHOK, false); // nl after clear line
lflag = __BitsU32_toggle__(lflag, ECHOKE, false); // print NL after BS
lflag = __BitsU32_toggle__(lflag, ECHOPRT, false); // print BS (BS SP BS)
lflag = __BitsU32_toggle__(lflag, IEXTEN, false); // special funcs
t->termios.c_lflag = lflag;
uint32_t iflag = t->termios.c_iflag;
iflag = __BitsU32_toggle__(iflag, IGNBRK, true); // ignore break control
iflag = __BitsU32_toggle__(iflag, BRKINT, true); // do not delete all data after break control
iflag = __BitsU32_toggle__(iflag, IXON, false); // disable react to Ctrl+S Ctlr+Q
iflag = __BitsU32_toggle__(iflag, ISTRIP, false); // strip
iflag = __BitsU32_toggle__(iflag, INLCR, false); // convert NL to CR
iflag = __BitsU32_toggle__(iflag, ICRNL, false); // convert CR to NL
iflag = __BitsU32_toggle__(iflag, XCASE, false); // convert register to UP
iflag = __BitsU32_toggle__(iflag, IUCLC, false); // convert register to down
iflag = __BitsU32_toggle__(iflag, IGNPAR, true); // ignore framing or parity errors
iflag = __BitsU32_toggle__(iflag, IMAXBEL, false); // no bell
t->termios.c_iflag = iflag;
uint32_t oflag = t->termios.c_oflag;
oflag = __BitsU32_toggle__(oflag, ONOCR, false); // on start line // Auto CR
oflag = __BitsU32_toggle__(oflag, ONLRET, false); // on end line // Auto CR
oflag = __BitsU32_toggle__(oflag, OPOST, true); // \_(O_o)_/
oflag = __BitsU32_toggle__(oflag, ONLCR, true); // NL to CR
oflag = __BitsU32_toggle__(oflag, OCRNL, false); // CR to NL
oflag = __BitsU32_toggle__(oflag, OLCUC, false); // convert to CAPS
oflag = __BitsU32_toggle__(oflag, XTABS, false); // convert tab
oflag = __BitsU32_toggle__(oflag, TAB3, false); // convert tab
oflag = __BitsU32_toggle__(oflag, OFDEL, false); // use null for deleted symbol
t->termios.c_oflag = oflag;
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return ok;
}
bool __OsConsoleFlags_apply__(
struct __OsConsoleFlags__ *t,
struct __OsConsoleInput__ *input,
struct __OsConsoleOutput__ *output
) {
// expected inited
bool ok = true;
#if __target_os__ == __TargetOs_windows__
int result1 = SetConsoleMode(input->handle, t->input_mode);
if (result1 == 0) {
ok = false;
// todo GetLastError();
}
int result2 = SetConsoleMode(output->__OsConsoleOutput_handle__, t->output_mode);
if (result2 == 0) {
ok = false;
// todo GetLastError();
}
#elif __target_os__ == __TargetOs_linux__
tcsetattr(input->fileno, TCSANOW, &t->termios);
tcsetattr(output->__OsConsoleOutput_handle__, TCSANOW, &t->termios);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return ok;
}
bool __OsConsoleFlags_init__(struct __OsConsoleFlags__ *t, struct __OsConsoleInput__* input, struct __OsConsoleOutput__ *output) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
bool result1 = GetConsoleMode(input->handle, &t->input_mode);
if (result1 != 0) {
bool result2 = GetConsoleMode(output->__OsConsoleOutput_handle__, &t->output_mode);
if (result2 != 0) {
t->inited = true;
} else {
ok = false;
}
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
int result = tcgetattr(input->fileno, &t->termios);
if (result == 0) {
t->inited = true;
} else {
ok = false;
}
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return ok;
}
// # __OsFallbackConsole_write__
size_t
__OsFallbackConsole_write__ (
void* unused_ctx,
char* data,
size_t len
) {
#if __target_os__ == __TargetOs_windows__
struct __OsConsoleOutput__ console_output;
__OsConsoleOutput_init__(&console_output, GetStdHandle(STD_OUTPUT_HANDLE));
__OsConsoleOutput_write__(&console_output, data, len);
#elif __target_os__ == __TargetOs_linux__
__OsConsoleOutput_write__ (NULL, data, len);
#else
#error "not implemented current __target_os__ or not defined. (expected __TargetOs_ value)"
#endif
return len;
}
// Helper
bool __OsHelper_init__(struct __OsHelper__* t) {
bool ok = true;
#if __target_os__ == __TargetOs_windows__
HMODULE instance = GetModuleHandleA(NULL);
if (instance != NULL) {
t->instance = instance;
HANDLE console_input_handle = GetStdHandle(STD_INPUT_HANDLE);
if (console_input_handle != INVALID_HANDLE_VALUE) {
t->console_input_handle = console_input_handle;
HANDLE console_output_handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (console_output_handle != INVALID_HANDLE_VALUE) {
t->console_output_handle = console_output_handle;
#if __with_network__
if (
WSAStartup(
514, // wVersionRequested ver 2.2
&t->wsdata
) == 0
) { } else {
ok = false;
}
#endif
} else {
ok = false;
}
} else {
ok = false;
}
} else {
ok = false;
}
#elif __target_os__ == __TargetOs_linux__
t->console_input_handle = stdin;
t->console_output_handle = 1; // standart output
#else
#error "__target_os__ not implemented"
#endif
return ok;
}
void __OsHelper_deinit__(struct __OsHelper__*t) {
#if __target_os__ == __TargetOs_windows__
#if __with_network__
WSACleanup();
#endif
FreeLibrary(t->instance);
#elif __target_os__ == __TargetOs_linux__
// nothing to do
#else
#error "__target_os__ not implemented"
#endif
}
void __OsHelper_process__(struct __OsHelper__* t) {
#if __target_os__ == __TargetOs_windows__
MSG msg;
if (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
#elif __target_os__ == __TargetOs_linux__
// nothing to do
#else
#error "__target_os__ not implemented"
#endif
}
// Scalpi
// mem
// ScalpiMemList
// __MemListLink__
// # __MemListLink_isFirst__
bool
__MemListLink_isFirst__(
struct __MemListLink__* link
) {
struct __MemListLink__* prev = link->prev;
bool prev_is_null = (link->prev) == NULL;
return prev_is_null;
}
// # __MemListLink_resetLinks__
void __MemListLink_resetLinks__(struct __MemListLink__* link) {
link->prev = NULL;
link->next = NULL;
link->list = NULL;
}
// # __MemListLink_init__
void __MemListLink_init__(
struct __MemListLink__* link
) {
__MemListLink_resetLinks__(link);
}
// # __MemList_init__
void __MemList_init__(
struct __MemList__* list
) {
list->first = NULL;
list->last = NULL;
list->count = 0;
}
// # __MemList_pushFirst__
void __MemList_pushFirst__(
struct __MemList__ *list,
struct __MemListLink__ *item // expected freed item
) {
struct __MemListLink__* first = list->first;
if (first) { // list not empty
first->prev = item;
item->next = first;
} else { // list is empty
list->last = item;
}
list->first = item;
item->list = list;
list->count += 1;
}
// # __MemList_pushLast__
void __MemList_pushLast__(
struct __MemList__ *list,
struct __MemListLink__ *item
) {
struct __MemListLink__* last = list->last;
if (last) {
last->next = item;
item->prev = last;
} else { // list empty
list->first = item;
}
list->last = item;
item->list = list;
list->count += 1;
}
// List
// # __MemList_pushBefore__
void __MemList_pushBefore__(
struct __MemList__* list,
struct __MemListLink__* before,
struct __MemListLink__* item
) {
struct __MemListLink__* prev = before->prev;
if (prev) { // non firts
prev->next = item;
} else { // is first
list->first = item;
}
item->prev = prev;
before->prev = item;
item->next = before;
item->list = list;
list->count += 1;
}
// # __MemList_pushAfter__
void __MemList_pushAfter__(
struct __MemList__* list,
struct __MemListLink__* after,
struct __MemListLink__* item
) {
struct __MemListLink__* next = after->next;
if (next) {
next->prev = item;
} else { // after is last
list->last = item;
}
item->next = next;
after->next = item;
item->prev = after;
item->list = list;
list->count += 1;
}
// text
// # __Text_countIndent__
size_t
__Text_countIndent__(
char* text,
size_t text_len, // can be 0
size_t tab_size
) {
size_t counted = 0;
size_t pos = 0;
while (pos < text_len) {
char symbol = text[pos];
if (symbol == ' ') {
counted = counted + 1;
} else if (symbol == '\t') {
counted = counted + tab_size;
} else {
break;
}
pos = pos + 1;
}
return counted;
}
// Buffer
// # __Buffer_push__
void __Buffer_push__(
char *buffer,
size_t *buffer_used, // expected < allocated
size_t pos, // expected < allocated
char item
) {
if (pos < *buffer_used) { // shiftSymbolsToRight
__Mem_copyBackward__(&buffer[pos + 1], &buffer[pos], *buffer_used - pos);
}
buffer[pos] = item;
(*buffer_used)++;
}
// # __Buffer_pop_check__
bool __Buffer_pop_check__(
size_t buffer_used,
size_t pos
) {
return ((buffer_used > 0) and (pos < buffer_used));
}
// # __Buffer_pop__
char __Buffer_pop__(
char *buffer,
size_t *buffer_used, // expected (*) > 0
size_t pos // expected <= buffer_used
) {
char ret = buffer[pos];
(*buffer_used)--;
if (pos < *buffer_used) {
__Mem_copy__(&buffer[pos], &buffer[pos + 1], *buffer_used - pos);
}
return ret;
}
// # __Buffer_addIndent_check__
bool
__Buffer_addIndent_check__(
char *buffer,
size_t *buffer_used,
size_t buffer_max,
size_t count
) {
size_t space = buffer_max - *buffer_used;
return space > count;
}
// # __Buffer_addIndent__
void __Buffer_addIndent__(
char *buffer,
size_t *buffer_used,
size_t count // expected < (buffer_max - *buffer_used)
) {
size_t pos = 0;
while (pos < count) {
__Buffer_push__(buffer, buffer_used, 0, ' ');
pos = pos + 1;
}
}
// # __Buffer_removeIndent__
void
__Buffer_removeIndent__(
char *buffer,
size_t *buffer_used, // expected >= count
size_t count // expected <= buffer_used
) {
size_t pos = 0;
while (pos < count) {
__Buffer_pop__(
buffer,
buffer_used, // (*) > 0 becouse expected *buffer_used >= loop_count
0
);
pos += 1;
}
}
// # __Buffer_setIndent__
bool
__Buffer_setIndent__(
char *buffer,
size_t *buffer_used,
size_t buffer_max,
size_t new_indent // expected < buffer_max
) {
bool ok = true;
size_t indent = __Text_countIndent__(buffer, *buffer_used, 1);
if (new_indent != indent) {
if (new_indent > indent) {
size_t delta = new_indent - indent;
if (__Buffer_addIndent_check__(buffer, buffer_used, buffer_max, delta)) {
__Buffer_addIndent__(buffer, buffer_used, delta);
} else {
ok = false;
}
} else { // new_indent < indent
size_t delta = indent - new_indent;
__Buffer_removeIndent__(buffer, buffer_used, delta);
}
}
return ok;
}
// File
// # __File_clear__
void __File_clear__(
__OsFileHandle__ file
) {
__OsFile_setPos__(file, 0);
__OsFile_truncate__(file);
}
// FileComplete
// # __FileComplete_clear__
bool __FileComplete_clear__(
const char* file_name,
size_t file_name_len
) {
bool ok = true;
__OsFileHandle__ file;
if (__OsFile_open__(&file, file_name, file_name_len)) {
__OsFile_clear__(file);
__OsFile_close__(file);
} else {
ok = false;
}
return ok;
}
// # __FileComplete_write__
bool __FileComplete_write__(
const char* file_name,
size_t file_name_len,
const char* bytes,
size_t bytes_len
) {
bool ok = true;
__OsFileHandle__ file;
if(__OsFile_exist__(file_name, file_name_len)) {
ok = __OsFile_open__(&file, file_name, file_name_len);
} else {
ok = __OsFile_create__(&file, file_name, file_name_len);
}
if (ok) {
if (__OsFile_write__(file, bytes, bytes_len, 0)) {
__OsFile_truncate__(file);
} else {
ok = false;
}
__OsFile_close__(file);
}
return ok;
}
// # __FileComplete_read__
bool __FileComplete_read__(
uintptr_t *ret_data_ptr,
size_t *ret_file_data_size, // not zeroed by this func. increment instead.
const char* file_name,
size_t file_name_len,
uint8_t align
) {
bool ok = true;
__OsFileHandle__ file;
if(__OsFile_exist__(file_name, file_name_len)) {
ok = __OsFile_open__(&file, file_name, file_name_len);
} else {
ok = __OsFile_create__(&file, file_name, file_name_len);
}
if (ok) {
size_t file_size = __OsFile_getSize__(file);
*ret_file_data_size += file_size;
char* file_data;
if (__AlignedPtr_allocAny__(ret_data_ptr, align, file_size)) {
if ( __OsFile_readToAny__( file, ret_data_ptr, file_size, 0 )) {
} else {
ok = false;
}
} else {
ok = false;
}
__OsFile_close__(file);
}
return ok;
}
// formats
// Base64
uint32_t Base64_getEncodeSize(uint32_t src_len) {
int blocks = ceilDiv32(src_len, 3);
return blocks * 4;
}
void Base64_encode3Bytes(unsigned char in[3], char out[4]) {
out[0] = Base64_standard_alphabet_chars[(in[0] & 0b11111100) >> 2];
out[1] = Base64_standard_alphabet_chars[((in[0] & 0b00000011) << 4) | ((in[1] & 0b11110000) >> 4)];
out[2] = Base64_standard_alphabet_chars[((in[1] & 0b00001111) << 2) | ((in[2] & 0b11000000) >> 6)];
out[3] = Base64_standard_alphabet_chars[(in[2] & 0b00111111)];
}
bool test_rot() {
char a = 0b11111100 >> 2;
if (a == 0b00111111) {
return true;
} else {
printf("%d: failed test_rot.", __LINE__);
}
return false;
}
void Base64_encode(char* src, size_t src_len, char* out) {
// EXAMPLE
// Source ASCII text: "Ma"
// Character M a
// Octets 77 (0x4d) 97 (0x61)
// Bits 0 1 0 0 1 1 0 1|0 1 1 0 0 0 0 1|0 0 _ _ _ _ _ _|
// Base64 0 1 0 0 1 1|0 1 0 1 1 0|0 0 0 1 0 0|_ _ _ _ _ _|
// Sextets 19 22 4 Padding
// Character T W E =
// Octets 84 (0x54) 87 (0x57) 69 (0x45) 61 (0x3D)
// parse normal octets
char* end_of_src = src + src_len;
while(true) {
if (src + 3 > end_of_src) break;
Base64_encode3Bytes((void*) src, out);
src += 3;
out += 4;
}
// parse extra_bytes
size_t extra_bytes = end_of_src - src;
if (extra_bytes > 0 ) {
char b[3] = {0};
__Mem_copy__(b, src, extra_bytes);
Base64_encode3Bytes((void*)b, out);
out += 4;
// add padding
size_t pads = 3 - extra_bytes;
for (char* pad = out - pads ;pad < out; pad++) {*pad = '=';}
}
}
// AP
// pack
size_t __FormatsAp_packNibble__(char* buffer, char data) {
if (data <= 16) {
*buffer = 'A' + data;
}
return 1;
}
size_t __FormatsAp_packByte__(
char* buffer,
char byte
) {
size_t writed = 0;
writed += __FormatsAp_packNibble__(&buffer[writed], (byte & 0xF0) >> 4);
writed += __FormatsAp_packNibble__(&buffer[writed], byte & 0x0F);
return writed;
}
size_t __FormatsAp_packBytes_calculateLen__(size_t len) {
return len * 2;
}
size_t __FormatsAp_packBytes__(
char* buffer,
char* data,
size_t len
) {
size_t writed = 0;
for(size_t pos = 0; pos < len; pos++) {
writed += __FormatsAp_packByte__(&buffer[writed], data[pos]);
}
return writed;
}
size_t __FormatsAp_writeToBuffer__(char buffer[], const char data[], size_t len) {
size_t writed = 0;
for(size_t pos = 0; pos < len; pos++) {
writed += __FormatsAp_packByte__(&buffer[writed], data[pos]);
}
return writed;
}
// parse
size_t Scalpi_formats_AP_parseNibble(char* buffer, char data) {
if (data >= 'A' && data <= 'P') {
*buffer = data - 'A';
} else if (data >= 'a' && data <= 'p') {
*buffer = data - 'a';
} else {
*buffer = 0;
}
return 1;
}
size_t Scalpi_formats_AP_parseByteToBuffer(char out_buffer[], const char* data) {
char buffer[2];
size_t writed = 0;
writed += Scalpi_formats_AP_parseNibble(&buffer[writed], data[0]);
writed += Scalpi_formats_AP_parseNibble(&buffer[writed], data[1]);
*out_buffer = (buffer[0] << 4) | buffer[1];
return 1;
}
size_t Scalpi_formats_AP_parseToBuffer(char buffer[], const char *ap, size_t ap_len) {
size_t writed = 0;
size_t readed = 0;
while(readed < ap_len) {
writed += Scalpi_formats_AP_parseByteToBuffer(&buffer[writed], &ap[readed]);
readed += 2;
}
return writed;
}
// crypto
// # Scalpi_crypto_sumBytes
char Scalpi_crypto_sumBytes(char* data, size_t data_len) {
char ret = 0;
for (size_t pos = 0; pos < data_len; pos++) {
ret += data[pos];
}
return ret;
}
// # Scalpi_crypto_xorBytes
char Scalpi_crypto_xorBytes(char* data, size_t data_len) {
char ret = 0;
for (size_t pos = 0; pos < data_len; pos++) {
ret ^= data[pos];
}
return ret;
}
// # Scalpi_crypto_xorCyclic
void Scalpi_crypto_xorCyclic(char* dest, char* a, size_t dest_len, char* b, size_t b_len) {
// expected dest_len == a.len
size_t ci = 0; // cyclical iterator
for (size_t pos = 0; pos < dest_len; pos++) {
dest[pos] = a[pos] ^ b[ci];
ci += 1;
if (ci == b_len) ci = 0;
}
}
// HEX
#define bytesLenToHexLen(len) (len * 2)
#define hexLenToBytesLen(len) (len >> 1)
void printHex(char* buffer_ptr, uintptr_t buffer_len) {
for (int i = 0; i < buffer_len; i++) {
printf(" %02X ", buffer_ptr[i]);
}
}
// parse
char Hex_parseNibble(char nibble) {
if (nibble >= 'a') return 10 + nibble - 'a';
if (nibble >= 'A') return 10 + nibble - 'A';
return nibble - '0';
}
char Hex_parseByte(char* hex_byte) {
char b_F0 = Hex_parseNibble(hex_byte[0]);
char b_0F = Hex_parseNibble(hex_byte[1]);
return (b_F0 << 4) | b_0F;
}
void Hex_parse(char* hex, char* buffer_ptr, size_t hex_len) {
char parsed;
size_t end_pos = hex_len >> 1;
for(size_t pos = 0; pos < end_pos; pos++) {
char parsed = Hex_parseByte(&hex[pos*2]);
buffer_ptr[pos] = parsed;
}
}
// pack
// small hex
char Hex_packNibble_h(char data) {
if (data <= 9) return '0' + data;
if (data <= 15) return 'a' + data - 10;
return 0;
}
void Hex_packByte_h(char data, char* hex_byte) {
hex_byte[0] = Hex_packNibble_h((data & 0xF0) >> 4);
hex_byte[1] = Hex_packNibble_h(data & 0x0F);
}
void Hex_pack_h(char* hex, char* data, size_t data_len) {
// expected hex.len is bytesLenToHexLen(len)
for(size_t pos = 0; pos < data_len; pos++) {
hex[pos * 2] = 'A';
hex[pos * 2 + 1] = 'F';
Hex_packByte_h(data[pos], &hex[pos * 2]);
}
}
// capital letters
char Hex_packNibble_H(char data) {
if (data <= 9) return '0' + data;
if (data <= 15) return 'A' + data - 10;
return 0;
}
void Hex_packByte_H(char data, char* hex_byte) {
hex_byte[0] = Hex_packNibble_H((data & 0xF0) >> 4);
hex_byte[1] = Hex_packNibble_H(data & 0x0F);
}
void Hex_pack_H(char* hex, char* data, size_t data_len) {
// expected hex.len is bytesLenToHexLen(len)
for(size_t pos = 0; pos < data_len; pos++) {
Hex_packByte_H(data[pos], &hex[pos * 2]);
}
}
// __Logger__
void __Logger_init__ (struct __Logger__* t) {
for (int i = 0; i < __arrayLen__(t->writers); i++) {
struct __Writer__* w = &t->writers[i];
w->context = 0;
w->write = 0;
}
}
void __Logger_writeToSelf__(struct __Logger__* t, const char bytes[], size_t len) {
for (size_t i = 0; i < __arrayLen__(t->writers); i++) {
struct __Writer__* w = &t->writers[i];
if (w->write) {
size_t writed = w->write(w->context, bytes, len);
}
}
}
// terminal
// # __TerminalInput_init__
void __TerminalInput_init__(
struct __TerminalInput__ *t
) {
t->ungrabed = 0;
}
// # __TerminalOutput_CursorPos__
void __TerminalOutputCursorPos_init__(__TerminalOutput_CursorPos__ *cursor_pos) {
cursor_pos->x = 0;
cursor_pos->y = 0;
}
// App
// AppEditorHistoryNote
// # __AppEditorHistoryNote_free__
void __AppEditorHistoryNote_free__(
struct __AppEditorHistoryNote__* ptr
) {
__AlignedPtr_freeAny__(ptr, sizeof(struct __AppEditorHistoryNote__));
}
// # __AppEditorHistoryNote_alloc__
bool __AppEditorHistoryNote_alloc__(
struct __AppEditorHistoryNote__ **ptr
) {
return __AlignedPtr_allocAny__( ptr, __alignOf__(struct __AppEditorHistoryNote__), sizeof(struct __AppEditorHistoryNote__) );
}
// # __App_init__
bool __App_init__(struct App* t) {
bool ok = true;
__Logger_init__(&t->logger); // preinit console output for debug
if (__OsHelper_init__(&t->__App_osHelper__)) {
t->tick = __os_getTick__();
if (!ok) __OsHelper_deinit__(&t->__App_osHelper__);
} else {
ok = false;
printf("%d app.os_helper not inited\r\n", __LINE__);
}
return ok;
}
// # __App_deinit__
void __App_deinit__(struct App* app) {
__OsHelper_deinit__(&app->__App_osHelper__);
}
// # __App_process__
bool __App_process__(struct App* t) {
bool ok = true;
__OsHelper_process__(&t->__App_osHelper__);
return ok;
}
// # __App_waitToNextFrame__
void __App_waitToNextFrame__(struct App* t) {
uint64_t expected_frame_end_time = t->tick + __Time_msPerS__ / __App_expectedFps__;
uint64_t resulting_frame_end_time = __os_getTick__();
if (resulting_frame_end_time > expected_frame_end_time + 120) {
uint64_t delta = resulting_frame_end_time - expected_frame_end_time;
printf("%d \t hitch detection: %zu delta: %zu ms \r\n", __LINE__, t->tick, delta);
}
uint64_t delay_sleep = 1;
if (resulting_frame_end_time < expected_frame_end_time) {
delay_sleep = expected_frame_end_time - resulting_frame_end_time;
}
Os_sleep(delay_sleep);
t->tick = resulting_frame_end_time + delay_sleep;
}
// main
bool tests() {
// const char* test_file_name = "scalpi_testing_file.txt";
// size_t test_file_name_len = __ZText_countLen__(test_file_name);
if ( true
and cpu_checkNumberFormat()
and __Mem_isEql_test_()
// and __FileComplete_write__(test_file_name, test_file_name_len, "abcd", 4)
// and __FileComplete_write__(test_file_name, test_file_name_len, "efgh", 4)
// and __FileComplete_write__(test_file_name, test_file_name_len, "ijkm", 4)
// and etc...
) {
return true;
} else {
printf("%d fail tests \r\n", __LINE__);
return false;
}
return true;
}
bool real_main(int args_len, char** args_ptr) {
bool ok = true;
if (tests()) {
printf("%d success tests \r\n", __LINE__);
if (false and __App_init__(&global_app)) {
while(true) {
if (!__App_process__(&global_app)) break;
__App_waitToNextFrame__(&global_app);
}
__App_deinit__(&global_app);
} else {
ok = false;
printf("%d fail: __App_init__\r\n", __LINE__);
}
} else {
ok = false;
printf("%d fail tests \r\n", __LINE__);
}
return ok;
}
#ifndef __COMPILED_FROM_ZIG_FILE__
int main(int args_len, char** args_ptr) {
trace_example();
if (real_main(args_len, args_ptr)) return 0;
return 1;
}
#endif