From 63f695d0743687ffea150483cd7a1e3d89fa2074 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 23 Jan 2017 01:19:43 -0500 Subject: [PATCH] got new organization system working on linux --- .../app_functions.h | 1 + 4coder_API/custom.h | 22 + 4coder_keycodes.h => 4coder_API/keycodes.h | 0 4coder_style.h => 4coder_API/style.h | 0 4coder_types.h => 4coder_API/types.h | 234 +- .../4coder_version.h => 4coder_API/version.h | 0 4coder_auto_indent.cpp | 95 +- 4coder_base_commands.cpp | 841 ++++++ 4coder_custom.h | 165 - 4coder_default_bindings.cpp | 47 +- 4coder_default_framework.h | 131 + 4coder_default_include.cpp | 2669 +---------------- 4coder_helper.h | 463 --- 4coder_helper/4coder_bind_helper.h | 232 ++ 4coder_helper/4coder_helper.h | 327 ++ 4coder_helper/4coder_long_seek.h | 993 ++++++ .../4coder_seek_types.h | 2 +- 4coder_helper/4coder_streaming.h | 259 ++ 4coder_jump_parsing.cpp | 96 +- 4coder_mem.h => 4coder_lib/4coder_mem.h | 86 +- 4coder_string.h => 4coder_lib/4coder_string.h | 957 +++--- 4coder_table.cpp => 4coder_lib/4coder_table.h | 171 +- 4coder_rect.h | 146 - 4coder_search.cpp | 403 ++- 4cpp_lexer.h => 4cpp/4cpp_lexer.h | 525 ++-- .../4cpp_lexer_tables.c | 0 4cpp_lexer_types.h => 4cpp/4cpp_lexer_types.h | 0 4ed.cpp | 247 +- 4ed.h | 13 +- 4ed_api_implementation.cpp | 166 +- 4ed_app_target.cpp | 39 +- 4ed_file_view.cpp | 106 +- 4ed_gui.cpp | 46 +- 4coder_gui.h => 4ed_gui.h | 0 4ed_layout.cpp | 20 +- 4ed_math.h | 173 +- 4ed_os_custom_api.h | 21 +- 4ed_rendering.h | 11 +- 4ed_rendering_helper.cpp | 14 + 4ed_site.ctm | Bin 420 -> 916 bytes 4ed_system.h | 58 +- 4ed_system_shared.cpp | 27 +- 4ed_system_shared.h | 2 +- 4tech_defines.h | 146 + _4coder_string.ctm | Bin 0 -> 324 bytes build.bat | 2 +- buildsuper.bat | 2 +- common/4coder_defines.h | 196 -- file/4coder_buffer.cpp | 10 +- file/4coder_file_tests.cpp | 22 - file/run_tests.bat | 11 - linux_4ed.cpp | 115 +- meta/4ed_metagen.cpp | 260 +- meta/4tech_file_moving.h | 439 +++ meta/4tech_meta_defines.h | 49 + meta/build.cpp | 503 +--- meta/fsm_table_generator.cpp | 6 +- meta/meta_parser.cpp | 300 +- not_shipping_4coder_default_view.cpp | 89 - power/4coder_experiments.cpp | 269 +- power/4coder_function_list.cpp | 282 ++ project.4coder | 2 +- site/abstract_document.cpp | 2 +- site/sitegen.cpp | 11 +- string/4coder_string_build_num.txt | 5 + string/4tech_standard_preamble.h | 25 + string/_4coder_string.ctm | Bin 0 -> 2436 bytes string/build.bat | 22 + .../internal_4coder_string.cpp | 568 ++-- string/string_builder.cpp | 487 +++ win32_4ed.cpp | 327 +- win32_api_impl.cpp | 243 -- 72 files changed, 7229 insertions(+), 6972 deletions(-) rename 4coder_custom_api.h => 4coder_API/app_functions.h (99%) create mode 100644 4coder_API/custom.h rename 4coder_keycodes.h => 4coder_API/keycodes.h (100%) rename 4coder_style.h => 4coder_API/style.h (100%) rename 4coder_types.h => 4coder_API/types.h (87%) rename common/4coder_version.h => 4coder_API/version.h (100%) create mode 100644 4coder_base_commands.cpp delete mode 100644 4coder_custom.h create mode 100644 4coder_default_framework.h delete mode 100644 4coder_helper.h create mode 100644 4coder_helper/4coder_bind_helper.h create mode 100644 4coder_helper/4coder_helper.h create mode 100644 4coder_helper/4coder_long_seek.h rename 4coder_seek_types.h => 4coder_helper/4coder_seek_types.h (97%) create mode 100644 4coder_helper/4coder_streaming.h rename 4coder_mem.h => 4coder_lib/4coder_mem.h (79%) rename 4coder_string.h => 4coder_lib/4coder_string.h (62%) rename 4coder_table.cpp => 4coder_lib/4coder_table.h (56%) delete mode 100644 4coder_rect.h rename 4cpp_lexer.h => 4cpp/4cpp_lexer.h (78%) rename 4cpp_lexer_tables.c => 4cpp/4cpp_lexer_tables.c (100%) rename 4cpp_lexer_types.h => 4cpp/4cpp_lexer_types.h (100%) rename 4coder_gui.h => 4ed_gui.h (100%) create mode 100644 4tech_defines.h create mode 100644 _4coder_string.ctm delete mode 100644 common/4coder_defines.h delete mode 100644 file/4coder_file_tests.cpp delete mode 100644 file/run_tests.bat create mode 100644 meta/4tech_file_moving.h create mode 100644 meta/4tech_meta_defines.h delete mode 100644 not_shipping_4coder_default_view.cpp create mode 100644 power/4coder_function_list.cpp create mode 100644 string/4coder_string_build_num.txt create mode 100644 string/4tech_standard_preamble.h create mode 100644 string/_4coder_string.ctm create mode 100644 string/build.bat rename internal_4coder_string.cpp => string/internal_4coder_string.cpp (84%) create mode 100644 string/string_builder.cpp delete mode 100644 win32_api_impl.cpp diff --git a/4coder_custom_api.h b/4coder_API/app_functions.h similarity index 99% rename from 4coder_custom_api.h rename to 4coder_API/app_functions.h index 0e2ec256..d0ae16b2 100644 --- a/4coder_custom_api.h +++ b/4coder_API/app_functions.h @@ -1,3 +1,4 @@ +struct Application_Links; #define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id) #define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags) #define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len) diff --git a/4coder_API/custom.h b/4coder_API/custom.h new file mode 100644 index 00000000..31518061 --- /dev/null +++ b/4coder_API/custom.h @@ -0,0 +1,22 @@ + +#ifndef FCODER_CUSTOM_H +#define FCODER_CUSTOM_H + +#include + +#include "version.h" +#include "keycodes.h" +#include "style.h" +// TODO(allen): I don't like having to pull in the types from my standalone libraries to define the API. +// What to do??? Hmmm.... +#include "4coder_lib/4coder_string.h" +#include "4cpp/4cpp_lexer_types.h" +#include "types.h" +#include "app_functions.h" + +extern "C" _GET_VERSION_SIG(get_alpha_4coder_version){ + int32_t result = (maj == MAJOR && min == MINOR && patch == PATCH); + return(result); +} + +#endif diff --git a/4coder_keycodes.h b/4coder_API/keycodes.h similarity index 100% rename from 4coder_keycodes.h rename to 4coder_API/keycodes.h diff --git a/4coder_style.h b/4coder_API/style.h similarity index 100% rename from 4coder_style.h rename to 4coder_API/style.h diff --git a/4coder_types.h b/4coder_API/types.h similarity index 87% rename from 4coder_types.h rename to 4coder_API/types.h index fa1d5356..0299721d 100644 --- a/4coder_types.h +++ b/4coder_API/types.h @@ -1,40 +1,34 @@ -#ifndef ENUM +#if !defined(FCODER_TYPES_H) +#define FCODER_TYPES_H + +#if !defined(FCODER_META_TAGS) +#define FCODER_META_TAGS + # define ENUM(type,name) typedef type name; enum name##_ -#endif - -#ifndef TYPEDEF # define TYPEDEF typedef -#endif - -#ifndef STRUCT +# define TYPEDEF_FUNC typedef # define STRUCT struct -#endif - -#ifndef UNION # define UNION union +# define GLOBAL_VAR static + #endif -/* DOC(bool32 is an alias name to signal that an integer parameter or field is for -true/false values.) */ +/* DOC(bool32 is an alias name to signal that an integer parameter or field is for true/false values.) */ TYPEDEF int32_t bool32; -/* DOC(int_color is an alias name to signal that an integer parameter or field is for -a color value, colors are specified as 24 bit integers in 3 channels: 0xRRGGBB.) */ +/* DOC(int_color is an alias name to signal that an integer parameter or field is for a color value, colors are specified as 24 bit integers in 3 channels: 0xRRGGBB.) */ TYPEDEF uint32_t int_color; -/* DOC(Key_Code is the alias for key codes including raw codes and codes translated -to textual input that takes modifiers into account.) */ +/* DOC(Key_Code is the alias for key codes including raw codes and codes translated to textual input that takes modifiers into account.) */ TYPEDEF unsigned char Key_Code; -/* DOC(Buffer_ID is used to name a 4coder buffer. Each buffer has a unique id but -when a buffer is closed it's id may be recycled by future, different buffers.) */ +/* DOC(Buffer_ID is used to name a 4coder buffer. Each buffer has a unique id but when a buffer is closed it's id may be recycled by future, different buffers.) */ TYPEDEF int32_t Buffer_ID; -/* DOC(View_ID is used to name a 4coder view. Each view has a unique id in -the interval [1,16].) */ +/* DOC(View_ID is used to name a 4coder view. Each view has a unique id in the interval [1,16].) */ TYPEDEF int32_t View_ID; /* DOC(A Key_Modifier acts as an index for specifying modifiers in arrays.) */ @@ -68,10 +62,6 @@ ENUM(uint64_t, Command_ID){ cmdid_undo, /* DOC(cmdid_redo reperforms an edit that was undone.) */ cmdid_redo, - /* DOC(cmdid_history_backward performs a step backwards through the file history, which includes previously lost redo branches.) */ - cmdid_history_backward, - /* DOC(cmdid_history_forward unperforms the previous cmdid_history_backward step if possible.) */ - cmdid_history_forward, /* DOC(cmdid_interactive_new begins an interactive dialogue to create a new buffer.) */ cmdid_interactive_new, @@ -358,15 +348,6 @@ ENUM(int32_t, View_Split_Position){ ViewSplit_Right }; -/* DOC(Generic_Command acts as a name for a command, and can name an internal command or a custom command.) */ -UNION Generic_Command{ - /*DOC(If this Generic_Command represents an internal command the cmdid field will have a value less than cmdid_count, and this field is the command id for the command.)*/ - Command_ID cmdid; - /*DOC(If this Generic_Command does not represent an internal command the command - field is the pointer to the custom command..)*/ - Custom_Command_Function *command; -}; - /* DOC(Key_Event_Data describes a key event, including the translation to a character, the translation to a character ignoring the state of caps lock, and an array of all the modifiers that were pressed at the time of the event.) */ STRUCT Key_Event_Data{ /* DOC(This field is the raw keycode which is always non-zero in valid key events.) */ @@ -385,6 +366,9 @@ STRUCT Key_Event_Data{ char modifiers[MDFR_INDEX_COUNT]; }; +// TODO(allen): GLOBAL_VAR meta parsing +GLOBAL_VAR Key_Event_Data null_key_event_data = {0}; + /* DOC(Mouse_State describes an entire mouse state complete with the position, left and right button states, the wheel state, and whether or not the mouse if in the window.) */ STRUCT Mouse_State{ /* DOC(This field indicates that the left button is held.) */ @@ -411,6 +395,8 @@ STRUCT Mouse_State{ int32_t y; }; +GLOBAL_VAR Mouse_State null_mouse_state = {0}; + /* DOC( Range describes an integer range typically used for ranges within a buffer. Ranges tend are usually not passed as a Range struct into the API, but this struct is used to return ranges. @@ -625,6 +611,26 @@ STRUCT Buffer_Summary{ bool32 unwrapped_lines; }; +GLOBAL_VAR Buffer_Summary null_buffer_summary = {0}; + +STRUCT i32_Rect{ + int32_t x0; + int32_t y0; + int32_t x1; + int32_t y1; +}; + +GLOBAL_VAR i32_Rect null_i32_rect = {0}; + +STRUCT f32_Rect{ + float x0; + float y0; + float x1; + float y1; +}; + +GLOBAL_VAR f32_Rect null_f32_rect = {0}; + /* DOC(View_Summary acts as a handle to a view and describes the state of the view.) DOC_SEE(Access_Flag) DOC_SEE(Full_Cursor) */ @@ -659,31 +665,14 @@ STRUCT View_Summary{ GUI_Scroll_Vars scroll_vars; }; -/* -DOC(User_Input describes a user input event which can be either a key press or mouse event.) -DOC_SEE(User_Input_Type_ID) -DOC_SEE(Generic_Command) -*/ -STRUCT User_Input{ - /* DOC(This field specifies whether the event was a key press or mouse event.) */ - User_Input_Type_ID type; - /* DOC(This field indicates that an abort event has occurred and the command needs to shut down.) */ - bool32 abort; - UNION{ - /* DOC(This field describes a key press event.) */ - Key_Event_Data key; - /* DOC(This field describes a mouse input event.) */ - Mouse_State mouse; - }; - /* DOC(If this event would trigger a command, this field specifies what the command would be.) */ - Generic_Command command; -}; +GLOBAL_VAR View_Summary null_view_summary = {0}; /* DOC(Query_Bar is a struct used to store information in the user's control that will be displayed as a drop down bar durring an interactive command.) */ STRUCT Query_Bar{ /* DOC(This specifies the prompt portion of the drop down bar.) */ String prompt; + /* DOC(This specifies the main string portion of the drop down bar.) */ String string; }; @@ -710,14 +699,12 @@ STRUCT Theme_Color{ ENUM(int32_t, Buffer_Batch_Edit_Type){ /* DOC(The BatchEdit_Normal operation is always correct but does the most work if there are tokens to correct.) */ BatchEdit_Normal, - /* DOC(The BatchEdit_PreserveTokens operation is one in which none of the edits add, delete, or change any tokens. - This usually applies when whitespace is being replaced with whitespace.) */ + /* DOC(The BatchEdit_PreserveTokens operation is one in which none of the edits add, delete, or change any tokens. This usually applies when whitespace is being replaced with whitespace.) */ BatchEdit_PreserveTokens }; /* -DOC(This struct is used to bundle the parameters of the buffer_batch_edit function. It is convenient -for a few functions that return a batch edit to the user.) +DOC(This struct is used to bundle the parameters of the buffer_batch_edit function. It is convenient for a few functions that return a batch edit to the user.) DOC_SEE(buffer_batch_edit) */ STRUCT Buffer_Batch_Edit{ @@ -733,3 +720,138 @@ STRUCT Buffer_Batch_Edit{ }; +/* DOC(Custom_Command_Function is a function type which matches the signature used for commands. To declare a command use CUSTOM_COMMAND_SIG.) DOC_SEE(CUSTOM_COMMAND_SIG) */ +TYPEDEF void Custom_Command_Function(struct Application_Links *app); + +// TODO(allen): Improve meta system so that the system for picking up macros is universal. +#define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app) + + +/* DOC(Generic_Command acts as a name for a command, and can name an internal command or a custom command.) */ +UNION Generic_Command{ + /*DOC(If this Generic_Command represents an internal command the cmdid field will have a value less than cmdid_count, and this field is the command id for the command.)*/ + Command_ID cmdid; + /*DOC(If this Generic_Command does not represent an internal command the command + field is the pointer to the custom command..)*/ + Custom_Command_Function *command; +}; + + +/* +DOC(User_Input describes a user input event which can be either a key press or mouse event.) +DOC_SEE(User_Input_Type_ID) +DOC_SEE(Generic_Command) +*/ +STRUCT User_Input{ + /* DOC(This field specifies whether the event was a key press or mouse event.) */ + User_Input_Type_ID type; + /* DOC(This field indicates that an abort event has occurred and the command needs to shut down.) */ + bool32 abort; + UNION{ + /* DOC(This field describes a key press event.) */ + Key_Event_Data key; + /* DOC(This field describes a mouse input event.) */ + Mouse_State mouse; + }; + /* DOC(If this event would trigger a command, this field specifies what the command would be.) */ + Generic_Command command; +}; + + +/* DOC(Hook_IDs name the various hooks into 4coder, these hooks use the Hook_Function signature.) +DOC_SEE(Hook_Function) */ +ENUM(int32_t, Hook_ID){ + /* DOC(TODO) */ + hook_start, + /* DOC(TODO) */ + hook_file_out_of_sync, + /* DOC(TODO) */ + hook_exit, + /* DOC(TODO) */ + hook_view_size_change, + // never below this + hook_type_count +}; + +/* DOC(Special_Hook_IDs name special hooks that use specialized signatures.) */ +ENUM(int32_t, Special_Hook_ID){ + /* DOC(TODO) */ + special_hook_scroll_rule = hook_type_count, + /* DOC(TODO) */ + special_hook_new_file, + /* DOC(TODO) */ + special_hook_open_file, + /* DOC(TODO) */ + special_hook_save_file, + /* DOC(TODO) */ + special_hook_command_caller, + /* DOC(TODO) */ + special_hook_input_filter, +}; + +TYPEDEF_FUNC int32_t Command_Caller_Hook_Function(struct Application_Links *app, Generic_Command cmd); +#define COMMAND_CALLER_HOOK(name) int32_t name(struct Application_Links *app, Generic_Command cmd) + +TYPEDEF_FUNC int32_t Hook_Function(struct Application_Links *app); +#define HOOK_SIG(name) int32_t name(struct Application_Links *app) + +TYPEDEF_FUNC int32_t Open_File_Hook_Function(struct Application_Links *app, int32_t buffer_id); +#define OPEN_FILE_HOOK_SIG(name) int32_t name(struct Application_Links *app, int32_t buffer_id) + +TYPEDEF_FUNC void Input_Filter_Function(Mouse_State *mouse); +#define INPUT_FILTER_SIG(name) void name(Mouse_State *mouse) + +TYPEDEF_FUNC int32_t Scroll_Rule_Function(float target_x, float target_y, float *scroll_x, float *scroll_y, int32_t view_id, int32_t is_new_target, float dt); +#define SCROLL_RULE_SIG(name) \ +int32_t name(float target_x, float target_y, float *scroll_x, float *scroll_y, int32_t view_id, int32_t is_new_target, float dt) + +TYPEDEF_FUNC int32_t Get_Binding_Data_Function(void *data, int32_t size); +#define GET_BINDING_DATA(name) int32_t name(void *data, int32_t size) + +// NOTE(allen): Definitions for the format that Get_Binding_Data uses to launch 4coder. +// TODO(allen): Find a way to transition to a more dynamic Command_Map system. + +ENUM(int32_t, Binding_Unit_Type){ + unit_header, + unit_map_begin, + unit_binding, + unit_callback, + unit_inherit, + unit_hook +}; + +ENUM(int32_t, Map_ID){ + mapid_global = (1 << 24), + mapid_file, + mapid_nomap +}; + +STRUCT Binding_Unit{ + Binding_Unit_Type type; + UNION{ + STRUCT{ int32_t total_size; int32_t user_map_count; int32_t error; } header; + + STRUCT{ int32_t mapid; int32_t replace; int32_t bind_count; } map_begin; + STRUCT{ int32_t mapid; } map_inherit; + STRUCT{ + int16_t code; + uint8_t modifiers; + int32_t command_id; + } binding; + STRUCT{ + int16_t code; + uint8_t modifiers; + Custom_Command_Function *func; + } callback; + STRUCT{ + int32_t hook_id; + void *func; + } hook; + }; +}; + +typedef int32_t _Get_Version_Function(int32_t maj, int32_t min, int32_t patch); +#define _GET_VERSION_SIG(n) int32_t n(int32_t maj, int32_t min, int32_t patch) + +#endif + diff --git a/common/4coder_version.h b/4coder_API/version.h similarity index 100% rename from common/4coder_version.h rename to 4coder_API/version.h diff --git a/4coder_auto_indent.cpp b/4coder_auto_indent.cpp index 94f2c7e5..9845364c 100644 --- a/4coder_auto_indent.cpp +++ b/4coder_auto_indent.cpp @@ -1,6 +1,27 @@ +/* +4coder_auto_indent.cpp - Commands for auto-indentation of C++ code. -#ifndef FCODER_AUTO_INDENT_INC -#define FCODER_AUTO_INDENT_INC +TYPE: 'drop-in-command-pack' +*/ + +// TOP + +#if !defined(FCODER_AUTO_INDENT_CPP) +#define FCODER_AUTO_INDENT_CPP + +#include "4coder_base_commands.cpp" +#include "4coder_helper/4coder_streaming.h" +#include "4coder_helper/4coder_long_seek.h" +#include "4coder_lib/4coder_mem.h" +#include "4coder_default_framework.h" + +#if !defined(DEFAULT_INDENT_FLAGS) +# define DEFAULT_INDENT_FLAGS 0 +#endif + +#if !defined(DEF_TAB_WIDTH) +# define DEF_TAB_WIDTH 4 +#endif // // Generic Line Indenter @@ -67,9 +88,7 @@ struct Indent_Options{ }; static Buffer_Batch_Edit -make_batch_from_indent_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer, - int32_t line_start, int32_t line_end, int32_t *indent_marks, - Indent_Options opts){ +make_batch_from_indent_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line_start, int32_t line_end, int32_t *indent_marks, Indent_Options opts){ Buffer_Batch_Edit result = {0}; @@ -140,20 +159,18 @@ make_batch_from_indent_marks(Application_Links *app, Partition *part, Buffer_Sum } static void -set_line_indents(Application_Links *app, Partition *part, Buffer_Summary *buffer, - int32_t line_start, int32_t line_end, int32_t *indent_marks, Indent_Options opts){ +set_line_indents(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line_start, int32_t line_end, int32_t *indent_marks, Indent_Options opts){ Buffer_Batch_Edit batch = make_batch_from_indent_marks(app, part, buffer, line_start, line_end, indent_marks, opts); if (batch.edit_count > 0){ buffer_batch_edit(app, buffer, batch.str, batch.str_len, - batch.edits, batch.edit_count, BatchEdit_PreserveTokens); + batch.edits, batch.edit_count, BatchEdit_PreserveTokens); } } static Cpp_Token* -seek_matching_token_backwards(Cpp_Token_Array tokens, Cpp_Token *token, - Cpp_Token_Type open_type, Cpp_Token_Type close_type){ +seek_matching_token_backwards(Cpp_Token_Array tokens, Cpp_Token *token, Cpp_Token_Type open_type, Cpp_Token_Type close_type){ int32_t nesting_level = 0; if (token <= tokens.tokens){ token = tokens.tokens; @@ -179,8 +196,7 @@ seek_matching_token_backwards(Cpp_Token_Array tokens, Cpp_Token *token, } static Cpp_Token* -find_anchor_token(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, - int32_t line_start, int32_t tab_width, int32_t *current_indent_out){ +find_anchor_token(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line_start, int32_t tab_width, int32_t *current_indent_out){ Cpp_Token *token = get_first_token_at_line(app, buffer, tokens, line_start); if (token == 0 && tokens.count == 0){ @@ -282,9 +298,7 @@ struct Indent_Parse_State{ }; static int32_t* -get_indentation_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer, - Cpp_Token_Array tokens, int32_t line_start, int32_t line_end, - bool32 exact_align, int32_t tab_width){ +get_indentation_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line_start, int32_t line_end, bool32 exact_align, int32_t tab_width){ int32_t indent_mark_count = line_end - line_start; int32_t *indent_marks = push_array(part, int32_t, indent_mark_count); @@ -595,5 +609,56 @@ buffer_auto_indent(Application_Links *app, Buffer_Summary *buffer, int32_t start return(result); } +// +// Commands +// + +static void +auto_tab_whole_file_by_summary(Application_Links *app, Buffer_Summary *buffer){ + buffer_auto_indent(app, buffer, 0, buffer->size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); +} + +CUSTOM_COMMAND_SIG(auto_tab_whole_file){ + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + auto_tab_whole_file_by_summary(app, &buffer); +} + +CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){ + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + buffer_auto_indent(app, &buffer, view.cursor.pos, view.cursor.pos, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); + move_past_lead_whitespace(app, &view, &buffer); +} + +CUSTOM_COMMAND_SIG(auto_tab_range){ + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + Range range = get_range(&view); + + buffer_auto_indent(app, &buffer, range.min, range.max, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); + move_past_lead_whitespace(app, &view, &buffer); +} + +CUSTOM_COMMAND_SIG(write_and_auto_tab){ + exec_command(app, write_character); + + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + buffer_auto_indent(app, &buffer, view.cursor.pos, view.cursor.pos, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_ExactAlignBlock); + move_past_lead_whitespace(app, &view, &buffer); +} + + + #endif +// BOTTOM + diff --git a/4coder_base_commands.cpp b/4coder_base_commands.cpp new file mode 100644 index 00000000..3c81d73f --- /dev/null +++ b/4coder_base_commands.cpp @@ -0,0 +1,841 @@ +/* +4coder_base_commands.cpp - Base commands such as inserting characters, and +moving the cursor, which work even without the default 4coder framework. + +TYPE: 'drop-in-command-pack' +*/ + +// TOP + +#if !defined(FCODER_BASE_COMMANDS_CPP) +#define FCODER_BASE_COMMANDS_CPP + +#include "4coder_helper/4coder_helper.h" +#include "4coder_helper/4coder_long_seek.h" + +// +// Fundamental Editing Commands +// + +CUSTOM_COMMAND_SIG(write_character){ + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + + User_Input in = get_command_input(app); + char character = 0; + + if (in.type == UserInputKey){ + character = in.key.character; + } + + if (character != 0){ + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t pos = view.cursor.pos; + buffer_replace_range(app, &buffer, pos, pos, &character, 1); + view_set_cursor(app, &view, seek_pos(view.cursor.pos + 1), true); + } +} + +CUSTOM_COMMAND_SIG(delete_char){ + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t start = view.cursor.pos; + + Full_Cursor cursor; + view_compute_cursor(app, &view, seek_character_pos(view.cursor.character_pos+1), &cursor); + int32_t end = cursor.pos; + + if (0 <= start && start < buffer.size){ + buffer_replace_range(app, &buffer, start, end, 0, 0); + } +} + +CUSTOM_COMMAND_SIG(backspace_char){ + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t end = view.cursor.pos; + + Full_Cursor cursor; + view_compute_cursor(app, &view, seek_character_pos(view.cursor.character_pos-1), &cursor); + int32_t start = cursor.pos; + + if (0 < end && end <= buffer.size){ + buffer_replace_range(app, &buffer, start, end, 0, 0); + view_set_cursor(app, &view, seek_character_pos(view.cursor.character_pos-1), true); + } +} + +CUSTOM_COMMAND_SIG(set_mark){ + View_Summary view = get_active_view(app, AccessProtected); + + view_set_mark(app, &view, seek_pos(view.cursor.pos)); + view_set_cursor(app, &view, seek_pos(view.cursor.pos), 1); +} + +CUSTOM_COMMAND_SIG(cursor_mark_swap){ + View_Summary view = get_active_view(app, AccessProtected); + + int32_t cursor = view.cursor.pos; + int32_t mark = view.mark.pos; + + view_set_cursor(app, &view, seek_pos(mark), true); + view_set_mark(app, &view, seek_pos(cursor)); +} + +CUSTOM_COMMAND_SIG(delete_range){ + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + Range range = get_range(&view); + buffer_replace_range(app, &buffer, range.min, range.max, 0, 0); +} + +// +// Basic Navigation Commands +// + +CUSTOM_COMMAND_SIG(center_view){ + View_Summary view = get_active_view(app, AccessProtected); + + i32_Rect region = view.file_region; + GUI_Scroll_Vars scroll = view.scroll_vars; + + float h = (float)(region.y1 - region.y0); + float y = get_view_y(&view); + y = y - h*.5f; + scroll.target_y = (int32_t)(y + .5f); + view_set_scroll(app, &view, scroll); +} + +CUSTOM_COMMAND_SIG(left_adjust_view){ + View_Summary view = get_active_view(app, AccessProtected); + + GUI_Scroll_Vars scroll = view.scroll_vars; + + float x = get_view_x(&view) - 30.f; + if (x < 0){ + x = 0.f; + } + + scroll.target_x = (int32_t)(x + .5f); + view_set_scroll(app, &view, scroll); +} + +bool32 +global_point_to_view_point(View_Summary *view, int32_t x, int32_t y, float *x_out, float *y_out){ + bool32 result = false; + + i32_Rect region = view->file_region; + + int32_t max_x = (region.x1 - region.x0); + int32_t max_y = (region.y1 - region.y0); + GUI_Scroll_Vars scroll_vars = view->scroll_vars; + + int32_t rx = x - region.x0; + int32_t ry = y - region.y0; + + if (ry >= 0 && rx >= 0 && rx < max_x && ry < max_y){ + result = 1; + } + + *x_out = (float)rx + scroll_vars.scroll_x; + *y_out = (float)ry + scroll_vars.scroll_y; + + return(result); +} + +CUSTOM_COMMAND_SIG(click_set_cursor){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + + Mouse_State mouse = get_mouse_state(app); + float rx = 0, ry = 0; + if (global_point_to_view_point(&view, mouse.x, mouse.y, &rx, &ry)){ + view_set_cursor(app, &view, seek_xy(rx, ry, 1, view.unwrapped_lines), 1); + } +} + +CUSTOM_COMMAND_SIG(click_set_mark){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + + Mouse_State mouse = get_mouse_state(app); + float rx = 0, ry = 0; + if (global_point_to_view_point(&view, mouse.x, mouse.y, &rx, &ry)){ + view_set_mark(app, &view, seek_xy(rx, ry, 1, view.unwrapped_lines)); + } +} + +inline void +move_vertical(Application_Links *app, float line_multiplier){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + + float new_y = get_view_y(&view) + line_multiplier*view.line_height; + float x = view.preferred_x; + + view_set_cursor(app, &view, seek_xy(x, new_y, 0, view.unwrapped_lines), 0); +} + +CUSTOM_COMMAND_SIG(move_up){ + move_vertical(app, -1.f); +} + +CUSTOM_COMMAND_SIG(move_down){ + move_vertical(app, 1.f); +} + +CUSTOM_COMMAND_SIG(move_up_10){ + move_vertical(app, -10.f); +} + +CUSTOM_COMMAND_SIG(move_down_10){ + move_vertical(app, 10.f); +} + +static float +get_page_jump(View_Summary *view){ + i32_Rect region = view->file_region; + float page_jump = 1; + + if (view->line_height > 0){ + page_jump = (float)(region.y1 - region.y0) / view->line_height; + page_jump -= 3.f; + if (page_jump <= 0){ + page_jump = 1.f; + } + } + + return(page_jump); +} + +CUSTOM_COMMAND_SIG(page_up){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + float page_jump = get_page_jump(&view); + move_vertical(app, -page_jump); +} + +CUSTOM_COMMAND_SIG(page_down){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + float page_jump = get_page_jump(&view); + move_vertical(app, page_jump); +} + + +CUSTOM_COMMAND_SIG(move_left){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + int32_t new_pos = view.cursor.character_pos - 1; + view_set_cursor(app, &view, seek_character_pos(new_pos), 1); +} + +CUSTOM_COMMAND_SIG(move_right){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + int32_t new_pos = view.cursor.character_pos + 1; + view_set_cursor(app, &view, seek_character_pos(new_pos), 1); +} + +// +// Long Seeks +// + +CUSTOM_COMMAND_SIG(seek_whitespace_up){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t new_pos = buffer_seek_whitespace_up(app, &buffer, view.cursor.pos); + view_set_cursor(app, &view, seek_pos(new_pos), true); +} + +CUSTOM_COMMAND_SIG(seek_whitespace_down){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t new_pos = buffer_seek_whitespace_down(app, &buffer, view.cursor.pos); + view_set_cursor(app, &view, seek_pos(new_pos), true); +} + +CUSTOM_COMMAND_SIG(seek_end_of_textual_line){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t new_pos = seek_line_end(app, &buffer, view.cursor.pos); + view_set_cursor(app, &view, seek_pos(new_pos), true); +} + +CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + int32_t new_pos = seek_line_beginning(app, &buffer, view.cursor.pos); + view_set_cursor(app, &view, seek_pos(new_pos), true); +} + +CUSTOM_COMMAND_SIG(seek_beginning_of_line){ + View_Summary view = get_active_view(app, AccessProtected); + + float y = view.cursor.wrapped_y; + if (view.unwrapped_lines){ + y = view.cursor.unwrapped_y; + } + + view_set_cursor(app, &view, seek_xy(0, y, 1, view.unwrapped_lines), 1); +} + +CUSTOM_COMMAND_SIG(seek_end_of_line){ + View_Summary view = get_active_view(app, AccessProtected); + + float y = view.cursor.wrapped_y; + if (view.unwrapped_lines){ + y = view.cursor.unwrapped_y; + } + + view_set_cursor(app, &view, seek_xy(100000.f, y, 1, view.unwrapped_lines), 1); +} + + +// +// Fancy Editing +// + +CUSTOM_COMMAND_SIG(to_uppercase){ + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + + Range range = get_range(&view); + int32_t size = range.max - range.min; + if (size <= app->memory_size){ + char *mem = (char*)app->memory; + + buffer_read_range(app, &buffer, range.min, range.max, mem); + for (int32_t i = 0; i < size; ++i){ + mem[i] = char_to_upper(mem[i]); + } + buffer_replace_range(app, &buffer, range.min, range.max, mem, size); + view_set_cursor(app, &view, seek_pos(range.max), true); + } +} + +CUSTOM_COMMAND_SIG(to_lowercase){ + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + + Range range = get_range(&view); + int32_t size = range.max - range.min; + if (size <= app->memory_size){ + char *mem = (char*)app->memory; + + buffer_read_range(app, &buffer, range.min, range.max, mem); + for (int32_t i = 0; i < size; ++i){ + mem[i] = char_to_lower(mem[i]); + } + buffer_replace_range(app, &buffer, range.min, range.max, mem, size); + view_set_cursor(app, &view, seek_pos(range.max), true); + } +} + +CUSTOM_COMMAND_SIG(clean_all_lines){ + // TODO(allen): This command always iterates accross the entire + // buffer, so streaming it is actually the wrong call. Rewrite this + // to minimize calls to buffer_read_range. + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + + int32_t line_count = buffer.line_count; + int32_t edit_max = line_count; + + if (edit_max*sizeof(Buffer_Edit) < app->memory_size){ + Buffer_Edit *edits = (Buffer_Edit*)app->memory; + + char data[1024]; + Stream_Chunk chunk = {0}; + + int32_t i = 0; + if (init_stream_chunk(&chunk, app, &buffer, i, data, sizeof(data))){ + Buffer_Edit *edit = edits; + + int32_t buffer_size = buffer.size; + int32_t still_looping = true; + int32_t last_hard = buffer_size; + do{ + for (; i < chunk.end; ++i){ + char at_pos = chunk.data[i]; + if (at_pos == '\n'){ + if (last_hard+1 < i){ + edit->str_start = 0; + edit->len = 0; + edit->start = last_hard+1; + edit->end = i; + ++edit; + } + last_hard = buffer_size; + } + else if (char_is_whitespace(at_pos)){ + // NOTE(allen): do nothing + } + else{ + last_hard = i; + } + } + + still_looping = forward_stream_chunk(&chunk); + }while(still_looping); + + if (last_hard+1 < buffer_size){ + edit->str_start = 0; + edit->len = 0; + edit->start = last_hard+1; + edit->end = buffer_size; + ++edit; + } + + int32_t edit_count = (int32_t)(edit - edits); + buffer_batch_edit(app, &buffer, 0, 0, edits, edit_count, BatchEdit_PreserveTokens); + } + } +} + + +// +// Scroll Bar Controlling +// + +CUSTOM_COMMAND_SIG(show_scrollbar){ + View_Summary view = get_active_view(app, AccessProtected); + view_set_setting(app, &view, ViewSetting_ShowScrollbar, true); +} + +CUSTOM_COMMAND_SIG(hide_scrollbar){ + View_Summary view = get_active_view(app, AccessProtected); + view_set_setting(app, &view, ViewSetting_ShowScrollbar, false); +} + + +// +// Basic Panel Management +// + +CUSTOM_COMMAND_SIG(basic_change_active_panel){ + View_Summary view = get_active_view(app, AccessAll); + get_view_next_looped(app, &view, AccessAll); + set_active_view(app, &view); +} + +CUSTOM_COMMAND_SIG(close_panel){ + View_Summary view = get_active_view(app, AccessAll); + close_view(app, &view); +} + +CUSTOM_COMMAND_SIG(open_panel_vsplit){ + View_Summary view = get_active_view(app, AccessAll); + View_Summary new_view = open_view(app, &view, ViewSplit_Right); + view_set_setting(app, &new_view, ViewSetting_ShowScrollbar, false); +} + +CUSTOM_COMMAND_SIG(open_panel_hsplit){ + View_Summary view = get_active_view(app, AccessAll); + View_Summary new_view = open_view(app, &view, ViewSplit_Bottom); + view_set_setting(app, &new_view, ViewSetting_ShowScrollbar, false); +} + + +// +// Common Settings Commands +// + +//toggle_fullscreen can be used as a command + +CUSTOM_COMMAND_SIG(toggle_line_wrap){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + bool32 unwrapped = view.unwrapped_lines; + buffer_set_setting(app, &buffer, BufferSetting_WrapLine, unwrapped); +} + +CUSTOM_COMMAND_SIG(increase_line_wrap){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + int32_t wrap = 0; + buffer_get_setting(app, &buffer, BufferSetting_WrapPosition, &wrap); + buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap + 10); +} + +CUSTOM_COMMAND_SIG(decrease_line_wrap){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + int32_t wrap = 0; + buffer_get_setting(app, &buffer, BufferSetting_WrapPosition, &wrap); + buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap - 10); +} + +CUSTOM_COMMAND_SIG(toggle_virtual_whitespace){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + int32_t vwhite = 0; + buffer_get_setting(app, &buffer, BufferSetting_VirtualWhitespace, &vwhite); + buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, !vwhite); +} + +CUSTOM_COMMAND_SIG(toggle_show_whitespace){ + View_Summary view = get_active_view(app, AccessProtected); + view_set_setting(app, &view, ViewSetting_ShowWhitespace, !view.show_whitespace); +} + +CUSTOM_COMMAND_SIG(eol_dosify){ + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + buffer_set_setting(app, &buffer, BufferSetting_Eol, 1); +} + +CUSTOM_COMMAND_SIG(eol_nixify){ + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + buffer_set_setting(app, &buffer, BufferSetting_Eol, 0); +} + +CUSTOM_COMMAND_SIG(exit_4coder){ + send_exit_signal(app); +} + + +// +// Interactive Commands +// + +CUSTOM_COMMAND_SIG(goto_line){ + uint32_t access = AccessProtected; + + Query_Bar bar = {0}; + char string_space[256]; + + bar.prompt = make_lit_string("Goto Line: "); + bar.string = make_fixed_width_string(string_space); + + if (query_user_number(app, &bar)){ + int32_t line_number = str_to_int_s(bar.string); + + View_Summary view = get_active_view(app, access); + view_set_cursor(app, &view, seek_line_char(line_number, 0), true); + } +} + +CUSTOM_COMMAND_SIG(search); +CUSTOM_COMMAND_SIG(reverse_search); + +static void +isearch(Application_Links *app, int32_t start_reversed){ + uint32_t access = AccessProtected; + + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + if (!buffer.exists) return; + + Query_Bar bar = {0}; + if (start_query_bar(app, &bar, 0) == 0) return; + + int32_t reverse = start_reversed; + int32_t pos = view.cursor.pos; + int32_t start_pos = pos; + int32_t first_pos = pos; + Range match = make_range(pos, pos); + + char bar_string_space[256]; + bar.string = make_fixed_width_string(bar_string_space); + + String isearch_str = make_lit_string("I-Search: "); + String rsearch_str = make_lit_string("Reverse-I-Search: "); + + User_Input in = {0}; + for (;;){ + view_set_highlight(app, &view, match.start, match.end, true); + + // NOTE(allen): Change the bar's prompt to match the current direction. + if (reverse) bar.prompt = rsearch_str; + else bar.prompt = isearch_str; + + in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); + if (in.abort) break; + + // NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we + // only asked to intercept key events. + Assert(in.type == UserInputKey); + + int32_t made_change = 0; + if (in.key.keycode == '\n' || in.key.keycode == '\t'){ + break; + } + else if (in.key.character && key_is_unmodified(&in.key)){ + append_s_char(&bar.string, in.key.character); + made_change = 1; + } + else if (in.key.keycode == key_back){ + if (bar.string.size > 0){ + --bar.string.size; + made_change = 1; + } + } + + int32_t step_forward = 0; + int32_t step_backward = 0; + + if ((in.command.command == search) || + in.key.keycode == key_page_down || in.key.keycode == key_down) step_forward = 1; + if ((in.command.command == reverse_search) || + in.key.keycode == key_page_up || in.key.keycode == key_up) step_backward = 1; + + start_pos = pos; + if (step_forward && reverse){ + start_pos = match.start + 1; + pos = start_pos; + reverse = 0; + step_forward = 0; + } + if (step_backward && !reverse){ + start_pos = match.start - 1; + pos = start_pos; + reverse = 1; + step_backward = 0; + } + + if (in.key.keycode != key_back){ + int32_t new_pos; + if (reverse){ + buffer_seek_string_insensitive_backward(app, &buffer, start_pos - 1, 0, + bar.string.str, bar.string.size, &new_pos); + if (new_pos >= 0){ + if (step_backward){ + pos = new_pos; + start_pos = new_pos; + buffer_seek_string_insensitive_backward(app, &buffer, start_pos - 1, 0, + bar.string.str, bar.string.size, &new_pos); + if (new_pos < 0) new_pos = start_pos; + } + match.start = new_pos; + match.end = match.start + bar.string.size; + } + } + else{ + buffer_seek_string_insensitive_forward(app, &buffer, start_pos + 1, 0, + bar.string.str, bar.string.size, &new_pos); + if (new_pos < buffer.size){ + if (step_forward){ + pos = new_pos; + start_pos = new_pos; + buffer_seek_string_insensitive_forward(app, &buffer, start_pos + 1, 0, + bar.string.str, bar.string.size, &new_pos); + if (new_pos >= buffer.size) new_pos = start_pos; + } + match.start = new_pos; + match.end = match.start + bar.string.size; + } + } + } + else{ + if (match.end > match.start + bar.string.size){ + match.end = match.start + bar.string.size; + } + } + } + view_set_highlight(app, &view, 0, 0, false); + if (in.abort){ + view_set_cursor(app, &view, seek_pos(first_pos), true); + return; + } + + view_set_cursor(app, &view, seek_pos(match.min), true); +} + +CUSTOM_COMMAND_SIG(search){ + isearch(app, false); +} + +CUSTOM_COMMAND_SIG(reverse_search){ + isearch(app, true); +} + +CUSTOM_COMMAND_SIG(replace_in_range){ + Query_Bar replace; + char replace_space[1024]; + replace.prompt = make_lit_string("Replace: "); + replace.string = make_fixed_width_string(replace_space); + + Query_Bar with; + char with_space[1024]; + with.prompt = make_lit_string("With: "); + with.string = make_fixed_width_string(with_space); + + if (!query_user_string(app, &replace)) return; + if (replace.string.size == 0) return; + + if (!query_user_string(app, &with)) return; + + String r = replace.string, w = with.string; + + uint32_t access = AccessOpen; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + + Range range = get_range(&view); + + int32_t pos, new_pos; + pos = range.min; + + buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); + + while (new_pos + r.size <= range.end){ + buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size); + refresh_view(app, &view); + range = get_range(&view); + pos = new_pos + w.size; + buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); + } +} + +CUSTOM_COMMAND_SIG(query_replace){ + Query_Bar replace; + char replace_space[1024]; + replace.prompt = make_lit_string("Replace: "); + replace.string = make_fixed_width_string(replace_space); + + Query_Bar with; + char with_space[1024]; + with.prompt = make_lit_string("With: "); + with.string = make_fixed_width_string(with_space); + + if (!query_user_string(app, &replace)) return; + if (replace.string.size == 0) return; + + if (!query_user_string(app, &with)) return; + + String r, w; + r = replace.string; + w = with.string; + + Query_Bar bar; + Buffer_Summary buffer; + View_Summary view; + int32_t pos, new_pos; + + bar.prompt = make_lit_string("Replace? (y)es, (n)ext, (esc)\n"); + bar.string = null_string; + + start_query_bar(app, &bar, 0); + + uint32_t access = AccessOpen; + view = get_active_view(app, access); + buffer = get_buffer(app, view.buffer_id, access); + + pos = view.cursor.pos; + buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); + + User_Input in = {0}; + while (new_pos < buffer.size){ + Range match = make_range(new_pos, new_pos + r.size); + view_set_highlight(app, &view, match.min, match.max, 1); + + in = get_user_input(app, EventOnAnyKey, EventOnButton); + if (in.abort || in.key.keycode == key_esc || !key_is_unmodified(&in.key)) break; + + if (in.key.character == 'y' || + in.key.character == 'Y' || + in.key.character == '\n' || + in.key.character == '\t'){ + buffer_replace_range(app, &buffer, match.min, match.max, w.str, w.size); + pos = match.start + w.size; + } + else{ + pos = match.max; + } + + buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); + } + + view_set_highlight(app, &view, 0, 0, 0); + if (in.abort) return; + + view_set_cursor(app, &view, seek_pos(pos), 1); +} + + +// +// cmdid wrappers +// + +CUSTOM_COMMAND_SIG(undo){ + exec_command(app, cmdid_undo); +} + +CUSTOM_COMMAND_SIG(redo){ + exec_command(app, cmdid_redo); +} + +CUSTOM_COMMAND_SIG(interactive_new){ + exec_command(app, cmdid_interactive_new); +} + +CUSTOM_COMMAND_SIG(interactive_open){ + exec_command(app, cmdid_interactive_open); +} + +CUSTOM_COMMAND_SIG(save_as){ + exec_command(app, cmdid_save_as); +} + +CUSTOM_COMMAND_SIG(interactive_switch_buffer){ + exec_command(app, cmdid_interactive_switch_buffer); +} + +CUSTOM_COMMAND_SIG(interactive_kill_buffer){ + exec_command(app, cmdid_interactive_kill_buffer); +} + +CUSTOM_COMMAND_SIG(reopen){ + exec_command(app, cmdid_reopen); +} + +CUSTOM_COMMAND_SIG(save){ + exec_command(app, cmdid_save); +} + +CUSTOM_COMMAND_SIG(kill_buffer){ + exec_command(app, cmdid_kill_buffer); +} + +CUSTOM_COMMAND_SIG(open_color_tweaker){ + exec_command(app, cmdid_open_color_tweaker); +} + +CUSTOM_COMMAND_SIG(open_config){ + exec_command(app, cmdid_open_config); +} + +CUSTOM_COMMAND_SIG(open_menu){ + exec_command(app, cmdid_open_menu); +} + +CUSTOM_COMMAND_SIG(open_debug){ + exec_command(app, cmdid_open_debug); +} + +#endif + +// BOTTOM + diff --git a/4coder_custom.h b/4coder_custom.h deleted file mode 100644 index e7dec44e..00000000 --- a/4coder_custom.h +++ /dev/null @@ -1,165 +0,0 @@ - -#ifndef FCODER_CUSTOM_H -#define FCODER_CUSTOM_H - -#include -// TODO(allen): We need to eliminate our dependence on this soon. -#include - - -#include "common/4coder_version.h" -#include "4coder_keycodes.h" -#include "4coder_style.h" -#include "4coder_rect.h" -#include "4coder_mem.h" -#include "4cpp_lexer_types.h" - -// TODO(allen): We need to eliminate this soon. -#ifndef FSTRING_STRUCT -#define FSTRING_STRUCT -typedef struct String{ - char *str; - int32_t size; - int32_t memory_size; -} String; - -typedef struct Offset_String{ - int32_t offset; - int32_t size; -} Offset_String; -#endif - -// These are regular hooks, any of them can be set to any function -// that matches the HOOK_SIG pattern. -enum Hook_ID{ - hook_start, - hook_file_out_of_sync, - hook_exit, - hook_view_size_change, - // never below this - hook_type_count -}; - -// These are for special hooks, each must bind to specialized signatures -// that do not necessarily have access to the app pointer. -enum Special_Hook_ID{ - _hook_scroll_rule = hook_type_count, - _hook_new_file, - _hook_open_file, - _hook_save_file, - _hook_command_caller, - _hook_input_filter, -}; - -#define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app) -typedef CUSTOM_COMMAND_SIG(Custom_Command_Function); - -#include "4coder_types.h" -#include "4coder_seek_types.h" -#include "4coder_gui.h" - -#define COMMAND_CALLER_HOOK(name) int32_t name(struct Application_Links *app, Generic_Command cmd) -typedef COMMAND_CALLER_HOOK(Command_Caller_Hook_Function); - -static Key_Event_Data null_key_event_data = {0}; -static Mouse_State null_mouse_state = {0}; -static Buffer_Summary null_buffer_summary = {0}; -static View_Summary null_view_summary = {0}; - -inline Range -make_range(int32_t p1, int32_t p2){ - Range range; - if (p1 < p2){ - range.min = p1; - range.max = p2; - } - else{ - range.min = p2; - range.max = p1; - } - return(range); -} - -#define HOOK_SIG(name) int32_t name(struct Application_Links *app) -#define SCROLL_RULE_SIG(name) int32_t name(float target_x, float target_y, float *scroll_x, float *scroll_y, int32_t view_id, int32_t is_new_target, float dt) -#define OPEN_FILE_HOOK_SIG(name) int32_t name(struct Application_Links *app, int32_t buffer_id) -#define INPUT_FILTER_SIG(name) void name(Mouse_State *mouse) - -typedef OPEN_FILE_HOOK_SIG(Open_File_Hook_Function); -typedef HOOK_SIG(Hook_Function); -typedef SCROLL_RULE_SIG(Scroll_Rule_Function); -typedef INPUT_FILTER_SIG(Input_Filter_Function); - - - - -struct Application_Links; -#include "4coder_custom_api.h" - - - -#define VIEW_ROUTINE_SIG(name) void name(struct Application_Links *app, int32_t view_id) -#define GET_BINDING_DATA(name) int32_t name(void *data, int32_t size) -#define _GET_VERSION_SIG(n) int32_t n(int32_t maj, int32_t min, int32_t patch) - -typedef VIEW_ROUTINE_SIG(View_Routine_Function); -typedef GET_BINDING_DATA(Get_Binding_Data_Function); -typedef _GET_VERSION_SIG(_Get_Version_Function); - -struct Custom_API{ - View_Routine_Function *view_routine; - Get_Binding_Data_Function *get_bindings; - _Get_Version_Function *get_alpha_4coder_version; -}; - -extern "C" _GET_VERSION_SIG(get_alpha_4coder_version){ - int32_t result = (maj == MAJOR && min == MINOR && patch == PATCH); - return(result); -} - -// NOTE(allen): definitions for the buffer that communicates to 4ed.exe - -enum Binding_Unit_Type{ - unit_header, - unit_map_begin, - unit_binding, - unit_callback, - unit_inherit, - unit_hook -}; - -enum Map_ID{ - mapid_global = (1 << 24), - mapid_file, - - // NOTE(allen): mapid_nomap will remain empty even if you attempt to fill it - // it is for setting a map's parent to nothing, in cases where you don't want - // to inherit from global (which is the default). - mapid_nomap -}; - -struct Binding_Unit{ - Binding_Unit_Type type; - union{ - struct{ int32_t total_size; int32_t user_map_count; int32_t error; } header; - - struct{ int32_t mapid; int32_t replace; int32_t bind_count; } map_begin; - struct{ int32_t mapid; } map_inherit; - struct{ - int16_t code; - uint8_t modifiers; - int32_t command_id; - } binding; - struct{ - int16_t code; - uint8_t modifiers; - Custom_Command_Function *func; - } callback; - struct{ - int32_t hook_id; - void *func; - } hook; - }; -}; - -#endif diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp index 23991bf7..354530b1 100644 --- a/4coder_default_bindings.cpp +++ b/4coder_default_bindings.cpp @@ -11,7 +11,6 @@ // 2^24 of them so don't be wasteful! enum My_Maps{ my_code_map, - my_maps_count }; @@ -31,15 +30,6 @@ CUSTOM_COMMAND_SIG(write_zero_struct){ write_string(app, make_lit_string(" = {0};")); } -CUSTOM_COMMAND_SIG(write_capital){ - User_Input command_in = get_command_input(app); - char c = command_in.key.character_no_caps_lock; - if (c != 0){ - c = char_to_upper(c); - write_string(app, make_string(&c, 1)); - } -} - CUSTOM_COMMAND_SIG(switch_to_compilation){ char name[] = "*compilation*"; @@ -119,31 +109,8 @@ CUSTOM_COMMAND_SIG(seek_whitespace_down_end_line){ } HOOK_SIG(my_start){ - init_memory(app); - - process_config_file(app); - - change_theme(app, default_theme_name.str, default_theme_name.size); - change_font(app, default_font_name.str, default_font_name.size, 1); - - exec_command(app, open_panel_vsplit); - exec_command(app, hide_scrollbar); - exec_command(app, change_active_panel); - exec_command(app, hide_scrollbar); - - // Theme options: - // "4coder" - // "Handmade Hero" - // "Twilight" - // "Woverine" - // "stb" - - // Font options: - // "Liberation Sans" - // "Liberation Mono" - // "Hack" - // "Cutive Mono" - // "Inconsolata" + default_4coder_initialize(app); + default_4coder_side_by_side_panels(app); // no meaning for return return(0); @@ -344,11 +311,11 @@ default_keys(Bind_Helper *context){ bind(context, 'P', MDFR_CTRL, close_panel); bind(context, ',', MDFR_CTRL, change_active_panel); - bind(context, 'n', MDFR_CTRL, cmdid_interactive_new); - bind(context, 'o', MDFR_CTRL, cmdid_interactive_open); + bind(context, 'n', MDFR_CTRL, interactive_new); + bind(context, 'o', MDFR_CTRL, interactive_open); bind(context, 'o', MDFR_ALT, open_in_other); - bind(context, 'k', MDFR_CTRL, cmdid_interactive_kill_buffer); - bind(context, 'i', MDFR_CTRL, cmdid_interactive_switch_buffer); + bind(context, 'k', MDFR_CTRL, interactive_kill_buffer); + bind(context, 'i', MDFR_CTRL, interactive_switch_buffer); bind(context, 'w', MDFR_CTRL, save_as); bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker); @@ -492,8 +459,6 @@ default_keys(Bind_Helper *context){ bind(context, 'F', MDFR_CTRL, list_all_locations); bind(context, 'F', MDFR_ALT, list_all_substring_locations_case_insensitive); bind(context, 'g', MDFR_CTRL, goto_line); - bind(context, 'h', MDFR_CTRL, cmdid_history_backward); - bind(context, 'H', MDFR_CTRL, cmdid_history_forward); bind(context, 'j', MDFR_CTRL, to_lowercase); bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer); bind(context, 'l', MDFR_CTRL, toggle_line_wrap); diff --git a/4coder_default_framework.h b/4coder_default_framework.h new file mode 100644 index 00000000..23e6528c --- /dev/null +++ b/4coder_default_framework.h @@ -0,0 +1,131 @@ +/* +4coder_default_framework.cpp - Sets up the basics of the framework that is used +for default 4coder behaviour. + +TYPE: 'internal-for-default-system' +*/ + +// TOP + +#if !defined(FCODER_DEFAULT_FRAMEWORK_H) +#define FCODER_DEFAULT_FRAMEWORK_H + +#include "4coder_helper/4coder_helper.h" +#include "4coder_lib/4coder_mem.h" + +// +// Global Memory +// + +static Partition global_part; +static General_Memory global_general; + +// +// Jump Buffer Locking +// + +static char locked_buffer_space[256]; +static String locked_buffer = make_fixed_width_string(locked_buffer_space); + +static void +unlock_jump_buffer(){ + locked_buffer.size = 0; +} + +static void +lock_jump_buffer(char *name, int32_t size){ + copy(&locked_buffer, make_string(name, size)); +} + +static void +lock_jump_buffer(Buffer_Summary buffer){ + copy(&locked_buffer, make_string(buffer.buffer_name, buffer.buffer_name_len)); +} + +static View_Summary +get_view_for_locked_jump_buffer(Application_Links *app){ + View_Summary view = {0}; + + if (locked_buffer.size > 0){ + Buffer_Summary buffer = get_buffer_by_name(app, locked_buffer.str, locked_buffer.size, AccessAll); + if (buffer.exists){ + view = get_first_view_with_buffer(app, buffer.buffer_id); + } + else{ + unlock_jump_buffer(); + } + } + + return(view); +} + +// +// Panel Management +// + +static View_ID special_note_view_id = 0; + +static void +close_special_note_view(Application_Links *app){ + View_Summary special_view = get_view(app, special_note_view_id, AccessAll); + if (special_view.exists){ + close_view(app, &special_view); + } + special_note_view_id = 0; +} + +static View_Summary +open_special_note_view(Application_Links *app, bool32 create_if_not_exist = true){ + View_Summary special_view = get_view(app, special_note_view_id, AccessAll); + + if (create_if_not_exist && !special_view.exists){ + View_Summary view = get_active_view(app, AccessAll); + special_view = open_view(app, &view, ViewSplit_Bottom); + view_set_setting(app, &special_view, ViewSetting_ShowScrollbar, false); + view_set_split_proportion(app, &special_view, .2f); + set_active_view(app, &view); + special_note_view_id = special_view.view_id; + } + + return(special_view); +} + +CUSTOM_COMMAND_SIG(change_active_panel){ + View_Summary view = get_active_view(app, AccessAll); + View_ID original_view_id = view.view_id; + + do{ + get_view_next_looped(app, &view, AccessAll); + if (view.view_id != special_note_view_id){ + break; + } + }while(view.view_id != original_view_id); + + if (view.exists){ + set_active_view(app, &view); + } +} + +// +// View Variabls +// + +enum Rewrite_Type{ + RewriteNone, + RewritePaste, + RewriteWordComplete +}; + +struct View_Paste_Index{ + int32_t rewrite; + int32_t next_rewrite; + int32_t index; +}; + +View_Paste_Index view_paste_index_[16]; +View_Paste_Index *view_paste_index = view_paste_index_ - 1; + +#endif + +// BOTTOM + diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index 2e9a8140..038017dc 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -2,1166 +2,67 @@ #ifndef FCODER_DEFAULT_INCLUDE #define FCODER_DEFAULT_INCLUDE -#include "4coder_custom.h" +#include "4coder_API/custom.h" + + +#include "4coder_jump_parsing.cpp" + +#include "4coder_default_framework.h" +#include "4coder_base_commands.cpp" +#include "4coder_auto_indent.cpp" +#include "4coder_search.cpp" + +#include "4coder_helper/4coder_bind_helper.h" +#include "4coder_helper/4coder_helper.h" +#include "4coder_helper/4coder_streaming.h" +#include "4coder_helper/4coder_long_seek.h" #define FSTRING_IMPLEMENTATION -#include "4coder_string.h" +#include "4coder_lib/4coder_string.h" +#include "4coder_lib/4coder_table.h" +#include "4coder_lib/4coder_mem.h" -#include "4coder_helper.h" +#include "4cpp/4cpp_lexer.h" #include -#ifndef DEFAULT_INDENT_FLAGS -# define DEFAULT_INDENT_FLAGS 0 -#endif - -#ifndef DEF_TAB_WIDTH -# define DEF_TAB_WIDTH 4 -#endif - // -// Useful helper functions +// Seeks Using Default Framework Memory // static int32_t -open_file(Application_Links *app, Buffer_Summary *buffer_out, char *filename, int32_t filename_len, int32_t background, int32_t never_new){ - int32_t result = false; - Buffer_Summary buffer = - get_buffer_by_name(app, filename, filename_len, - AccessProtected|AccessHidden); - - if (buffer.exists){ - if (buffer_out) *buffer_out = buffer; - result = true; - } - else{ - Buffer_Create_Flag flags = 0; - if (background){ - flags |= BufferCreate_Background; - } - if (never_new){ - flags |= BufferCreate_NeverNew; - } - buffer = create_buffer(app, filename, filename_len, flags); - if (buffer.exists){ - if (buffer_out) *buffer_out = buffer; - result = true; - } - } - +buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags){ + int32_t result = buffer_boundary_seek(app, buffer, &global_part, start_pos, seek_forward, flags); return(result); } -static int32_t -view_open_file(Application_Links *app, View_Summary *view, char *filename, int32_t filename_len, int32_t never_new){ - int32_t result = 0; - - if (view){ - Buffer_Summary buffer = {0}; - if (open_file(app, &buffer, filename, filename_len, false, never_new)){ - view_set_buffer(app, view, buffer.buffer_id, 0); - result = 1; - } - } - - return(result); -} - -static int32_t -read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line, String *str){ - - Partial_Cursor begin = {0}; - Partial_Cursor end = {0}; - - int32_t success = 0; - - if (buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &begin)){ - if (buffer_compute_cursor(app, buffer, seek_line_char(line, 65536), &end)){ - if (begin.line == line){ - if (0 <= begin.pos && begin.pos <= end.pos && end.pos <= buffer->size){ - int32_t size = (end.pos - begin.pos); - *str = make_string(push_array(part, char, size+1), size+1); - if (str->str){ - success = 1; - buffer_read_range(app, buffer, begin.pos, end.pos, str->str); - str->size = size; - terminate_with_null(str); - } - } - } - } - } - - return(success); -} - - -// -// Memory -// - -static Partition global_part; -static General_Memory global_general; - -void -init_memory(Application_Links *app){ - int32_t part_size = (32 << 20); - int32_t general_size = (4 << 20); - - void *part_mem = memory_allocate(app, part_size); - global_part = make_part(part_mem, part_size); - - void *general_mem = memory_allocate(app, general_size); - general_memory_open(&global_general, general_mem, general_size); -} - - -// -// Helpers -// - -static void -refresh_buffer(Application_Links *app, Buffer_Summary *buffer){ - *buffer = get_buffer(app, buffer->buffer_id, AccessAll); -} - static void -refresh_view(Application_Links *app, View_Summary *view){ - *view = get_view(app, view->view_id, AccessAll); -} - - -// -// Buffer Streaming -// - -struct Stream_Chunk{ - Application_Links *app; - Buffer_Summary *buffer; - - char *base_data; - int32_t start, end; - int32_t min_start, max_end; - bool32 add_null; - int32_t data_size; - - char *data; -}; - -static int32_t -round_down(int32_t x, int32_t b){ - int32_t r = 0; - if (x >= 0){ - r = x - (x % b); - } - return(r); -} - -static int32_t -round_up(int32_t x, int32_t b){ - int32_t r = 0; - if (x >= 0){ - r = x - (x % b) + b; - } - return(r); -} - -static bool32 -init_stream_chunk(Stream_Chunk *chunk, Application_Links *app, Buffer_Summary *buffer, - int32_t pos, char *data, int32_t size){ - bool32 result = 0; - - refresh_buffer(app, buffer); - if (pos >= 0 && pos < buffer->size && size > 0){ - chunk->app = app; - chunk->buffer = buffer; - chunk->base_data = data; - chunk->data_size = size; - chunk->start = round_down(pos, size); - chunk->end = round_up(pos, size); - - if (chunk->max_end > buffer->size || chunk->max_end == 0){ - chunk->max_end = buffer->size; - } - - if (chunk->max_end && chunk->max_end < chunk->end){ - chunk->end = chunk->max_end; - } - if (chunk->min_start && chunk->min_start > chunk->start){ - chunk->start = chunk->min_start; - } - - if (chunk->start < chunk->end){ - buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); - chunk->data = chunk->base_data - chunk->start; - result = 1; - } - } - - return(result); -} - -static bool32 -forward_stream_chunk(Stream_Chunk *chunk){ - Application_Links *app = chunk->app; - Buffer_Summary *buffer = chunk->buffer; - bool32 result = 0; - - refresh_buffer(app, buffer); - if (chunk->end < buffer->size){ - chunk->start = chunk->end; - chunk->end += chunk->data_size; - - if (chunk->max_end && chunk->max_end < chunk->end){ - chunk->end = chunk->max_end; - } - if (chunk->min_start && chunk->min_start > chunk->start){ - chunk->start = chunk->min_start; - } - - if (chunk->start < chunk->end){ - buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); - chunk->data = chunk->base_data - chunk->start; - result = 1; - } - } - - else if (chunk->add_null && chunk->end + 1 < buffer->size){ - chunk->start = buffer->size; - chunk->end = buffer->size + 1; - chunk->base_data[0] = 0; - chunk->data = chunk->base_data - chunk->start; - result = 1; - } - - return(result); -} - -static bool32 -backward_stream_chunk(Stream_Chunk *chunk){ - Application_Links *app = chunk->app; - Buffer_Summary *buffer = chunk->buffer; - bool32 result = 0; - - refresh_buffer(app, buffer); - if (chunk->start > 0){ - chunk->end = chunk->start; - chunk->start -= chunk->data_size; - - if (chunk->max_end && chunk->max_end < chunk->end){ - chunk->end = chunk->max_end; - } - if (chunk->min_start && chunk->min_start > chunk->start){ - chunk->start = chunk->min_start; - } - - if (chunk->start < chunk->end){ - buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); - chunk->data = chunk->base_data - chunk->start; - result = 1; - } - } - - else if (chunk->add_null && chunk->start > -1){ - chunk->start = -1; - chunk->end = 0; - chunk->base_data[0] = 0; - chunk->data = chunk->base_data - chunk->start; - result = 1; - } - - return(result); -} - -typedef struct Stream_Tokens{ - Application_Links *app; - Buffer_Summary *buffer; - - Cpp_Token *base_tokens; - Cpp_Token *tokens; - int32_t start, end; - int32_t count, token_count; -} Stream_Tokens; - -static bool32 -init_stream_tokens(Stream_Tokens *stream, Application_Links *app, Buffer_Summary *buffer, int32_t pos, Cpp_Token *data, int32_t count){ - bool32 result = 0; - - refresh_buffer(app, buffer); - - int32_t token_count = buffer_token_count(app, buffer); - if (buffer->tokens_are_ready && pos >= 0 && pos < token_count && count > 0){ - stream->app = app; - stream->buffer = buffer; - stream->base_tokens = data; - stream->count = count; - stream->start = round_down(pos, count); - stream->end = round_up(pos, count); - stream->token_count = token_count; - - buffer_read_tokens(app, buffer, stream->start, stream->end, stream->base_tokens); - stream->tokens = stream->base_tokens - stream->start; - result = 1; - } - - return(result); -} - -static Stream_Tokens -begin_temp_stream_token(Stream_Tokens *stream){ - return(*stream); -} - -static void -end_temp_stream_token(Stream_Tokens *stream, Stream_Tokens temp){ - if (stream->start != temp.start || stream->end != temp.end){ - Application_Links *app = stream->app; - buffer_read_tokens(app, temp.buffer, temp.start, temp.end, temp.base_tokens); - stream->tokens = stream->base_tokens - temp.start; - stream->start = temp.start; - stream->end = temp.end; - } -} - -static bool32 -forward_stream_tokens(Stream_Tokens *stream){ - Application_Links *app = stream->app; - Buffer_Summary *buffer = stream->buffer; - bool32 result = 0; - - refresh_buffer(app, buffer); - if (stream->end < stream->token_count){ - stream->start = stream->end; - stream->end += stream->count; - - if (stream->token_count < stream->end){ - stream->end = stream->token_count; - } - - if (stream->start < stream->end){ - buffer_read_tokens(app, buffer, stream->start, stream->end, stream->base_tokens); - stream->tokens = stream->base_tokens - stream->start; - result = 1; - } - } - - return(result); -} - -static bool32 -backward_stream_tokens(Stream_Tokens *stream){ - Application_Links *app = stream->app; - Buffer_Summary *buffer = stream->buffer; - bool32 result = 0; - - refresh_buffer(app, buffer); - if (stream->start > 0){ - stream->end = stream->start; - stream->start -= stream->count; - - if (0 > stream->start){ - stream->start = 0; - } - - if (stream->start < stream->end){ - buffer_read_tokens(app, buffer, stream->start, stream->end, stream->base_tokens); - stream->tokens = stream->base_tokens - stream->start; - result = 1; - } - } - - return(result); -} - -void -buffer_seek_delimiter_forward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, char delim, int32_t *result){ - if (buffer->exists){ - char chunk[1024]; - int32_t size = sizeof(chunk); - Stream_Chunk stream = {0}; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){ - int32_t still_looping = 1; - do{ - for(; pos < stream.end; ++pos){ - char at_pos = stream.data[pos]; - if (at_pos == delim){ - *result = pos; - goto finished; - } - } - still_looping = forward_stream_chunk(&stream); - }while (still_looping); - } - } - - *result = buffer->size; - - finished:; -} - -static void -buffer_seek_delimiter_backward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, char delim, int32_t *result){ - if (buffer->exists){ - char chunk[1024]; - int32_t size = sizeof(chunk); - Stream_Chunk stream = {0}; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){ - int32_t still_looping = 1; - do{ - for(; pos >= stream.start; --pos){ - char at_pos = stream.data[pos]; - if (at_pos == delim){ - *result = pos; - goto finished; - } - } - still_looping = backward_stream_chunk(&stream); - }while (still_looping); - } - } - - *result = 0; - - finished:; -} - -// TODO(allen): This duplication is driving me crazy... I've gotta -// upgrade the meta programming system another level. - -// NOTE(allen): This is limitted to a string size of 512. -// You can push it up or do something more clever by just -// replacing char read_buffer[512]; with more memory. -static void -buffer_seek_string_forward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t end, char *str, int32_t size, int32_t *result){ - char read_buffer[512]; - - if (buffer->size > end){ - *result = buffer->size; - } - else{ - *result = end; - } - - if (size > 0 && size <= sizeof(read_buffer)){ - if (buffer->exists){ - String read_str = make_fixed_width_string(read_buffer); - String needle_str = make_string(str, size); - char first_char = str[0]; - - read_str.size = size; - - char chunk[1024]; - Stream_Chunk stream = {0}; - stream.max_end = end; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, sizeof(chunk))){ - int32_t still_looping = 1; - do{ - for(; pos < stream.end; ++pos){ - char at_pos = stream.data[pos]; - if (at_pos == first_char){ - buffer_read_range(app, buffer, pos, pos+size, read_buffer); - if (match_ss(needle_str, read_str)){ - *result = pos; - goto finished; - } - } - } - still_looping = forward_stream_chunk(&stream); - }while (still_looping); - } - } - - if (end == 0){ - *result = buffer->size; - } - else{ - *result = end; - } - - finished:; - } -} - -// NOTE(allen): This is limitted to a string size of 512. -// You can push it up or do something more clever by just -// replacing char read_buffer[512]; with more memory. -static void -buffer_seek_string_backward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t min, char *str, int32_t size, int32_t *result){ - char read_buffer[512]; - - *result = min-1; - if (size > 0 && size <= sizeof(read_buffer)){ - if (buffer->exists){ - String read_str = make_fixed_width_string(read_buffer); - String needle_str = make_string(str, size); - char first_char = str[0]; - - read_str.size = size; - - char chunk[1024]; - Stream_Chunk stream = {0}; - stream.min_start = min; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, sizeof(chunk))){ - int32_t still_looping = 1; - do{ - for(; pos >= stream.start; --pos){ - char at_pos = stream.data[pos]; - if (at_pos == first_char){ - buffer_read_range(app, buffer, pos, pos+size, read_buffer); - if (match_ss(needle_str, read_str)){ - *result = pos; - goto finished; - } - } - } - still_looping = backward_stream_chunk(&stream); - }while (still_looping); - } - } - - finished:; - } -} - -// NOTE(allen): This is limitted to a string size of 512. -// You can push it up or do something more clever by just -// replacing char read_buffer[512]; with more memory. -static void -buffer_seek_string_insensitive_forward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t end, char *str, int32_t size, int32_t *result){ - char read_buffer[512]; - char chunk[1024]; - int32_t chunk_size = sizeof(chunk); - Stream_Chunk stream = {0}; - stream.max_end = end; - - if (buffer->size > end){ - *result = buffer->size; - } - else{ - *result = end; - } - - if (size > 0 && size <= sizeof(read_buffer)){ - if (buffer->exists){ - String read_str = make_fixed_width_string(read_buffer); - String needle_str = make_string(str, size); - char first_char = char_to_upper(str[0]); - - read_str.size = size; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ - int32_t still_looping = 1; - do{ - for(; pos < stream.end; ++pos){ - char at_pos = char_to_upper(stream.data[pos]); - if (at_pos == first_char){ - buffer_read_range(app, buffer, pos, pos+size, read_buffer); - if (match_insensitive_ss(needle_str, read_str)){ - *result = pos; - goto finished; - } - } - } - still_looping = forward_stream_chunk(&stream); - }while (still_looping); - } - } - - finished:; - } -} - -// NOTE(allen): This is limitted to a string size of 512. -// You can push it up or do something more clever by just -// replacing char read_buffer[512]; with more memory. -static void -buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t min, char *str, int32_t size, int32_t *result){ - char read_buffer[512]; - char chunk[1024]; - int32_t chunk_size = sizeof(chunk); - Stream_Chunk stream = {0}; - stream.min_start = min; - - *result = min-1; - if (size > 0 && size <= sizeof(read_buffer)){ - if (buffer->exists){ - String read_str = make_fixed_width_string(read_buffer); - String needle_str = make_string(str, size); - char first_char = char_to_upper(str[0]); - - read_str.size = size; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ - int32_t still_looping = 1; - do{ - for(; pos >= stream.start; --pos){ - char at_pos = char_to_upper(stream.data[pos]); - if (at_pos == first_char){ - buffer_read_range(app, buffer, pos, pos+size, read_buffer); - if (match_insensitive_ss(needle_str, read_str)){ - *result = pos; - goto finished; - } - } - } - still_looping = backward_stream_chunk(&stream); - }while (still_looping); - } - } - - finished:; - } -} - - -// -// Some Basic Buffer Positioning -// - -#include "4cpp_lexer.h" - -static int32_t -buffer_get_line_start(Application_Links *app, Buffer_Summary *buffer, int32_t line){ - Partial_Cursor partial_cursor; - int32_t result = buffer->size; - if (line <= buffer->line_count){ - buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &partial_cursor); - result = partial_cursor.pos; - } - return(result); -} - -static int32_t -buffer_get_line_end(Application_Links *app, Buffer_Summary *buffer, int32_t line){ - Partial_Cursor partial_cursor; - int32_t result = buffer->size; - if (line <= buffer->line_count){ - buffer_compute_cursor(app, buffer, seek_line_char(line, 65536), &partial_cursor); - result = partial_cursor.pos; - } - return(result); -} - -static bool32 -buffer_line_is_blank(Application_Links *app, Buffer_Summary *buffer, int32_t line){ - Partial_Cursor start, end; - bool32 result = 0; - if (line <= buffer->line_count){ - buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &start); - buffer_compute_cursor(app, buffer, seek_line_char(line, 65536), &end); - - static const int32_t chunk_size = 1024; - char chunk[chunk_size]; - Stream_Chunk stream = {0}; - int32_t i = start.pos; - stream.max_end = end.pos; - - result = true; - if (init_stream_chunk(&stream, app, buffer, i, chunk, chunk_size)){ - bool32 still_looping = false; - do{ - for (;i < stream.end; ++i){ - char c = stream.data[i]; - if (!(c == ' ' || c == '\t' || c == '\r' || c == '\v' || c == '\n')){ - result = false; - goto double_break; - } - } - still_looping = forward_stream_chunk(&stream); - }while(still_looping); - } - double_break:; - } - return(result); -} - -static int32_t -buffer_get_line_index(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - Partial_Cursor partial_cursor; - buffer_compute_cursor(app, buffer, seek_pos(pos), &partial_cursor); - return(partial_cursor.line); -} - -static Cpp_Token* -get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line, int32_t *line_start_out = 0){ - int32_t line_start = buffer_get_line_start(app, buffer, line); - Cpp_Get_Token_Result get_token = cpp_get_token(tokens, line_start); - - if (get_token.in_whitespace){ - get_token.token_index += 1; - } - - if (line_start_out){ - *line_start_out = line_start; - } - - Cpp_Token *result = 0; - if (get_token.token_index < tokens.count){ - result = tokens.tokens + get_token.token_index; - } - - return(result); -} - - -// -// Fundamental Editing -// - -inline float -get_view_y(View_Summary view){ - float y = view.cursor.wrapped_y; - if (view.unwrapped_lines){ - y = view.cursor.unwrapped_y; - } - return(y); -} - -inline float -get_view_x(View_Summary view){ - float x = view.cursor.wrapped_x; - if (view.unwrapped_lines){ - x = view.cursor.unwrapped_x; - } - return(x); -} - -CUSTOM_COMMAND_SIG(write_character){ - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - - User_Input in = get_command_input(app); - char character = 0; - - if (in.type == UserInputKey){ - character = in.key.character; - } - - if (character != 0){ - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t pos = view.cursor.pos; - buffer_replace_range(app, &buffer, pos, pos, &character, 1); - view_set_cursor(app, &view, seek_pos(view.cursor.pos + 1), true); - } -} - -CUSTOM_COMMAND_SIG(delete_char){ - uint32_t access = AccessOpen; +basic_seek(Application_Links *app, int32_t seek_type, uint32_t flags){ + uint32_t access = AccessProtected; View_Summary view = get_active_view(app, access); Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t start = view.cursor.pos; - - Full_Cursor cursor; - view_compute_cursor(app, &view, seek_character_pos(view.cursor.character_pos+1), &cursor); - int32_t end = cursor.pos; - - if (0 <= start && start < buffer.size){ - buffer_replace_range(app, &buffer, start, end, 0, 0); - } + int32_t pos = buffer_boundary_seek(app, &buffer, view.cursor.pos, seek_type, flags); + view_set_cursor(app, &view, seek_pos(pos), true); } -CUSTOM_COMMAND_SIG(backspace_char){ - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t end = view.cursor.pos; - - Full_Cursor cursor; - view_compute_cursor(app, &view, seek_character_pos(view.cursor.character_pos-1), &cursor); - int32_t start = cursor.pos; - - if (0 < end && end <= buffer.size){ - buffer_replace_range(app, &buffer, start, end, 0, 0); - view_set_cursor(app, &view, seek_character_pos(view.cursor.character_pos-1), true); - } -} +#define seek_command(n, dir, flags) CUSTOM_COMMAND_SIG(seek_##n##_##dir){ basic_seek(app, dir, flags); } -CUSTOM_COMMAND_SIG(set_mark){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - - view_set_mark(app, &view, seek_pos(view.cursor.pos)); - view_set_cursor(app, &view, seek_pos(view.cursor.pos), 1); -} +#define right true +#define left false -CUSTOM_COMMAND_SIG(cursor_mark_swap){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - - int32_t cursor = view.cursor.pos; - int32_t mark = view.mark.pos; - - view_set_cursor(app, &view, seek_pos(mark), true); - view_set_mark(app, &view, seek_pos(cursor)); -} +seek_command(whitespace, right, BoundaryWhitespace) +seek_command(whitespace, left, BoundaryWhitespace) +seek_command(token, right, BoundaryToken) +seek_command(token, left, BoundaryToken) +seek_command(white_or_token, right, BoundaryToken | BoundaryWhitespace) +seek_command(white_or_token, left, BoundaryToken | BoundaryWhitespace) +seek_command(alphanumeric, right, BoundaryAlphanumeric) +seek_command(alphanumeric, left, BoundaryAlphanumeric) +seek_command(alphanumeric_or_camel, right, BoundaryAlphanumeric | BoundaryCamelCase) +seek_command(alphanumeric_or_camel, left, BoundaryAlphanumeric | BoundaryCamelCase) -CUSTOM_COMMAND_SIG(delete_range){ - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - Range range = get_range(&view); - buffer_replace_range(app, &buffer, range.min, range.max, 0, 0); -} - -// -// Basic Navigation -// - -CUSTOM_COMMAND_SIG(center_view){ - View_Summary view = get_active_view(app, AccessProtected); - - i32_Rect region = view.file_region; - GUI_Scroll_Vars scroll = view.scroll_vars; - - float h = (float)(region.y1 - region.y0); - float y = get_view_y(view); - y = y - h*.5f; - scroll.target_y = (int32_t)(y + .5f); - view_set_scroll(app, &view, scroll); -} - -CUSTOM_COMMAND_SIG(left_adjust_view){ - View_Summary view = get_active_view(app, AccessProtected); - - GUI_Scroll_Vars scroll = view.scroll_vars; - - float x = get_view_x(view) - 30.f; - if (x < 0){ - x = 0.f; - } - - scroll.target_x = (int32_t)(x + .5f); - view_set_scroll(app, &view, scroll); -} - -int32_t -get_relative_xy(View_Summary *view, int32_t x, int32_t y, float *x_out, float *y_out){ - int32_t result = false; - - i32_Rect region = view->file_region; - - int32_t max_x = (region.x1 - region.x0); - int32_t max_y = (region.y1 - region.y0); - GUI_Scroll_Vars scroll_vars = view->scroll_vars; - - int32_t rx = x - region.x0; - int32_t ry = y - region.y0; - - if (ry >= 0){ - if (rx >= 0 && rx < max_x && ry >= 0 && ry < max_y){ - result = 1; - } - } - - *x_out = (float)rx + scroll_vars.scroll_x; - *y_out = (float)ry + scroll_vars.scroll_y; - - return(result); -} - -CUSTOM_COMMAND_SIG(click_set_cursor){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - - Mouse_State mouse = get_mouse_state(app); - float rx = 0, ry = 0; - if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){ - view_set_cursor(app, &view, seek_xy(rx, ry, 1, view.unwrapped_lines), 1); - } -} - -CUSTOM_COMMAND_SIG(click_set_mark){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - - Mouse_State mouse = get_mouse_state(app); - float rx = 0, ry = 0; - if (get_relative_xy(&view, mouse.x, mouse.y, &rx, &ry)){ - view_set_mark(app, &view, seek_xy(rx, ry, 1, view.unwrapped_lines)); - } -} - -inline void -move_vertical(Application_Links *app, float line_multiplier){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - - float new_y = get_view_y(view) + line_multiplier*view.line_height; - float x = view.preferred_x; - - view_set_cursor(app, &view, seek_xy(x, new_y, 0, view.unwrapped_lines), 0); -} - -CUSTOM_COMMAND_SIG(move_up){ - move_vertical(app, -1.f); -} - -CUSTOM_COMMAND_SIG(move_down){ - move_vertical(app, 1.f); -} - -CUSTOM_COMMAND_SIG(move_up_10){ - move_vertical(app, -10.f); -} - -CUSTOM_COMMAND_SIG(move_down_10){ - move_vertical(app, 10.f); -} - -static float -get_page_jump(View_Summary *view){ - i32_Rect region = view->file_region; - float page_jump = 1; - - if (view->line_height > 0){ - page_jump = (float)(region.y1 - region.y0) / view->line_height; - page_jump -= 3.f; - if (page_jump <= 0){ - page_jump = 1.f; - } - } - - return(page_jump); -} - -CUSTOM_COMMAND_SIG(page_up){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - float page_jump = get_page_jump(&view); - move_vertical(app, -page_jump); -} - -CUSTOM_COMMAND_SIG(page_down){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - float page_jump = get_page_jump(&view); - move_vertical(app, page_jump); -} - - -CUSTOM_COMMAND_SIG(move_left){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - int32_t new_pos = view.cursor.character_pos - 1; - view_set_cursor(app, &view, seek_character_pos(new_pos), 1); -} - -CUSTOM_COMMAND_SIG(move_right){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - int32_t new_pos = view.cursor.character_pos + 1; - view_set_cursor(app, &view, seek_character_pos(new_pos), 1); -} - -// -// Auto Indenting and Whitespace -// - -static int32_t -seek_line_end(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char chunk[1024]; - int32_t chunk_size = sizeof(chunk); - Stream_Chunk stream = {0}; - - int32_t still_looping; - char at_pos; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ - still_looping = 1; - do{ - for (; pos < stream.end; ++pos){ - at_pos = stream.data[pos]; - if (at_pos == '\n'){ - goto double_break; - } - } - still_looping = forward_stream_chunk(&stream); - }while(still_looping); - double_break:; - - if (pos > buffer->size){ - pos = buffer->size; - } - } - - return(pos); -} - -static int32_t -seek_line_beginning(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char chunk[1024]; - int32_t chunk_size = sizeof(chunk); - Stream_Chunk stream = {0}; - - int32_t still_looping; - char at_pos; - - --pos; - if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ - still_looping = 1; - do{ - for (; pos >= stream.start; --pos){ - at_pos = stream.data[pos]; - if (at_pos == '\n'){ - goto double_break; - } - } - still_looping = backward_stream_chunk(&stream); - }while(still_looping); - double_break:; - - if (pos != 0){ - ++pos; - } - if (pos < 0){ - pos = 0; - } - } - - return(pos); -} - -static void -move_past_lead_whitespace(Application_Links *app, View_Summary *view, Buffer_Summary *buffer){ - refresh_view(app, view); - - int32_t new_pos = seek_line_beginning(app, buffer, view->cursor.pos); - char space[1024]; - Stream_Chunk chunk = {0}; - int32_t still_looping = false; - - int32_t i = new_pos; - if (init_stream_chunk(&chunk, app, buffer, i, space, sizeof(space))){ - do{ - for (; i < chunk.end; ++i){ - char at_pos = chunk.data[i]; - if (at_pos == '\n' || !char_is_whitespace(at_pos)){ - goto break2; - } - } - still_looping = forward_stream_chunk(&chunk); - }while(still_looping); - break2:; - - if (i > view->cursor.pos){ - view_set_cursor(app, view, seek_pos(i), true); - } - } -} - -#include "4coder_auto_indent.cpp" - -CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){ - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - buffer_auto_indent(app, &buffer, view.cursor.pos, view.cursor.pos, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); - move_past_lead_whitespace(app, &view, &buffer); -} - -static void -auto_tab_whole_file_by_summary(Application_Links *app, Buffer_Summary *buffer){ - buffer_auto_indent(app, buffer, 0, buffer->size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); -} - -CUSTOM_COMMAND_SIG(auto_tab_whole_file){ - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - auto_tab_whole_file_by_summary(app, &buffer); -} - -CUSTOM_COMMAND_SIG(auto_tab_range){ - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - Range range = get_range(&view); - - buffer_auto_indent(app, &buffer, range.min, range.max, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens); - move_past_lead_whitespace(app, &view, &buffer); -} - -CUSTOM_COMMAND_SIG(write_and_auto_tab){ - exec_command(app, write_character); - - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - buffer_auto_indent(app, &buffer, view.cursor.pos, view.cursor.pos, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_ExactAlignBlock); - move_past_lead_whitespace(app, &view, &buffer); -} - -CUSTOM_COMMAND_SIG(clean_all_lines){ - // TODO(allen): This command always iterates accross the entire - // buffer, so streaming it is actually the wrong call. Rewrite this - // to minimize calls to buffer_read_range. - View_Summary view = get_active_view(app, AccessOpen); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); - - int32_t line_count = buffer.line_count; - int32_t edit_max = line_count; - - if (edit_max*sizeof(Buffer_Edit) < app->memory_size){ - Buffer_Edit *edits = (Buffer_Edit*)app->memory; - - char data[1024]; - Stream_Chunk chunk = {0}; - - int32_t i = 0; - if (init_stream_chunk(&chunk, app, &buffer, i, data, sizeof(data))){ - Buffer_Edit *edit = edits; - - int32_t buffer_size = buffer.size; - int32_t still_looping = true; - int32_t last_hard = buffer_size; - do{ - for (; i < chunk.end; ++i){ - char at_pos = chunk.data[i]; - if (at_pos == '\n'){ - if (last_hard+1 < i){ - edit->str_start = 0; - edit->len = 0; - edit->start = last_hard+1; - edit->end = i; - ++edit; - } - last_hard = buffer_size; - } - else if (char_is_whitespace(at_pos)){ - // NOTE(allen): do nothing - } - else{ - last_hard = i; - } - } - - still_looping = forward_stream_chunk(&chunk); - }while(still_looping); - - if (last_hard+1 < buffer_size){ - edit->str_start = 0; - edit->len = 0; - edit->start = last_hard+1; - edit->end = buffer_size; - ++edit; - } - - int32_t edit_count = (int32_t)(edit - edits); - buffer_batch_edit(app, &buffer, 0, 0, edits, edit_count, BatchEdit_PreserveTokens); - } - } -} +#undef right +#undef left // // Clipboard @@ -1218,21 +119,6 @@ CUSTOM_COMMAND_SIG(cut){ clipboard_cut(app, range.min, range.max, 0, access); } -enum Rewrite_Type{ - RewriteNone, - RewritePaste, - RewriteWordComplete -}; - -struct View_Paste_Index{ - int32_t rewrite; - int32_t next_rewrite; - int32_t index; -}; - -View_Paste_Index view_paste_index_[16]; -View_Paste_Index *view_paste_index = view_paste_index_ - 1; - CUSTOM_COMMAND_SIG(paste){ uint32_t access = AccessOpen; int32_t count = clipboard_count(app, 0); @@ -1321,663 +207,7 @@ CUSTOM_COMMAND_SIG(paste_next_and_indent){ exec_command(app, auto_tab_range); } -// -// Fancy Editing -// - -CUSTOM_COMMAND_SIG(to_uppercase){ - View_Summary view = get_active_view(app, AccessOpen); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); - - Range range = get_range(&view); - int32_t size = range.max - range.min; - if (size <= app->memory_size){ - char *mem = (char*)app->memory; - - buffer_read_range(app, &buffer, range.min, range.max, mem); - for (int32_t i = 0; i < size; ++i){ - mem[i] = char_to_upper(mem[i]); - } - buffer_replace_range(app, &buffer, range.min, range.max, mem, size); - view_set_cursor(app, &view, seek_pos(range.max), true); - } -} - -CUSTOM_COMMAND_SIG(to_lowercase){ - View_Summary view = get_active_view(app, AccessOpen); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); - - Range range = get_range(&view); - int32_t size = range.max - range.min; - if (size <= app->memory_size){ - char *mem = (char*)app->memory; - - buffer_read_range(app, &buffer, range.min, range.max, mem); - for (int32_t i = 0; i < size; ++i){ - mem[i] = char_to_lower(mem[i]); - } - buffer_replace_range(app, &buffer, range.min, range.max, mem, size); - view_set_cursor(app, &view, seek_pos(range.max), true); - } -} - -// -// Various Forms of Seek -// - -static int32_t -buffer_seek_whitespace_up(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char chunk[1024]; - int32_t chunk_size = sizeof(chunk); - Stream_Chunk stream = {0}; - - char at_pos; - - --pos; - if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ - // Step 1: Find the first non-whitespace character - // behind the current position. - int32_t still_looping = 1; - while (still_looping){ - for (; pos >= stream.start; --pos){ - at_pos = stream.data[pos]; - if (!char_is_whitespace(at_pos)){ - goto double_break_1; - } - } - still_looping = backward_stream_chunk(&stream); - } - double_break_1:; - - // Step 2: Continue scanning backward, at each '\n' - // mark the beginning of another line by setting - // no_hard to true, set it back to false if a - // non-whitespace character is discovered before - // the next '\n' - int32_t no_hard = false; - while (still_looping){ - for (; pos >= stream.start; --pos){ - at_pos = stream.data[pos]; - if (at_pos == '\n'){ - if (no_hard){ - goto double_break_2; - } - else{ - no_hard = true; - } - } - else if (!char_is_whitespace(at_pos)){ - no_hard = false; - } - } - still_looping = backward_stream_chunk(&stream); - } - double_break_2:; - - if (pos != 0){ - ++pos; - } - } - - return(pos); -} - -static int32_t -buffer_seek_whitespace_down(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char chunk[1024]; - int32_t chunk_size = sizeof(chunk); - Stream_Chunk stream = {0}; - - int32_t no_hard; - int32_t prev_endline; - int32_t still_looping; - char at_pos; - - if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ - // step 1: find the first non-whitespace character - // ahead of the current position. - still_looping = true; - do{ - for (; pos < stream.end; ++pos){ - at_pos = stream.data[pos]; - if (!char_is_whitespace(at_pos)){ - goto double_break_1; - } - } - still_looping = forward_stream_chunk(&stream); - } while(still_looping); - double_break_1:; - - // step 2: continue scanning forward, at each '\n' - // mark it as the beginning of a new line by updating - // the prev_endline value. if another '\n' is found - // with non-whitespace then the previous line was - // all whitespace. - no_hard = false; - prev_endline = -1; - while(still_looping){ - for (; pos < stream.end; ++pos){ - at_pos = stream.data[pos]; - if (at_pos == '\n'){ - if (no_hard){ - goto double_break_2; - } - else{ - no_hard = true; - prev_endline = pos; - } - } - else if (!char_is_whitespace(at_pos)){ - no_hard = false; - } - } - still_looping = forward_stream_chunk(&stream); - } - double_break_2:; - - if (prev_endline == -1 || prev_endline+1 >= buffer->size){ - pos = buffer->size; - } - else{ - pos = prev_endline+1; - } - } - - return(pos); -} - -CUSTOM_COMMAND_SIG(seek_whitespace_up){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t new_pos = buffer_seek_whitespace_up(app, &buffer, view.cursor.pos); - view_set_cursor(app, &view, - seek_pos(new_pos), - true); -} - -CUSTOM_COMMAND_SIG(seek_whitespace_down){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t new_pos = buffer_seek_whitespace_down(app, &buffer, view.cursor.pos); - view_set_cursor(app, &view, - seek_pos(new_pos), - true); -} - -CUSTOM_COMMAND_SIG(seek_end_of_textual_line){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t new_pos = seek_line_end(app, &buffer, view.cursor.pos); - view_set_cursor(app, &view, seek_pos(new_pos), true); -} - -CUSTOM_COMMAND_SIG(seek_beginning_of_textual_line){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - int32_t new_pos = seek_line_beginning(app, &buffer, view.cursor.pos); - view_set_cursor(app, &view, seek_pos(new_pos), true); -} - -CUSTOM_COMMAND_SIG(seek_beginning_of_line){ - View_Summary view = get_active_view(app, AccessProtected); - - float y = view.cursor.wrapped_y; - if (view.unwrapped_lines){ - y = view.cursor.unwrapped_y; - } - - view_set_cursor(app, &view, seek_xy(0, y, 1, view.unwrapped_lines), 1); -} - -CUSTOM_COMMAND_SIG(seek_end_of_line){ - View_Summary view = get_active_view(app, AccessProtected); - - float y = view.cursor.wrapped_y; - if (view.unwrapped_lines){ - y = view.cursor.unwrapped_y; - } - - view_set_cursor(app, &view, seek_xy(100000.f, y, 1, view.unwrapped_lines), 1); -} - -// TODO(allen): REDUCE DUPLICATION! -static int32_t -buffer_seek_whitespace_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char data_chunk[1024]; - Stream_Chunk stream = {0}; - - if (init_stream_chunk(&stream, app, buffer, - pos, data_chunk, sizeof(data_chunk))){ - - bool32 still_looping = 1; - do{ - for (; pos < stream.end; ++pos){ - if (!char_is_whitespace(stream.data[pos])){ - goto double_break1; - } - } - still_looping = forward_stream_chunk(&stream); - }while(still_looping); - double_break1:; - - still_looping = 1; - do{ - for (; pos < stream.end; ++pos){ - if (char_is_whitespace(stream.data[pos])){ - goto double_break2; - } - } - still_looping = forward_stream_chunk(&stream); - }while(still_looping); - double_break2:; - } - - return(pos); -} - -static int32_t -buffer_seek_whitespace_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char data_chunk[1024]; - Stream_Chunk stream = {0}; - - --pos; - if (pos > 0){ - if (init_stream_chunk(&stream, app, buffer, - pos, data_chunk, sizeof(data_chunk))){ - - bool32 still_looping = 1; - do{ - for (; pos >= stream.start; --pos){ - if (!char_is_whitespace(stream.data[pos])){ - goto double_break1; - } - } - still_looping = backward_stream_chunk(&stream); - }while(still_looping); - double_break1:; - - still_looping = 1; - do{ - for (; pos >= stream.start; --pos){ - if (char_is_whitespace(stream.data[pos])){ - ++pos; - goto double_break2; - } - } - still_looping = backward_stream_chunk(&stream); - }while(still_looping); - double_break2:; - } - } - else{ - pos = 0; - } - - return(pos); -} - -static int32_t -buffer_seek_alphanumeric_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char data_chunk[1024]; - Stream_Chunk stream = {0}; - - if (init_stream_chunk(&stream, app, buffer, - pos, data_chunk, sizeof(data_chunk))){ - - bool32 still_looping = 1; - do{ - for (; pos < stream.end; ++pos){ - if (char_is_alpha_numeric_true(stream.data[pos])){ - goto double_break1; - } - } - still_looping = forward_stream_chunk(&stream); - }while(still_looping); - double_break1:; - - still_looping = 1; - do{ - for (; pos < stream.end; ++pos){ - if (!char_is_alpha_numeric_true(stream.data[pos])){ - goto double_break2; - } - } - still_looping = forward_stream_chunk(&stream); - }while(still_looping); - double_break2:; - } - - return(pos); -} - -static int32_t -buffer_seek_alphanumeric_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char data_chunk[1024]; - Stream_Chunk stream = {0}; - - --pos; - if (pos > 0){ - if (init_stream_chunk(&stream, app, buffer, - pos, data_chunk, sizeof(data_chunk))){ - - bool32 still_looping = 1; - do{ - for (; pos >= stream.start; --pos){ - if (char_is_alpha_numeric_true(stream.data[pos])){ - goto double_break1; - } - } - still_looping = backward_stream_chunk(&stream); - }while(still_looping); - double_break1:; - - still_looping = 1; - do{ - for (; pos >= stream.start; --pos){ - if (!char_is_alpha_numeric_true(stream.data[pos])){ - ++pos; - goto double_break2; - } - } - still_looping = backward_stream_chunk(&stream); - }while(still_looping); - double_break2:; - } - } - else{ - pos = 0; - } - - return(pos); -} - -static int32_t -buffer_seek_range_camel_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t an_pos){ - char data_chunk[1024]; - Stream_Chunk stream = {0}; - - ++pos; - if (pos < an_pos){ - stream.max_end = an_pos; - if (init_stream_chunk(&stream, app, buffer, - pos, data_chunk, sizeof(data_chunk))){ - - char c = 0, pc = stream.data[pos]; - ++pos; - - bool32 still_looping = 1; - do{ - for (; pos < stream.end; ++pos){ - c = stream.data[pos]; - if (char_is_upper(c) && char_is_lower(pc)){ - goto double_break1; - } - pc = c; - } - still_looping = forward_stream_chunk(&stream); - }while(still_looping); - double_break1:; - } - } - else{ - pos = an_pos; - } - - return(pos); -} - -static int32_t -buffer_seek_range_camel_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t an_pos){ - char data_chunk[1024]; - Stream_Chunk stream = {0}; - - --pos; - if (pos > 0){ - stream.min_start = an_pos+1; - if (init_stream_chunk(&stream, app, buffer, pos, data_chunk, sizeof(data_chunk))){ - - char c = 0, pc = stream.data[pos]; - - bool32 still_looping = 1; - do{ - for (; pos >= stream.start; --pos){ - c = stream.data[pos]; - if (char_is_upper(c) && char_is_lower(pc)){ - goto double_break1; - } - pc = c; - } - still_looping = backward_stream_chunk(&stream); - }while(still_looping); - double_break1:; - } - } - else{ - pos = 0; - } - - return(pos); -} - -static int32_t -buffer_seek_alphanumeric_or_camel_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - int32_t an_pos = buffer_seek_alphanumeric_right(app, buffer, pos); - int32_t result = buffer_seek_range_camel_right(app, buffer, pos, an_pos); - return(result); -} - -static int32_t -buffer_seek_alphanumeric_or_camel_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - int32_t an_pos = buffer_seek_alphanumeric_left(app, buffer, pos); - int32_t result = buffer_seek_range_camel_left(app, buffer, pos, an_pos); - return(result); -} - -static int32_t -seek_token_left(Cpp_Token_Array *tokens, int32_t pos){ - Cpp_Get_Token_Result get = cpp_get_token(*tokens, pos); - if (get.token_index == -1){ - get.token_index = 0; - } - - Cpp_Token *token = tokens->tokens + get.token_index; - if (token->start == pos && get.token_index > 0){ - --token; - } - - return(token->start); -} - -static int32_t -seek_token_right(Cpp_Token_Array *tokens, int32_t pos){ - Cpp_Get_Token_Result get = cpp_get_token(*tokens, pos); - if (get.in_whitespace){ - ++get.token_index; - } - if (get.token_index >= tokens->count){ - get.token_index = tokens->count-1; - } - - Cpp_Token *token = tokens->tokens + get.token_index; - return(token->start + token->size); -} - -static Cpp_Token_Array -buffer_get_all_tokens(Application_Links *app, Partition *part, Buffer_Summary *buffer){ - Cpp_Token_Array array = {0}; - - if (buffer->exists && buffer->is_lexed){ - array.count = buffer_token_count(app, buffer); - array.max_count = array.count; - array.tokens = push_array(part, Cpp_Token, array.count); - buffer_read_tokens(app, buffer, 0, array.count, array.tokens); - } - - return(array); -} - -static int32_t -buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, Partition *part, - int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)/* -DOC_PARAM(buffer, The buffer parameter specifies the buffer through which to seek.) -DOC_PARAM(start_pos, The beginning position of the seek is specified by start_pos measured in absolute position.) -DOC_PARAM(seek_forward, If this parameter is non-zero it indicates that the seek should move foward through the buffer.) -DOC_PARAM(flags, This field specifies the types of boundaries at which the seek should stop.) - -DOC_RETURN(This call returns the absolute position where the seek stopped. -If the seek goes below 0 the returned value is -1. -If the seek goes past the end the returned value is the size of the buffer.) - -DOC_SEE(Seek_Boundary_Flag) -DOC_SEE(4coder_Buffer_Positioning_System) -*/{ - int32_t result = 0; - - // TODO(allen): reduce duplication? - Temp_Memory temp = begin_temp_memory(part); - if (buffer->exists){ - int32_t pos[4]; - int32_t size = buffer->size; - int32_t new_pos = 0; - - if (start_pos < 0){ - start_pos = 0; - } - else if (start_pos > size){ - start_pos = size; - } - - if (seek_forward){ - for (int32_t i = 0; i < ArrayCount(pos); ++i){ - pos[i] = size; - } - - if (flags & BoundaryWhitespace){ - pos[0] = buffer_seek_whitespace_right(app, buffer, start_pos); - } - - if (flags & BoundaryToken){ - if (buffer->tokens_are_ready){ - Cpp_Token_Array array = buffer_get_all_tokens(app, part, buffer); - pos[1] = seek_token_right(&array, start_pos); - } - else{ - pos[1] = buffer_seek_whitespace_right(app, buffer, start_pos); - } - } - - if (flags & BoundaryAlphanumeric){ - pos[2] = buffer_seek_alphanumeric_right(app, buffer, start_pos); - if (flags & BoundaryCamelCase){ - pos[3] = buffer_seek_range_camel_right(app, buffer, start_pos, pos[2]); - } - } - else{ - if (flags & BoundaryCamelCase){ - pos[3] = buffer_seek_alphanumeric_or_camel_right(app, buffer, start_pos); - } - } - - new_pos = size; - for (int32_t i = 0; i < ArrayCount(pos); ++i){ - if (pos[i] < new_pos){ - new_pos = pos[i]; - } - } - } - else{ - for (int32_t i = 0; i < ArrayCount(pos); ++i){ - pos[i] = 0; - } - - if (flags & BoundaryWhitespace){ - pos[0] = buffer_seek_whitespace_left(app, buffer, start_pos); - } - - if (flags & BoundaryToken){ - if (buffer->tokens_are_ready){ - Cpp_Token_Array array = buffer_get_all_tokens(app, part, buffer); - pos[1] = seek_token_left(&array, start_pos); - } - else{ - pos[1] = buffer_seek_whitespace_left(app, buffer, start_pos); - } - } - - if (flags & BoundaryAlphanumeric){ - pos[2] = buffer_seek_alphanumeric_left(app, buffer, start_pos); - if (flags & BoundaryCamelCase){ - pos[3] = buffer_seek_range_camel_left(app, buffer, start_pos, pos[2]); - } - } - else{ - if (flags & BoundaryCamelCase){ - pos[3] = buffer_seek_alphanumeric_or_camel_left(app, buffer, start_pos); - } - } - - new_pos = 0; - for (int32_t i = 0; i < ArrayCount(pos); ++i){ - if (pos[i] > new_pos){ - new_pos = pos[i]; - } - } - } - result = new_pos; - } - end_temp_memory(temp); - - return(result); -} - -static int32_t -buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, - int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags){ - int32_t result = buffer_boundary_seek(app, buffer, &global_part, start_pos, seek_forward, flags); - return(result); -} - -static void -basic_seek(Application_Links *app, int32_t seek_type, uint32_t flags){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - int32_t pos = buffer_boundary_seek(app, &buffer, view.cursor.pos, seek_type, flags); - view_set_cursor(app, &view, seek_pos(pos), true); -} - -#define seek_command(n, dir, flags)\ -CUSTOM_COMMAND_SIG(seek_##n##_##dir){ basic_seek(app, dir, flags); } - -#define right true -#define left false - -seek_command(whitespace, right, BoundaryWhitespace) -seek_command(whitespace, left, BoundaryWhitespace) -seek_command(token, right, BoundaryToken) -seek_command(token, left, BoundaryToken) -seek_command(white_or_token, right, BoundaryToken | BoundaryWhitespace) -seek_command(white_or_token, left, BoundaryToken | BoundaryWhitespace) -seek_command(alphanumeric, right, BoundaryAlphanumeric) -seek_command(alphanumeric, left, BoundaryAlphanumeric) -seek_command(alphanumeric_or_camel, right, BoundaryAlphanumeric | BoundaryCamelCase) -seek_command(alphanumeric_or_camel, left, BoundaryAlphanumeric | BoundaryCamelCase) - -#undef right -#undef left - - -// -// special string writing commands -// +////////////////////////// static void write_string(Application_Links *app, View_Summary *view, Buffer_Summary *buffer, String string){ @@ -1993,10 +223,6 @@ write_string(Application_Links *app, String string){ write_string(app, &view, &buffer, string); } -CUSTOM_COMMAND_SIG(write_increment){ - write_string(app, make_lit_string("++")); -} - static void long_braces(Application_Links *app, char *text, int32_t size){ uint32_t access = AccessOpen; @@ -2130,91 +356,7 @@ CUSTOM_COMMAND_SIG(snipe_token_or_word){ buffer_replace_range(app, &buffer, range.start, range.end, 0, 0); } -// -// Scroll Bar Controlling -// -CUSTOM_COMMAND_SIG(show_scrollbar){ - View_Summary view = get_active_view(app, AccessProtected); - view_set_setting(app, &view, ViewSetting_ShowScrollbar, true); -} - -CUSTOM_COMMAND_SIG(hide_scrollbar){ - View_Summary view = get_active_view(app, AccessProtected); - view_set_setting(app, &view, ViewSetting_ShowScrollbar, false); -} - -// -// Panel Management -// - -static void -get_view_next_looped(Application_Links *app, View_Summary *view, uint32_t access){ - get_view_next(app, view, access); - if (!view->exists){ - *view = get_view_first(app, access); - } -} - -static View_ID special_note_view_id = 0; - -static void -close_special_note_view(Application_Links *app){ - View_Summary special_view = get_view(app, special_note_view_id, AccessAll); - if (special_view.exists){ - close_view(app, &special_view); - } - special_note_view_id = 0; -} - -static View_Summary -open_special_note_view(Application_Links *app, bool32 create_if_not_exist = true){ - View_Summary special_view = get_view(app, special_note_view_id, AccessAll); - - if (create_if_not_exist && !special_view.exists){ - View_Summary view = get_active_view(app, AccessAll); - special_view = open_view(app, &view, ViewSplit_Bottom); - view_set_setting(app, &special_view, ViewSetting_ShowScrollbar, false); - view_set_split_proportion(app, &special_view, .2f); - set_active_view(app, &view); - special_note_view_id = special_view.view_id; - } - - return(special_view); -} - -CUSTOM_COMMAND_SIG(change_active_panel){ - View_Summary view = get_active_view(app, AccessAll); - View_ID original_view_id = view.view_id; - - do{ - get_view_next_looped(app, &view, AccessAll); - if (view.view_id != special_note_view_id){ - break; - } - }while(view.view_id != original_view_id); - - if (view.exists){ - set_active_view(app, &view); - } -} - -CUSTOM_COMMAND_SIG(close_panel){ - View_Summary view = get_active_view(app, AccessAll); - close_view(app, &view); -} - -CUSTOM_COMMAND_SIG(open_panel_vsplit){ - View_Summary view = get_active_view(app, AccessAll); - View_Summary new_view = open_view(app, &view, ViewSplit_Right); - view_set_setting(app, &new_view, ViewSetting_ShowScrollbar, false); -} - -CUSTOM_COMMAND_SIG(open_panel_hsplit){ - View_Summary view = get_active_view(app, AccessAll); - View_Summary new_view = open_view(app, &view, ViewSplit_Bottom); - view_set_setting(app, &new_view, ViewSetting_ShowScrollbar, false); -} // // Open File In Quotes @@ -2266,270 +408,12 @@ CUSTOM_COMMAND_SIG(open_file_in_quotes){ CUSTOM_COMMAND_SIG(open_in_other){ exec_command(app, change_active_panel); - exec_command(app, cmdid_interactive_open); + exec_command(app, interactive_open); } -CUSTOM_COMMAND_SIG(save_as){ - exec_command(app, cmdid_save_as); -} - -CUSTOM_COMMAND_SIG(goto_line){ - uint32_t access = AccessProtected; - - Query_Bar bar = {0}; - char string_space[256]; - - bar.prompt = make_lit_string("Goto Line: "); - bar.string = make_fixed_width_string(string_space); - - if (query_user_number(app, &bar)){ - int32_t line_number = str_to_int_s(bar.string); - active_view_to_line(app, access, line_number); - } -} - -CUSTOM_COMMAND_SIG(search); -CUSTOM_COMMAND_SIG(reverse_search); - -static void -isearch(Application_Links *app, int32_t start_reversed){ - uint32_t access = AccessProtected; - - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - if (!buffer.exists) return; - - Query_Bar bar = {0}; - if (start_query_bar(app, &bar, 0) == 0) return; - - int32_t reverse = start_reversed; - int32_t pos = view.cursor.pos; - int32_t start_pos = pos; - int32_t first_pos = pos; - Range match = make_range(pos, pos); - - char bar_string_space[256]; - bar.string = make_fixed_width_string(bar_string_space); - - String isearch_str = make_lit_string("I-Search: "); - String rsearch_str = make_lit_string("Reverse-I-Search: "); - - User_Input in = {0}; - for (;;){ - view_set_highlight(app, &view, match.start, match.end, true); - - // NOTE(allen): Change the bar's prompt to match the current direction. - if (reverse) bar.prompt = rsearch_str; - else bar.prompt = isearch_str; - - in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); - if (in.abort) break; - - // NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we - // only asked to intercept key events. - - assert(in.type == UserInputKey); - - int32_t made_change = 0; - if (in.key.keycode == '\n' || in.key.keycode == '\t'){ - break; - } - else if (in.key.character && key_is_unmodified(&in.key)){ - append_s_char(&bar.string, in.key.character); - made_change = 1; - } - else if (in.key.keycode == key_back){ - if (bar.string.size > 0){ - --bar.string.size; - made_change = 1; - } - } - - int32_t step_forward = 0; - int32_t step_backward = 0; - - if ((in.command.command == search) || - in.key.keycode == key_page_down || in.key.keycode == key_down) step_forward = 1; - if ((in.command.command == reverse_search) || - in.key.keycode == key_page_up || in.key.keycode == key_up) step_backward = 1; - - start_pos = pos; - if (step_forward && reverse){ - start_pos = match.start + 1; - pos = start_pos; - reverse = 0; - step_forward = 0; - } - if (step_backward && !reverse){ - start_pos = match.start - 1; - pos = start_pos; - reverse = 1; - step_backward = 0; - } - - if (in.key.keycode != key_back){ - int32_t new_pos; - if (reverse){ - buffer_seek_string_insensitive_backward(app, &buffer, start_pos - 1, 0, - bar.string.str, bar.string.size, &new_pos); - if (new_pos >= 0){ - if (step_backward){ - pos = new_pos; - start_pos = new_pos; - buffer_seek_string_insensitive_backward(app, &buffer, start_pos - 1, 0, - bar.string.str, bar.string.size, &new_pos); - if (new_pos < 0) new_pos = start_pos; - } - match.start = new_pos; - match.end = match.start + bar.string.size; - } - } - else{ - buffer_seek_string_insensitive_forward(app, &buffer, start_pos + 1, 0, - bar.string.str, bar.string.size, &new_pos); - if (new_pos < buffer.size){ - if (step_forward){ - pos = new_pos; - start_pos = new_pos; - buffer_seek_string_insensitive_forward(app, &buffer, start_pos + 1, 0, - bar.string.str, bar.string.size, &new_pos); - if (new_pos >= buffer.size) new_pos = start_pos; - } - match.start = new_pos; - match.end = match.start + bar.string.size; - } - } - } - else{ - if (match.end > match.start + bar.string.size){ - match.end = match.start + bar.string.size; - } - } - } - view_set_highlight(app, &view, 0, 0, false); - if (in.abort){ - view_set_cursor(app, &view, seek_pos(first_pos), true); - return; - } - - view_set_cursor(app, &view, seek_pos(match.min), true); -} - -CUSTOM_COMMAND_SIG(search){ - isearch(app, false); -} - -CUSTOM_COMMAND_SIG(reverse_search){ - isearch(app, true); -} - -CUSTOM_COMMAND_SIG(replace_in_range){ - Query_Bar replace; - char replace_space[1024]; - replace.prompt = make_lit_string("Replace: "); - replace.string = make_fixed_width_string(replace_space); - - Query_Bar with; - char with_space[1024]; - with.prompt = make_lit_string("With: "); - with.string = make_fixed_width_string(with_space); - - if (!query_user_string(app, &replace)) return; - if (replace.string.size == 0) return; - - if (!query_user_string(app, &with)) return; - - String r = replace.string, w = with.string; - - uint32_t access = AccessOpen; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - - Range range = get_range(&view); - - int32_t pos, new_pos; - pos = range.min; - - buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); - - while (new_pos + r.size <= range.end){ - buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size); - refresh_view(app, &view); - range = get_range(&view); - pos = new_pos + w.size; - buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); - } -} - -CUSTOM_COMMAND_SIG(query_replace){ - Query_Bar replace; - char replace_space[1024]; - replace.prompt = make_lit_string("Replace: "); - replace.string = make_fixed_width_string(replace_space); - - Query_Bar with; - char with_space[1024]; - with.prompt = make_lit_string("With: "); - with.string = make_fixed_width_string(with_space); - - if (!query_user_string(app, &replace)) return; - if (replace.string.size == 0) return; - - if (!query_user_string(app, &with)) return; - - String r, w; - r = replace.string; - w = with.string; - - Query_Bar bar; - Buffer_Summary buffer; - View_Summary view; - int32_t pos, new_pos; - - bar.prompt = make_lit_string("Replace? (y)es, (n)ext, (esc)\n"); - bar.string = null_string; - - start_query_bar(app, &bar, 0); - - uint32_t access = AccessOpen; - view = get_active_view(app, access); - buffer = get_buffer(app, view.buffer_id, access); - - pos = view.cursor.pos; - buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); - - User_Input in = {0}; - while (new_pos < buffer.size){ - Range match = make_range(new_pos, new_pos + r.size); - view_set_highlight(app, &view, match.min, match.max, 1); - - in = get_user_input(app, EventOnAnyKey, EventOnButton); - if (in.abort || in.key.keycode == key_esc || !key_is_unmodified(&in.key)) break; - - if (in.key.character == 'y' || - in.key.character == 'Y' || - in.key.character == '\n' || - in.key.character == '\t'){ - buffer_replace_range(app, &buffer, match.min, match.max, w.str, w.size); - pos = match.start + w.size; - } - else{ - pos = match.max; - } - - buffer_seek_string_forward(app, &buffer, pos, 0, r.str, r.size, &new_pos); - } - - view_set_highlight(app, &view, 0, 0, 0); - if (in.abort) return; - - view_set_cursor(app, &view, seek_pos(pos), 1); -} - // -// Fast Buffer Management +// System Commands // static char out_buffer_space[1024]; @@ -2570,441 +454,6 @@ CUSTOM_COMMAND_SIG(execute_previous_cli){ } } -// -// Common Settings Commands -// - -//toggle_fullscreen can be used as a command - -CUSTOM_COMMAND_SIG(toggle_line_wrap){ - View_Summary view = get_active_view(app, AccessProtected); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); - - bool32 unwrapped = view.unwrapped_lines; - buffer_set_setting(app, &buffer, BufferSetting_WrapLine, unwrapped); -} - -CUSTOM_COMMAND_SIG(increase_line_wrap){ - View_Summary view = get_active_view(app, AccessProtected); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); - - int32_t wrap = 0; - buffer_get_setting(app, &buffer, BufferSetting_WrapPosition, &wrap); - buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap + 10); -} - -CUSTOM_COMMAND_SIG(decrease_line_wrap){ - View_Summary view = get_active_view(app, AccessProtected); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); - - int32_t wrap = 0; - buffer_get_setting(app, &buffer, BufferSetting_WrapPosition, &wrap); - buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, wrap - 10); -} - -CUSTOM_COMMAND_SIG(toggle_virtual_whitespace){ - View_Summary view = get_active_view(app, AccessProtected); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); - - int32_t vwhite = 0; - buffer_get_setting(app, &buffer, BufferSetting_VirtualWhitespace, &vwhite); - buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, !vwhite); -} - -CUSTOM_COMMAND_SIG(toggle_show_whitespace){ - View_Summary view = get_active_view(app, AccessProtected); - view_set_setting(app, &view, ViewSetting_ShowWhitespace, !view.show_whitespace); -} - -CUSTOM_COMMAND_SIG(eol_dosify){ - View_Summary view = get_active_view(app, AccessOpen); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); - buffer_set_setting(app, &buffer, BufferSetting_Eol, 1); -} - -CUSTOM_COMMAND_SIG(eol_nixify){ - View_Summary view = get_active_view(app, AccessOpen); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); - buffer_set_setting(app, &buffer, BufferSetting_Eol, 0); -} - -CUSTOM_COMMAND_SIG(exit_4coder){ - send_exit_signal(app); -} - - -// -// "Full Search" Based Commands -// - -#include "4coder_table.cpp" -#include "4coder_search.cpp" -#include "4coder_jump_parsing.cpp" - -static void -get_search_all_string(Application_Links *app, Query_Bar *bar){ - char string_space[1024]; - bar->prompt = make_lit_string("List Locations For: "); - bar->string = make_fixed_width_string(string_space); - - if (!query_user_string(app, bar)){ - bar->string.size = 0; - } -} - -static void -generic_search_all_buffers(Application_Links *app, General_Memory *general, Partition *part, String string, uint32_t match_flags){ - Search_Set set = {0}; - Search_Iter iter = {0}; - - search_iter_init(general, &iter, string.size); - copy_ss(&iter.word, string); - - int32_t buffer_count = get_buffer_count(app); - search_set_init(general, &set, buffer_count); - - Search_Range *ranges = set.ranges; - - String search_name = make_lit_string("*search*"); - Buffer_Summary search_buffer = get_buffer_by_name(app, search_name.str, search_name.size, AccessAll); - if (!search_buffer.exists){ - search_buffer = create_buffer(app, search_name.str, search_name.size, BufferCreate_AlwaysNew); - buffer_set_setting(app, &search_buffer, BufferSetting_Unimportant, true); - buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, true); - buffer_set_setting(app, &search_buffer, BufferSetting_WrapLine, false); - } - else{ - buffer_replace_range(app, &search_buffer, 0, search_buffer.size, 0, 0); - } - - { - View_Summary view = get_active_view(app, AccessProtected); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); - - int32_t j = 0; - if (buffer.exists){ - if (buffer.buffer_id != search_buffer.buffer_id){ - ranges[0].type = SearchRange_FrontToBack; - ranges[0].flags = match_flags; - ranges[0].buffer = buffer.buffer_id; - ranges[0].start = 0; - ranges[0].size = buffer.size; - j = 1; - } - } - - for (Buffer_Summary buffer_it = get_buffer_first(app, AccessAll); - buffer_it.exists; - get_buffer_next(app, &buffer_it, AccessAll)){ - if (buffer.buffer_id != buffer_it.buffer_id){ - if (search_buffer.buffer_id != buffer_it.buffer_id){ - ranges[j].type = SearchRange_FrontToBack; - ranges[j].flags = match_flags; - ranges[j].buffer = buffer_it.buffer_id; - ranges[j].start = 0; - ranges[j].size = buffer_it.size; - ++j; - } - } - } - set.count = j; - } - - Temp_Memory temp = begin_temp_memory(part); - Partition line_part = partition_sub_part(part, (4 << 10)); - char *str = (char*)partition_current(part); - int32_t part_size = 0; - int32_t size = 0; - for (;;){ - Search_Match match = search_next_match(app, &set, &iter); - if (match.found_match){ - Partial_Cursor word_pos = {0}; - if (buffer_compute_cursor(app, &match.buffer, seek_pos(match.start), &word_pos)){ - int32_t file_len = match.buffer.file_name_len; - int32_t line_num_len = int_to_str_size(word_pos.line); - int32_t column_num_len = int_to_str_size(word_pos.character); - - Temp_Memory line_temp = begin_temp_memory(&line_part); - String line_str = {0}; - read_line(app, &line_part, &match.buffer, word_pos.line, &line_str); - line_str = skip_chop_whitespace(line_str); - - int32_t str_len = file_len + 1 + line_num_len + 1 + column_num_len + 1 + 1 + line_str.size + 1; - - char *spare = push_array(part, char, str_len); - - if (spare == 0){ - buffer_replace_range(app, &search_buffer, size, size, str, part_size); - size += part_size; - - end_temp_memory(temp); - temp = begin_temp_memory(part); - - part_size = 0; - spare = push_array(part, char, str_len); - } - - part_size += str_len; - - String out_line = make_string_cap(spare, 0, str_len); - append_ss(&out_line, make_string(match.buffer.file_name, file_len)); - append_s_char(&out_line, ':'); - append_int_to_str(&out_line, word_pos.line); - append_s_char(&out_line, ':'); - append_int_to_str(&out_line, word_pos.character); - append_s_char(&out_line, ':'); - append_s_char(&out_line, ' '); - append_ss(&out_line, line_str); - append_s_char(&out_line, '\n'); - Assert(out_line.size == str_len); - - end_temp_memory(line_temp); - } - } - else{ - break; - } - } - - buffer_replace_range(app, &search_buffer, size, size, str, part_size); - - View_Summary view = get_active_view(app, AccessAll); - view_set_buffer(app, &view, search_buffer.buffer_id, 0); - - lock_jump_buffer(search_name.str, search_name.size); - - end_temp_memory(temp); -} - -CUSTOM_COMMAND_SIG(list_all_locations){ - Query_Bar bar; - get_search_all_string(app, &bar); - if (bar.string.size == 0) return; - generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchWholeWord); -} - -CUSTOM_COMMAND_SIG(list_all_substring_locations){ - Query_Bar bar; - get_search_all_string(app, &bar); - if (bar.string.size == 0) return; - generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchSubstring); -} - -CUSTOM_COMMAND_SIG(list_all_locations_case_insensitive){ - Query_Bar bar; - get_search_all_string(app, &bar); - if (bar.string.size == 0) return; - generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchWholeWord); -} - -CUSTOM_COMMAND_SIG(list_all_substring_locations_case_insensitive){ - Query_Bar bar; - get_search_all_string(app, &bar); - if (bar.string.size == 0) return; - generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchSubstring); -} - -CUSTOM_COMMAND_SIG(list_all_locations_of_identifier){ - View_Summary view = get_active_view(app, AccessProtected); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); - - Cpp_Get_Token_Result get_result = {0}; - bool32 success = buffer_get_token_index(app, &buffer, view.cursor.pos, &get_result); - - if (success && !get_result.in_whitespace){ - char space[128]; - int32_t size = get_result.token_end - get_result.token_start; - - if (size > 0 && size <= sizeof(space)){ - success = buffer_read_range(app, &buffer, get_result.token_start, - get_result.token_end, space); - if (success){ - String str = make_string(space, size); - exec_command(app, change_active_panel); - generic_search_all_buffers(app, &global_general, &global_part, - str, SearchFlag_MatchWholeWord); - } - } - } -} - -struct Word_Complete_State{ - Search_Set set; - Search_Iter iter; - Table hits; - String_Space str; - int32_t word_start; - int32_t word_end; - int32_t initialized; -}; - -static Word_Complete_State complete_state = {0}; - -CUSTOM_COMMAND_SIG(word_complete){ - View_Summary view = get_active_view(app, AccessOpen); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); - - // NOTE(allen): I just do this because this command is a lot of work - // and there is no point in doing any of it if nothing will happen anyway. - if (buffer.exists){ - int32_t do_init = false; - - if (view_paste_index[view.view_id].rewrite != RewriteWordComplete){ - do_init = true; - } - view_paste_index[view.view_id].next_rewrite = RewriteWordComplete; - if (!complete_state.initialized){ - do_init = true; - } - - int32_t word_end = 0; - int32_t word_start = 0; - int32_t cursor_pos = 0; - int32_t size = 0; - - if (do_init){ - // NOTE(allen): Get the range where the - // partial word is written. - word_end = view.cursor.pos; - word_start = word_end; - cursor_pos = word_end - 1; - - char space[1024]; - Stream_Chunk chunk = {0}; - if (init_stream_chunk(&chunk, app, &buffer, cursor_pos, space, sizeof(space))){ - int32_t still_looping = true; - do{ - for (; cursor_pos >= chunk.start; --cursor_pos){ - char c = chunk.data[cursor_pos]; - if (char_is_alpha(c)){ - word_start = cursor_pos; - } - else if (!char_is_numeric(c)){ - goto double_break; - } - } - still_looping = backward_stream_chunk(&chunk); - }while(still_looping); - } - double_break:; - - size = word_end - word_start; - - if (size == 0){ - complete_state.initialized = false; - return; - } - - // NOTE(allen): Initialize the search iterator - // with the partial word. - complete_state.initialized = true; - search_iter_init(&global_general, &complete_state.iter, size); - buffer_read_range(app, &buffer, word_start, word_end, - complete_state.iter.word.str); - complete_state.iter.word.size = size; - - // NOTE(allen): Initialize the set of ranges to be searched. - int32_t buffer_count = get_buffer_count(app); - search_set_init(&global_general, &complete_state.set, buffer_count); - - Search_Range *ranges = complete_state.set.ranges; - ranges[0].type = SearchRange_Wave; - ranges[0].flags = SearchFlag_MatchWordPrefix; - ranges[0].buffer = buffer.buffer_id; - ranges[0].start = 0; - ranges[0].size = buffer.size; - ranges[0].mid_start = word_start; - ranges[0].mid_size = size; - - int32_t j = 1; - for (Buffer_Summary buffer_it = get_buffer_first(app, AccessAll); - buffer_it.exists; - get_buffer_next(app, &buffer_it, AccessAll)){ - if (buffer.buffer_id != buffer_it.buffer_id){ - ranges[j].type = SearchRange_FrontToBack; - ranges[j].flags = SearchFlag_MatchWordPrefix; - ranges[j].buffer = buffer_it.buffer_id; - ranges[j].start = 0; - ranges[j].size = buffer_it.size; - ++j; - } - } - complete_state.set.count = j; - - // NOTE(allen): Initialize the search hit table. - search_hits_init(&global_general, &complete_state.hits, &complete_state.str, - 100, (4 << 10)); - search_hit_add(&global_general, &complete_state.hits, &complete_state.str, - complete_state.iter.word.str, - complete_state.iter.word.size); - - complete_state.word_start = word_start; - complete_state.word_end = word_end; - } - else{ - word_start = complete_state.word_start; - word_end = complete_state.word_end; - size = complete_state.iter.word.size; - } - - // NOTE(allen): Iterate through matches. - if (size > 0){ - for (;;){ - int32_t match_size = 0; - Search_Match match = - search_next_match(app, &complete_state.set, - &complete_state.iter); - - if (match.found_match){ - match_size = match.end - match.start; - Temp_Memory temp = begin_temp_memory(&global_part); - char *spare = push_array(&global_part, char, match_size); - - buffer_read_range(app, &match.buffer, - match.start, match.end, spare); - - if (search_hit_add(&global_general, &complete_state.hits, &complete_state.str, - spare, match_size)){ - buffer_replace_range(app, &buffer, word_start, word_end, - spare, match_size); - view_set_cursor(app, &view, - seek_pos(word_start + match_size), - true); - - complete_state.word_end = word_start + match_size; - complete_state.set.ranges[0].mid_size = match_size; - end_temp_memory(temp); - break; - } - end_temp_memory(temp); - } - else{ - complete_state.iter.pos = 0; - complete_state.iter.i = 0; - - search_hits_init(&global_general, &complete_state.hits, &complete_state.str, - 100, (4 << 10)); - search_hit_add(&global_general, &complete_state.hits, &complete_state.str, - complete_state.iter.word.str, - complete_state.iter.word.size); - - match_size = complete_state.iter.word.size; - char *str = complete_state.iter.word.str; - buffer_replace_range(app, &buffer, word_start, word_end, - str, match_size); - view_set_cursor(app, &view, - seek_pos(word_start + match_size), - true); - - complete_state.word_end = word_start + match_size; - complete_state.set.ranges[0].mid_size = match_size; - break; - } - } - } - } -} - // // Default Building Stuff @@ -4216,5 +1665,37 @@ CUSTOM_COMMAND_SIG(project_fkey_command){ } } +// +// Default Framework +// + +void +init_memory(Application_Links *app){ + int32_t part_size = (32 << 20); + int32_t general_size = (4 << 20); + + void *part_mem = memory_allocate(app, part_size); + global_part = make_part(part_mem, part_size); + + void *general_mem = memory_allocate(app, general_size); + general_memory_open(&global_general, general_mem, general_size); +} + +static void +default_4coder_initialize(Application_Links *app){ + init_memory(app); + process_config_file(app); + change_theme(app, default_theme_name.str, default_theme_name.size); + change_font(app, default_font_name.str, default_font_name.size, 1); +} + +static void +default_4coder_side_by_side_panels(Application_Links *app){ + exec_command(app, open_panel_vsplit); + exec_command(app, hide_scrollbar); + exec_command(app, change_active_panel); + exec_command(app, hide_scrollbar); +} + #endif diff --git a/4coder_helper.h b/4coder_helper.h deleted file mode 100644 index 1fb5eeca..00000000 --- a/4coder_helper.h +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Bind helper struct and functions - */ - -#ifndef FCODER_HELPER_H -#define FCODER_HELPER_H - -struct Bind_Helper{ - Binding_Unit *cursor, *start, *end; - Binding_Unit *header, *group; - int32_t write_total; - int32_t error; -}; - -#define BH_ERR_NONE 0 -#define BH_ERR_MISSING_END 1 -#define BH_ERR_MISSING_BEGIN 2 -#define BH_ERR_OUT_OF_MEMORY 3 - -inline Binding_Unit* -write_unit(Bind_Helper *helper, Binding_Unit unit){ - Binding_Unit *p = 0; - helper->write_total += sizeof(*p); - if (helper->error == 0 && helper->cursor != helper->end){ - p = helper->cursor++; - *p = unit; - } - return p; -} - -inline Bind_Helper -begin_bind_helper(void *data, int32_t size){ - Bind_Helper result; - - result.header = 0; - result.group = 0; - result.write_total = 0; - result.error = 0; - - result.cursor = (Binding_Unit*)data; - result.start = result.cursor; - result.end = result.start + size / sizeof(*result.cursor); - - Binding_Unit unit; - unit.type = unit_header; - unit.header.total_size = sizeof(*result.header); - result.header = write_unit(&result, unit); - result.header->header.user_map_count = 0; - - return result; -} - -inline void -begin_map_(Bind_Helper *helper, int32_t mapid, int32_t replace){ - if (helper->group != 0 && helper->error == 0) helper->error = BH_ERR_MISSING_END; - if (!helper->error && mapid < mapid_global) ++helper->header->header.user_map_count; - - Binding_Unit unit; - unit.type = unit_map_begin; - unit.map_begin.mapid = mapid; - unit.map_begin.replace = replace; - helper->group = write_unit(helper, unit); - helper->group->map_begin.bind_count = 0; -} - -inline void -begin_map(Bind_Helper *helper, int32_t mapid){ - begin_map_(helper, mapid, 0); -} - -inline void -restart_map(Bind_Helper *helper, int32_t mapid){ - begin_map_(helper, mapid, 1); -} - -inline void -end_map(Bind_Helper *helper){ - if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; - helper->group = 0; -} - -inline void -bind(Bind_Helper *helper, short code, unsigned char modifiers, int32_t cmdid){ - if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; - if (!helper->error) ++helper->group->map_begin.bind_count; - - Binding_Unit unit; - unit.type = unit_binding; - unit.binding.command_id = cmdid; - unit.binding.code = code; - unit.binding.modifiers = modifiers; - - write_unit(helper, unit); -} - -inline void -bind(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){ - if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; - if (!helper->error) ++helper->group->map_begin.bind_count; - - Binding_Unit unit; - unit.type = unit_callback; - unit.callback.func = func; - unit.callback.code = code; - unit.callback.modifiers = modifiers; - - write_unit(helper, unit); -} - -inline void -bind_vanilla_keys(Bind_Helper *helper, int32_t cmdid){ - bind(helper, 0, 0, cmdid); -} - -inline void -bind_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){ - bind(helper, 0, 0, func); -} - -inline void -bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, int32_t cmdid){ - bind(helper, 0, modifiers, cmdid); -} - -inline void -bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, Custom_Command_Function *func){ - bind(helper, 0, modifiers, func); -} - -inline void -inherit_map(Bind_Helper *helper, int32_t mapid){ - if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; - if (!helper->error && mapid < mapid_global) ++helper->header->header.user_map_count; - - Binding_Unit unit; - unit.type = unit_inherit; - unit.map_inherit.mapid = mapid; - - write_unit(helper, unit); -} - -inline void -set_hook(Bind_Helper *helper, int32_t hook_id, Hook_Function *func){ - Binding_Unit unit; - unit.type = unit_hook; - unit.hook.hook_id = hook_id; - unit.hook.func = (void*) func; - - write_unit(helper, unit); -} - -inline void -set_scroll_rule(Bind_Helper *helper, Scroll_Rule_Function *func){ - Binding_Unit unit; - unit.type = unit_hook; - unit.hook.hook_id = _hook_scroll_rule; - unit.hook.func = (void*) func; - - write_unit(helper, unit); -} - -inline void -set_new_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ - Binding_Unit unit; - unit.type = unit_hook; - unit.hook.hook_id = _hook_new_file; - unit.hook.func = (void*) func; - - write_unit(helper, unit); -} - -inline void -set_open_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ - Binding_Unit unit; - unit.type = unit_hook; - unit.hook.hook_id = _hook_open_file; - unit.hook.func = (void*) func; - - write_unit(helper, unit); -} - -inline void -set_save_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ - Binding_Unit unit; - unit.type = unit_hook; - unit.hook.hook_id = _hook_save_file; - unit.hook.func = (void*) func; - - write_unit(helper, unit); -} - -inline void -set_command_caller(Bind_Helper *helper, Command_Caller_Hook_Function *func){ - Binding_Unit unit; - unit.type = unit_hook; - unit.hook.hook_id = _hook_command_caller; - unit.hook.func = (void*) func; - - write_unit(helper, unit); -} - -inline void -set_input_filter(Bind_Helper *helper, Input_Filter_Function *func){ - Binding_Unit unit; - unit.type = unit_hook; - unit.hook.hook_id = _hook_input_filter; - unit.hook.func = (void*) func; - - write_unit(helper, unit); -} - -inline int32_t -end_bind_helper(Bind_Helper *helper){ - int32_t result; - if (helper->header){ - helper->header->header.total_size = (int32_t)(helper->cursor - helper->start); - helper->header->header.error = helper->error; - } - result = helper->write_total; - return(result); -} - -inline Range -get_range(View_Summary *view){ - Range range = make_range(view->cursor.pos, view->mark.pos); - return(range); -} - -struct Buffer_Rect{ - int32_t char0,line0; - int32_t char1,line1; -}; - -#ifndef Swap -#define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0) -#endif - -inline Buffer_Rect -get_rect(View_Summary *view){ - Buffer_Rect rect = {0}; - - rect.char0 = view->mark.character; - rect.line0 = view->mark.line; - - rect.char1 = view->cursor.character; - rect.line1 = view->cursor.line; - - if (rect.line0 > rect.line1){ - Swap(int32_t, rect.line0, rect.line1); - } - if (rect.char0 > rect.char1){ - Swap(int32_t, rect.char0, rect.char1); - } - - return(rect); -} - -inline i32_Rect -get_line_x_rect(View_Summary *view){ - i32_Rect rect = {0}; - - if (view->unwrapped_lines){ - rect.x0 = (int32_t)view->mark.unwrapped_x; - rect.x1 = (int32_t)view->cursor.unwrapped_x; - } - else{ - rect.x0 = (int32_t)view->mark.wrapped_x; - rect.x1 = (int32_t)view->cursor.wrapped_x; - } - rect.y0 = view->mark.line; - rect.y1 = view->cursor.line; - - if (rect.y0 > rect.y1){ - Swap(int32_t, rect.y0, rect.y1); - } - if (rect.x0 > rect.x1){ - Swap(int32_t, rect.x0, rect.x1); - } - - return(rect); -} - -inline void -exec_command(Application_Links *app, Custom_Command_Function *func){ - func(app); -} - -inline void -exec_command(Application_Links *app, Generic_Command cmd){ - if (cmd.cmdid < cmdid_count){ - exec_command(app, cmd.cmdid); - } - else{ - exec_command(app, cmd.command); - } -} - -inline void -active_view_to_line(Application_Links *app, uint32_t access, int32_t line_number){ - View_Summary view; - view = get_active_view(app, access); - - // NOTE(allen|a3.4.4): We don't have to worry about whether this is a valid line number. - // When it's not possible to place a cursor at the position for whatever reason it will set the - // cursor to a nearby valid position. - view_set_cursor(app, &view, seek_line_char(line_number, 0), 1); -} - -inline View_Summary -get_first_view_with_buffer(Application_Links *app, int32_t buffer_id){ - View_Summary result = {}; - View_Summary test = {}; - - if (buffer_id != 0){ - uint32_t access = AccessAll; - for(test = get_view_first(app, access); - test.exists; - get_view_next(app, &test, access)){ - - Buffer_Summary buffer = get_buffer(app, test.buffer_id, access); - - if(buffer.buffer_id == buffer_id){ - result = test; - break; - } - } - } - - return(result); -} - -inline int32_t -key_is_unmodified(Key_Event_Data *key){ - char *mods = key->modifiers; - int32_t unmodified = !mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]; - return(unmodified); -} - -static int32_t -query_user_general(Application_Links *app, Query_Bar *bar, int32_t force_number){ - User_Input in; - int32_t success = 1; - int32_t good_character = 0; - - // NOTE(allen|a3.4.4): It will not cause an *error* if we continue on after failing to. - // start a query bar, but it will be unusual behavior from the point of view of the - // user, if this command starts intercepting input even though no prompt is shown. - // This will only happen if you have a lot of bars open already or if the current view - // doesn't support query bars. - if (start_query_bar(app, bar, 0) == 0) return 0; - - while (1){ - // NOTE(allen|a3.4.4): This call will block until the user does one of the input - // types specified in the flags. The first set of flags are inputs you'd like to intercept - // that you don't want to abort on. The second set are inputs that you'd like to cause - // the command to abort. If an event satisfies both flags, it is treated as an abort. - in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); - - // NOTE(allen|a3.4.4): The responsible thing to do on abort is to end the command - // without waiting on get_user_input again. - if (in.abort){ - success = 0; - break; - } - - good_character = 0; - if (key_is_unmodified(&in.key)){ - if (force_number){ - if (in.key.character >= '0' && in.key.character <= '9'){ - good_character = 1; - } - } - else{ - if (in.key.character != 0){ - good_character = 1; - } - } - } - - // NOTE(allen|a3.4.4): All we have to do to update the query bar is edit our - // local Query_Bar struct! This is handy because it means our Query_Bar - // is always correct for typical use without extra work updating the bar. - if (in.type == UserInputKey){ - if (in.key.keycode == '\n' || in.key.keycode == '\t'){ - break; - } - else if (in.key.keycode == key_back){ - if (bar->string.size > 0){ - --bar->string.size; - } - } - else if (good_character){ - append_s_char(&bar->string, in.key.character); - } - } - } - - terminate_with_null(&bar->string); - - return(success); -} - -inline int32_t -query_user_string(Application_Links *app, Query_Bar *bar){ - int32_t success = query_user_general(app, bar, 0); - return(success); -} - -inline int32_t -query_user_number(Application_Links *app, Query_Bar *bar){ - int32_t success = query_user_general(app, bar, 1); - return(success); -} - -inline Buffer_Summary -get_active_buffer(Application_Links *app, uint32_t access){ - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - return(buffer); -} - -inline char -buffer_get_char(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ - char result = ' '; - *buffer = get_buffer(app, buffer->buffer_id, AccessAll); - if (pos >= 0 && pos < buffer->size){ - buffer_read_range(app, buffer, pos, pos+1, &result); - } - return(result); -} - -inline Buffer_Identifier -buffer_identifier(char *str, int32_t len){ - Buffer_Identifier identifier; - identifier.name = str; - identifier.name_len = len; - identifier.id = 0; - return(identifier); -} - -inline Buffer_Identifier -buffer_identifier(int32_t id){ - Buffer_Identifier identifier; - identifier.name = 0; - identifier.name_len = 0; - identifier.id = id; - return(identifier); -} - -static Buffer_Summary -create_buffer(Application_Links *app, char *filename, int32_t filename_len, Buffer_Create_Flag flags){ - - Buffer_Summary buffer = {0}; - - Buffer_Creation_Data data = {0}; - begin_buffer_creation(app, &data, flags); - buffer_creation_name(app, &data, filename, filename_len, 0); - buffer = end_buffer_creation(app, &data); - - return(buffer); -} - -#endif diff --git a/4coder_helper/4coder_bind_helper.h b/4coder_helper/4coder_bind_helper.h new file mode 100644 index 00000000..e4be14a1 --- /dev/null +++ b/4coder_helper/4coder_bind_helper.h @@ -0,0 +1,232 @@ +/* +* Helpers for setting bindings. +*/ + +// TOP + +#if !defined(FCODER_BIND_HELPER_H) +#define FCODER_BIND_HELPER_H + +// +// Binding Helper +// + +struct Bind_Helper{ + Binding_Unit *cursor, *start, *end; + Binding_Unit *header, *group; + int32_t write_total; + int32_t error; +}; + +#define BH_ERR_NONE 0 +#define BH_ERR_MISSING_END 1 +#define BH_ERR_MISSING_BEGIN 2 +#define BH_ERR_OUT_OF_MEMORY 3 + +inline Binding_Unit* +write_unit(Bind_Helper *helper, Binding_Unit unit){ + Binding_Unit *p = 0; + helper->write_total += sizeof(*p); + if (helper->error == 0 && helper->cursor != helper->end){ + p = helper->cursor++; + *p = unit; + } + return p; +} + +inline Bind_Helper +begin_bind_helper(void *data, int32_t size){ + Bind_Helper result; + + result.header = 0; + result.group = 0; + result.write_total = 0; + result.error = 0; + + result.cursor = (Binding_Unit*)data; + result.start = result.cursor; + result.end = result.start + size / sizeof(*result.cursor); + + Binding_Unit unit; + unit.type = unit_header; + unit.header.total_size = sizeof(*result.header); + result.header = write_unit(&result, unit); + result.header->header.user_map_count = 0; + + return result; +} + +inline void +begin_map_(Bind_Helper *helper, int32_t mapid, int32_t replace){ + if (helper->group != 0 && helper->error == 0) helper->error = BH_ERR_MISSING_END; + if (!helper->error && mapid < mapid_global) ++helper->header->header.user_map_count; + + Binding_Unit unit; + unit.type = unit_map_begin; + unit.map_begin.mapid = mapid; + unit.map_begin.replace = replace; + helper->group = write_unit(helper, unit); + helper->group->map_begin.bind_count = 0; +} + +inline void +begin_map(Bind_Helper *helper, int32_t mapid){ + begin_map_(helper, mapid, 0); +} + +inline void +restart_map(Bind_Helper *helper, int32_t mapid){ + begin_map_(helper, mapid, 1); +} + +inline void +end_map(Bind_Helper *helper){ + if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; + helper->group = 0; +} + +inline void +bind(Bind_Helper *helper, short code, unsigned char modifiers, int32_t cmdid){ + if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; + if (!helper->error) ++helper->group->map_begin.bind_count; + + Binding_Unit unit; + unit.type = unit_binding; + unit.binding.command_id = cmdid; + unit.binding.code = code; + unit.binding.modifiers = modifiers; + + write_unit(helper, unit); +} + +inline void +bind(Bind_Helper *helper, short code, unsigned char modifiers, Custom_Command_Function *func){ + if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; + if (!helper->error) ++helper->group->map_begin.bind_count; + + Binding_Unit unit; + unit.type = unit_callback; + unit.callback.func = func; + unit.callback.code = code; + unit.callback.modifiers = modifiers; + + write_unit(helper, unit); +} + +inline void +bind_vanilla_keys(Bind_Helper *helper, int32_t cmdid){ + bind(helper, 0, 0, cmdid); +} + +inline void +bind_vanilla_keys(Bind_Helper *helper, Custom_Command_Function *func){ + bind(helper, 0, 0, func); +} + +inline void +bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, int32_t cmdid){ + bind(helper, 0, modifiers, cmdid); +} + +inline void +bind_vanilla_keys(Bind_Helper *helper, unsigned char modifiers, Custom_Command_Function *func){ + bind(helper, 0, modifiers, func); +} + +inline void +inherit_map(Bind_Helper *helper, int32_t mapid){ + if (helper->group == 0 && helper->error == 0) helper->error = BH_ERR_MISSING_BEGIN; + if (!helper->error && mapid < mapid_global) ++helper->header->header.user_map_count; + + Binding_Unit unit; + unit.type = unit_inherit; + unit.map_inherit.mapid = mapid; + + write_unit(helper, unit); +} + +inline void +set_hook(Bind_Helper *helper, int32_t hook_id, Hook_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = hook_id; + unit.hook.func = (void*) func; + + write_unit(helper, unit); +} + +inline void +set_scroll_rule(Bind_Helper *helper, Scroll_Rule_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = special_hook_scroll_rule; + unit.hook.func = (void*) func; + + write_unit(helper, unit); +} + +inline void +set_new_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = special_hook_new_file; + unit.hook.func = (void*) func; + + write_unit(helper, unit); +} + +inline void +set_open_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = special_hook_open_file; + unit.hook.func = (void*) func; + + write_unit(helper, unit); +} + +inline void +set_save_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = special_hook_save_file; + unit.hook.func = (void*) func; + + write_unit(helper, unit); +} + +inline void +set_command_caller(Bind_Helper *helper, Command_Caller_Hook_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = special_hook_command_caller; + unit.hook.func = (void*) func; + + write_unit(helper, unit); +} + +inline void +set_input_filter(Bind_Helper *helper, Input_Filter_Function *func){ + Binding_Unit unit; + unit.type = unit_hook; + unit.hook.hook_id = special_hook_input_filter; + unit.hook.func = (void*) func; + + write_unit(helper, unit); +} + +inline int32_t +end_bind_helper(Bind_Helper *helper){ + int32_t result; + if (helper->header){ + helper->header->header.total_size = (int32_t)(helper->cursor - helper->start); + helper->header->header.error = helper->error; + } + result = helper->write_total; + return(result); +} + +#endif + +// BOTTOM + diff --git a/4coder_helper/4coder_helper.h b/4coder_helper/4coder_helper.h new file mode 100644 index 00000000..28b26898 --- /dev/null +++ b/4coder_helper/4coder_helper.h @@ -0,0 +1,327 @@ +/* + * Miscellaneous helpers for common operations. + */ + +#if !defined(FCODER_HELPER_H) +#define FCODER_HELPER_H + +#include "4coder_seek_types.h" + +inline void +exec_command(Application_Links *app, Custom_Command_Function *func){ + func(app); +} + +inline void +exec_command(Application_Links *app, Generic_Command cmd){ + if (cmd.cmdid < cmdid_count){ + exec_command(app, cmd.cmdid); + } + else{ + exec_command(app, cmd.command); + } +} + +inline View_Summary +get_first_view_with_buffer(Application_Links *app, int32_t buffer_id){ + View_Summary result = {}; + View_Summary test = {}; + + if (buffer_id != 0){ + uint32_t access = AccessAll; + for(test = get_view_first(app, access); + test.exists; + get_view_next(app, &test, access)){ + + Buffer_Summary buffer = get_buffer(app, test.buffer_id, access); + + if(buffer.buffer_id == buffer_id){ + result = test; + break; + } + } + } + + return(result); +} + +inline int32_t +key_is_unmodified(Key_Event_Data *key){ + char *mods = key->modifiers; + int32_t unmodified = !mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]; + return(unmodified); +} + +static int32_t +query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){ + User_Input in; + int32_t success = 1; + int32_t good_character = 0; + + // NOTE(allen|a3.4.4): It will not cause an *error* if we continue on after failing to. + // start a query bar, but it will be unusual behavior from the point of view of the + // user, if this command starts intercepting input even though no prompt is shown. + // This will only happen if you have a lot of bars open already or if the current view + // doesn't support query bars. + if (start_query_bar(app, bar, 0) == 0) return 0; + + for (;;){ + // NOTE(allen|a3.4.4): This call will block until the user does one of the input + // types specified in the flags. The first set of flags are inputs you'd like to intercept + // that you don't want to abort on. The second set are inputs that you'd like to cause + // the command to abort. If an event satisfies both flags, it is treated as an abort. + in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton); + + // NOTE(allen|a3.4.4): The responsible thing to do on abort is to end the command + // without waiting on get_user_input again. + if (in.abort){ + success = 0; + break; + } + + good_character = 0; + if (key_is_unmodified(&in.key)){ + if (force_number){ + if (in.key.character >= '0' && in.key.character <= '9'){ + good_character = 1; + } + } + else{ + if (in.key.character != 0){ + good_character = 1; + } + } + } + + // NOTE(allen|a3.4.4): All we have to do to update the query bar is edit our + // local Query_Bar struct! This is handy because it means our Query_Bar + // is always correct for typical use without extra work updating the bar. + if (in.type == UserInputKey){ + if (in.key.keycode == '\n' || in.key.keycode == '\t'){ + break; + } + else if (in.key.keycode == key_back){ + if (bar->string.size > 0){ + --bar->string.size; + } + } + else if (good_character){ + append_s_char(&bar->string, in.key.character); + } + } + } + + terminate_with_null(&bar->string); + + return(success); +} + +inline int32_t +query_user_string(Application_Links *app, Query_Bar *bar){ + int32_t success = query_user_general(app, bar, false); + return(success); +} + +inline int32_t +query_user_number(Application_Links *app, Query_Bar *bar){ + int32_t success = query_user_general(app, bar, true); + return(success); +} + +inline char +buffer_get_char(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char result = ' '; + *buffer = get_buffer(app, buffer->buffer_id, AccessAll); + if (pos >= 0 && pos < buffer->size){ + buffer_read_range(app, buffer, pos, pos+1, &result); + } + return(result); +} + +inline Buffer_Identifier +buffer_identifier(char *str, int32_t len){ + Buffer_Identifier identifier; + identifier.name = str; + identifier.name_len = len; + identifier.id = 0; + return(identifier); +} + +inline Buffer_Identifier +buffer_identifier(int32_t id){ + Buffer_Identifier identifier; + identifier.name = 0; + identifier.name_len = 0; + identifier.id = id; + return(identifier); +} + +static Buffer_Summary +create_buffer(Application_Links *app, char *filename, int32_t filename_len, Buffer_Create_Flag flags){ + Buffer_Summary buffer = {0}; + + Buffer_Creation_Data data = {0}; + begin_buffer_creation(app, &data, flags); + buffer_creation_name(app, &data, filename, filename_len, 0); + buffer = end_buffer_creation(app, &data); + + return(buffer); +} + +inline Range +make_range(int32_t p1, int32_t p2){ + Range range; + if (p1 < p2){ + range.min = p1; + range.max = p2; + } + else{ + range.min = p2; + range.max = p1; + } + return(range); +} + +struct Buffer_Rect{ + int32_t char0, line0; + int32_t char1, line1; +}; + +#ifndef Swap +#define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0) +#endif + +inline Buffer_Rect +get_rect(View_Summary *view){ + Buffer_Rect rect = {0}; + + rect.char0 = view->mark.character; + rect.line0 = view->mark.line; + + rect.char1 = view->cursor.character; + rect.line1 = view->cursor.line; + + if (rect.line0 > rect.line1){ + Swap(int32_t, rect.line0, rect.line1); + } + if (rect.char0 > rect.char1){ + Swap(int32_t, rect.char0, rect.char1); + } + + return(rect); +} + +inline i32_Rect +get_line_x_rect(View_Summary *view){ + i32_Rect rect = {0}; + + if (view->unwrapped_lines){ + rect.x0 = (int32_t)view->mark.unwrapped_x; + rect.x1 = (int32_t)view->cursor.unwrapped_x; + } + else{ + rect.x0 = (int32_t)view->mark.wrapped_x; + rect.x1 = (int32_t)view->cursor.wrapped_x; + } + rect.y0 = view->mark.line; + rect.y1 = view->cursor.line; + + if (rect.y0 > rect.y1){ + Swap(int32_t, rect.y0, rect.y1); + } + if (rect.x0 > rect.x1){ + Swap(int32_t, rect.x0, rect.x1); + } + + return(rect); +} + +static int32_t +open_file(Application_Links *app, Buffer_Summary *buffer_out, char *filename, int32_t filename_len, int32_t background, int32_t never_new){ + int32_t result = false; + Buffer_Summary buffer = get_buffer_by_name(app, filename, filename_len, AccessProtected|AccessHidden); + + if (buffer.exists){ + if (buffer_out) *buffer_out = buffer; + result = true; + } + else{ + Buffer_Create_Flag flags = 0; + if (background){ + flags |= BufferCreate_Background; + } + if (never_new){ + flags |= BufferCreate_NeverNew; + } + buffer = create_buffer(app, filename, filename_len, flags); + if (buffer.exists){ + if (buffer_out) *buffer_out = buffer; + result = true; + } + } + + return(result); +} + +static int32_t +view_open_file(Application_Links *app, View_Summary *view, char *filename, int32_t filename_len, int32_t never_new){ + int32_t result = 0; + + if (view){ + Buffer_Summary buffer = {0}; + if (open_file(app, &buffer, filename, filename_len, false, never_new)){ + view_set_buffer(app, view, buffer.buffer_id, 0); + result = 1; + } + } + + return(result); +} + +static void +get_view_next_looped(Application_Links *app, View_Summary *view, uint32_t access){ + get_view_next(app, view, access); + if (!view->exists){ + *view = get_view_first(app, access); + } +} + +static void +refresh_buffer(Application_Links *app, Buffer_Summary *buffer){ + *buffer = get_buffer(app, buffer->buffer_id, AccessAll); +} + +static void +refresh_view(Application_Links *app, View_Summary *view){ + *view = get_view(app, view->view_id, AccessAll); +} + +inline float +get_view_y(View_Summary *view){ + float y = view->cursor.wrapped_y; + if (view->unwrapped_lines){ + y = view->cursor.unwrapped_y; + } + return(y); +} + +inline float +get_view_x(View_Summary *view){ + float x = view->cursor.wrapped_x; + if (view->unwrapped_lines){ + x = view->cursor.unwrapped_x; + } + return(x); +} + +inline Range +get_range(View_Summary *view){ + Range range = make_range(view->cursor.pos, view->mark.pos); + return(range); +} + +#if !defined(ArrayCount) +# define ArrayCount(a) (sizeof(a)/sizeof(a[0])) +#endif + +#endif diff --git a/4coder_helper/4coder_long_seek.h b/4coder_helper/4coder_long_seek.h new file mode 100644 index 00000000..83cc91f0 --- /dev/null +++ b/4coder_helper/4coder_long_seek.h @@ -0,0 +1,993 @@ +/* + * Helpers for doing long range seeks. + */ + +// TOP + +#if !defined(FCODER_LONG_SEEK_H) +#define FCODER_LONG_SEEK_H + +#include "4coder_helper/4coder_streaming.h" +#include "4coder_lib/4coder_mem.h" +#include "4cpp/4cpp_lexer.h" + +// +// Whitespace Based Seeks +// + +static int32_t +seek_line_end(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char chunk[1024]; + int32_t chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + int32_t still_looping; + char at_pos; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + still_looping = 1; + do{ + for (; pos < stream.end; ++pos){ + at_pos = stream.data[pos]; + if (at_pos == '\n'){ + goto double_break; + } + } + still_looping = forward_stream_chunk(&stream); + }while(still_looping); + double_break:; + + if (pos > buffer->size){ + pos = buffer->size; + } + } + + return(pos); +} + +static int32_t +seek_line_beginning(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char chunk[1024]; + int32_t chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + int32_t still_looping; + char at_pos; + + --pos; + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + still_looping = 1; + do{ + for (; pos >= stream.start; --pos){ + at_pos = stream.data[pos]; + if (at_pos == '\n'){ + goto double_break; + } + } + still_looping = backward_stream_chunk(&stream); + }while(still_looping); + double_break:; + + if (pos != 0){ + ++pos; + } + if (pos < 0){ + pos = 0; + } + } + + return(pos); +} + +static void +move_past_lead_whitespace(Application_Links *app, View_Summary *view, Buffer_Summary *buffer){ + refresh_view(app, view); + + int32_t new_pos = seek_line_beginning(app, buffer, view->cursor.pos); + char space[1024]; + Stream_Chunk chunk = {0}; + int32_t still_looping = false; + + int32_t i = new_pos; + if (init_stream_chunk(&chunk, app, buffer, i, space, sizeof(space))){ + do{ + for (; i < chunk.end; ++i){ + char at_pos = chunk.data[i]; + if (at_pos == '\n' || !char_is_whitespace(at_pos)){ + goto break2; + } + } + still_looping = forward_stream_chunk(&chunk); + }while(still_looping); + break2:; + + if (i > view->cursor.pos){ + view_set_cursor(app, view, seek_pos(i), true); + } + } +} + +static int32_t +buffer_seek_whitespace_up(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char chunk[1024]; + int32_t chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + char at_pos; + + --pos; + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + // Step 1: Find the first non-whitespace character + // behind the current position. + int32_t still_looping = 1; + while (still_looping){ + for (; pos >= stream.start; --pos){ + at_pos = stream.data[pos]; + if (!char_is_whitespace(at_pos)){ + goto double_break_1; + } + } + still_looping = backward_stream_chunk(&stream); + } + double_break_1:; + + // Step 2: Continue scanning backward, at each '\n' + // mark the beginning of another line by setting + // no_hard to true, set it back to false if a + // non-whitespace character is discovered before + // the next '\n' + int32_t no_hard = false; + while (still_looping){ + for (; pos >= stream.start; --pos){ + at_pos = stream.data[pos]; + if (at_pos == '\n'){ + if (no_hard){ + goto double_break_2; + } + else{ + no_hard = true; + } + } + else if (!char_is_whitespace(at_pos)){ + no_hard = false; + } + } + still_looping = backward_stream_chunk(&stream); + } + double_break_2:; + + if (pos != 0){ + ++pos; + } + } + + return(pos); +} + +static int32_t +buffer_seek_whitespace_down(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char chunk[1024]; + int32_t chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + int32_t no_hard; + int32_t prev_endline; + int32_t still_looping; + char at_pos; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + // step 1: find the first non-whitespace character + // ahead of the current position. + still_looping = true; + do{ + for (; pos < stream.end; ++pos){ + at_pos = stream.data[pos]; + if (!char_is_whitespace(at_pos)){ + goto double_break_1; + } + } + still_looping = forward_stream_chunk(&stream); + } while(still_looping); + double_break_1:; + + // step 2: continue scanning forward, at each '\n' + // mark it as the beginning of a new line by updating + // the prev_endline value. if another '\n' is found + // with non-whitespace then the previous line was + // all whitespace. + no_hard = false; + prev_endline = -1; + while(still_looping){ + for (; pos < stream.end; ++pos){ + at_pos = stream.data[pos]; + if (at_pos == '\n'){ + if (no_hard){ + goto double_break_2; + } + else{ + no_hard = true; + prev_endline = pos; + } + } + else if (!char_is_whitespace(at_pos)){ + no_hard = false; + } + } + still_looping = forward_stream_chunk(&stream); + } + double_break_2:; + + if (prev_endline == -1 || prev_endline+1 >= buffer->size){ + pos = buffer->size; + } + else{ + pos = prev_endline+1; + } + } + + return(pos); +} +static int32_t +buffer_seek_whitespace_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char data_chunk[1024]; + Stream_Chunk stream = {0}; + + if (init_stream_chunk(&stream, app, buffer, + pos, data_chunk, sizeof(data_chunk))){ + + bool32 still_looping = 1; + do{ + for (; pos < stream.end; ++pos){ + if (!char_is_whitespace(stream.data[pos])){ + goto double_break1; + } + } + still_looping = forward_stream_chunk(&stream); + }while(still_looping); + double_break1:; + + still_looping = 1; + do{ + for (; pos < stream.end; ++pos){ + if (char_is_whitespace(stream.data[pos])){ + goto double_break2; + } + } + still_looping = forward_stream_chunk(&stream); + }while(still_looping); + double_break2:; + } + + return(pos); +} + +static int32_t +buffer_seek_whitespace_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char data_chunk[1024]; + Stream_Chunk stream = {0}; + + --pos; + if (pos > 0){ + if (init_stream_chunk(&stream, app, buffer, + pos, data_chunk, sizeof(data_chunk))){ + + bool32 still_looping = 1; + do{ + for (; pos >= stream.start; --pos){ + if (!char_is_whitespace(stream.data[pos])){ + goto double_break1; + } + } + still_looping = backward_stream_chunk(&stream); + }while(still_looping); + double_break1:; + + still_looping = 1; + do{ + for (; pos >= stream.start; --pos){ + if (char_is_whitespace(stream.data[pos])){ + ++pos; + goto double_break2; + } + } + still_looping = backward_stream_chunk(&stream); + }while(still_looping); + double_break2:; + } + } + else{ + pos = 0; + } + + return(pos); +} + +// +// Boundary Type Seeks +// + +static int32_t +buffer_seek_alphanumeric_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char data_chunk[1024]; + Stream_Chunk stream = {0}; + + if (init_stream_chunk(&stream, app, buffer, + pos, data_chunk, sizeof(data_chunk))){ + + bool32 still_looping = 1; + do{ + for (; pos < stream.end; ++pos){ + if (char_is_alpha_numeric_true(stream.data[pos])){ + goto double_break1; + } + } + still_looping = forward_stream_chunk(&stream); + }while(still_looping); + double_break1:; + + still_looping = 1; + do{ + for (; pos < stream.end; ++pos){ + if (!char_is_alpha_numeric_true(stream.data[pos])){ + goto double_break2; + } + } + still_looping = forward_stream_chunk(&stream); + }while(still_looping); + double_break2:; + } + + return(pos); +} + +static int32_t +buffer_seek_alphanumeric_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + char data_chunk[1024]; + Stream_Chunk stream = {0}; + + --pos; + if (pos > 0){ + if (init_stream_chunk(&stream, app, buffer, + pos, data_chunk, sizeof(data_chunk))){ + + bool32 still_looping = 1; + do{ + for (; pos >= stream.start; --pos){ + if (char_is_alpha_numeric_true(stream.data[pos])){ + goto double_break1; + } + } + still_looping = backward_stream_chunk(&stream); + }while(still_looping); + double_break1:; + + still_looping = 1; + do{ + for (; pos >= stream.start; --pos){ + if (!char_is_alpha_numeric_true(stream.data[pos])){ + ++pos; + goto double_break2; + } + } + still_looping = backward_stream_chunk(&stream); + }while(still_looping); + double_break2:; + } + } + else{ + pos = 0; + } + + return(pos); +} + +static int32_t +buffer_seek_range_camel_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t an_pos){ + char data_chunk[1024]; + Stream_Chunk stream = {0}; + + ++pos; + if (pos < an_pos){ + stream.max_end = an_pos; + if (init_stream_chunk(&stream, app, buffer, + pos, data_chunk, sizeof(data_chunk))){ + + char c = 0, pc = stream.data[pos]; + ++pos; + + bool32 still_looping = 1; + do{ + for (; pos < stream.end; ++pos){ + c = stream.data[pos]; + if (char_is_upper(c) && char_is_lower(pc)){ + goto double_break1; + } + pc = c; + } + still_looping = forward_stream_chunk(&stream); + }while(still_looping); + double_break1:; + } + } + else{ + pos = an_pos; + } + + return(pos); +} + +static int32_t +buffer_seek_range_camel_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t an_pos){ + char data_chunk[1024]; + Stream_Chunk stream = {0}; + + --pos; + if (pos > 0){ + stream.min_start = an_pos+1; + if (init_stream_chunk(&stream, app, buffer, pos, data_chunk, sizeof(data_chunk))){ + + char c = 0, pc = stream.data[pos]; + + bool32 still_looping = 1; + do{ + for (; pos >= stream.start; --pos){ + c = stream.data[pos]; + if (char_is_upper(c) && char_is_lower(pc)){ + goto double_break1; + } + pc = c; + } + still_looping = backward_stream_chunk(&stream); + }while(still_looping); + double_break1:; + } + } + else{ + pos = 0; + } + + return(pos); +} + +static int32_t +buffer_seek_alphanumeric_or_camel_right(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + int32_t an_pos = buffer_seek_alphanumeric_right(app, buffer, pos); + int32_t result = buffer_seek_range_camel_right(app, buffer, pos, an_pos); + return(result); +} + +static int32_t +buffer_seek_alphanumeric_or_camel_left(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + int32_t an_pos = buffer_seek_alphanumeric_left(app, buffer, pos); + int32_t result = buffer_seek_range_camel_left(app, buffer, pos, an_pos); + return(result); +} + +static int32_t +seek_token_left(Cpp_Token_Array *tokens, int32_t pos){ + Cpp_Get_Token_Result get = cpp_get_token(*tokens, pos); + if (get.token_index == -1){ + get.token_index = 0; + } + + Cpp_Token *token = tokens->tokens + get.token_index; + if (token->start == pos && get.token_index > 0){ + --token; + } + + return(token->start); +} + +static int32_t +seek_token_right(Cpp_Token_Array *tokens, int32_t pos){ + Cpp_Get_Token_Result get = cpp_get_token(*tokens, pos); + if (get.in_whitespace){ + ++get.token_index; + } + if (get.token_index >= tokens->count){ + get.token_index = tokens->count-1; + } + + Cpp_Token *token = tokens->tokens + get.token_index; + return(token->start + token->size); +} + +static Cpp_Token_Array +buffer_get_all_tokens(Application_Links *app, Partition *part, Buffer_Summary *buffer){ + Cpp_Token_Array array = {0}; + + if (buffer->exists && buffer->is_lexed){ + array.count = buffer_token_count(app, buffer); + array.max_count = array.count; + array.tokens = push_array(part, Cpp_Token, array.count); + buffer_read_tokens(app, buffer, 0, array.count, array.tokens); + } + + return(array); +} + +static int32_t +buffer_boundary_seek(Application_Links *app, Buffer_Summary *buffer, Partition *part, int32_t start_pos, bool32 seek_forward, Seek_Boundary_Flag flags)/* +DOC_PARAM(buffer, The buffer parameter specifies the buffer through which to seek.) +DOC_PARAM(start_pos, The beginning position of the seek is specified by start_pos measured in absolute position.) +DOC_PARAM(seek_forward, If this parameter is non-zero it indicates that the seek should move foward through the buffer.) +DOC_PARAM(flags, This field specifies the types of boundaries at which the seek should stop.) + +DOC_RETURN(This call returns the absolute position where the seek stopped. +If the seek goes below 0 the returned value is -1. +If the seek goes past the end the returned value is the size of the buffer.) + +DOC_SEE(Seek_Boundary_Flag) +DOC_SEE(4coder_Buffer_Positioning_System) +*/{ + int32_t result = 0; + + // TODO(allen): reduce duplication? + Temp_Memory temp = begin_temp_memory(part); + if (buffer->exists){ + int32_t pos[4]; + int32_t size = buffer->size; + int32_t new_pos = 0; + + if (start_pos < 0){ + start_pos = 0; + } + else if (start_pos > size){ + start_pos = size; + } + + if (seek_forward){ + for (int32_t i = 0; i < ArrayCount(pos); ++i){ + pos[i] = size; + } + + if (flags & BoundaryWhitespace){ + pos[0] = buffer_seek_whitespace_right(app, buffer, start_pos); + } + + if (flags & BoundaryToken){ + if (buffer->tokens_are_ready){ + Cpp_Token_Array array = buffer_get_all_tokens(app, part, buffer); + pos[1] = seek_token_right(&array, start_pos); + } + else{ + pos[1] = buffer_seek_whitespace_right(app, buffer, start_pos); + } + } + + if (flags & BoundaryAlphanumeric){ + pos[2] = buffer_seek_alphanumeric_right(app, buffer, start_pos); + if (flags & BoundaryCamelCase){ + pos[3] = buffer_seek_range_camel_right(app, buffer, start_pos, pos[2]); + } + } + else{ + if (flags & BoundaryCamelCase){ + pos[3] = buffer_seek_alphanumeric_or_camel_right(app, buffer, start_pos); + } + } + + new_pos = size; + for (int32_t i = 0; i < ArrayCount(pos); ++i){ + if (pos[i] < new_pos){ + new_pos = pos[i]; + } + } + } + else{ + for (int32_t i = 0; i < ArrayCount(pos); ++i){ + pos[i] = 0; + } + + if (flags & BoundaryWhitespace){ + pos[0] = buffer_seek_whitespace_left(app, buffer, start_pos); + } + + if (flags & BoundaryToken){ + if (buffer->tokens_are_ready){ + Cpp_Token_Array array = buffer_get_all_tokens(app, part, buffer); + pos[1] = seek_token_left(&array, start_pos); + } + else{ + pos[1] = buffer_seek_whitespace_left(app, buffer, start_pos); + } + } + + if (flags & BoundaryAlphanumeric){ + pos[2] = buffer_seek_alphanumeric_left(app, buffer, start_pos); + if (flags & BoundaryCamelCase){ + pos[3] = buffer_seek_range_camel_left(app, buffer, start_pos, pos[2]); + } + } + else{ + if (flags & BoundaryCamelCase){ + pos[3] = buffer_seek_alphanumeric_or_camel_left(app, buffer, start_pos); + } + } + + new_pos = 0; + for (int32_t i = 0; i < ArrayCount(pos); ++i){ + if (pos[i] > new_pos){ + new_pos = pos[i]; + } + } + } + result = new_pos; + } + end_temp_memory(temp); + + return(result); +} + +// +// Character Seeks +// + +void +buffer_seek_delimiter_forward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, char delim, int32_t *result){ + if (buffer->exists){ + char chunk[1024]; + int32_t size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){ + int32_t still_looping = 1; + do{ + for(; pos < stream.end; ++pos){ + char at_pos = stream.data[pos]; + if (at_pos == delim){ + *result = pos; + goto finished; + } + } + still_looping = forward_stream_chunk(&stream); + }while (still_looping); + } + } + + *result = buffer->size; + + finished:; +} + +static void +buffer_seek_delimiter_backward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, char delim, int32_t *result){ + if (buffer->exists){ + char chunk[1024]; + int32_t size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){ + int32_t still_looping = 1; + do{ + for(; pos >= stream.start; --pos){ + char at_pos = stream.data[pos]; + if (at_pos == delim){ + *result = pos; + goto finished; + } + } + still_looping = backward_stream_chunk(&stream); + }while (still_looping); + } + } + + *result = 0; + + finished:; +} + +// +// Buffer Substring Seeks +// + +// TODO(allen): This duplication is driving me crazy... I've gotta +// upgrade the meta programming system another level. + +// NOTE(allen): This is limitted to a string size of 512. +// You can push it up or do something more clever by just +// replacing char read_buffer[512]; with more memory. +static void +buffer_seek_string_forward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t end, char *str, int32_t size, int32_t *result){ + char read_buffer[512]; + + if (buffer->size > end){ + *result = buffer->size; + } + else{ + *result = end; + } + + if (size > 0 && size <= sizeof(read_buffer)){ + if (buffer->exists){ + String read_str = make_fixed_width_string(read_buffer); + String needle_str = make_string(str, size); + char first_char = str[0]; + + read_str.size = size; + + char chunk[1024]; + Stream_Chunk stream = {0}; + stream.max_end = end; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, sizeof(chunk))){ + int32_t still_looping = 1; + do{ + for(; pos < stream.end; ++pos){ + char at_pos = stream.data[pos]; + if (at_pos == first_char){ + buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match_ss(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = forward_stream_chunk(&stream); + }while (still_looping); + } + } + + if (end == 0){ + *result = buffer->size; + } + else{ + *result = end; + } + + finished:; + } +} + +// NOTE(allen): This is limitted to a string size of 512. +// You can push it up or do something more clever by just +// replacing char read_buffer[512]; with more memory. +static void +buffer_seek_string_backward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t min, char *str, int32_t size, int32_t *result){ + char read_buffer[512]; + + *result = min-1; + if (size > 0 && size <= sizeof(read_buffer)){ + if (buffer->exists){ + String read_str = make_fixed_width_string(read_buffer); + String needle_str = make_string(str, size); + char first_char = str[0]; + + read_str.size = size; + + char chunk[1024]; + Stream_Chunk stream = {0}; + stream.min_start = min; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, sizeof(chunk))){ + int32_t still_looping = 1; + do{ + for(; pos >= stream.start; --pos){ + char at_pos = stream.data[pos]; + if (at_pos == first_char){ + buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match_ss(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = backward_stream_chunk(&stream); + }while (still_looping); + } + } + + finished:; + } +} + +// NOTE(allen): This is limitted to a string size of 512. +// You can push it up or do something more clever by just +// replacing char read_buffer[512]; with more memory. +static void +buffer_seek_string_insensitive_forward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t end, char *str, int32_t size, int32_t *result){ + char read_buffer[512]; + char chunk[1024]; + int32_t chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + stream.max_end = end; + + if (buffer->size > end){ + *result = buffer->size; + } + else{ + *result = end; + } + + if (size > 0 && size <= sizeof(read_buffer)){ + if (buffer->exists){ + String read_str = make_fixed_width_string(read_buffer); + String needle_str = make_string(str, size); + char first_char = char_to_upper(str[0]); + + read_str.size = size; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + int32_t still_looping = 1; + do{ + for(; pos < stream.end; ++pos){ + char at_pos = char_to_upper(stream.data[pos]); + if (at_pos == first_char){ + buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match_insensitive_ss(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = forward_stream_chunk(&stream); + }while (still_looping); + } + } + + finished:; + } +} + +// NOTE(allen): This is limitted to a string size of 512. +// You can push it up or do something more clever by just +// replacing char read_buffer[512]; with more memory. +static void +buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary *buffer, int32_t pos, int32_t min, char *str, int32_t size, int32_t *result){ + char read_buffer[512]; + char chunk[1024]; + int32_t chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + stream.min_start = min; + + *result = min-1; + if (size > 0 && size <= sizeof(read_buffer)){ + if (buffer->exists){ + String read_str = make_fixed_width_string(read_buffer); + String needle_str = make_string(str, size); + char first_char = char_to_upper(str[0]); + + read_str.size = size; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + int32_t still_looping = 1; + do{ + for(; pos >= stream.start; --pos){ + char at_pos = char_to_upper(stream.data[pos]); + if (at_pos == first_char){ + buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match_insensitive_ss(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = backward_stream_chunk(&stream); + }while (still_looping); + } + } + + finished:; + } +} + + +// +// Buffer Line Positioning +// + +static int32_t +read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line, String *str){ + Partial_Cursor begin = {0}; + Partial_Cursor end = {0}; + + int32_t success = 0; + + if (buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &begin)){ + if (buffer_compute_cursor(app, buffer, seek_line_char(line, 65536), &end)){ + if (begin.line == line){ + if (0 <= begin.pos && begin.pos <= end.pos && end.pos <= buffer->size){ + int32_t size = (end.pos - begin.pos); + *str = make_string(push_array(part, char, size+1), size+1); + if (str->str){ + success = 1; + buffer_read_range(app, buffer, begin.pos, end.pos, str->str); + str->size = size; + terminate_with_null(str); + } + } + } + } + } + + return(success); +} + +static int32_t +buffer_get_line_start(Application_Links *app, Buffer_Summary *buffer, int32_t line){ + Partial_Cursor partial_cursor; + int32_t result = buffer->size; + if (line <= buffer->line_count){ + buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &partial_cursor); + result = partial_cursor.pos; + } + return(result); +} + +static int32_t +buffer_get_line_end(Application_Links *app, Buffer_Summary *buffer, int32_t line){ + Partial_Cursor partial_cursor; + int32_t result = buffer->size; + if (line <= buffer->line_count){ + buffer_compute_cursor(app, buffer, seek_line_char(line, 65536), &partial_cursor); + result = partial_cursor.pos; + } + return(result); +} + +static bool32 +buffer_line_is_blank(Application_Links *app, Buffer_Summary *buffer, int32_t line){ + Partial_Cursor start, end; + bool32 result = 0; + if (line <= buffer->line_count){ + buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &start); + buffer_compute_cursor(app, buffer, seek_line_char(line, 65536), &end); + + static const int32_t chunk_size = 1024; + char chunk[chunk_size]; + Stream_Chunk stream = {0}; + int32_t i = start.pos; + stream.max_end = end.pos; + + result = true; + if (init_stream_chunk(&stream, app, buffer, i, chunk, chunk_size)){ + bool32 still_looping = false; + do{ + for (;i < stream.end; ++i){ + char c = stream.data[i]; + if (!(c == ' ' || c == '\t' || c == '\r' || c == '\v' || c == '\n')){ + result = false; + goto double_break; + } + } + still_looping = forward_stream_chunk(&stream); + }while(still_looping); + } + double_break:; + } + return(result); +} + +static int32_t +buffer_get_line_index(Application_Links *app, Buffer_Summary *buffer, int32_t pos){ + Partial_Cursor partial_cursor; + buffer_compute_cursor(app, buffer, seek_pos(pos), &partial_cursor); + return(partial_cursor.line); +} + +static Cpp_Token* +get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line, int32_t *line_start_out = 0){ + int32_t line_start = buffer_get_line_start(app, buffer, line); + Cpp_Get_Token_Result get_token = cpp_get_token(tokens, line_start); + + if (get_token.in_whitespace){ + get_token.token_index += 1; + } + + if (line_start_out){ + *line_start_out = line_start; + } + + Cpp_Token *result = 0; + if (get_token.token_index < tokens.count){ + result = tokens.tokens + get_token.token_index; + } + + return(result); +} + + +#endif + +// BOTTOM + diff --git a/4coder_seek_types.h b/4coder_helper/4coder_seek_types.h similarity index 97% rename from 4coder_seek_types.h rename to 4coder_helper/4coder_seek_types.h index 3e156a02..f5e8738e 100644 --- a/4coder_seek_types.h +++ b/4coder_helper/4coder_seek_types.h @@ -9,7 +9,7 @@ // TOP -#ifndef FRED_BUFFER_TYPES_H +#if !defined(FRED_BUFFER_TYPES_H) #define FRED_BUFFER_TYPES_H static Buffer_Seek diff --git a/4coder_helper/4coder_streaming.h b/4coder_helper/4coder_streaming.h new file mode 100644 index 00000000..a239d08e --- /dev/null +++ b/4coder_helper/4coder_streaming.h @@ -0,0 +1,259 @@ +/* + * Helpers for streaming over buffer data to avoid having to read it all at once. + */ + +// TOP + +#if !defined(FCODER_STREAMING_H) +#define FCODER_STREAMING_H + +#include "4coder_helper/4coder_helper.h" + +struct Stream_Chunk{ + Application_Links *app; + Buffer_Summary *buffer; + + char *base_data; + int32_t start, end; + int32_t min_start, max_end; + bool32 add_null; + int32_t data_size; + + char *data; +}; + +static int32_t +round_down(int32_t x, int32_t b){ + int32_t r = 0; + if (x >= 0){ + r = x - (x % b); + } + return(r); +} + +static int32_t +round_up(int32_t x, int32_t b){ + int32_t r = 0; + if (x >= 0){ + r = x - (x % b) + b; + } + return(r); +} + +static bool32 +init_stream_chunk(Stream_Chunk *chunk, Application_Links *app, Buffer_Summary *buffer, + int32_t pos, char *data, int32_t size){ + bool32 result = 0; + + refresh_buffer(app, buffer); + if (pos >= 0 && pos < buffer->size && size > 0){ + chunk->app = app; + chunk->buffer = buffer; + chunk->base_data = data; + chunk->data_size = size; + chunk->start = round_down(pos, size); + chunk->end = round_up(pos, size); + + if (chunk->max_end > buffer->size || chunk->max_end == 0){ + chunk->max_end = buffer->size; + } + + if (chunk->max_end && chunk->max_end < chunk->end){ + chunk->end = chunk->max_end; + } + if (chunk->min_start && chunk->min_start > chunk->start){ + chunk->start = chunk->min_start; + } + + if (chunk->start < chunk->end){ + buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); + chunk->data = chunk->base_data - chunk->start; + result = 1; + } + } + + return(result); +} + +static bool32 +forward_stream_chunk(Stream_Chunk *chunk){ + Application_Links *app = chunk->app; + Buffer_Summary *buffer = chunk->buffer; + bool32 result = 0; + + refresh_buffer(app, buffer); + if (chunk->end < buffer->size){ + chunk->start = chunk->end; + chunk->end += chunk->data_size; + + if (chunk->max_end && chunk->max_end < chunk->end){ + chunk->end = chunk->max_end; + } + if (chunk->min_start && chunk->min_start > chunk->start){ + chunk->start = chunk->min_start; + } + + if (chunk->start < chunk->end){ + buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); + chunk->data = chunk->base_data - chunk->start; + result = 1; + } + } + + else if (chunk->add_null && chunk->end + 1 < buffer->size){ + chunk->start = buffer->size; + chunk->end = buffer->size + 1; + chunk->base_data[0] = 0; + chunk->data = chunk->base_data - chunk->start; + result = 1; + } + + return(result); +} + +static bool32 +backward_stream_chunk(Stream_Chunk *chunk){ + Application_Links *app = chunk->app; + Buffer_Summary *buffer = chunk->buffer; + bool32 result = 0; + + refresh_buffer(app, buffer); + if (chunk->start > 0){ + chunk->end = chunk->start; + chunk->start -= chunk->data_size; + + if (chunk->max_end && chunk->max_end < chunk->end){ + chunk->end = chunk->max_end; + } + if (chunk->min_start && chunk->min_start > chunk->start){ + chunk->start = chunk->min_start; + } + + if (chunk->start < chunk->end){ + buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); + chunk->data = chunk->base_data - chunk->start; + result = 1; + } + } + + else if (chunk->add_null && chunk->start > -1){ + chunk->start = -1; + chunk->end = 0; + chunk->base_data[0] = 0; + chunk->data = chunk->base_data - chunk->start; + result = 1; + } + + return(result); +} + +struct Stream_Tokens{ + Application_Links *app; + Buffer_Summary *buffer; + + Cpp_Token *base_tokens; + Cpp_Token *tokens; + int32_t start, end; + int32_t count, token_count; +}; + +static bool32 +init_stream_tokens(Stream_Tokens *stream, Application_Links *app, Buffer_Summary *buffer, int32_t pos, Cpp_Token *data, int32_t count){ + bool32 result = 0; + + refresh_buffer(app, buffer); + + int32_t token_count = buffer_token_count(app, buffer); + if (buffer->tokens_are_ready && pos >= 0 && pos < token_count && count > 0){ + stream->app = app; + stream->buffer = buffer; + stream->base_tokens = data; + stream->count = count; + stream->start = round_down(pos, count); + stream->end = round_up(pos, count); + stream->token_count = token_count; + + if (stream->start < 0){ + stream->start = 0; + } + if (stream->end > stream->token_count){ + stream->end = stream->token_count; + } + + buffer_read_tokens(app, buffer, stream->start, stream->end, stream->base_tokens); + stream->tokens = stream->base_tokens - stream->start; + result = 1; + } + + return(result); +} + +static Stream_Tokens +begin_temp_stream_token(Stream_Tokens *stream){ + return(*stream); +} + +static void +end_temp_stream_token(Stream_Tokens *stream, Stream_Tokens temp){ + if (stream->start != temp.start || stream->end != temp.end){ + Application_Links *app = stream->app; + buffer_read_tokens(app, temp.buffer, temp.start, temp.end, temp.base_tokens); + stream->tokens = stream->base_tokens - temp.start; + stream->start = temp.start; + stream->end = temp.end; + } +} + +static bool32 +forward_stream_tokens(Stream_Tokens *stream){ + Application_Links *app = stream->app; + Buffer_Summary *buffer = stream->buffer; + bool32 result = 0; + + refresh_buffer(app, buffer); + if (stream->end < stream->token_count){ + stream->start = stream->end; + stream->end += stream->count; + + if (stream->end > stream->token_count){ + stream->end = stream->token_count; + } + + if (stream->start < stream->end){ + buffer_read_tokens(app, buffer, stream->start, stream->end, stream->base_tokens); + stream->tokens = stream->base_tokens - stream->start; + result = 1; + } + } + + return(result); +} + +static bool32 +backward_stream_tokens(Stream_Tokens *stream){ + Application_Links *app = stream->app; + Buffer_Summary *buffer = stream->buffer; + bool32 result = 0; + + refresh_buffer(app, buffer); + if (stream->start > 0){ + stream->end = stream->start; + stream->start -= stream->count; + + if (0 > stream->start){ + stream->start = 0; + } + + if (stream->start < stream->end){ + buffer_read_tokens(app, buffer, stream->start, stream->end, stream->base_tokens); + stream->tokens = stream->base_tokens - stream->start; + result = 1; + } + } + + return(result); +} + +#endif + +// BOTTOM diff --git a/4coder_jump_parsing.cpp b/4coder_jump_parsing.cpp index 7f092b7b..84f30ad2 100644 --- a/4coder_jump_parsing.cpp +++ b/4coder_jump_parsing.cpp @@ -1,7 +1,21 @@ +/* +4coder_jump_parsing.cpp - Commands and helpers for parsing jump locations from +compiler errors and jumping to them in the corresponding buffer. -#ifndef FCODER_JUMP_PARSING +TYPE: 'drop-in-command-pack' +*/ + +// TOP + +#if !defined(FCODER_JUMP_PARSING) #define FCODER_JUMP_PARSING +#include "4coder_default_framework.h" +#include "4coder_helper/4coder_long_seek.h" +#include "4coder_helper/4coder_helper.h" + +#include "4coder_lib/4coder_mem.h" + typedef struct Name_Based_Jump_Location{ String file; int32_t line; @@ -38,8 +52,7 @@ ms_style_verify(String line, int32_t paren_pos){ } static int32_t -parse_jump_location(String line, Name_Based_Jump_Location *location, - int32_t skip_sub_errors, int32_t *colon_char){ +parse_jump_location(String line, Name_Based_Jump_Location *location, int32_t skip_sub_errors, int32_t *colon_char){ int32_t result = false; String original_line = line; @@ -150,12 +163,7 @@ parse_jump_location(String line, Name_Based_Jump_Location *location, } static int32_t -parse_jump_from_buffer_line(Application_Links *app, - Partition *part, - int32_t buffer_id, - int32_t line, - int32_t skip_sub_errors, - Name_Based_Jump_Location *location){ +parse_jump_from_buffer_line(Application_Links *app, Partition *part, int32_t buffer_id, int32_t line, int32_t skip_sub_errors, Name_Based_Jump_Location *location){ int32_t result = false; String line_str = {0}; @@ -193,15 +201,7 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor){ // static int32_t -seek_next_jump_in_buffer(Application_Links *app, - Partition *part, - int32_t buffer_id, - int32_t first_line, - bool32 skip_sub_errors, - int32_t direction, - int32_t *line_out, - int32_t *colon_index_out, - Name_Based_Jump_Location *location_out){ +seek_next_jump_in_buffer(Application_Links *app, Partition *part, int32_t buffer_id, int32_t first_line, bool32 skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){ Assert(direction == 1 || direction == -1); @@ -247,14 +247,7 @@ convert_name_based_to_id_based(Application_Links *app, Name_Based_Jump_Location } static int32_t -seek_next_jump_in_view(Application_Links *app, - Partition *part, - View_Summary *view, - int32_t skip_sub_errors, - int32_t direction, - int32_t *line_out, - int32_t *colon_index_out, - Name_Based_Jump_Location *location_out){ +seek_next_jump_in_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){ int32_t result = false; Name_Based_Jump_Location location = {0}; @@ -287,13 +280,7 @@ skip_this_jump(ID_Based_Jump_Location prev, ID_Based_Jump_Location jump){ static ID_Based_Jump_Location prev_location = {0}; static int32_t -advance_cursor_in_jump_view(Application_Links *app, - Partition *part, - View_Summary *view, - int32_t skip_repeats, - int32_t skip_sub_error, - int32_t direction, - Name_Based_Jump_Location *location_out){ +advance_cursor_in_jump_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_repeats, int32_t skip_sub_error, int32_t direction, Name_Based_Jump_Location *location_out){ int32_t result = true; Name_Based_Jump_Location location = {0}; @@ -325,47 +312,8 @@ advance_cursor_in_jump_view(Application_Links *app, return(result); } -static char locked_buffer_space[256]; -static String locked_buffer = make_fixed_width_string(locked_buffer_space); - -static void -unlock_jump_buffer(){ - locked_buffer.size = 0; -} - -static void -lock_jump_buffer(char *name, int32_t size){ - copy(&locked_buffer, make_string(name, size)); -} - -static void -lock_jump_buffer(Buffer_Summary buffer){ - copy(&locked_buffer, make_string(buffer.buffer_name, buffer.buffer_name_len)); -} - -static View_Summary -get_view_for_locked_jump_buffer(Application_Links *app){ - View_Summary view = {0}; - - if (locked_buffer.size > 0){ - Buffer_Summary buffer = get_buffer_by_name(app, locked_buffer.str, locked_buffer.size, AccessAll); - if (buffer.exists){ - view = get_first_view_with_buffer(app, buffer.buffer_id); - } - else{ - unlock_jump_buffer(); - } - } - - return(view); -} - static int32_t -seek_error(Application_Links *app, - Partition *part, - int32_t skip_repeats, - int32_t skip_sub_errors, - int32_t direction){ +seek_error(Application_Links *app, Partition *part, int32_t skip_repeats, int32_t skip_sub_errors, int32_t direction){ int32_t result = 0; View_Summary view = get_view_for_locked_jump_buffer(app); @@ -438,3 +386,5 @@ CUSTOM_COMMAND_SIG(goto_first_jump){ #endif +// BOTTOM + diff --git a/4coder_mem.h b/4coder_lib/4coder_mem.h similarity index 79% rename from 4coder_mem.h rename to 4coder_lib/4coder_mem.h index b04b9dc7..d0301cbf 100644 --- a/4coder_mem.h +++ b/4coder_lib/4coder_mem.h @@ -1,30 +1,62 @@ +/* +4coder_mem.h - Preversioning +no warranty implied; use at your own risk -#ifndef FCODER_MEM_H +This software is in the public domain. Where that dedication is not +recognized, you are granted a perpetual, irrevocable license to copy, +distribute, and modify this file as you see fit. +*/ + +#if !defined(FCODER_MEM_H) #define FCODER_MEM_H -#ifndef Assert -# define Assert(n) do{ if(!(n)){*(int*)0 = 0xA11E;} }while(0) +// 4tech_standard_preamble.h +#if !defined(FTECH_INTEGERS) +#define FTECH_INTEGERS +#include +typedef int8_t i8_4tech; +typedef int16_t i16_4tech; +typedef int32_t i32_4tech; +typedef int64_t i64_4tech; + +typedef uint8_t u8_4tech; +typedef uint16_t u16_4tech; +typedef uint32_t u32_4tech; +typedef uint64_t u64_4tech; + +typedef float f32_4tech; +typedef double f64_4tech; + +typedef int8_t b8_4tech; +typedef int32_t b32_4tech; #endif +#if !defined(Assert) +# define Assert(n) do{ if (!(n)) *(int*)0 = 0xA11E; }while(0) +#endif +// standard preamble end + +#include + struct Partition{ char *base; - int32_t pos; - int32_t max; + i32_4tech pos; + i32_4tech max; }; struct Temp_Memory{ void *handle; - int32_t pos; + i32_4tech pos; }; struct Tail_Temp_Partition{ Partition part; void *handle; - int32_t old_max; + i32_4tech old_max; }; inline Partition -make_part(void *memory, int32_t size){ +make_part(void *memory, i32_4tech size){ Partition partition; partition.base = (char*)memory; partition.pos = 0; @@ -33,7 +65,7 @@ make_part(void *memory, int32_t size){ } inline void* -partition_allocate(Partition *data, int32_t size){ +partition_allocate(Partition *data, i32_4tech size){ void *ret = 0; if (size > 0 && data->pos + size <= data->max){ ret = data->base + data->pos; @@ -43,7 +75,7 @@ partition_allocate(Partition *data, int32_t size){ } inline void -partition_align(Partition *data, uint32_t boundary){ +partition_align(Partition *data, u32_4tech boundary){ --boundary; data->pos = (data->pos + boundary) & (~boundary); } @@ -53,13 +85,13 @@ partition_current(Partition *data){ return(data->base + data->pos); } -inline int32_t +inline i32_4tech partition_remaining(Partition *data){ return(data->max - data->pos); } inline Partition -partition_sub_part(Partition *data, int32_t size){ +partition_sub_part(Partition *data, i32_4tech size){ Partition result = {}; void *d = partition_allocate(data, size); if (d){ @@ -86,7 +118,7 @@ end_temp_memory(Temp_Memory temp){ } inline Tail_Temp_Partition -begin_tail_part(Partition *data, int32_t size){ +begin_tail_part(Partition *data, i32_4tech size){ Tail_Temp_Partition result = {0}; if (data->pos + size <= data->max){ result.handle = data; @@ -121,9 +153,9 @@ struct Bubble{ Bubble *next; Bubble *prev2; Bubble *next2; - int32_t size; - uint32_t flags; - uint32_t _unused_[4]; + i32_4tech size; + u32_4tech flags; + u32_4tech _unused_[4]; }; struct General_Memory{ @@ -178,12 +210,12 @@ general_sentinel_init(Bubble *bubble){ #define BUBBLE_MIN_SIZE 1024 static void -general_memory_attempt_split(General_Memory *general, Bubble *bubble, int32_t wanted_size){ - int32_t remaining_size = bubble->size - wanted_size; +general_memory_attempt_split(General_Memory *general, Bubble *bubble, i32_4tech wanted_size){ + i32_4tech remaining_size = bubble->size - wanted_size; if (remaining_size >= BUBBLE_MIN_SIZE){ bubble->size = wanted_size; Bubble *new_bubble = (Bubble*)((char*)(bubble + 1) + wanted_size); - new_bubble->flags = (uint32_t)MEM_BUBBLE_FLAG_INIT; + new_bubble->flags = (u32_4tech)MEM_BUBBLE_FLAG_INIT; new_bubble->size = remaining_size - sizeof(Bubble); insert_bubble(bubble, new_bubble); insert_bubble2(&general->free_sentinel, new_bubble); @@ -206,20 +238,20 @@ general_memory_attempt_merge(Bubble *left, Bubble *right){ // NOTE(allen): public procedures static void -general_memory_open(General_Memory *general, void *memory, int32_t size){ +general_memory_open(General_Memory *general, void *memory, i32_4tech size){ general_sentinel_init(&general->sentinel); general_sentinel_init(&general->free_sentinel); general_sentinel_init(&general->used_sentinel); Bubble *first = (Bubble*)memory; - first->flags = (uint32_t)MEM_BUBBLE_FLAG_INIT; + first->flags = (u32_4tech)MEM_BUBBLE_FLAG_INIT; first->size = size - sizeof(Bubble); insert_bubble(&general->sentinel, first); insert_bubble2(&general->free_sentinel, first); } #if defined(Assert) -static int32_t +static i32_4tech general_memory_check(General_Memory *general){ Bubble *sentinel = &general->sentinel; for (Bubble *bubble = sentinel->next; @@ -243,12 +275,12 @@ general_memory_check(General_Memory *general){ return(1); } #else -static int32_t +static i32_4tech general_memory_check(General_Memory *general){} #endif static void* -general_memory_allocate(General_Memory *general, int32_t size){ +general_memory_allocate(General_Memory *general, i32_4tech size){ void *result = 0; if (size < BUBBLE_MIN_SIZE) size = BUBBLE_MIN_SIZE; for (Bubble *bubble = general->free_sentinel.next2; @@ -284,10 +316,10 @@ general_memory_free(General_Memory *general, void *memory){ } static void* -general_memory_reallocate(General_Memory *general, void *old, int32_t old_size, int32_t size){ +general_memory_reallocate(General_Memory *general, void *old, i32_4tech old_size, i32_4tech size){ void *result = old; Bubble *bubble = ((Bubble*)old) - 1; - int32_t additional_space = size - bubble->size; + i32_4tech additional_space = size - bubble->size; if (additional_space > 0){ Bubble *next = bubble->next; if (!(next->flags & MEM_BUBBLE_USED) && @@ -305,7 +337,7 @@ general_memory_reallocate(General_Memory *general, void *old, int32_t old_size, } inline void* -general_memory_reallocate_nocopy(General_Memory *general, void *old, int32_t size){ +general_memory_reallocate_nocopy(General_Memory *general, void *old, i32_4tech size){ void *result = general_memory_reallocate(general, old, 0, size); return(result); } diff --git a/4coder_string.h b/4coder_lib/4coder_string.h similarity index 62% rename from 4coder_string.h rename to 4coder_lib/4coder_string.h index d1242d6a..958c81dd 100644 --- a/4coder_string.h +++ b/4coder_lib/4coder_string.h @@ -1,66 +1,85 @@ +/* +4coder_string.h - Version 1.0.14 +no warranty implied; use at your own risk + +This software is in the public domain. Where that dedication is not +recognized, you are granted a perpetual, irrevocable license to copy, +distribute, and modify this file as you see fit. + +To include implementation: #define FSTRING_IMPLEMENTATION +To use in C mode: #define FSTRING_C +*/ // TOP -#if defined(FSTRING_C) -# if defined(FSTRING_INLINE) -# undef FSTRING_INLINE -# endif -# define FSTRING_INLINE static -#endif - -#if defined(FSTRING_IMPLEMENTATION) && defined(FSTRING_GUARD) -# undef FSTRING_IMPLEMENTATION -#endif - +// 4tech_standard_preamble.h +#if !defined(FTECH_INTEGERS) +#define FTECH_INTEGERS #include +typedef int8_t i8_4tech; +typedef int16_t i16_4tech; +typedef int32_t i32_4tech; +typedef int64_t i64_4tech; -#ifndef FSTRING_LINK +typedef uint8_t u8_4tech; +typedef uint16_t u16_4tech; +typedef uint32_t u32_4tech; +typedef uint64_t u64_4tech; + +typedef float f32_4tech; +typedef double f64_4tech; + +typedef int8_t b8_4tech; +typedef int32_t b32_4tech; +#endif + +#if !defined(Assert) +# define Assert(n) do{ if (!(n)) *(int*)0 = 0xA11E; }while(0) +#endif +// standard preamble end + + +#if !defined(FSTRING_LINK) # define FSTRING_LINK static #endif -#ifndef FSTRING_INLINE -# define FSTRING_INLINE inline +#if !defined(FSTRING_INLINE) +# if defined(FSTRING_C) +# define FSTRING_INLINE static +# else +# define FSTRING_INLINE inline +# endif #endif -#ifndef FSTRING_STRUCT -#define FSTRING_STRUCT +#if !defined(FSTRING_GUARD) +#define literal(s) (s), (sizeof(s)-1) + typedef struct String{ char *str; - int32_t size; - int32_t memory_size; + i32_4tech size; + i32_4tech memory_size; } String; -typedef struct Offset_String{ - int32_t offset; - int32_t size; -} Offset_String; -#endif - -#ifndef fstr_bool -# define fstr_bool int32_t -#endif - -#ifndef literal -# define literal(s) (s), (sizeof(s)-1) +static String null_string = {0}; #endif #if !defined(FCODER_STRING_H) #define FCODER_STRING_H -FSTRING_INLINE fstr_bool char_is_slash(char c); -FSTRING_INLINE fstr_bool char_is_upper(char c); -FSTRING_INLINE fstr_bool char_is_lower(char c); +FSTRING_INLINE b32_4tech char_is_slash(char c); +FSTRING_INLINE b32_4tech char_is_upper(char c); +FSTRING_INLINE b32_4tech char_is_lower(char c); FSTRING_INLINE char char_to_upper(char c); FSTRING_INLINE char char_to_lower(char c); -FSTRING_INLINE fstr_bool char_is_whitespace(char c); -FSTRING_INLINE fstr_bool char_is_alpha_numeric(char c); -FSTRING_INLINE fstr_bool char_is_alpha_numeric_true(char c); -FSTRING_INLINE fstr_bool char_is_alpha(char c); -FSTRING_INLINE fstr_bool char_is_alpha_true(char c); -FSTRING_INLINE fstr_bool char_is_hex(char c); -FSTRING_INLINE fstr_bool char_is_numeric(char c); -FSTRING_INLINE String make_string_cap(void *str, int32_t size, int32_t mem_size); -FSTRING_INLINE String make_string(void *str, int32_t size); +FSTRING_INLINE b32_4tech char_is_whitespace(char c); +FSTRING_INLINE b32_4tech char_is_alpha_numeric(char c); +FSTRING_INLINE b32_4tech char_is_alpha_numeric_true(char c); +FSTRING_INLINE b32_4tech char_is_alpha(char c); +FSTRING_INLINE b32_4tech char_is_alpha_true(char c); +FSTRING_INLINE b32_4tech char_is_hex(char c); +FSTRING_INLINE b32_4tech char_is_numeric(char c); +FSTRING_INLINE String make_string_cap(void *str, i32_4tech size, i32_4tech mem_size); +FSTRING_INLINE String make_string(void *str, i32_4tech size); #ifndef make_lit_string # define make_lit_string(s) (make_string_cap((char*)(s), sizeof(s)-1, sizeof(s))) #endif @@ -70,68 +89,68 @@ FSTRING_INLINE String make_string(void *str, int32_t size); #ifndef expand_str # define expand_str(s) ((s).str), ((s).size) #endif -FSTRING_LINK int32_t str_size(char *str); +FSTRING_LINK i32_4tech str_size(char *str); FSTRING_INLINE String make_string_slowly(void *str); -FSTRING_INLINE String substr_tail(String str, int32_t start); -FSTRING_INLINE String substr(String str, int32_t start, int32_t size); +FSTRING_INLINE String substr_tail(String str, i32_4tech start); +FSTRING_INLINE String substr(String str, i32_4tech start, i32_4tech size); FSTRING_LINK String skip_whitespace(String str); FSTRING_LINK String chop_whitespace(String str); FSTRING_LINK String skip_chop_whitespace(String str); FSTRING_INLINE String tailstr(String str); -FSTRING_LINK fstr_bool match_cc(char *a, char *b); -FSTRING_LINK fstr_bool match_sc(String a, char *b); -FSTRING_INLINE fstr_bool match_cs(char *a, String b); -FSTRING_LINK fstr_bool match_ss(String a, String b); -FSTRING_LINK fstr_bool match_part_ccl(char *a, char *b, int32_t *len); -FSTRING_LINK fstr_bool match_part_scl(String a, char *b, int32_t *len); -FSTRING_INLINE fstr_bool match_part_cc(char *a, char *b); -FSTRING_INLINE fstr_bool match_part_sc(String a, char *b); -FSTRING_LINK fstr_bool match_part_cs(char *a, String b); -FSTRING_LINK fstr_bool match_part_ss(String a, String b); -FSTRING_LINK fstr_bool match_insensitive_cc(char *a, char *b); -FSTRING_LINK fstr_bool match_insensitive_sc(String a, char *b); -FSTRING_INLINE fstr_bool match_insensitive_cs(char *a, String b); -FSTRING_LINK fstr_bool match_insensitive_ss(String a, String b); -FSTRING_LINK fstr_bool match_part_insensitive_ccl(char *a, char *b, int32_t *len); -FSTRING_LINK fstr_bool match_part_insensitive_scl(String a, char *b, int32_t *len); -FSTRING_INLINE fstr_bool match_part_insensitive_cc(char *a, char *b); -FSTRING_INLINE fstr_bool match_part_insensitive_sc(String a, char *b); -FSTRING_LINK fstr_bool match_part_insensitive_cs(char *a, String b); -FSTRING_LINK fstr_bool match_part_insensitive_ss(String a, String b); -FSTRING_LINK int32_t compare_cc(char *a, char *b); -FSTRING_LINK int32_t compare_sc(String a, char *b); -FSTRING_INLINE int32_t compare_cs(char *a, String b); -FSTRING_LINK int32_t compare_ss(String a, String b); -FSTRING_LINK int32_t find_c_char(char *str, int32_t start, char character); -FSTRING_LINK int32_t find_s_char(String str, int32_t start, char character); -FSTRING_LINK int32_t rfind_s_char(String str, int32_t start, char character); -FSTRING_LINK int32_t find_c_chars(char *str, int32_t start, char *characters); -FSTRING_LINK int32_t find_s_chars(String str, int32_t start, char *characters); -FSTRING_LINK int32_t find_substr_c(char *str, int32_t start, String seek); -FSTRING_LINK int32_t find_substr_s(String str, int32_t start, String seek); -FSTRING_LINK int32_t rfind_substr_s(String str, int32_t start, String seek); -FSTRING_LINK int32_t find_substr_insensitive_c(char *str, int32_t start, String seek); -FSTRING_LINK int32_t find_substr_insensitive_s(String str, int32_t start, String seek); -FSTRING_INLINE fstr_bool has_substr_c(char *s, String seek); -FSTRING_INLINE fstr_bool has_substr_s(String s, String seek); -FSTRING_INLINE fstr_bool has_substr_insensitive_c(char *s, String seek); -FSTRING_INLINE fstr_bool has_substr_insensitive_s(String s, String seek); -FSTRING_LINK int32_t copy_fast_unsafe_cc(char *dest, char *src); -FSTRING_LINK int32_t copy_fast_unsafe_cs(char *dest, String src); -FSTRING_LINK fstr_bool copy_checked_ss(String *dest, String src); -FSTRING_LINK fstr_bool copy_partial_sc(String *dest, char *src); -FSTRING_LINK fstr_bool copy_partial_ss(String *dest, String src); -FSTRING_INLINE int32_t copy_cc(char *dest, char *src); +FSTRING_LINK b32_4tech match_cc(char *a, char *b); +FSTRING_LINK b32_4tech match_sc(String a, char *b); +FSTRING_INLINE b32_4tech match_cs(char *a, String b); +FSTRING_LINK b32_4tech match_ss(String a, String b); +FSTRING_LINK b32_4tech match_part_ccl(char *a, char *b, i32_4tech *len); +FSTRING_LINK b32_4tech match_part_scl(String a, char *b, i32_4tech *len); +FSTRING_INLINE b32_4tech match_part_cc(char *a, char *b); +FSTRING_INLINE b32_4tech match_part_sc(String a, char *b); +FSTRING_LINK b32_4tech match_part_cs(char *a, String b); +FSTRING_LINK b32_4tech match_part_ss(String a, String b); +FSTRING_LINK b32_4tech match_insensitive_cc(char *a, char *b); +FSTRING_LINK b32_4tech match_insensitive_sc(String a, char *b); +FSTRING_INLINE b32_4tech match_insensitive_cs(char *a, String b); +FSTRING_LINK b32_4tech match_insensitive_ss(String a, String b); +FSTRING_LINK b32_4tech match_part_insensitive_ccl(char *a, char *b, i32_4tech *len); +FSTRING_LINK b32_4tech match_part_insensitive_scl(String a, char *b, i32_4tech *len); +FSTRING_INLINE b32_4tech match_part_insensitive_cc(char *a, char *b); +FSTRING_INLINE b32_4tech match_part_insensitive_sc(String a, char *b); +FSTRING_LINK b32_4tech match_part_insensitive_cs(char *a, String b); +FSTRING_LINK b32_4tech match_part_insensitive_ss(String a, String b); +FSTRING_LINK i32_4tech compare_cc(char *a, char *b); +FSTRING_LINK i32_4tech compare_sc(String a, char *b); +FSTRING_INLINE i32_4tech compare_cs(char *a, String b); +FSTRING_LINK i32_4tech compare_ss(String a, String b); +FSTRING_LINK i32_4tech find_c_char(char *str, i32_4tech start, char character); +FSTRING_LINK i32_4tech find_s_char(String str, i32_4tech start, char character); +FSTRING_LINK i32_4tech rfind_s_char(String str, i32_4tech start, char character); +FSTRING_LINK i32_4tech find_c_chars(char *str, i32_4tech start, char *characters); +FSTRING_LINK i32_4tech find_s_chars(String str, i32_4tech start, char *characters); +FSTRING_LINK i32_4tech find_substr_c(char *str, i32_4tech start, String seek); +FSTRING_LINK i32_4tech find_substr_s(String str, i32_4tech start, String seek); +FSTRING_LINK i32_4tech rfind_substr_s(String str, i32_4tech start, String seek); +FSTRING_LINK i32_4tech find_substr_insensitive_c(char *str, i32_4tech start, String seek); +FSTRING_LINK i32_4tech find_substr_insensitive_s(String str, i32_4tech start, String seek); +FSTRING_INLINE b32_4tech has_substr_c(char *s, String seek); +FSTRING_INLINE b32_4tech has_substr_s(String s, String seek); +FSTRING_INLINE b32_4tech has_substr_insensitive_c(char *s, String seek); +FSTRING_INLINE b32_4tech has_substr_insensitive_s(String s, String seek); +FSTRING_LINK i32_4tech copy_fast_unsafe_cc(char *dest, char *src); +FSTRING_LINK i32_4tech copy_fast_unsafe_cs(char *dest, String src); +FSTRING_LINK b32_4tech copy_checked_ss(String *dest, String src); +FSTRING_LINK b32_4tech copy_partial_sc(String *dest, char *src); +FSTRING_LINK b32_4tech copy_partial_ss(String *dest, String src); +FSTRING_INLINE i32_4tech copy_cc(char *dest, char *src); FSTRING_INLINE void copy_ss(String *dest, String src); FSTRING_INLINE void copy_sc(String *dest, char *src); -FSTRING_LINK fstr_bool append_checked_ss(String *dest, String src); -FSTRING_LINK fstr_bool append_partial_sc(String *dest, char *src); -FSTRING_LINK fstr_bool append_partial_ss(String *dest, String src); -FSTRING_LINK fstr_bool append_s_char(String *dest, char c); -FSTRING_INLINE fstr_bool append_ss(String *dest, String src); -FSTRING_INLINE fstr_bool append_sc(String *dest, char *src); -FSTRING_LINK fstr_bool terminate_with_null(String *str); -FSTRING_LINK fstr_bool append_padding(String *dest, char c, int32_t target_size); +FSTRING_LINK b32_4tech append_checked_ss(String *dest, String src); +FSTRING_LINK b32_4tech append_partial_sc(String *dest, char *src); +FSTRING_LINK b32_4tech append_partial_ss(String *dest, String src); +FSTRING_LINK b32_4tech append_s_char(String *dest, char c); +FSTRING_INLINE b32_4tech append_ss(String *dest, String src); +FSTRING_INLINE b32_4tech append_sc(String *dest, char *src); +FSTRING_LINK b32_4tech terminate_with_null(String *str); +FSTRING_LINK b32_4tech append_padding(String *dest, char c, i32_4tech target_size); FSTRING_LINK void replace_char(String *str, char replace, char with); FSTRING_LINK void to_lower_cc(char *src, char *dst); FSTRING_LINK void to_lower_ss(String *dst, String src); @@ -140,35 +159,35 @@ FSTRING_LINK void to_upper_cc(char *src, char *dst); FSTRING_LINK void to_upper_ss(String *dst, String src); FSTRING_LINK void to_upper_s(String *str); FSTRING_LINK void to_camel_cc(char *src, char *dst); -FSTRING_LINK int32_t int_to_str_size(int32_t x); -FSTRING_LINK fstr_bool int_to_str(String *dest, int32_t x); -FSTRING_LINK fstr_bool append_int_to_str(String *dest, int32_t x); -FSTRING_LINK int32_t u64_to_str_size(uint64_t x); -FSTRING_LINK fstr_bool u64_to_str(String *dest, uint64_t x); -FSTRING_LINK fstr_bool append_u64_to_str(String *dest, uint64_t x); -FSTRING_LINK int32_t float_to_str_size(float x); -FSTRING_LINK fstr_bool append_float_to_str(String *dest, float x); -FSTRING_LINK fstr_bool float_to_str(String *dest, float x); -FSTRING_LINK int32_t str_is_int_c(char *str); -FSTRING_LINK fstr_bool str_is_int_s(String str); -FSTRING_LINK int32_t str_to_int_c(char *str); -FSTRING_LINK int32_t str_to_int_s(String str); -FSTRING_LINK int32_t hexchar_to_int(char c); -FSTRING_LINK char int_to_hexchar(int32_t x); -FSTRING_LINK uint32_t hexstr_to_int(String str); -FSTRING_LINK fstr_bool color_to_hexstr(String *s, uint32_t color); -FSTRING_LINK fstr_bool hexstr_to_color(String s, uint32_t *out); -FSTRING_LINK int32_t reverse_seek_slash_pos(String str, int32_t pos); -FSTRING_INLINE int32_t reverse_seek_slash(String str); +FSTRING_LINK i32_4tech int_to_str_size(i32_4tech x); +FSTRING_LINK b32_4tech int_to_str(String *dest, i32_4tech x); +FSTRING_LINK b32_4tech append_int_to_str(String *dest, i32_4tech x); +FSTRING_LINK i32_4tech u64_to_str_size(uint64_t x); +FSTRING_LINK b32_4tech u64_to_str(String *dest, uint64_t x); +FSTRING_LINK b32_4tech append_u64_to_str(String *dest, uint64_t x); +FSTRING_LINK i32_4tech float_to_str_size(float x); +FSTRING_LINK b32_4tech append_float_to_str(String *dest, float x); +FSTRING_LINK b32_4tech float_to_str(String *dest, float x); +FSTRING_LINK i32_4tech str_is_int_c(char *str); +FSTRING_LINK b32_4tech str_is_int_s(String str); +FSTRING_LINK i32_4tech str_to_int_c(char *str); +FSTRING_LINK i32_4tech str_to_int_s(String str); +FSTRING_LINK i32_4tech hexchar_to_int(char c); +FSTRING_LINK char int_to_hexchar(i32_4tech x); +FSTRING_LINK u32_4tech hexstr_to_int(String str); +FSTRING_LINK b32_4tech color_to_hexstr(String *s, u32_4tech color); +FSTRING_LINK b32_4tech hexstr_to_color(String s, u32_4tech *out); +FSTRING_LINK i32_4tech reverse_seek_slash_pos(String str, i32_4tech pos); +FSTRING_INLINE i32_4tech reverse_seek_slash(String str); FSTRING_INLINE String front_of_directory(String dir); FSTRING_INLINE String path_of_directory(String dir); -FSTRING_LINK fstr_bool set_last_folder_sc(String *dir, char *folder_name, char slash); -FSTRING_LINK fstr_bool set_last_folder_ss(String *dir, String folder_name, char slash); +FSTRING_LINK b32_4tech set_last_folder_sc(String *dir, char *folder_name, char slash); +FSTRING_LINK b32_4tech set_last_folder_ss(String *dir, String folder_name, char slash); FSTRING_LINK String file_extension(String str); -FSTRING_LINK fstr_bool remove_extension(String *str); -FSTRING_LINK fstr_bool remove_last_folder(String *str); -FSTRING_LINK fstr_bool string_set_match_table(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index); -FSTRING_LINK fstr_bool string_set_match(String *str_set, int32_t count, String str, int32_t *match_index); +FSTRING_LINK b32_4tech remove_extension(String *str); +FSTRING_LINK b32_4tech remove_last_folder(String *str); +FSTRING_LINK b32_4tech string_set_match_table(void *str_set, i32_4tech item_size, i32_4tech count, String str, i32_4tech *match_index); +FSTRING_LINK b32_4tech string_set_match(String *str_set, i32_4tech count, String str, i32_4tech *match_index); FSTRING_LINK String get_first_double_line(String source); FSTRING_LINK String get_next_double_line(String source, String line); FSTRING_LINK String get_next_word(String source, String prev_word); @@ -178,60 +197,60 @@ FSTRING_LINK String get_first_word(String source); #if !defined(FSTRING_C) && !defined(FSTRING_GUARD) -FSTRING_INLINE String make_string(void *str, int32_t size, int32_t mem_size){return(make_string_cap(str,size,mem_size));} -FSTRING_INLINE String substr(String str, int32_t start){return(substr_tail(str,start));} -FSTRING_LINK fstr_bool match(char *a, char *b){return(match_cc(a,b));} -FSTRING_LINK fstr_bool match(String a, char *b){return(match_sc(a,b));} -FSTRING_INLINE fstr_bool match(char *a, String b){return(match_cs(a,b));} -FSTRING_LINK fstr_bool match(String a, String b){return(match_ss(a,b));} -FSTRING_LINK fstr_bool match_part(char *a, char *b, int32_t *len){return(match_part_ccl(a,b,len));} -FSTRING_LINK fstr_bool match_part(String a, char *b, int32_t *len){return(match_part_scl(a,b,len));} -FSTRING_INLINE fstr_bool match_part(char *a, char *b){return(match_part_cc(a,b));} -FSTRING_INLINE fstr_bool match_part(String a, char *b){return(match_part_sc(a,b));} -FSTRING_LINK fstr_bool match_part(char *a, String b){return(match_part_cs(a,b));} -FSTRING_LINK fstr_bool match_part(String a, String b){return(match_part_ss(a,b));} -FSTRING_LINK fstr_bool match_insensitive(char *a, char *b){return(match_insensitive_cc(a,b));} -FSTRING_LINK fstr_bool match_insensitive(String a, char *b){return(match_insensitive_sc(a,b));} -FSTRING_INLINE fstr_bool match_insensitive(char *a, String b){return(match_insensitive_cs(a,b));} -FSTRING_LINK fstr_bool match_insensitive(String a, String b){return(match_insensitive_ss(a,b));} -FSTRING_LINK fstr_bool match_part_insensitive(char *a, char *b, int32_t *len){return(match_part_insensitive_ccl(a,b,len));} -FSTRING_LINK fstr_bool match_part_insensitive(String a, char *b, int32_t *len){return(match_part_insensitive_scl(a,b,len));} -FSTRING_INLINE fstr_bool match_part_insensitive(char *a, char *b){return(match_part_insensitive_cc(a,b));} -FSTRING_INLINE fstr_bool match_part_insensitive(String a, char *b){return(match_part_insensitive_sc(a,b));} -FSTRING_LINK fstr_bool match_part_insensitive(char *a, String b){return(match_part_insensitive_cs(a,b));} -FSTRING_LINK fstr_bool match_part_insensitive(String a, String b){return(match_part_insensitive_ss(a,b));} -FSTRING_LINK int32_t compare(char *a, char *b){return(compare_cc(a,b));} -FSTRING_LINK int32_t compare(String a, char *b){return(compare_sc(a,b));} -FSTRING_INLINE int32_t compare(char *a, String b){return(compare_cs(a,b));} -FSTRING_LINK int32_t compare(String a, String b){return(compare_ss(a,b));} -FSTRING_LINK int32_t find(char *str, int32_t start, char character){return(find_c_char(str,start,character));} -FSTRING_LINK int32_t find(String str, int32_t start, char character){return(find_s_char(str,start,character));} -FSTRING_LINK int32_t rfind(String str, int32_t start, char character){return(rfind_s_char(str,start,character));} -FSTRING_LINK int32_t find(char *str, int32_t start, char *characters){return(find_c_chars(str,start,characters));} -FSTRING_LINK int32_t find(String str, int32_t start, char *characters){return(find_s_chars(str,start,characters));} -FSTRING_LINK int32_t find_substr(char *str, int32_t start, String seek){return(find_substr_c(str,start,seek));} -FSTRING_LINK int32_t find_substr(String str, int32_t start, String seek){return(find_substr_s(str,start,seek));} -FSTRING_LINK int32_t rfind_substr(String str, int32_t start, String seek){return(rfind_substr_s(str,start,seek));} -FSTRING_LINK int32_t find_substr_insensitive(char *str, int32_t start, String seek){return(find_substr_insensitive_c(str,start,seek));} -FSTRING_LINK int32_t find_substr_insensitive(String str, int32_t start, String seek){return(find_substr_insensitive_s(str,start,seek));} -FSTRING_INLINE fstr_bool has_substr(char *s, String seek){return(has_substr_c(s,seek));} -FSTRING_INLINE fstr_bool has_substr(String s, String seek){return(has_substr_s(s,seek));} -FSTRING_INLINE fstr_bool has_substr_insensitive(char *s, String seek){return(has_substr_insensitive_c(s,seek));} -FSTRING_INLINE fstr_bool has_substr_insensitive(String s, String seek){return(has_substr_insensitive_s(s,seek));} -FSTRING_LINK int32_t copy_fast_unsafe(char *dest, char *src){return(copy_fast_unsafe_cc(dest,src));} -FSTRING_LINK int32_t copy_fast_unsafe(char *dest, String src){return(copy_fast_unsafe_cs(dest,src));} -FSTRING_LINK fstr_bool copy_checked(String *dest, String src){return(copy_checked_ss(dest,src));} -FSTRING_LINK fstr_bool copy_partial(String *dest, char *src){return(copy_partial_sc(dest,src));} -FSTRING_LINK fstr_bool copy_partial(String *dest, String src){return(copy_partial_ss(dest,src));} -FSTRING_INLINE int32_t copy(char *dest, char *src){return(copy_cc(dest,src));} +FSTRING_INLINE String make_string(void *str, i32_4tech size, i32_4tech mem_size){return(make_string_cap(str,size,mem_size));} +FSTRING_INLINE String substr(String str, i32_4tech start){return(substr_tail(str,start));} +FSTRING_LINK b32_4tech match(char *a, char *b){return(match_cc(a,b));} +FSTRING_LINK b32_4tech match(String a, char *b){return(match_sc(a,b));} +FSTRING_INLINE b32_4tech match(char *a, String b){return(match_cs(a,b));} +FSTRING_LINK b32_4tech match(String a, String b){return(match_ss(a,b));} +FSTRING_LINK b32_4tech match_part(char *a, char *b, i32_4tech *len){return(match_part_ccl(a,b,len));} +FSTRING_LINK b32_4tech match_part(String a, char *b, i32_4tech *len){return(match_part_scl(a,b,len));} +FSTRING_INLINE b32_4tech match_part(char *a, char *b){return(match_part_cc(a,b));} +FSTRING_INLINE b32_4tech match_part(String a, char *b){return(match_part_sc(a,b));} +FSTRING_LINK b32_4tech match_part(char *a, String b){return(match_part_cs(a,b));} +FSTRING_LINK b32_4tech match_part(String a, String b){return(match_part_ss(a,b));} +FSTRING_LINK b32_4tech match_insensitive(char *a, char *b){return(match_insensitive_cc(a,b));} +FSTRING_LINK b32_4tech match_insensitive(String a, char *b){return(match_insensitive_sc(a,b));} +FSTRING_INLINE b32_4tech match_insensitive(char *a, String b){return(match_insensitive_cs(a,b));} +FSTRING_LINK b32_4tech match_insensitive(String a, String b){return(match_insensitive_ss(a,b));} +FSTRING_LINK b32_4tech match_part_insensitive(char *a, char *b, i32_4tech *len){return(match_part_insensitive_ccl(a,b,len));} +FSTRING_LINK b32_4tech match_part_insensitive(String a, char *b, i32_4tech *len){return(match_part_insensitive_scl(a,b,len));} +FSTRING_INLINE b32_4tech match_part_insensitive(char *a, char *b){return(match_part_insensitive_cc(a,b));} +FSTRING_INLINE b32_4tech match_part_insensitive(String a, char *b){return(match_part_insensitive_sc(a,b));} +FSTRING_LINK b32_4tech match_part_insensitive(char *a, String b){return(match_part_insensitive_cs(a,b));} +FSTRING_LINK b32_4tech match_part_insensitive(String a, String b){return(match_part_insensitive_ss(a,b));} +FSTRING_LINK i32_4tech compare(char *a, char *b){return(compare_cc(a,b));} +FSTRING_LINK i32_4tech compare(String a, char *b){return(compare_sc(a,b));} +FSTRING_INLINE i32_4tech compare(char *a, String b){return(compare_cs(a,b));} +FSTRING_LINK i32_4tech compare(String a, String b){return(compare_ss(a,b));} +FSTRING_LINK i32_4tech find(char *str, i32_4tech start, char character){return(find_c_char(str,start,character));} +FSTRING_LINK i32_4tech find(String str, i32_4tech start, char character){return(find_s_char(str,start,character));} +FSTRING_LINK i32_4tech rfind(String str, i32_4tech start, char character){return(rfind_s_char(str,start,character));} +FSTRING_LINK i32_4tech find(char *str, i32_4tech start, char *characters){return(find_c_chars(str,start,characters));} +FSTRING_LINK i32_4tech find(String str, i32_4tech start, char *characters){return(find_s_chars(str,start,characters));} +FSTRING_LINK i32_4tech find_substr(char *str, i32_4tech start, String seek){return(find_substr_c(str,start,seek));} +FSTRING_LINK i32_4tech find_substr(String str, i32_4tech start, String seek){return(find_substr_s(str,start,seek));} +FSTRING_LINK i32_4tech rfind_substr(String str, i32_4tech start, String seek){return(rfind_substr_s(str,start,seek));} +FSTRING_LINK i32_4tech find_substr_insensitive(char *str, i32_4tech start, String seek){return(find_substr_insensitive_c(str,start,seek));} +FSTRING_LINK i32_4tech find_substr_insensitive(String str, i32_4tech start, String seek){return(find_substr_insensitive_s(str,start,seek));} +FSTRING_INLINE b32_4tech has_substr(char *s, String seek){return(has_substr_c(s,seek));} +FSTRING_INLINE b32_4tech has_substr(String s, String seek){return(has_substr_s(s,seek));} +FSTRING_INLINE b32_4tech has_substr_insensitive(char *s, String seek){return(has_substr_insensitive_c(s,seek));} +FSTRING_INLINE b32_4tech has_substr_insensitive(String s, String seek){return(has_substr_insensitive_s(s,seek));} +FSTRING_LINK i32_4tech copy_fast_unsafe(char *dest, char *src){return(copy_fast_unsafe_cc(dest,src));} +FSTRING_LINK i32_4tech copy_fast_unsafe(char *dest, String src){return(copy_fast_unsafe_cs(dest,src));} +FSTRING_LINK b32_4tech copy_checked(String *dest, String src){return(copy_checked_ss(dest,src));} +FSTRING_LINK b32_4tech copy_partial(String *dest, char *src){return(copy_partial_sc(dest,src));} +FSTRING_LINK b32_4tech copy_partial(String *dest, String src){return(copy_partial_ss(dest,src));} +FSTRING_INLINE i32_4tech copy(char *dest, char *src){return(copy_cc(dest,src));} FSTRING_INLINE void copy(String *dest, String src){return(copy_ss(dest,src));} FSTRING_INLINE void copy(String *dest, char *src){return(copy_sc(dest,src));} -FSTRING_LINK fstr_bool append_checked(String *dest, String src){return(append_checked_ss(dest,src));} -FSTRING_LINK fstr_bool append_partial(String *dest, char *src){return(append_partial_sc(dest,src));} -FSTRING_LINK fstr_bool append_partial(String *dest, String src){return(append_partial_ss(dest,src));} -FSTRING_LINK fstr_bool append(String *dest, char c){return(append_s_char(dest,c));} -FSTRING_INLINE fstr_bool append(String *dest, String src){return(append_ss(dest,src));} -FSTRING_INLINE fstr_bool append(String *dest, char *src){return(append_sc(dest,src));} +FSTRING_LINK b32_4tech append_checked(String *dest, String src){return(append_checked_ss(dest,src));} +FSTRING_LINK b32_4tech append_partial(String *dest, char *src){return(append_partial_sc(dest,src));} +FSTRING_LINK b32_4tech append_partial(String *dest, String src){return(append_partial_ss(dest,src));} +FSTRING_LINK b32_4tech append(String *dest, char c){return(append_s_char(dest,c));} +FSTRING_INLINE b32_4tech append(String *dest, String src){return(append_ss(dest,src));} +FSTRING_INLINE b32_4tech append(String *dest, char *src){return(append_sc(dest,src));} FSTRING_LINK void to_lower(char *src, char *dst){return(to_lower_cc(src,dst));} FSTRING_LINK void to_lower(String *dst, String src){return(to_lower_ss(dst,src));} FSTRING_LINK void to_lower(String *str){return(to_lower_s(str));} @@ -239,28 +258,24 @@ FSTRING_LINK void to_upper(char *src, char *dst){return(to_uppe FSTRING_LINK void to_upper(String *dst, String src){return(to_upper_ss(dst,src));} FSTRING_LINK void to_upper(String *str){return(to_upper_s(str));} FSTRING_LINK void to_camel(char *src, char *dst){return(to_camel_cc(src,dst));} -FSTRING_LINK int32_t str_is_int(char *str){return(str_is_int_c(str));} -FSTRING_LINK fstr_bool str_is_int(String str){return(str_is_int_s(str));} -FSTRING_LINK int32_t str_to_int(char *str){return(str_to_int_c(str));} -FSTRING_LINK int32_t str_to_int(String str){return(str_to_int_s(str));} -FSTRING_LINK int32_t reverse_seek_slash(String str, int32_t pos){return(reverse_seek_slash_pos(str,pos));} -FSTRING_LINK fstr_bool set_last_folder(String *dir, char *folder_name, char slash){return(set_last_folder_sc(dir,folder_name,slash));} -FSTRING_LINK fstr_bool set_last_folder(String *dir, String folder_name, char slash){return(set_last_folder_ss(dir,folder_name,slash));} -FSTRING_LINK fstr_bool string_set_match(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index){return(string_set_match_table(str_set,item_size,count,str,match_index));} +FSTRING_LINK i32_4tech str_is_int(char *str){return(str_is_int_c(str));} +FSTRING_LINK b32_4tech str_is_int(String str){return(str_is_int_s(str));} +FSTRING_LINK i32_4tech str_to_int(char *str){return(str_to_int_c(str));} +FSTRING_LINK i32_4tech str_to_int(String str){return(str_to_int_s(str));} +FSTRING_LINK i32_4tech reverse_seek_slash(String str, i32_4tech pos){return(reverse_seek_slash_pos(str,pos));} +FSTRING_LINK b32_4tech set_last_folder(String *dir, char *folder_name, char slash){return(set_last_folder_sc(dir,folder_name,slash));} +FSTRING_LINK b32_4tech set_last_folder(String *dir, String folder_name, char slash){return(set_last_folder_ss(dir,folder_name,slash));} +FSTRING_LINK b32_4tech string_set_match(void *str_set, i32_4tech item_size, i32_4tech count, String str, i32_4tech *match_index){return(string_set_match_table(str_set,item_size,count,str,match_index));} #endif -#if !defined(FSTRING_GUARD) -static String null_string = {0}; -#endif - // // Character Helpers // #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_slash(char c) { return (c == '\\' || c == '/'); @@ -268,7 +283,7 @@ char_is_slash(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_upper(char c) { return (c >= 'A' && c <= 'Z'); @@ -276,7 +291,7 @@ char_is_upper(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_lower(char c) { return (c >= 'a' && c <= 'z'); @@ -284,7 +299,7 @@ char_is_lower(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE char +FSTRING_INLINE char char_to_upper(char c) { return (c >= 'a' && c <= 'z') ? c + (char)('A' - 'a') : c; @@ -292,7 +307,7 @@ char_to_upper(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE char +FSTRING_INLINE char char_to_lower(char c) { return (c >= 'A' && c <= 'Z') ? c - (char)('A' - 'a') : c; @@ -300,7 +315,7 @@ char_to_lower(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_whitespace(char c) { return (c == ' ' || c == '\n' || c == '\r' || c == '\t'); @@ -308,7 +323,7 @@ char_is_whitespace(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_alpha_numeric(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_'); @@ -316,7 +331,7 @@ char_is_alpha_numeric(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_alpha_numeric_true(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'); @@ -324,7 +339,7 @@ char_is_alpha_numeric_true(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_alpha(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'); @@ -332,7 +347,7 @@ char_is_alpha(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_alpha_true(char c) { return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); @@ -340,7 +355,7 @@ char_is_alpha_true(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_hex(char c) { return (c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'); @@ -348,7 +363,7 @@ char_is_hex(char c) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech char_is_numeric(char c) { return (c >= '0' && c <= '9'); @@ -362,8 +377,8 @@ char_is_numeric(char c) #if !defined(FSTRING_GUARD) - FSTRING_INLINE String -make_string_cap(void *str, int32_t size, int32_t mem_size){ +FSTRING_INLINE String +make_string_cap(void *str, i32_4tech size, i32_4tech mem_size){ String result; result.str = (char*)str; result.size = size; @@ -373,8 +388,8 @@ make_string_cap(void *str, int32_t size, int32_t mem_size){ #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE String -make_string(void *str, int32_t size){ +FSTRING_INLINE String +make_string(void *str, i32_4tech size){ String result; result.str = (char*)str; result.size = size; @@ -384,17 +399,17 @@ make_string(void *str, int32_t size){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech str_size(char *str) { - int32_t i = 0; + i32_4tech i = 0; while (str[i]) ++i; return(i); } #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE String +FSTRING_INLINE String make_string_slowly(void *str) { String result; @@ -407,8 +422,8 @@ make_string_slowly(void *str) #if !defined(FSTRING_GUARD) - FSTRING_INLINE String -substr_tail(String str, int32_t start) +FSTRING_INLINE String +substr_tail(String str, i32_4tech start) { String result; result.str = str.str + start; @@ -419,8 +434,8 @@ substr_tail(String str, int32_t start) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE String -substr(String str, int32_t start, int32_t size) +FSTRING_INLINE String +substr(String str, i32_4tech start, i32_4tech size) { String result; result.str = str.str + start; @@ -434,11 +449,11 @@ substr(String str, int32_t start, int32_t size) #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String skip_whitespace(String str) { String result = {0}; - int32_t i = 0; + i32_4tech i = 0; for (; i < str.size && char_is_whitespace(str.str[i]); ++i); result = substr(str, i, str.size - i); return(result); @@ -446,11 +461,11 @@ skip_whitespace(String str) #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String chop_whitespace(String str) { String result = {0}; - int32_t i = str.size; + i32_4tech i = str.size; for (; i > 0 && char_is_whitespace(str.str[i-1]); --i); result = substr(str, 0, i); return(result); @@ -458,7 +473,7 @@ chop_whitespace(String str) #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String skip_chop_whitespace(String str) { str = skip_whitespace(str); @@ -468,7 +483,7 @@ skip_chop_whitespace(String str) #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE String +FSTRING_INLINE String tailstr(String str) { String result; @@ -486,9 +501,9 @@ tailstr(String str) #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_cc(char *a, char *b){ - for (int32_t i = 0;; ++i){ + for (i32_4tech i = 0;; ++i){ if (a[i] != b[i]){ return 0; } @@ -501,9 +516,9 @@ match_cc(char *a, char *b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_sc(String a, char *b){ - int32_t i = 0; + i32_4tech i = 0; for (; i < a.size; ++i){ if (a.str[i] != b[i]){ return 0; @@ -518,7 +533,7 @@ match_sc(String a, char *b){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech match_cs(char *a, String b){ return(match_sc(b,a)); } @@ -526,12 +541,12 @@ match_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_ss(String a, String b){ if (a.size != b.size){ return 0; } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (a.str[i] != b.str[i]){ return 0; } @@ -542,9 +557,9 @@ match_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -match_part_ccl(char *a, char *b, int32_t *len){ - int32_t i; +FSTRING_LINK b32_4tech +match_part_ccl(char *a, char *b, i32_4tech *len){ + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (a[i] != b[i]){ return 0; @@ -557,9 +572,9 @@ match_part_ccl(char *a, char *b, int32_t *len){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -match_part_scl(String a, char *b, int32_t *len){ - int32_t i; +FSTRING_LINK b32_4tech +match_part_scl(String a, char *b, i32_4tech *len){ + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (a.str[i] != b[i] || i == a.size){ return 0; @@ -572,27 +587,27 @@ match_part_scl(String a, char *b, int32_t *len){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech match_part_cc(char *a, char *b){ - int32_t x; + i32_4tech x; return match_part_ccl(a,b,&x); } #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech match_part_sc(String a, char *b){ - int32_t x; + i32_4tech x; return match_part_scl(a,b,&x); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_part_cs(char *a, String b){ - for (int32_t i = 0; i != b.size; ++i){ + for (i32_4tech i = 0; i != b.size; ++i){ if (a[i] != b.str[i]){ return 0; } @@ -603,12 +618,12 @@ match_part_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_part_ss(String a, String b){ if (a.size < b.size){ return 0; } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (a.str[i] != b.str[i]){ return 0; } @@ -619,9 +634,9 @@ match_part_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_insensitive_cc(char *a, char *b){ - for (int32_t i = 0;; ++i){ + for (i32_4tech i = 0;; ++i){ if (char_to_upper(a[i]) != char_to_upper(b[i])){ return 0; @@ -635,9 +650,9 @@ match_insensitive_cc(char *a, char *b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_insensitive_sc(String a, char *b){ - int32_t i = 0; + i32_4tech i = 0; for (; i < a.size; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b[i])){ @@ -653,7 +668,7 @@ match_insensitive_sc(String a, char *b){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech match_insensitive_cs(char *a, String b){ return match_insensitive_sc(b,a); } @@ -661,12 +676,12 @@ match_insensitive_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_insensitive_ss(String a, String b){ if (a.size != b.size){ return 0; } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b.str[i])){ return 0; @@ -678,9 +693,9 @@ match_insensitive_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -match_part_insensitive_ccl(char *a, char *b, int32_t *len){ - int32_t i; +FSTRING_LINK b32_4tech +match_part_insensitive_ccl(char *a, char *b, i32_4tech *len){ + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (char_to_upper(a[i]) != char_to_upper(b[i])){ return 0; @@ -693,9 +708,9 @@ match_part_insensitive_ccl(char *a, char *b, int32_t *len){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -match_part_insensitive_scl(String a, char *b, int32_t *len){ - int32_t i; +FSTRING_LINK b32_4tech +match_part_insensitive_scl(String a, char *b, i32_4tech *len){ + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b[i]) || i == a.size){ @@ -709,27 +724,27 @@ match_part_insensitive_scl(String a, char *b, int32_t *len){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech match_part_insensitive_cc(char *a, char *b){ - int32_t x; + i32_4tech x; return match_part_insensitive_ccl(a,b,&x); } #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech match_part_insensitive_sc(String a, char *b){ - int32_t x; + i32_4tech x; return match_part_insensitive_scl(a,b,&x); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_part_insensitive_cs(char *a, String b){ - for (int32_t i = 0; i != b.size; ++i){ + for (i32_4tech i = 0; i != b.size; ++i){ if (char_to_upper(a[i]) != char_to_upper(b.str[i])){ return(0); } @@ -740,12 +755,12 @@ match_part_insensitive_cs(char *a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech match_part_insensitive_ss(String a, String b){ if (a.size < b.size){ return(0); } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b.str[i])){ return(0); } @@ -756,9 +771,9 @@ match_part_insensitive_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech compare_cc(char *a, char *b){ - int32_t i = 0, r = 0; + i32_4tech i = 0, r = 0; while (a[i] == b[i] && a[i] != 0){ ++i; } @@ -769,9 +784,9 @@ compare_cc(char *a, char *b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech compare_sc(String a, char *b){ - int32_t i = 0, r = 0; + i32_4tech i = 0, r = 0; while (i < a.size && a.str[i] == b[i]){ ++i; } @@ -792,19 +807,19 @@ compare_sc(String a, char *b){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE int32_t +FSTRING_INLINE i32_4tech compare_cs(char *a, String b){ - int32_t r = -compare_sc(b,a); + i32_4tech r = -compare_sc(b,a); return(r); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech compare_ss(String a, String b){ - int32_t i = 0, r = 0; - int32_t m = a.size; + i32_4tech i = 0, r = 0; + i32_4tech m = a.size; if (b.size < m){ m = b.size; } @@ -829,9 +844,9 @@ compare_ss(String a, String b){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_c_char(char *str, int32_t start, char character){ - int32_t i = start; +FSTRING_LINK i32_4tech +find_c_char(char *str, i32_4tech start, char character){ + i32_4tech i = start; while (str[i] != character && str[i] != 0) ++i; return(i); } @@ -839,9 +854,9 @@ find_c_char(char *str, int32_t start, char character){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_s_char(String str, int32_t start, char character){ - int32_t i = start; +FSTRING_LINK i32_4tech +find_s_char(String str, i32_4tech start, char character){ + i32_4tech i = start; while (i < str.size && str.str[i] != character) ++i; return(i); } @@ -849,9 +864,9 @@ find_s_char(String str, int32_t start, char character){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -rfind_s_char(String str, int32_t start, char character){ - int32_t i = start; +FSTRING_LINK i32_4tech +rfind_s_char(String str, i32_4tech start, char character){ + i32_4tech i = start; while (i >= 0 && str.str[i] != character) --i; return(i); } @@ -859,9 +874,9 @@ rfind_s_char(String str, int32_t start, char character){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_c_chars(char *str, int32_t start, char *characters){ - int32_t i = start, j; +FSTRING_LINK i32_4tech +find_c_chars(char *str, i32_4tech start, char *characters){ + i32_4tech i = start, j; while (str[i] != 0){ for (j = 0; characters[j]; ++j){ if (str[i] == characters[j]){ @@ -876,9 +891,9 @@ find_c_chars(char *str, int32_t start, char *characters){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_s_chars(String str, int32_t start, char *characters){ - int32_t i = start, j; +FSTRING_LINK i32_4tech +find_s_chars(String str, i32_4tech start, char *characters){ + i32_4tech i = start, j; while (i < str.size){ for (j = 0; characters[j]; ++j){ if (str.str[i] == characters[j]){ @@ -893,10 +908,10 @@ find_s_chars(String str, int32_t start, char *characters){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_substr_c(char *str, int32_t start, String seek){ - int32_t i, j, k; - fstr_bool hit; +FSTRING_LINK i32_4tech +find_substr_c(char *str, i32_4tech start, String seek){ + i32_4tech i, j, k; + b32_4tech hit; if (seek.size == 0){ i = str_size(str); @@ -922,10 +937,10 @@ find_substr_c(char *str, int32_t start, String seek){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_substr_s(String str, int32_t start, String seek){ - int32_t stop_at, i, j, k; - fstr_bool hit; +FSTRING_LINK i32_4tech +find_substr_s(String str, i32_4tech start, String seek){ + i32_4tech stop_at, i, j, k; + b32_4tech hit; if (seek.size == 0){ return str.size; @@ -951,10 +966,10 @@ find_substr_s(String str, int32_t start, String seek){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -rfind_substr_s(String str, int32_t start, String seek){ - int32_t i, j, k; - fstr_bool hit; +FSTRING_LINK i32_4tech +rfind_substr_s(String str, i32_4tech start, String seek){ + i32_4tech i, j, k; + b32_4tech hit; if (seek.size == 0){ return -1; @@ -982,10 +997,10 @@ rfind_substr_s(String str, int32_t start, String seek){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_substr_insensitive_c(char *str, int32_t start, String seek){ - int32_t i, j, k; - fstr_bool hit; +FSTRING_LINK i32_4tech +find_substr_insensitive_c(char *str, i32_4tech start, String seek){ + i32_4tech i, j, k; + b32_4tech hit; char a_upper, b_upper; if (seek.size == 0){ @@ -1013,11 +1028,11 @@ find_substr_insensitive_c(char *str, int32_t start, String seek){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -find_substr_insensitive_s(String str, int32_t start, String seek){ - int32_t i, j, k; - int32_t stop_at; - fstr_bool hit; +FSTRING_LINK i32_4tech +find_substr_insensitive_s(String str, i32_4tech start, String seek){ + i32_4tech i, j, k; + i32_4tech stop_at; + b32_4tech hit; char a_upper, b_upper; if (seek.size == 0){ @@ -1046,7 +1061,7 @@ find_substr_insensitive_s(String str, int32_t start, String seek){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech has_substr_c(char *s, String seek){ return (s[find_substr_c(s, 0, seek)] != 0); } @@ -1054,7 +1069,7 @@ has_substr_c(char *s, String seek){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech has_substr_s(String s, String seek){ return (find_substr_s(s, 0, seek) < s.size); } @@ -1062,7 +1077,7 @@ has_substr_s(String s, String seek){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech has_substr_insensitive_c(char *s, String seek){ return (s[find_substr_insensitive_c(s, 0, seek)] != 0); } @@ -1070,7 +1085,7 @@ has_substr_insensitive_c(char *s, String seek){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech has_substr_insensitive_s(String s, String seek){ return (find_substr_insensitive_s(s, 0, seek) < s.size); } @@ -1082,7 +1097,7 @@ has_substr_insensitive_s(String s, String seek){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech copy_fast_unsafe_cc(char *dest, char *src){ char *start = dest; while (*src != 0){ @@ -1090,15 +1105,15 @@ copy_fast_unsafe_cc(char *dest, char *src){ ++dest; ++src; } - return (int32_t)(dest - start); + return (i32_4tech)(dest - start); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech copy_fast_unsafe_cs(char *dest, String src){ - int32_t i = 0; + i32_4tech i = 0; while (i != src.size){ dest[i] = src.str[i]; ++i; @@ -1109,10 +1124,10 @@ copy_fast_unsafe_cs(char *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech copy_checked_ss(String *dest, String src){ char *dest_str; - int32_t i; + i32_4tech i; if (dest->memory_size < src.size){ return 0; } @@ -1127,10 +1142,10 @@ copy_checked_ss(String *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech copy_partial_sc(String *dest, char *src){ - int32_t i = 0; - int32_t memory_size = dest->memory_size; + i32_4tech i = 0; + i32_4tech memory_size = dest->memory_size; char *dest_str = dest->str; while (src[i] != 0){ if (i >= memory_size){ @@ -1146,16 +1161,16 @@ copy_partial_sc(String *dest, char *src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech copy_partial_ss(String *dest, String src){ char *dest_str = dest->str; - int32_t memory_size = dest->memory_size; - fstr_bool result = 0; + i32_4tech memory_size = dest->memory_size; + b32_4tech result = 0; if (memory_size >= src.size){ result = 1; memory_size = src.size; } - for (int32_t i = 0; i < memory_size; ++i){ + for (i32_4tech i = 0; i < memory_size; ++i){ dest_str[i] = src.str[i]; } dest->size = memory_size; @@ -1165,7 +1180,7 @@ copy_partial_ss(String *dest, String src){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE int32_t +FSTRING_INLINE i32_4tech copy_cc(char *dest, char *src){ return copy_fast_unsafe_cc(dest, src); } @@ -1173,7 +1188,7 @@ copy_cc(char *dest, char *src){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE void +FSTRING_INLINE void copy_ss(String *dest, String src){ copy_checked_ss(dest, src); } @@ -1181,7 +1196,7 @@ copy_ss(String *dest, String src){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE void +FSTRING_INLINE void copy_sc(String *dest, char *src){ copy_partial_sc(dest, src); } @@ -1189,11 +1204,11 @@ copy_sc(String *dest, char *src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech append_checked_ss(String *dest, String src){ String end; end = tailstr(*dest); - fstr_bool result = copy_checked_ss(&end, src); + b32_4tech result = copy_checked_ss(&end, src); // NOTE(allen): This depends on end.size still being 0 if // the check failed and no coppy occurred. dest->size += end.size; @@ -1203,10 +1218,10 @@ append_checked_ss(String *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech append_partial_sc(String *dest, char *src){ String end = tailstr(*dest); - fstr_bool result = copy_partial_sc(&end, src); + b32_4tech result = copy_partial_sc(&end, src); dest->size += end.size; return result; } @@ -1214,10 +1229,10 @@ append_partial_sc(String *dest, char *src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech append_partial_ss(String *dest, String src){ String end = tailstr(*dest); - fstr_bool result = copy_partial_ss(&end, src); + b32_4tech result = copy_partial_ss(&end, src); dest->size += end.size; return result; } @@ -1225,9 +1240,9 @@ append_partial_ss(String *dest, String src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech append_s_char(String *dest, char c){ - fstr_bool result = 0; + b32_4tech result = 0; if (dest->size < dest->memory_size){ dest->str[dest->size++] = c; result = 1; @@ -1238,7 +1253,7 @@ append_s_char(String *dest, char c){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech append_ss(String *dest, String src){ return append_partial_ss(dest, src); } @@ -1246,16 +1261,16 @@ append_ss(String *dest, String src){ #if !defined(FSTRING_GUARD) - FSTRING_INLINE fstr_bool +FSTRING_INLINE b32_4tech append_sc(String *dest, char *src){ return append_partial_sc(dest, src); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech terminate_with_null(String *str){ - fstr_bool result = 0; + b32_4tech result = 0; if (str->size < str->memory_size){ str->str[str->size] = 0; result = 1; @@ -1265,11 +1280,11 @@ terminate_with_null(String *str){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -append_padding(String *dest, char c, int32_t target_size){ - fstr_bool result = 1; - int32_t offset = target_size - dest->size; - int32_t r = 0; +FSTRING_LINK b32_4tech +append_padding(String *dest, char c, i32_4tech target_size){ + b32_4tech result = 1; + i32_4tech offset = target_size - dest->size; + i32_4tech r = 0; if (offset > 0){ for (r = 0; r < offset; ++r){ if (append_s_char(dest, c) == 0){ @@ -1288,10 +1303,10 @@ append_padding(String *dest, char c, int32_t target_size){ // #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void replace_char(String *str, char replace, char with){ char *s = str->str; - int32_t i = 0; + i32_4tech i = 0; for (i = 0; i < str->size; ++i, ++s){ if (*s == replace) *s = with; } @@ -1300,7 +1315,7 @@ replace_char(String *str, char replace, char with){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void to_lower_cc(char *src, char *dst){ for (; *src != 0; ++src){ *dst++ = char_to_lower(*src); @@ -1311,10 +1326,10 @@ to_lower_cc(char *src, char *dst){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void to_lower_ss(String *dst, String src){ - int32_t i = 0; - int32_t size = src.size; + i32_4tech i = 0; + i32_4tech size = src.size; char *c = src.str; char *d = dst->str; @@ -1329,10 +1344,10 @@ to_lower_ss(String *dst, String src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void to_lower_s(String *str){ - int32_t i = 0; - int32_t size = str->size; + i32_4tech i = 0; + i32_4tech size = str->size; char *c = str->str; for (; i < size; ++c, ++i){ *c = char_to_lower(*c); @@ -1342,7 +1357,7 @@ to_lower_s(String *str){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void to_upper_cc(char *src, char *dst){ for (; *src != 0; ++src){ *dst++ = char_to_upper(*src); @@ -1353,10 +1368,10 @@ to_upper_cc(char *src, char *dst){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void to_upper_ss(String *dst, String src){ - int32_t i = 0; - int32_t size = src.size; + i32_4tech i = 0; + i32_4tech size = src.size; char *c = src.str; char *d = dst->str; @@ -1371,10 +1386,10 @@ to_upper_ss(String *dst, String src){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void to_upper_s(String *str){ - int32_t i = 0; - int32_t size = str->size; + i32_4tech i = 0; + i32_4tech size = str->size; char *c = str->str; for (; i < size; ++c, ++i){ *c = char_to_upper(*c); @@ -1384,10 +1399,10 @@ to_upper_s(String *str){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK void +FSTRING_LINK void to_camel_cc(char *src, char *dst){ char *c, ch; - int32_t is_first = 1; + i32_4tech is_first = 1; for (c = src; *c != 0; ++c){ ch = *c; if (char_is_alpha_numeric_true(ch)){ @@ -1414,9 +1429,9 @@ to_camel_cc(char *src, char *dst){ // #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -int_to_str_size(int32_t x){ - int32_t size = 1; +FSTRING_LINK i32_4tech +int_to_str_size(i32_4tech x){ + i32_4tech size = 1; if (x < 0){ size = 2; } @@ -1430,13 +1445,13 @@ int_to_str_size(int32_t x){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -int_to_str(String *dest, int32_t x){ - fstr_bool result = 1; +FSTRING_LINK b32_4tech +int_to_str(String *dest, i32_4tech x){ + b32_4tech result = 1; char *str = dest->str; - int32_t memory_size = dest->memory_size; - int32_t size, i, j; - fstr_bool negative; + i32_4tech memory_size = dest->memory_size; + i32_4tech size, i, j; + b32_4tech negative; if (x == 0){ str[0] = '0'; @@ -1460,8 +1475,7 @@ int_to_str(String *dest, int32_t x){ str[size++] = (char)('0' + i); } if (result){ - // NOTE(allen): Start i = 0 if not negative, start i = 1 if is negative - // because - should not be flipped if it is negative :) + // NOTE(allen): Start i = 0 if not negative, start i = 1 if is negative because - should not be flipped if it is negative :) for (i = negative, j = size-1; i < j; ++i, --j){ char temp = str[i]; str[i] = str[j]; @@ -1478,10 +1492,10 @@ int_to_str(String *dest, int32_t x){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -append_int_to_str(String *dest, int32_t x){ +FSTRING_LINK b32_4tech +append_int_to_str(String *dest, i32_4tech x){ String last_part = tailstr(*dest); - fstr_bool result = int_to_str(&last_part, x); + b32_4tech result = int_to_str(&last_part, x); if (result){ dest->size += last_part.size; } @@ -1490,9 +1504,9 @@ append_int_to_str(String *dest, int32_t x){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech u64_to_str_size(uint64_t x){ - int32_t size; + i32_4tech size; if (x < 0){ size = 0; } @@ -1509,12 +1523,12 @@ u64_to_str_size(uint64_t x){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech u64_to_str(String *dest, uint64_t x){ - fstr_bool result = 1; + b32_4tech result = 1; char *str = dest->str; - int32_t memory_size = dest->memory_size; - int32_t size, i, j; + i32_4tech memory_size = dest->memory_size; + i32_4tech size, i, j; if (x == 0){ str[0] = '0'; @@ -1548,10 +1562,10 @@ u64_to_str(String *dest, uint64_t x){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech append_u64_to_str(String *dest, uint64_t x){ String last_part = tailstr(*dest); - fstr_bool result = u64_to_str(&last_part, x); + b32_4tech result = u64_to_str(&last_part, x); if (result){ dest->size += last_part.size; } @@ -1559,11 +1573,11 @@ append_u64_to_str(String *dest, uint64_t x){ } #endif -#ifndef FSTRING_GUARD +#if !defined(FSTRING_GUARD) typedef struct Float_To_Str_Variables{ - fstr_bool negative; - int32_t int_part; - int32_t dec_part; + b32_4tech negative; + i32_4tech int_part; + i32_4tech dec_part; } Float_To_Str_Variables; static Float_To_Str_Variables @@ -1575,27 +1589,26 @@ get_float_vars(float x){ x = -x; } - vars.int_part = (int32_t)(x); - vars.dec_part = (int32_t)((x - vars.int_part) * 1000); + vars.int_part = (i32_4tech)(x); + vars.dec_part = (i32_4tech)((x - vars.int_part) * 1000); return(vars); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech float_to_str_size(float x){ Float_To_Str_Variables vars = get_float_vars(x); - int32_t size = - vars.negative + int_to_str_size(vars.int_part) + 1 + int_to_str_size(vars.dec_part); + i32_4tech size = vars.negative + int_to_str_size(vars.int_part) + 1 + int_to_str_size(vars.dec_part); return(size); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech append_float_to_str(String *dest, float x){ - fstr_bool result = 1; + b32_4tech result = 1; Float_To_Str_Variables vars = get_float_vars(x); if (vars.negative){ @@ -1611,9 +1624,9 @@ append_float_to_str(String *dest, float x){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech float_to_str(String *dest, float x){ - fstr_bool result = 1; + b32_4tech result = 1; dest->size = 0; append_float_to_str(dest, x); return(result); @@ -1622,9 +1635,9 @@ float_to_str(String *dest, float x){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech str_is_int_c(char *str){ - fstr_bool result = 1; + b32_4tech result = 1; for (; *str; ++str){ if (!char_is_numeric(*str)){ result = 0; @@ -1637,10 +1650,10 @@ str_is_int_c(char *str){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech str_is_int_s(String str){ - fstr_bool result = 1; - for (int32_t i = 0; i < str.size; ++i){ + b32_4tech result = 1; + for (i32_4tech i = 0; i < str.size; ++i){ if (!char_is_numeric(str.str[i])){ result = 0; break; @@ -1652,9 +1665,9 @@ str_is_int_s(String str){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech str_to_int_c(char *str){ - int32_t x = 0; + i32_4tech x = 0; for (; *str; ++str){ if (*str >= '0' && *str <= '9'){ x *= 10; @@ -1671,9 +1684,9 @@ str_to_int_c(char *str){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech str_to_int_s(String str){ - int32_t x, i; + i32_4tech x, i; if (str.size == 0){ x = 0; } @@ -1689,9 +1702,9 @@ str_to_int_s(String str){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t +FSTRING_LINK i32_4tech hexchar_to_int(char c){ - int32_t x = 0; + i32_4tech x = 0; if (c >= '0' && c <= '9'){ x = c-'0'; } @@ -1706,17 +1719,17 @@ hexchar_to_int(char c){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK char -int_to_hexchar(int32_t x){ +FSTRING_LINK char +int_to_hexchar(i32_4tech x){ return (x<10)?((char)x+'0'):((char)x+'a'-10); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK uint32_t +FSTRING_LINK u32_4tech hexstr_to_int(String str){ - uint32_t x; - int32_t i; + u32_4tech x; + i32_4tech i; if (str.size == 0){ x = 0; } @@ -1732,10 +1745,10 @@ hexstr_to_int(String str){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -color_to_hexstr(String *s, uint32_t color){ - fstr_bool result = 0; - int32_t i; +FSTRING_LINK b32_4tech +color_to_hexstr(String *s, u32_4tech color){ + b32_4tech result = 0; + i32_4tech i; if (s->memory_size == 7 || s->memory_size == 8){ result = 1; @@ -1761,19 +1774,19 @@ color_to_hexstr(String *s, uint32_t color){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -hexstr_to_color(String s, uint32_t *out){ - fstr_bool result = 0; - uint32_t color = 0; +FSTRING_LINK b32_4tech +hexstr_to_color(String s, u32_4tech *out){ + b32_4tech result = 0; + u32_4tech color = 0; if (s.size == 6){ result = 1; - color = (uint32_t)hexstr_to_int(s); + color = (u32_4tech)hexstr_to_int(s); color |= (0xFF << 24); *out = color; } else if (s.size == 8){ result = 1; - color = (uint32_t)hexstr_to_int(s); + color = (u32_4tech)hexstr_to_int(s); *out = color; } return(result); @@ -1786,9 +1799,9 @@ hexstr_to_color(String s, uint32_t *out){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK int32_t -reverse_seek_slash_pos(String str, int32_t pos){ - int32_t i = str.size - 1 - pos; +FSTRING_LINK i32_4tech +reverse_seek_slash_pos(String str, i32_4tech pos){ + i32_4tech i = str.size - 1 - pos; while (i >= 0 && !char_is_slash(str.str[i])){ --i; } @@ -1797,21 +1810,21 @@ reverse_seek_slash_pos(String str, int32_t pos){ #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE int32_t +FSTRING_INLINE i32_4tech reverse_seek_slash(String str){ return(reverse_seek_slash_pos(str, 0)); } #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE String +FSTRING_INLINE String front_of_directory(String dir){ return substr_tail(dir, reverse_seek_slash(dir) + 1); } #endif #if !defined(FSTRING_GUARD) - FSTRING_INLINE String +FSTRING_INLINE String path_of_directory(String dir){ return substr(dir, 0, reverse_seek_slash(dir) + 1); } @@ -1819,10 +1832,10 @@ path_of_directory(String dir){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech set_last_folder_sc(String *dir, char *folder_name, char slash){ - fstr_bool result = 0; - int32_t size = reverse_seek_slash(*dir) + 1; + b32_4tech result = 0; + i32_4tech size = reverse_seek_slash(*dir) + 1; dir->size = size; if (append_sc(dir, folder_name)){ if (append_s_char(dir, slash)){ @@ -1838,10 +1851,10 @@ set_last_folder_sc(String *dir, char *folder_name, char slash){ #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech set_last_folder_ss(String *dir, String folder_name, char slash){ - fstr_bool result = 0; - int32_t size = reverse_seek_slash(*dir) + 1; + b32_4tech result = 0; + i32_4tech size = reverse_seek_slash(*dir) + 1; dir->size = size; if (append_ss(dir, folder_name)){ if (append_s_char(dir, slash)){ @@ -1856,9 +1869,9 @@ set_last_folder_ss(String *dir, String folder_name, char slash){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String file_extension(String str){ - int32_t i; + i32_4tech i; for (i = str.size - 1; i >= 0; --i){ if (str.str[i] == '.') break; } @@ -1868,10 +1881,10 @@ file_extension(String str){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech remove_extension(String *str){ - fstr_bool result = 0; - int32_t i; + b32_4tech result = 0; + i32_4tech i; for (i = str->size - 1; i >= 0; --i){ if (str->str[i] == '.') break; } @@ -1884,10 +1897,10 @@ remove_extension(String *str){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool +FSTRING_LINK b32_4tech remove_last_folder(String *str){ - fstr_bool result = 0; - int32_t end = reverse_seek_slash_pos(*str, 1); + b32_4tech result = 0; + i32_4tech end = reverse_seek_slash_pos(*str, 1); if (end >= 0){ result = 1; str->size = end + 1; @@ -1899,10 +1912,10 @@ remove_last_folder(String *str){ // TODO(allen): Add hash-table extension to string sets. #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -string_set_match_table(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index){ - fstr_bool result = 0; - int32_t i = 0; +FSTRING_LINK b32_4tech +string_set_match_table(void *str_set, i32_4tech item_size, i32_4tech count, String str, i32_4tech *match_index){ + b32_4tech result = 0; + i32_4tech i = 0; uint8_t *ptr = (uint8_t*)str_set; for (; i < count; ++i, ptr += item_size){ if (match_ss(*(String*)ptr, str)){ @@ -1916,19 +1929,19 @@ string_set_match_table(void *str_set, int32_t item_size, int32_t count, String s #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK fstr_bool -string_set_match(String *str_set, int32_t count, String str, int32_t *match_index){ - fstr_bool result = string_set_match_table(str_set, sizeof(String), count, str, match_index); +FSTRING_LINK b32_4tech +string_set_match(String *str_set, i32_4tech count, String str, i32_4tech *match_index){ + b32_4tech result = string_set_match_table(str_set, sizeof(String), count, str, match_index); return(result); } #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String get_first_double_line(String source){ String line = {0}; - int32_t pos0 = find_substr_s(source, 0, make_lit_string("\n\n")); - int32_t pos1 = find_substr_s(source, 0, make_lit_string("\r\n\r\n")); + i32_4tech pos0 = find_substr_s(source, 0, make_lit_string("\n\n")); + i32_4tech pos1 = find_substr_s(source, 0, make_lit_string("\r\n\r\n")); if (pos1 < pos0){ pos0 = pos1; } @@ -1938,11 +1951,11 @@ get_first_double_line(String source){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String get_next_double_line(String source, String line){ String next = {0}; - int32_t pos = (int32_t)(line.str - source.str) + line.size; - int32_t start = 0, pos0 = 0, pos1 = 0; + i32_4tech pos = (i32_4tech)(line.str - source.str) + line.size; + i32_4tech start = 0, pos0 = 0, pos1 = 0; if (pos < source.size){ //Assert(source.str[pos] == '\n' || source.str[pos] == '\r'); @@ -1963,12 +1976,12 @@ get_next_double_line(String source, String line){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String get_next_word(String source, String prev_word){ String word = {0}; - int32_t pos0 = (int32_t)(prev_word.str - source.str) + prev_word.size; - int32_t pos1 = 0; + i32_4tech pos0 = (i32_4tech)(prev_word.str - source.str) + prev_word.size; + i32_4tech pos1 = 0; char c = 0; for (; pos0 < source.size; ++pos0){ @@ -1994,7 +2007,7 @@ get_next_word(String source, String prev_word){ #endif #if defined(FSTRING_IMPLEMENTATION) - FSTRING_LINK String +FSTRING_LINK String get_first_word(String source){ String start_str = make_string(source.str, 0); String word = get_next_word(source, start_str); @@ -2002,40 +2015,37 @@ get_first_word(String source){ } #endif +// TODO(allen): eliminate this. #ifndef FSTRING_EXPERIMENTAL #define FSTRING_EXPERIMENTAL // NOTE(allen): experimental section, things below here are // not promoted to public API level yet. -#ifndef ArrayCount -# define ArrayCount(a) ((sizeof(a))/sizeof(*a)) -#endif - typedef struct Absolutes{ String a[8]; - int32_t count; + i32_4tech count; } Absolutes; static void -get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){ +get_absolutes(String name, Absolutes *absolutes, b32_4tech implicit_first, b32_4tech implicit_last){ if (name.size != 0){ - int32_t count = 0; - int32_t max = ArrayCount(absolutes->a) - 1; + i32_4tech count = 0; + i32_4tech max = sizeof(absolutes->a)/sizeof(absolutes->a[0]) - 1; if (implicit_last) --max; String str; str.str = name.str; str.size = 0; str.memory_size = 0; - fstr_bool prev_was_wild = 0; + b32_4tech prev_was_wild = 0; if (implicit_first){ absolutes->a[count++] = str; prev_was_wild = 1; } - int32_t i; + i32_4tech i; for (i = 0; i < name.size; ++i){ if (name.str[i] == '*' && count < max){ if (!prev_was_wild){ @@ -2068,15 +2078,15 @@ get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_ } } -static fstr_bool -wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){ - fstr_bool r = 1; +static b32_4tech +wildcard_match_c(Absolutes *absolutes, char *x, i32_4tech case_sensitive){ + b32_4tech r = 1; if (absolutes->count > 0){ String *a = absolutes->a; - fstr_bool (*match_func)(char*, String); - fstr_bool (*match_part_func)(char*, String); + b32_4tech (*match_func)(char*, String); + b32_4tech (*match_part_func)(char*, String); if (case_sensitive){ match_func = match_cs; @@ -2129,8 +2139,8 @@ wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){ return(r); } -static fstr_bool -wildcard_match_s(Absolutes *absolutes, String x, int32_t case_sensitive){ +static b32_4tech +wildcard_match_s(Absolutes *absolutes, String x, i32_4tech case_sensitive){ terminate_with_null(&x); return(wildcard_match_c(absolutes, x.str, case_sensitive)); } @@ -2139,6 +2149,7 @@ wildcard_match_s(Absolutes *absolutes, String x, int32_t case_sensitive){ #if defined(FSTRING_IMPLEMENTATION) #undef FSTRING_IMPLEMENTATION +#define FSTRING_IMPL_GUARD #endif #if !defined(FSTRING_GUARD) diff --git a/4coder_table.cpp b/4coder_lib/4coder_table.h similarity index 56% rename from 4coder_table.cpp rename to 4coder_lib/4coder_table.h index 936d4bf3..df587ce3 100644 --- a/4coder_table.cpp +++ b/4coder_lib/4coder_table.h @@ -1,45 +1,72 @@ /* - * Mr. 4th Dimention - Allen Webster - * - * 14.02.2016 - * - * C style genereic hash table - * - */ +4coder_table.h - Preversioning +no warranty implied; use at your own risk + +This software is in the public domain. Where that dedication is not +recognized, you are granted a perpetual, irrevocable license to copy, +distribute, and modify this file as you see fit. +*/ // TOP +#if !defined(FCODER_TABLE_H) +#define FCODER_TABLE_H + +// 4tech_standard_preamble.h +#if !defined(FTECH_INTEGERS) +#define FTECH_INTEGERS +#include +typedef int8_t i8_4tech; +typedef int16_t i16_4tech; +typedef int32_t i32_4tech; +typedef int64_t i64_4tech; + +typedef uint8_t u8_4tech; +typedef uint16_t u16_4tech; +typedef uint32_t u32_4tech; +typedef uint64_t u64_4tech; + +typedef float f32_4tech; +typedef double f64_4tech; + +typedef int8_t b8_4tech; +typedef int32_t b32_4tech; +#endif + +#if !defined(Assert) +# define Assert(n) do{ if (!(n)) *(int*)0 = 0xA11E; }while(0) +#endif +// standard preamble end + #define TableHashEmpty 0 #define TableHashDeleted 1 #define TableHashMin 0x10000000 -#include -#include #include -typedef uint32_t Hash_Function(void *item, void *arg); -typedef int32_t Compare_Function(void *key, void *item, void *arg); +typedef u32_4tech Hash_Function(void *item, void *arg); +typedef i32_4tech Compare_Function(void *key, void *item, void *arg); struct Table{ - uint32_t *hash_array; + u32_4tech *hash_array; char *data_array; - int32_t count, max; - int32_t item_size; + i32_4tech count, max; + i32_4tech item_size; }; -static int32_t -table_required_mem_size(int32_t table_size, int32_t item_size){ - int32_t hash_size = ((table_size * sizeof(uint32_t)) + 7) & ~7; - int32_t mem_size = hash_size + table_size * item_size; +static i32_4tech +table_required_mem_size(i32_4tech table_size, i32_4tech item_size){ + i32_4tech hash_size = ((table_size * sizeof(u32_4tech)) + 7) & ~7; + i32_4tech mem_size = hash_size + table_size * item_size; return(mem_size); } static void -table_init_memory(Table *table, void *memory, int32_t table_size, int32_t item_size){ - int32_t hash_size = table_size * sizeof(uint32_t); +table_init_memory(Table *table, void *memory, i32_4tech table_size, i32_4tech item_size){ + i32_4tech hash_size = table_size * sizeof(u32_4tech); hash_size = (hash_size + 7) & ~7; - table->hash_array = (uint32_t*)memory; + table->hash_array = (u32_4tech*)memory; table->data_array = (char*)(table->hash_array) + hash_size; table->count = 0; @@ -47,23 +74,23 @@ table_init_memory(Table *table, void *memory, int32_t table_size, int32_t item_s table->item_size = item_size; } -static int32_t +static i32_4tech table_at_capacity(Table *table){ - int32_t result = true; + i32_4tech result = true; if (table->count * 8 < table->max * 7){ result = false; } return(result); } -static int32_t +static i32_4tech table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ - assert(table->count * 8 < table->max * 7); + Assert(table->count * 8 < table->max * 7); - uint32_t hash = (hash_func(item, arg) | TableHashMin); - int32_t i = hash % table->max; - int32_t start = i; - uint32_t *inspect = table->hash_array + i; + u32_4tech hash = (hash_func(item, arg) | TableHashMin); + i32_4tech i = hash % table->max; + i32_4tech start = i; + u32_4tech *inspect = table->hash_array + i; while (*inspect >= TableHashMin){ if (*inspect == hash){ @@ -77,7 +104,7 @@ table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare i = 0; inspect = table->hash_array; } - assert(i != start); + Assert(i != start); } *inspect = hash; memcpy(table->data_array + i*table->item_size, item, table->item_size); @@ -86,14 +113,14 @@ table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare return(0); } -static int32_t -table_find_pos(Table *table, void *search_key, void *arg, int32_t *pos, int32_t *index, Hash_Function *hash_func, Compare_Function *comp_func){ - assert((table->count - 1) * 8 < table->max * 7); +static i32_4tech +table_find_pos(Table *table, void *search_key, void *arg, i32_4tech *pos, i32_4tech *index, Hash_Function *hash_func, Compare_Function *comp_func){ + Assert((table->count - 1) * 8 < table->max * 7); - uint32_t hash = (hash_func(search_key, arg) | TableHashMin); - int32_t i = hash % table->max; - int32_t start = i; - uint32_t *inspect = table->hash_array + i; + u32_4tech hash = (hash_func(search_key, arg) | TableHashMin); + i32_4tech i = hash % table->max; + i32_4tech start = i; + u32_4tech *inspect = table->hash_array + i; while (*inspect != TableHashEmpty){ if (*inspect == hash){ @@ -118,7 +145,7 @@ table_find_pos(Table *table, void *search_key, void *arg, int32_t *pos, int32_t inline void* table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ void *result = 0; - int32_t pos; + i32_4tech pos; if (table_find_pos(table, search_key, arg, &pos, 0, hash_func, comp_func)){ result = table->data_array + pos; } @@ -126,15 +153,15 @@ table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_f } inline void -table_remove_index(Table *table, int32_t index){ +table_remove_index(Table *table, i32_4tech index){ table->hash_array[index] = TableHashDeleted; --table->count; } -inline int32_t +inline i32_4tech table_remove_match(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ - int32_t result = false; - int32_t index; + i32_4tech result = false; + i32_4tech index; if (table_find_pos(table, search_key, arg, 0, &index, hash_func, comp_func)){ table_remove_index(table, index); result = true; @@ -150,14 +177,14 @@ table_clear(Table *table){ static void table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ - assert((dst->count + src->count - 1) * 7 < dst->max * 8); - assert(dst->item_size == src->item_size); + Assert((dst->count + src->count - 1) * 7 < dst->max * 8); + Assert(dst->item_size == src->item_size); - int32_t count = src->count; - int32_t item_size = src->item_size; - uint32_t *hash_item = src->hash_array; + i32_4tech count = src->count; + i32_4tech item_size = src->item_size; + u32_4tech *hash_item = src->hash_array; char *data_item = src->data_array; - for (int32_t i = 0, c = 0; + for (i32_4tech i = 0, c = 0; c < count; ++i, ++hash_item, data_item += item_size){ if (*hash_item >= TableHashMin){ @@ -167,67 +194,71 @@ table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compar } } -static uint32_t +static u32_4tech tbl_string_hash(void *item, void *arg){ String *string = (String*)item; - char *str = string->str; - int32_t i = 0, len = string->size; - uint32_t x = 5381; - char c; + u32_4tech x = 5381; (void)arg; + char *str = string->str; + i32_4tech len = string->size; + i32_4tech i = 0; while (i < len){ - c = str[i++]; + char c = str[i++]; x = ((x << 5) + x) + c; } return(x); } -static int32_t +static i32_4tech tbl_string_compare(void *a, void *b, void *arg){ String *stra = (String*)a; String *strb = (String*)b; - int32_t result = !match_ss(*stra, *strb); + i32_4tech result = !match_ss(*stra, *strb); return(result); } -static uint32_t +struct Offset_String{ + i32_4tech offset; + i32_4tech size; +}; + +static u32_4tech tbl_offset_string_hash(void *item, void *arg){ Offset_String *string = (Offset_String*)item; - char *str; - int32_t i,len; - uint32_t x = 5381; - char c; + u32_4tech x = 5381; - str = ((char*)arg) + string->offset; - len = string->size; - i = 0; + char *str = ((char*)arg) + string->offset; + i32_4tech len = string->size; + i32_4tech i = 0; while (i < len){ - c = str[i++]; + char c = str[i++]; x = ((x << 5) + x) + c; } return(x); } -static int32_t +static i32_4tech tbl_offset_string_compare(void *a, void *b, void *arg){ Offset_String *ostra = (Offset_String*)a; Offset_String *ostrb = (Offset_String*)b; String stra = make_string((char*)arg + ostra->offset, ostra->size); String strb = make_string((char*)arg + ostrb->offset, ostrb->size); - int32_t result = !match_ss(stra, strb); + i32_4tech result = !match_ss(stra, strb); return(result); } struct String_Space{ char *space; - int32_t pos, new_pos, max; + i32_4tech pos; + i32_4tech new_pos; + i32_4tech max; }; static Offset_String -strspace_append(String_Space *space, char *str, int32_t len){ +strspace_append(String_Space *space, char *str, i32_4tech len){ Offset_String result = {}; if (space->new_pos + len <= space->max){ result.offset = space->new_pos; @@ -249,5 +280,7 @@ strspace_discard_prev(String_Space *space){ space->new_pos = space->pos; } +#endif + // BOTTOM diff --git a/4coder_rect.h b/4coder_rect.h deleted file mode 100644 index fd0f0de3..00000000 --- a/4coder_rect.h +++ /dev/null @@ -1,146 +0,0 @@ - -#ifndef FCODER_RECT_H -#define FCODER_RECT_H - -#include - -struct i32_Rect{ - int32_t x0, y0; - int32_t x1, y1; -}; - -struct f32_Rect{ - float x0, y0; - float x1, y1; -}; - -inline i32_Rect -i32_rect_zero(){ - i32_Rect rect={0}; - return(rect); -} - -inline f32_Rect -f32_rect_zero(){ - f32_Rect rect={0}; - return(rect); -} - -inline i32_Rect -i32R(int32_t l, int32_t t, int32_t r, int32_t b){ - i32_Rect rect; - rect.x0 = l; rect.y0 = t; - rect.x1 = r; rect.y1 = b; - return(rect); -} - -inline i32_Rect -i32R(f32_Rect r){ - i32_Rect rect; - rect.x0 = (int32_t)r.x0; - rect.y0 = (int32_t)r.y0; - rect.x1 = (int32_t)r.x1; - rect.y1 = (int32_t)r.y1; - return(rect); -} - -inline i32_Rect -i32XYWH(int32_t x, int32_t y, int32_t w, int32_t h){ - i32_Rect rect; - rect.x0 = x; rect.y0 = y; - rect.x1 = x+w; rect.y1 = y+h; - return(rect); -} - -inline f32_Rect -f32R(float l, float t, float r, float b){ - f32_Rect rect; - rect.x0 = l; rect.y0 = t; - rect.x1 = r; rect.y1 = b; - return(rect); -} - -inline f32_Rect -f32R(i32_Rect r){ - f32_Rect rect; - rect.x0 = (float)r.x0; - rect.y0 = (float)r.y0; - rect.x1 = (float)r.x1; - rect.y1 = (float)r.y1; - return(rect); -} - -inline f32_Rect -f32XYWH(float x, float y, float w, float h){ - f32_Rect rect; - rect.x0 = x; rect.y0 = y; - rect.x1 = x+w; rect.y1 = y+h; - return(rect); -} - -inline int32_t -rect_equal(i32_Rect r1, i32_Rect r2){ - int32_t result = (r1.x0 == r2.x0 && - r1.y0 == r2.y0 && - r1.x1 == r2.x1 && - r1.y1 == r2.y1); - return(result); -} - -inline int32_t -hit_check(int32_t x, int32_t y, int32_t x0, int32_t y0, int32_t x1, int32_t y1){ - return (x >= x0 && x < x1 && y >= y0 && y < y1); -} - -inline int32_t -hit_check(int32_t x, int32_t y, i32_Rect rect){ - return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1)); -} - -inline int32_t -hit_check(int32_t x, int32_t y, float x0, float y0, float x1, float y1){ - return (x >= x0 && x < x1 && y >= y0 && y < y1); -} - -inline int32_t -hit_check(int32_t x, int32_t y, f32_Rect rect){ - return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1)); -} - -inline int32_t -positive_area(i32_Rect rect){ - return (rect.x0 < rect.x1 && rect.y0 < rect.y1); -} - -inline i32_Rect -get_inner_rect(i32_Rect outer, int32_t margin){ - i32_Rect r; - r.x0 = outer.x0 + margin; - r.y0 = outer.y0 + margin; - r.x1 = outer.x1 - margin; - r.y1 = outer.y1 - margin; - return r; -} - -inline int32_t -fits_inside(i32_Rect rect, i32_Rect outer){ - return (rect.x0 >= outer.x0 && rect.x1 <= outer.x1 && - rect.y0 >= outer.y0 && rect.y1 <= outer.y1); -} - -inline i32_Rect -rect_clamp_to_rect(i32_Rect rect, i32_Rect clamp_box){ - if (rect.x0 < clamp_box.x0) rect.x0 = clamp_box.x0; - if (rect.y0 < clamp_box.y0) rect.y0 = clamp_box.y0; - if (rect.x1 > clamp_box.x1) rect.x1 = clamp_box.x1; - if (rect.y1 > clamp_box.y1) rect.y1 = clamp_box.y1; - return rect; -} - -inline i32_Rect -rect_clamp_to_rect(int32_t left, int32_t top, int32_t right, int32_t bottom, i32_Rect clamp_box){ - return rect_clamp_to_rect(i32R(left, top, right, bottom), clamp_box); -} - - -#endif \ No newline at end of file diff --git a/4coder_search.cpp b/4coder_search.cpp index 37126728..d44e8dff 100644 --- a/4coder_search.cpp +++ b/4coder_search.cpp @@ -1,7 +1,27 @@ +/* +4coder_search.cpp - Commands that search accross buffers including word complete, +and list all locations. -#ifndef FCODER_SEARCH +TYPE: 'drop-in-command-pack' +*/ + +// TOP + +#if !defined(FCODER_SEARCH) #define FCODER_SEARCH +#include "4coder_lib/4coder_table.h" +#include "4coder_lib/4coder_mem.h" + +#include "4coder_helper/4coder_streaming.h" +#include "4coder_helper/4coder_long_seek.h" + +#include "4coder_default_framework.h" + +// +// Search Iteration Systems +// + enum Search_Range_Type{ SearchRange_FrontToBack, SearchRange_BackToFront, @@ -120,7 +140,7 @@ static int32_t search_hit_add(General_Memory *general, Table *hits, String_Space *space, char *str, int32_t len){ int32_t result = false; - assert(len != 0); + Assert(len != 0); Offset_String ostring = strspace_append(space, str, len); if (ostring.size == 0){ @@ -133,7 +153,7 @@ search_hit_add(General_Memory *general, Table *hits, String_Space *space, char * ostring = strspace_append(space, str, len); } - assert(ostring.size != 0); + Assert(ostring.size != 0); if (table_at_capacity(hits)){ Table new_hits = {0}; @@ -479,4 +499,381 @@ search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){ return(result); } +// +// Generic Search All Buffers +// + +static void +get_search_all_string(Application_Links *app, Query_Bar *bar){ + char string_space[1024]; + bar->prompt = make_lit_string("List Locations For: "); + bar->string = make_fixed_width_string(string_space); + + if (!query_user_string(app, bar)){ + bar->string.size = 0; + } +} + +static void +generic_search_all_buffers(Application_Links *app, General_Memory *general, Partition *part, String string, uint32_t match_flags){ + Search_Set set = {0}; + Search_Iter iter = {0}; + + search_iter_init(general, &iter, string.size); + copy_ss(&iter.word, string); + + int32_t buffer_count = get_buffer_count(app); + search_set_init(general, &set, buffer_count); + + Search_Range *ranges = set.ranges; + + String search_name = make_lit_string("*search*"); + Buffer_Summary search_buffer = get_buffer_by_name(app, search_name.str, search_name.size, AccessAll); + if (!search_buffer.exists){ + search_buffer = create_buffer(app, search_name.str, search_name.size, BufferCreate_AlwaysNew); + buffer_set_setting(app, &search_buffer, BufferSetting_Unimportant, true); + buffer_set_setting(app, &search_buffer, BufferSetting_ReadOnly, true); + buffer_set_setting(app, &search_buffer, BufferSetting_WrapLine, false); + } + else{ + buffer_replace_range(app, &search_buffer, 0, search_buffer.size, 0, 0); + } + + { + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + int32_t j = 0; + if (buffer.exists){ + if (buffer.buffer_id != search_buffer.buffer_id){ + ranges[0].type = SearchRange_FrontToBack; + ranges[0].flags = match_flags; + ranges[0].buffer = buffer.buffer_id; + ranges[0].start = 0; + ranges[0].size = buffer.size; + j = 1; + } + } + + for (Buffer_Summary buffer_it = get_buffer_first(app, AccessAll); + buffer_it.exists; + get_buffer_next(app, &buffer_it, AccessAll)){ + if (buffer.buffer_id != buffer_it.buffer_id){ + if (search_buffer.buffer_id != buffer_it.buffer_id){ + ranges[j].type = SearchRange_FrontToBack; + ranges[j].flags = match_flags; + ranges[j].buffer = buffer_it.buffer_id; + ranges[j].start = 0; + ranges[j].size = buffer_it.size; + ++j; + } + } + } + set.count = j; + } + + Temp_Memory temp = begin_temp_memory(part); + Partition line_part = partition_sub_part(part, (4 << 10)); + char *str = (char*)partition_current(part); + int32_t part_size = 0; + int32_t size = 0; + for (;;){ + Search_Match match = search_next_match(app, &set, &iter); + if (match.found_match){ + Partial_Cursor word_pos = {0}; + if (buffer_compute_cursor(app, &match.buffer, seek_pos(match.start), &word_pos)){ + int32_t file_len = match.buffer.file_name_len; + int32_t line_num_len = int_to_str_size(word_pos.line); + int32_t column_num_len = int_to_str_size(word_pos.character); + + Temp_Memory line_temp = begin_temp_memory(&line_part); + String line_str = {0}; + read_line(app, &line_part, &match.buffer, word_pos.line, &line_str); + line_str = skip_chop_whitespace(line_str); + + int32_t str_len = file_len + 1 + line_num_len + 1 + column_num_len + 1 + 1 + line_str.size + 1; + + char *spare = push_array(part, char, str_len); + + if (spare == 0){ + buffer_replace_range(app, &search_buffer, size, size, str, part_size); + size += part_size; + + end_temp_memory(temp); + temp = begin_temp_memory(part); + + part_size = 0; + spare = push_array(part, char, str_len); + } + + part_size += str_len; + + String out_line = make_string_cap(spare, 0, str_len); + append_ss(&out_line, make_string(match.buffer.file_name, file_len)); + append_s_char(&out_line, ':'); + append_int_to_str(&out_line, word_pos.line); + append_s_char(&out_line, ':'); + append_int_to_str(&out_line, word_pos.character); + append_s_char(&out_line, ':'); + append_s_char(&out_line, ' '); + append_ss(&out_line, line_str); + append_s_char(&out_line, '\n'); + Assert(out_line.size == str_len); + + end_temp_memory(line_temp); + } + } + else{ + break; + } + } + + buffer_replace_range(app, &search_buffer, size, size, str, part_size); + + View_Summary view = get_active_view(app, AccessAll); + view_set_buffer(app, &view, search_buffer.buffer_id, 0); + + lock_jump_buffer(search_name.str, search_name.size); + + end_temp_memory(temp); +} + +// +// List Commands +// + +CUSTOM_COMMAND_SIG(list_all_locations){ + Query_Bar bar; + get_search_all_string(app, &bar); + if (bar.string.size == 0) return; + generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchWholeWord); +} + +CUSTOM_COMMAND_SIG(list_all_substring_locations){ + Query_Bar bar; + get_search_all_string(app, &bar); + if (bar.string.size == 0) return; + generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_MatchSubstring); +} + +CUSTOM_COMMAND_SIG(list_all_locations_case_insensitive){ + Query_Bar bar; + get_search_all_string(app, &bar); + if (bar.string.size == 0) return; + generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchWholeWord); +} + +CUSTOM_COMMAND_SIG(list_all_substring_locations_case_insensitive){ + Query_Bar bar; + get_search_all_string(app, &bar); + if (bar.string.size == 0) return; + generic_search_all_buffers(app, &global_general, &global_part, bar.string, SearchFlag_CaseInsensitive | SearchFlag_MatchSubstring); +} + +CUSTOM_COMMAND_SIG(list_all_locations_of_identifier){ + View_Summary view = get_active_view(app, AccessProtected); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected); + + Cpp_Get_Token_Result get_result = {0}; + bool32 success = buffer_get_token_index(app, &buffer, view.cursor.pos, &get_result); + + if (success && !get_result.in_whitespace){ + char space[128]; + int32_t size = get_result.token_end - get_result.token_start; + + if (size > 0 && size <= sizeof(space)){ + success = buffer_read_range(app, &buffer, get_result.token_start, get_result.token_end, space); + if (success){ + String str = make_string(space, size); + exec_command(app, change_active_panel); + generic_search_all_buffers(app, &global_general, &global_part, str, SearchFlag_MatchWholeWord); + } + } + } +} + +// +// Word Complete Command +// + +struct Word_Complete_State{ + Search_Set set; + Search_Iter iter; + Table hits; + String_Space str; + int32_t word_start; + int32_t word_end; + int32_t initialized; +}; + +static Word_Complete_State complete_state = {0}; + +CUSTOM_COMMAND_SIG(word_complete){ + View_Summary view = get_active_view(app, AccessOpen); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessOpen); + + // NOTE(allen): I just do this because this command is a lot of work + // and there is no point in doing any of it if nothing will happen anyway. + if (buffer.exists){ + int32_t do_init = false; + + if (view_paste_index[view.view_id].rewrite != RewriteWordComplete){ + do_init = true; + } + view_paste_index[view.view_id].next_rewrite = RewriteWordComplete; + if (!complete_state.initialized){ + do_init = true; + } + + int32_t word_end = 0; + int32_t word_start = 0; + int32_t cursor_pos = 0; + int32_t size = 0; + + if (do_init){ + // NOTE(allen): Get the range where the + // partial word is written. + word_end = view.cursor.pos; + word_start = word_end; + cursor_pos = word_end - 1; + + char space[1024]; + Stream_Chunk chunk = {0}; + if (init_stream_chunk(&chunk, app, &buffer, cursor_pos, space, sizeof(space))){ + int32_t still_looping = true; + do{ + for (; cursor_pos >= chunk.start; --cursor_pos){ + char c = chunk.data[cursor_pos]; + if (char_is_alpha(c)){ + word_start = cursor_pos; + } + else if (!char_is_numeric(c)){ + goto double_break; + } + } + still_looping = backward_stream_chunk(&chunk); + }while(still_looping); + } + double_break:; + + size = word_end - word_start; + + if (size == 0){ + complete_state.initialized = false; + return; + } + + // NOTE(allen): Initialize the search iterator + // with the partial word. + complete_state.initialized = true; + search_iter_init(&global_general, &complete_state.iter, size); + buffer_read_range(app, &buffer, word_start, word_end, + complete_state.iter.word.str); + complete_state.iter.word.size = size; + + // NOTE(allen): Initialize the set of ranges to be searched. + int32_t buffer_count = get_buffer_count(app); + search_set_init(&global_general, &complete_state.set, buffer_count); + + Search_Range *ranges = complete_state.set.ranges; + ranges[0].type = SearchRange_Wave; + ranges[0].flags = SearchFlag_MatchWordPrefix; + ranges[0].buffer = buffer.buffer_id; + ranges[0].start = 0; + ranges[0].size = buffer.size; + ranges[0].mid_start = word_start; + ranges[0].mid_size = size; + + int32_t j = 1; + for (Buffer_Summary buffer_it = get_buffer_first(app, AccessAll); + buffer_it.exists; + get_buffer_next(app, &buffer_it, AccessAll)){ + if (buffer.buffer_id != buffer_it.buffer_id){ + ranges[j].type = SearchRange_FrontToBack; + ranges[j].flags = SearchFlag_MatchWordPrefix; + ranges[j].buffer = buffer_it.buffer_id; + ranges[j].start = 0; + ranges[j].size = buffer_it.size; + ++j; + } + } + complete_state.set.count = j; + + // NOTE(allen): Initialize the search hit table. + search_hits_init(&global_general, &complete_state.hits, &complete_state.str, + 100, (4 << 10)); + search_hit_add(&global_general, &complete_state.hits, &complete_state.str, + complete_state.iter.word.str, + complete_state.iter.word.size); + + complete_state.word_start = word_start; + complete_state.word_end = word_end; + } + else{ + word_start = complete_state.word_start; + word_end = complete_state.word_end; + size = complete_state.iter.word.size; + } + + // NOTE(allen): Iterate through matches. + if (size > 0){ + for (;;){ + int32_t match_size = 0; + Search_Match match = + search_next_match(app, &complete_state.set, + &complete_state.iter); + + if (match.found_match){ + match_size = match.end - match.start; + Temp_Memory temp = begin_temp_memory(&global_part); + char *spare = push_array(&global_part, char, match_size); + + buffer_read_range(app, &match.buffer, + match.start, match.end, spare); + + if (search_hit_add(&global_general, &complete_state.hits, &complete_state.str, + spare, match_size)){ + buffer_replace_range(app, &buffer, word_start, word_end, + spare, match_size); + view_set_cursor(app, &view, + seek_pos(word_start + match_size), + true); + + complete_state.word_end = word_start + match_size; + complete_state.set.ranges[0].mid_size = match_size; + end_temp_memory(temp); + break; + } + end_temp_memory(temp); + } + else{ + complete_state.iter.pos = 0; + complete_state.iter.i = 0; + + search_hits_init(&global_general, &complete_state.hits, &complete_state.str, + 100, (4 << 10)); + search_hit_add(&global_general, &complete_state.hits, &complete_state.str, + complete_state.iter.word.str, + complete_state.iter.word.size); + + match_size = complete_state.iter.word.size; + char *str = complete_state.iter.word.str; + buffer_replace_range(app, &buffer, word_start, word_end, + str, match_size); + view_set_cursor(app, &view, + seek_pos(word_start + match_size), + true); + + complete_state.word_end = word_start + match_size; + complete_state.set.ranges[0].mid_size = match_size; + break; + } + } + } + } +} + #endif + +// BOTTOM + diff --git a/4cpp_lexer.h b/4cpp/4cpp_lexer.h similarity index 78% rename from 4cpp_lexer.h rename to 4cpp/4cpp_lexer.h index 67ca78ad..473c1d15 100644 --- a/4cpp_lexer.h +++ b/4cpp/4cpp_lexer.h @@ -1,163 +1,197 @@ +/* +4cpp_lexer.h - Preversioning +no warranty implied; use at your own risk + +This software is in the public domain. Where that dedication is not +recognized, you are granted a perpetual, irrevocable license to copy, +distribute, and modify this file as you see fit. +*/ // TOP #ifndef FCPP_NEW_LEXER_INC #define FCPP_NEW_LEXER_INC -#ifndef Assert +// 4tech_standard_preamble.h +#if !defined(FTECH_INTEGERS) +#define FTECH_INTEGERS +#include +typedef int8_t i8_4tech; +typedef int16_t i16_4tech; +typedef int32_t i32_4tech; +typedef int64_t i64_4tech; + +typedef uint8_t u8_4tech; +typedef uint16_t u16_4tech; +typedef uint32_t u32_4tech; +typedef uint64_t u64_4tech; + +typedef float f32_4tech; +typedef double f64_4tech; + +typedef int8_t b8_4tech; +typedef int32_t b32_4tech; +#endif + +#if !defined(Assert) # define Assert(n) do{ if (!(n)) *(int*)0 = 0xA11E; }while(0) #endif +#if !defined(API_EXPORT) +# define API_EXPORT +#endif +// standard preamble end + +// duff-routine defines +#define DfrCase(PC) case PC: goto resumespot_##PC +#define DfrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } +#define DfrReturn(n) { *S_ptr = S; S_ptr->__pc__ = -1; return(n); } + #ifndef FCPP_LINK # define FCPP_LINK static #endif -#ifndef API_EXPORT -#define API_EXPORT -#endif - -#include -#if !defined(FSTRING_GUARD) -# define FSTRING_IMPLEMENTATION -# include "4coder_string.h" -#endif #include "4cpp_lexer_types.h" #include "4cpp_lexer_tables.c" // TODO(allen): revisit this keyword data declaration system struct String_And_Flag{ - String str; - uint32_t flags; + char *str; + u32_4tech length; + u32_4tech flags; }; +#define make_stafl(s,f) (s), sizeof(s)-1, f + static String_And_Flag preprops[] = { - {make_lit_string("include"), CPP_PP_INCLUDE } , - {make_lit_string("INCLUDE"), CPP_PP_INCLUDE } , - {make_lit_string("ifndef" ), CPP_PP_IFNDEF } , - {make_lit_string("IFNDEF" ), CPP_PP_IFNDEF } , - {make_lit_string("define" ), CPP_PP_DEFINE } , - {make_lit_string("DEFINE" ), CPP_PP_DEFINE } , - {make_lit_string("import" ), CPP_PP_IMPORT } , - {make_lit_string("IMPORT" ), CPP_PP_IMPORT } , - {make_lit_string("pragma" ), CPP_PP_PRAGMA } , - {make_lit_string("PRAGMA" ), CPP_PP_PRAGMA } , - {make_lit_string("undef" ), CPP_PP_UNDEF } , - {make_lit_string("UNDEF" ), CPP_PP_UNDEF } , - {make_lit_string("endif" ), CPP_PP_ENDIF } , - {make_lit_string("ENDIF" ), CPP_PP_ENDIF } , - {make_lit_string("error" ), CPP_PP_ERROR } , - {make_lit_string("ERROR" ), CPP_PP_ERROR } , - {make_lit_string("ifdef" ), CPP_PP_IFDEF } , - {make_lit_string("IFDEF" ), CPP_PP_IFDEF } , - {make_lit_string("using" ), CPP_PP_USING } , - {make_lit_string("USING" ), CPP_PP_USING } , - {make_lit_string("else" ), CPP_PP_ELSE } , - {make_lit_string("ELSE" ), CPP_PP_ELSE } , - {make_lit_string("elif" ), CPP_PP_ELIF } , - {make_lit_string("ELIF" ), CPP_PP_ELIF } , - {make_lit_string("line" ), CPP_PP_LINE } , - {make_lit_string("LINE" ), CPP_PP_LINE } , - {make_lit_string("if" ), CPP_PP_IF } , - {make_lit_string("IF" ), CPP_PP_IF } , + {make_stafl("include" , CPP_PP_INCLUDE )} , + {make_stafl("INCLUDE" , CPP_PP_INCLUDE )} , + {make_stafl("ifndef" , CPP_PP_IFNDEF )} , + {make_stafl("IFNDEF" , CPP_PP_IFNDEF )} , + {make_stafl("define" , CPP_PP_DEFINE )} , + {make_stafl("DEFINE" , CPP_PP_DEFINE )} , + {make_stafl("import" , CPP_PP_IMPORT )} , + {make_stafl("IMPORT" , CPP_PP_IMPORT )} , + {make_stafl("pragma" , CPP_PP_PRAGMA )} , + {make_stafl("PRAGMA" , CPP_PP_PRAGMA )} , + {make_stafl("undef" , CPP_PP_UNDEF )} , + {make_stafl("UNDEF" , CPP_PP_UNDEF )} , + {make_stafl("endif" , CPP_PP_ENDIF )} , + {make_stafl("ENDIF" , CPP_PP_ENDIF )} , + {make_stafl("error" , CPP_PP_ERROR )} , + {make_stafl("ERROR" , CPP_PP_ERROR )} , + {make_stafl("ifdef" , CPP_PP_IFDEF )} , + {make_stafl("IFDEF" , CPP_PP_IFDEF )} , + {make_stafl("using" , CPP_PP_USING )} , + {make_stafl("USING" , CPP_PP_USING )} , + {make_stafl("else" , CPP_PP_ELSE )} , + {make_stafl("ELSE" , CPP_PP_ELSE )} , + {make_stafl("elif" , CPP_PP_ELIF )} , + {make_stafl("ELIF" , CPP_PP_ELIF )} , + {make_stafl("line" , CPP_PP_LINE )} , + {make_stafl("LINE" , CPP_PP_LINE )} , + {make_stafl("if" , CPP_PP_IF )} , + {make_stafl("IF" , CPP_PP_IF )} , }; +static i32_4tech preprops_count = sizeof(preprops)/sizeof(preprops[0]); static String_And_Flag keywords[] = { - {make_lit_string("true") , CPP_TOKEN_BOOLEAN_CONSTANT}, - {make_lit_string("false") , CPP_TOKEN_BOOLEAN_CONSTANT}, + {make_stafl("true" , CPP_TOKEN_BOOLEAN_CONSTANT)}, + {make_stafl("false" , CPP_TOKEN_BOOLEAN_CONSTANT)}, - {make_lit_string("and") , CPP_TOKEN_AND}, - {make_lit_string("and_eq") , CPP_TOKEN_ANDEQ}, - {make_lit_string("bitand") , CPP_TOKEN_BIT_AND}, - {make_lit_string("bitor") , CPP_TOKEN_BIT_OR}, - {make_lit_string("or") , CPP_TOKEN_OR}, - {make_lit_string("or_eq") , CPP_TOKEN_OREQ}, - {make_lit_string("sizeof") , CPP_TOKEN_SIZEOF}, - {make_lit_string("alignof") , CPP_TOKEN_ALIGNOF}, - {make_lit_string("decltype") , CPP_TOKEN_DECLTYPE}, - {make_lit_string("throw") , CPP_TOKEN_THROW}, - {make_lit_string("new") , CPP_TOKEN_NEW}, - {make_lit_string("delete") , CPP_TOKEN_DELETE}, - {make_lit_string("xor") , CPP_TOKEN_BIT_XOR}, - {make_lit_string("xor_eq") , CPP_TOKEN_XOREQ}, - {make_lit_string("not") , CPP_TOKEN_NOT}, - {make_lit_string("not_eq") , CPP_TOKEN_NOTEQ}, - {make_lit_string("typeid") , CPP_TOKEN_TYPEID}, - {make_lit_string("compl") , CPP_TOKEN_BIT_NOT}, + {make_stafl("and" , CPP_TOKEN_AND)}, + {make_stafl("and_eq" , CPP_TOKEN_ANDEQ)}, + {make_stafl("bitand" , CPP_TOKEN_BIT_AND)}, + {make_stafl("bitor" , CPP_TOKEN_BIT_OR)}, + {make_stafl("or" , CPP_TOKEN_OR)}, + {make_stafl("or_eq" , CPP_TOKEN_OREQ)}, + {make_stafl("sizeof" , CPP_TOKEN_SIZEOF)}, + {make_stafl("alignof" , CPP_TOKEN_ALIGNOF)}, + {make_stafl("decltype" , CPP_TOKEN_DECLTYPE)}, + {make_stafl("throw" , CPP_TOKEN_THROW)}, + {make_stafl("new" , CPP_TOKEN_NEW)}, + {make_stafl("delete" , CPP_TOKEN_DELETE)}, + {make_stafl("xor" , CPP_TOKEN_BIT_XOR)}, + {make_stafl("xor_eq" , CPP_TOKEN_XOREQ)}, + {make_stafl("not" , CPP_TOKEN_NOT)}, + {make_stafl("not_eq" , CPP_TOKEN_NOTEQ)}, + {make_stafl("typeid" , CPP_TOKEN_TYPEID)}, + {make_stafl("compl" , CPP_TOKEN_BIT_NOT)}, - {make_lit_string("void") , CPP_TOKEN_KEY_TYPE}, - {make_lit_string("bool") , CPP_TOKEN_KEY_TYPE}, - {make_lit_string("char") , CPP_TOKEN_KEY_TYPE}, - {make_lit_string("int") , CPP_TOKEN_KEY_TYPE}, - {make_lit_string("float") , CPP_TOKEN_KEY_TYPE}, - {make_lit_string("double") , CPP_TOKEN_KEY_TYPE}, + {make_stafl("void" , CPP_TOKEN_KEY_TYPE)}, + {make_stafl("bool" , CPP_TOKEN_KEY_TYPE)}, + {make_stafl("char" , CPP_TOKEN_KEY_TYPE)}, + {make_stafl("int" , CPP_TOKEN_KEY_TYPE)}, + {make_stafl("float" , CPP_TOKEN_KEY_TYPE)}, + {make_stafl("double" , CPP_TOKEN_KEY_TYPE)}, - {make_lit_string("long") , CPP_TOKEN_KEY_MODIFIER}, - {make_lit_string("short") , CPP_TOKEN_KEY_MODIFIER}, - {make_lit_string("unsigned") , CPP_TOKEN_KEY_MODIFIER}, + {make_stafl("long" , CPP_TOKEN_KEY_MODIFIER)}, + {make_stafl("short" , CPP_TOKEN_KEY_MODIFIER)}, + {make_stafl("unsigned" , CPP_TOKEN_KEY_MODIFIER)}, - {make_lit_string("const") , CPP_TOKEN_KEY_QUALIFIER}, - {make_lit_string("volatile") , CPP_TOKEN_KEY_QUALIFIER}, + {make_stafl("const" , CPP_TOKEN_KEY_QUALIFIER)}, + {make_stafl("volatile" , CPP_TOKEN_KEY_QUALIFIER)}, - {make_lit_string("asm") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("break") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("case") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("catch") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("continue") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("default") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("do") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("else") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("for") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("goto") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("if") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("return") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("switch") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("try") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("while") , CPP_TOKEN_KEY_CONTROL_FLOW}, - {make_lit_string("static_assert") , CPP_TOKEN_KEY_CONTROL_FLOW}, + {make_stafl("asm" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("break" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("case" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("catch" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("continue" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("default" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("do" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("else" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("for" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("goto" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("if" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("return" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("switch" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("try" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("while" , CPP_TOKEN_KEY_CONTROL_FLOW)}, + {make_stafl("static_assert" , CPP_TOKEN_KEY_CONTROL_FLOW)}, - {make_lit_string("const_cast") , CPP_TOKEN_KEY_CAST}, - {make_lit_string("dynamic_cast") , CPP_TOKEN_KEY_CAST}, - {make_lit_string("reinterpret_cast") , CPP_TOKEN_KEY_CAST}, - {make_lit_string("static_cast") , CPP_TOKEN_KEY_CAST}, + {make_stafl("const_cast" , CPP_TOKEN_KEY_CAST)}, + {make_stafl("dynamic_cast" , CPP_TOKEN_KEY_CAST)}, + {make_stafl("reinterpret_cast" , CPP_TOKEN_KEY_CAST)}, + {make_stafl("static_cast" , CPP_TOKEN_KEY_CAST)}, - {make_lit_string("class") , CPP_TOKEN_KEY_TYPE_DECLARATION}, - {make_lit_string("enum") , CPP_TOKEN_KEY_TYPE_DECLARATION}, - {make_lit_string("struct") , CPP_TOKEN_KEY_TYPE_DECLARATION}, - {make_lit_string("typedef") , CPP_TOKEN_KEY_TYPE_DECLARATION}, - {make_lit_string("union") , CPP_TOKEN_KEY_TYPE_DECLARATION}, - {make_lit_string("template") , CPP_TOKEN_KEY_TYPE_DECLARATION}, - {make_lit_string("typename") , CPP_TOKEN_KEY_TYPE_DECLARATION}, + {make_stafl("class" , CPP_TOKEN_KEY_TYPE_DECLARATION)}, + {make_stafl("enum" , CPP_TOKEN_KEY_TYPE_DECLARATION)}, + {make_stafl("struct" , CPP_TOKEN_KEY_TYPE_DECLARATION)}, + {make_stafl("typedef" , CPP_TOKEN_KEY_TYPE_DECLARATION)}, + {make_stafl("union" , CPP_TOKEN_KEY_TYPE_DECLARATION)}, + {make_stafl("template" , CPP_TOKEN_KEY_TYPE_DECLARATION)}, + {make_stafl("typename" , CPP_TOKEN_KEY_TYPE_DECLARATION)}, - {make_lit_string("friend") , CPP_TOKEN_KEY_ACCESS}, - {make_lit_string("namespace") , CPP_TOKEN_KEY_ACCESS}, - {make_lit_string("private") , CPP_TOKEN_KEY_ACCESS}, - {make_lit_string("protected") , CPP_TOKEN_KEY_ACCESS}, - {make_lit_string("public") , CPP_TOKEN_KEY_ACCESS}, - {make_lit_string("using") , CPP_TOKEN_KEY_ACCESS}, + {make_stafl("friend" , CPP_TOKEN_KEY_ACCESS)}, + {make_stafl("namespace" , CPP_TOKEN_KEY_ACCESS)}, + {make_stafl("private" , CPP_TOKEN_KEY_ACCESS)}, + {make_stafl("protected" , CPP_TOKEN_KEY_ACCESS)}, + {make_stafl("public" , CPP_TOKEN_KEY_ACCESS)}, + {make_stafl("using" , CPP_TOKEN_KEY_ACCESS)}, - {make_lit_string("extern") , CPP_TOKEN_KEY_LINKAGE}, - {make_lit_string("export") , CPP_TOKEN_KEY_LINKAGE}, - {make_lit_string("inline") , CPP_TOKEN_KEY_LINKAGE}, - {make_lit_string("static") , CPP_TOKEN_KEY_LINKAGE}, - {make_lit_string("virtual") , CPP_TOKEN_KEY_LINKAGE}, + {make_stafl("extern" , CPP_TOKEN_KEY_LINKAGE)}, + {make_stafl("export" , CPP_TOKEN_KEY_LINKAGE)}, + {make_stafl("inline" , CPP_TOKEN_KEY_LINKAGE)}, + {make_stafl("static" , CPP_TOKEN_KEY_LINKAGE)}, + {make_stafl("virtual" , CPP_TOKEN_KEY_LINKAGE)}, - {make_lit_string("alignas") , CPP_TOKEN_KEY_OTHER}, - {make_lit_string("explicit") , CPP_TOKEN_KEY_OTHER}, - {make_lit_string("noexcept") , CPP_TOKEN_KEY_OTHER}, - {make_lit_string("nullptr") , CPP_TOKEN_KEY_OTHER}, - {make_lit_string("operator") , CPP_TOKEN_KEY_OTHER}, - {make_lit_string("register") , CPP_TOKEN_KEY_OTHER}, - {make_lit_string("this") , CPP_TOKEN_KEY_OTHER}, - {make_lit_string("thread_local") , CPP_TOKEN_KEY_OTHER}, + {make_stafl("alignas" , CPP_TOKEN_KEY_OTHER)}, + {make_stafl("explicit" , CPP_TOKEN_KEY_OTHER)}, + {make_stafl("noexcept" , CPP_TOKEN_KEY_OTHER)}, + {make_stafl("nullptr" , CPP_TOKEN_KEY_OTHER)}, + {make_stafl("operator" , CPP_TOKEN_KEY_OTHER)}, + {make_stafl("register" , CPP_TOKEN_KEY_OTHER)}, + {make_stafl("this" , CPP_TOKEN_KEY_OTHER)}, + {make_stafl("thread_local" , CPP_TOKEN_KEY_OTHER)}, #if defined(FCPP_LEXER_EXTRA_KEYWORDS) FCPP_LEXER_EXTRA_KEYWORDS #endif }; - +static i32_4tech keywords_count = sizeof(keywords)/sizeof(keywords[0]); API_EXPORT FCPP_LINK Cpp_Get_Token_Result -cpp_get_token(Cpp_Token_Array array, int32_t pos)/* +cpp_get_token(Cpp_Token_Array array, i32_4tech pos)/* DOC_PARAM(array, The array of tokens from which to get a token.) DOC_PARAM(pos, The position, measured in bytes, to get the token for.) DOC_RETURN(A Cpp_Get_Token_Result struct is returned containing the index of a token and a flag indicating whether the pos is contained in the token or in whitespace after the token.) @@ -169,10 +203,10 @@ DOC_SEE(Cpp_Get_Token_Result) Cpp_Get_Token_Result result = {}; Cpp_Token *token_array = array.tokens; Cpp_Token *token = 0; - int32_t first = 0; - int32_t count = array.count; - int32_t last = count; - int32_t this_start = 0, next_start = 0; + i32_4tech first = 0; + i32_4tech count = array.count; + i32_4tech last = count; + i32_4tech this_start = 0, next_start = 0; if (count > 0){ for (;;){ @@ -272,35 +306,57 @@ cpp_pp_directive_to_state(Cpp_Token_Type type){ return(result); } -// duff-routine defines -#define DrCase(PC) case PC: goto resumespot_##PC +FCPP_LINK b32_4tech +cpp__match(char *a, i32_4tech a_len, char *b, i32_4tech b_len){ + b32_4tech result = false; + if (a_len == b_len){ + char *a_end = a + a_len; + result = true; + for (; a < a_end; ++a, ++b){ + if (*a != *b){ + result = false; + break; + } + } + } + return(result); +} -#define DrYield(PC, n)\ -{ token_array_out->count = token_i; *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } - -#define DrReturn(n) { token_array_out->count = token_i; *S_ptr = S; S_ptr->__pc__ = -1; return(n); } +FCPP_LINK b32_4tech +cpp__table_match(String_And_Flag *table, i32_4tech count, char *s, i32_4tech len, i32_4tech *index_out){ + b32_4tech result = false; + String_And_Flag *entry = table; + *index_out = -1; + for (i32_4tech i = 0; i < count; ++i, ++entry){ + if (cpp__match(entry->str, entry->length, s, len)){ + result = true; + *index_out = i; + break; + } + } + return(result); +} FCPP_LINK Cpp_Lex_Result -cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t size, - Cpp_Token_Array *token_array_out){ +cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech size, Cpp_Token_Array *token_array_out){ Cpp_Lex_Data S = *S_ptr; Cpp_Token *out_tokens = token_array_out->tokens; - int32_t token_i = token_array_out->count; - int32_t max_token_i = token_array_out->max_count; + i32_4tech token_i = token_array_out->count; + i32_4tech max_token_i = token_array_out->max_count; - uint8_t c = 0; + u8_4tech c = 0; - int32_t end_pos = size + S.chunk_pos; + i32_4tech end_pos = size + S.chunk_pos; chunk -= S.chunk_pos; switch (S.__pc__){ - DrCase(1); - DrCase(2); - DrCase(3); - DrCase(4); - DrCase(5); - DrCase(7); + DfrCase(1); + DfrCase(2); + DfrCase(3); + DfrCase(4); + DfrCase(5); + DfrCase(7); } for (;;){ @@ -308,14 +364,15 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz for(;;){ for (; S.pp_state < LSPP_count && S.pos < end_pos;){ c = chunk[S.pos++]; - int32_t i = S.pp_state + whitespace_fsm_eq_classes[c]; + i32_4tech i = S.pp_state + whitespace_fsm_eq_classes[c]; S.pp_state = whitespace_fsm_table[i]; } S.white_done = (S.pp_state >= LSPP_count); if (S.white_done == 0){ S.chunk_pos += size; - DrYield(4, LexResult_NeedChunk); + token_array_out->count = token_i; + DfrYield(4, LexResult_NeedChunk); } else{ break; @@ -333,14 +390,14 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz S.fsm = null_lex_fsm; for(;;){ { - uint16_t *eq_classes = get_eq_classes[S.pp_state]; - uint8_t *fsm_table = get_table[S.pp_state]; + u16_4tech *eq_classes = get_eq_classes[S.pp_state]; + u8_4tech *fsm_table = get_table[S.pp_state]; for (; S.fsm.state < LS_count && S.pos < end_pos;){ c = chunk[S.pos++]; S.tb[(S.tb_pos++) & (sizeof(S.tb)-1)] = c; - int32_t i = S.fsm.state + eq_classes[c]; + i32_4tech i = S.fsm.state + eq_classes[c]; S.fsm.state = fsm_table[i]; S.fsm.multi_line |= multiline_state_table[S.fsm.state]; } @@ -349,7 +406,8 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz if (S.fsm.emit_token == 0){ S.chunk_pos += size; - DrYield(3, LexResult_NeedChunk); + token_array_out->count = token_i; + DfrYield(3, LexResult_NeedChunk); } else{ break; @@ -406,7 +464,8 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz if (S.white_done == 0){ S.chunk_pos += size; - DrYield(1, LexResult_NeedChunk); + token_array_out->count = token_i; + DfrYield(1, LexResult_NeedChunk); } else break; } @@ -431,20 +490,19 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz { --S.pos; - int32_t word_size = S.pos - S.token_start; + i32_4tech word_size = S.pos - S.token_start; if (word_size < sizeof(S.tb)){ if (S.pp_state == LSPP_body_if){ - if (match_ss(make_string(S.tb, word_size), make_lit_string("defined"))){ + if (cpp__match(S.tb, word_size, "defined", sizeof("defined")-1)){ S.token.type = CPP_PP_DEFINED; S.token.flags = CPP_TFLAG_IS_OPERATOR | CPP_TFLAG_IS_KEYWORD; break; } } - int32_t sub_match = -1; - string_set_match_table(keywords, sizeof(*keywords), ArrayCount(keywords), - make_string(S.tb, S.tb_pos-1), &sub_match); + i32_4tech sub_match = -1; + cpp__table_match(keywords, keywords_count, S.tb, S.tb_pos-1, &sub_match); if (sub_match != -1){ String_And_Flag data = keywords[sub_match]; @@ -481,23 +539,22 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz --S.pos; if (S.tb_pos < sizeof(S.tb)){ - int32_t pos = S.tb_pos-1; - int32_t i = 1; + i32_4tech pos = S.tb_pos-1; + i32_4tech i = 1; for (;i < pos; ++i){ if (S.tb[i] != ' '){ break; } } - int32_t sub_match = -1; - string_set_match_table(preprops, sizeof(*preprops), ArrayCount(preprops), - make_string(S.tb+i, pos-i), &sub_match); + i32_4tech sub_match = -1; + cpp__table_match(preprops, preprops_count, S.tb+i, pos-i, &sub_match); if (sub_match != -1){ String_And_Flag data = preprops[sub_match]; S.token.type = (Cpp_Token_Type)data.flags; S.token.flags = CPP_TFLAG_PP_DIRECTIVE; - S.pp_state = (uint8_t)cpp_pp_directive_to_state(S.token.type); + S.pp_state = (u8_4tech)cpp_pp_directive_to_state(S.token.type); break; } } @@ -521,7 +578,8 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz if (S.fsm.emit_token == 0){ S.chunk_pos += size; - DrYield(5, LexResult_NeedChunk); + token_array_out->count = token_i; + DfrYield(5, LexResult_NeedChunk); } else break; } @@ -863,16 +921,20 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz S.token.size = S.pos - S.token_start; } if ((S.token.flags & CPP_TFLAG_PP_DIRECTIVE) == 0){ - S.token.flags |= (S.pp_state != LSPP_default)?(CPP_TFLAG_PP_BODY):(0); + if (S.pp_state != LSPP_default){ + S.token.flags |= CPP_TFLAG_PP_BODY; + } } out_tokens[token_i++] = S.token; if (token_i == max_token_i){ if (S.pos == end_pos){ S.chunk_pos += size; - DrYield(7, LexResult_NeedChunk); + token_array_out->count = token_i; + DfrYield(7, LexResult_NeedChunk); } - DrYield(2, LexResult_NeedTokenMemory); + token_array_out->count = token_i; + DfrYield(2, LexResult_NeedTokenMemory); } } @@ -881,16 +943,13 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz } } - DrReturn(LexResult_Finished); + token_array_out->count = token_i; + DfrReturn(LexResult_Finished); } -#undef DrYield -#undef DrReturn -#undef DrCase - FCPP_LINK Cpp_Lex_Result -cpp_lex_nonalloc_null_end_out_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t size, - Cpp_Token_Array *token_array_out, int32_t max_tokens_out){ +cpp_lex_nonalloc_null_end_out_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech size, + Cpp_Token_Array *token_array_out, i32_4tech max_tokens_out){ Cpp_Token_Array temp_array = *token_array_out; if (temp_array.max_count > temp_array.count + max_tokens_out){ temp_array.max_count = temp_array.count + max_tokens_out; @@ -909,7 +968,7 @@ cpp_lex_nonalloc_null_end_out_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t si } FCPP_LINK Cpp_Lex_Result -cpp_lex_nonalloc_no_null_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t size, int32_t full_size, +cpp_lex_nonalloc_no_null_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech size, i32_4tech full_size, Cpp_Token_Array *token_array_out){ Cpp_Lex_Result result = 0; if (S_ptr->pos >= full_size){ @@ -929,8 +988,8 @@ cpp_lex_nonalloc_no_null_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t size } FCPP_LINK Cpp_Lex_Result -cpp_lex_nonalloc_no_null_out_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t size, int32_t full_size, - Cpp_Token_Array *token_array_out, int32_t max_tokens_out){ +cpp_lex_nonalloc_no_null_out_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech size, i32_4tech full_size, + Cpp_Token_Array *token_array_out, i32_4tech max_tokens_out){ Cpp_Token_Array temp_stack = *token_array_out; if (temp_stack.max_count > temp_stack.count + max_tokens_out){ temp_stack.max_count = temp_stack.count + max_tokens_out; @@ -950,11 +1009,11 @@ cpp_lex_nonalloc_no_null_out_limit(Cpp_Lex_Data *S_ptr, char *chunk, int32_t siz return(result); } -#define HAS_NULL_TERM ((int32_t)(-1)) -#define NO_OUT_LIMIT ((int32_t)(-1)) +#define HAS_NULL_TERM ((i32_4tech)(-1)) +#define NO_OUT_LIMIT ((i32_4tech)(-1)) API_EXPORT FCPP_LINK Cpp_Lex_Result -cpp_lex_step(Cpp_Lex_Data *S_ptr, char *chunk, int32_t size, int32_t full_size, Cpp_Token_Array *token_array_out, int32_t max_tokens_out)/* +cpp_lex_step(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech size, i32_4tech full_size, Cpp_Token_Array *token_array_out, i32_4tech max_tokens_out)/* DOC_PARAM(S_ptr, The lexer state. Go to the Cpp_Lex_Data section to see how to initialize the state.) DOC_PARAM(chunk, The first or next chunk of the file being lexed.) DOC_PARAM(size, The number of bytes in the chunk including the null terminator if the chunk ends in a null terminator. If the chunk ends in a null terminator the system will interpret it as the end of the file.) @@ -1031,7 +1090,7 @@ as the file being lexed.) return(data); } -API_EXPORT FCPP_LINK int32_t +API_EXPORT FCPP_LINK i32_4tech cpp_lex_data_temp_size(Cpp_Lex_Data *lex_data)/* DOC_PARAM(lex_data, The lex state from which to get the temporary buffer size.) DOC(This call gets the current size of the temporary buffer in the lexer state so @@ -1039,7 +1098,7 @@ that you can move to a new temporary buffer by copying the data over.) DOC_SEE(cpp_lex_data_temp_read) DOC_SEE(cpp_lex_data_new_temp) */{ - int32_t result = lex_data->tb_pos; + i32_4tech result = lex_data->tb_pos; Assert(lex_data->tb != 0); return(result); } @@ -1053,7 +1112,7 @@ DOC(This call reads the current contents of the temporary buffer.) DOC_SEE(cpp_lex_data_temp_size) DOC_SEE(cpp_lex_data_new_temp) */{ - int32_t size = lex_data->tb_pos; + i32_4tech size = lex_data->tb_pos; char *src = lex_data->tb; char *end = src + size; for (; src < end; ++src, ++out_buffer){ @@ -1066,21 +1125,21 @@ cpp_lex_data_new_temp_DEP(Cpp_Lex_Data *lex_data, char *new_buffer) /*DOC(Deprecated in 4cpp Lexer 1.0.1*/{} FCPP_LINK char -cpp_token_get_pp_state(uint16_t bitfield){ +cpp_token_get_pp_state(u16_4tech bitfield){ return (char)(bitfield); } FCPP_LINK void -cpp_shift_token_starts(Cpp_Token_Array *array, int32_t from_token_i, int32_t shift_amount){ +cpp_shift_token_starts(Cpp_Token_Array *array, i32_4tech from_token_i, i32_4tech shift_amount){ Cpp_Token *token = array->tokens + from_token_i; - int32_t count = array->count, i = 0; + i32_4tech count = array->count, i = 0; for (i = from_token_i; i < count; ++i, ++token){ token->start += shift_amount; } } FCPP_LINK Cpp_Token -cpp_index_array(Cpp_Token_Array *array, int32_t file_size, int32_t index){ +cpp_index_array(Cpp_Token_Array *array, i32_4tech file_size, i32_4tech index){ Cpp_Token result; if (index < array->count){ result = array->tokens[index]; @@ -1096,7 +1155,7 @@ cpp_index_array(Cpp_Token_Array *array, int32_t file_size, int32_t index){ } API_EXPORT FCPP_LINK Cpp_Relex_Range -cpp_get_relex_range(Cpp_Token_Array *array, int32_t start_pos, int32_t end_pos) +cpp_get_relex_range(Cpp_Token_Array *array, i32_4tech start_pos, i32_4tech end_pos) /* DOC_PARAM(array, A pointer to the token array that will be modified by the relex, this array should already contain the tokens for the previous state of the file.) @@ -1129,7 +1188,7 @@ The start and end points are based on the edited region of the file before the e } API_EXPORT FCPP_LINK Cpp_Relex_Data -cpp_relex_init(Cpp_Token_Array *array, int32_t start_pos, int32_t end_pos, int32_t character_shift_amount) +cpp_relex_init(Cpp_Token_Array *array, i32_4tech start_pos, i32_4tech end_pos, i32_4tech character_shift_amount) /* DOC_PARAM(array, A pointer to the token array that will be modified by the relex, this array should already contain the tokens for the previous state of the file.) @@ -1172,7 +1231,7 @@ DOC_SEE(cpp_relex_is_start_chunk) return(state); } -API_EXPORT FCPP_LINK int32_t +API_EXPORT FCPP_LINK i32_4tech cpp_relex_start_position(Cpp_Relex_Data *S_ptr) /* DOC_PARAM(S_ptr, A pointer to a state that is done with the first stage of initialization (cpp_relex_init)) @@ -1187,12 +1246,12 @@ DOC_SEE(cpp_relex_init) DOC_SEE(cpp_relex_declare_first_chunk_position) */{ - int32_t result = S_ptr->relex_start_position; + i32_4tech result = S_ptr->relex_start_position; return(result); } API_EXPORT FCPP_LINK void -cpp_relex_declare_first_chunk_position(Cpp_Relex_Data *S_ptr, int32_t position) +cpp_relex_declare_first_chunk_position(Cpp_Relex_Data *S_ptr, i32_4tech position) /* DOC_PARAM(S_ptr, A pointer to a state that is done with the first stage of initialization (cpp_relex_init)) DOC_PARAM(position, The start position of the first chunk that will be fed to the relex process.) @@ -1210,8 +1269,8 @@ DOC_SEE(cpp_relex_start_position) S_ptr->lex.chunk_pos = position; } -API_EXPORT FCPP_LINK int32_t -cpp_relex_is_start_chunk(Cpp_Relex_Data *S_ptr, char *chunk, int32_t chunk_size) +API_EXPORT FCPP_LINK i32_4tech +cpp_relex_is_start_chunk(Cpp_Relex_Data *S_ptr, char *chunk, i32_4tech chunk_size) /* DOC_PARAM(S_ptr, A pointer to a state that is done with the first stage of initialization (cpp_relex_init)) DOC_PARAM(chunk, The chunk to check.) @@ -1228,11 +1287,11 @@ in the one and only call to cpp_relex_step.) DOC_SEE(cpp_relex_init) */{ - int32_t pos = S_ptr->relex_start_position; - int32_t start = S_ptr->lex.chunk_pos; - int32_t end = start + chunk_size; + i32_4tech pos = S_ptr->relex_start_position; + i32_4tech start = S_ptr->lex.chunk_pos; + i32_4tech end = start + chunk_size; - int32_t good_chunk = 0; + i32_4tech good_chunk = 0; if (start <= pos && pos < end){ good_chunk = 1; } @@ -1249,19 +1308,8 @@ DOC_SEE(cpp_relex_init) return(good_chunk); } -// duff-routine defines -#define DrCase(PC) case PC: goto resumespot_##PC - -#define DrYield(PC, n) { \ - S_ptr->result_state = n; \ - *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } - -#define DrReturn(n) { \ - S_ptr->result_state = n; \ - *S_ptr = S; S_ptr->__pc__ = -1; return(n); } - API_EXPORT FCPP_LINK Cpp_Lex_Result -cpp_relex_step(Cpp_Relex_Data *S_ptr, char *chunk, int32_t chunk_size, int32_t full_size, +cpp_relex_step(Cpp_Relex_Data *S_ptr, char *chunk, i32_4tech chunk_size, i32_4tech full_size, Cpp_Token_Array *array, Cpp_Token_Array *relex_array) /* DOC_PARAM(S_ptr, A pointer to a fully initiazed relex state.) @@ -1316,8 +1364,8 @@ DOC_SEE(cpp_relex_abort) Cpp_Lex_Result step_result = LexResult_Finished; switch (S.__pc__){ - DrCase(1); - DrCase(2); + DfrCase(1); + DfrCase(2); } cpp_shift_token_starts(array, S.end_token_index, S.character_shift_amount); @@ -1325,9 +1373,7 @@ DOC_SEE(cpp_relex_abort) // TODO(allen): This can be better I suspect. for (;;){ - step_result = - cpp_lex_nonalloc_no_null_out_limit(&S.lex, chunk, chunk_size, full_size, - relex_array, 1); + step_result = cpp_lex_nonalloc_no_null_out_limit(&S.lex, chunk, chunk_size, full_size, relex_array, 1); switch (step_result){ case LexResult_HitTokenLimit: @@ -1349,24 +1395,29 @@ DOC_SEE(cpp_relex_abort) } break; - case LexResult_NeedChunk: DrYield(1, LexResult_NeedChunk); break; + case LexResult_NeedChunk: + { + S_ptr->result_state = LexResult_NeedChunk; + DfrYield(1, LexResult_NeedChunk); + }break; - case LexResult_NeedTokenMemory: DrYield(2, LexResult_NeedTokenMemory); break; + case LexResult_NeedTokenMemory: + { + S_ptr->result_state = LexResult_NeedTokenMemory; + DfrYield(2, LexResult_NeedTokenMemory); + }break; case LexResult_Finished: goto double_break; } } double_break:; - DrReturn(LexResult_Finished); + S_ptr->result_state = LexResult_Finished; + DfrReturn(LexResult_Finished); } -#undef DrYield -#undef DrReturn -#undef DrCase - -API_EXPORT FCPP_LINK int32_t -cpp_relex_get_new_count(Cpp_Relex_Data *S_ptr, int32_t current_count, Cpp_Token_Array *relex_array) +API_EXPORT FCPP_LINK i32_4tech +cpp_relex_get_new_count(Cpp_Relex_Data *S_ptr, i32_4tech current_count, Cpp_Token_Array *relex_array) /* DOC_PARAM(S_ptr, A pointer to a state that has gone through cpp_relex_step with a LexResult_Finished return.) DOC_PARAM(current_count, The count of tokens in the original array before the edit.) @@ -1376,11 +1427,11 @@ DOC(After getting a LexResult_Finished from cpp_relex_step, this call can be use the size the new array will have. If the original array doesn't have enough capacity to store the new array, it's capacity should be increased before passing to cpp_relex_complete.) */{ - int32_t result = -1; + i32_4tech result = -1; if (S_ptr->result_state == LexResult_Finished){ - int32_t delete_amount = S_ptr->end_token_index - S_ptr->start_token_index; - int32_t shift_amount = relex_array->count - delete_amount; + i32_4tech delete_amount = S_ptr->end_token_index - S_ptr->start_token_index; + i32_4tech shift_amount = relex_array->count - delete_amount; result = current_count + shift_amount; } @@ -1392,12 +1443,12 @@ the new array, it's capacity should be increased before passing to cpp_relex_com #endif FCPP_LINK void -cpp__block_move(void *dst, void *src, int32_t size){ +cpp__block_move(void *dst, void *src, i32_4tech size){ #if !defined(FCPP_FORBID_MEMCPY) memmove(dst, src, size); #else // TODO(allen): find a way to write a fast one of these. - uint8_t *d = (uint8_t*)dst, *s = (uint8_t*)src; + u8_4tech *d = (u8_4tech*)dst, *s = (u8_4tech*)src; if (d < s || d >= s + size){ for (; size > 0; --size){ *(d++) = *(s++); @@ -1424,11 +1475,11 @@ DOC(After getting a LexResult_Finished from cpp_relex_step, and ensuring that array has a large enough capacity by calling cpp_relex_get_new_count, this call does the necessary replacement of tokens in the array to make it match the new file.) */{ - int32_t delete_amount = S_ptr->end_token_index - S_ptr->start_token_index; - int32_t shift_amount = relex_array->count - delete_amount; + i32_4tech delete_amount = S_ptr->end_token_index - S_ptr->start_token_index; + i32_4tech shift_amount = relex_array->count - delete_amount; if (shift_amount != 0){ - int32_t shift_size = array->count - S_ptr->end_token_index; + i32_4tech shift_size = array->count - S_ptr->end_token_index; if (shift_size > 0){ Cpp_Token *old_base = array->tokens + S_ptr->end_token_index; cpp__block_move(old_base + shift_amount, old_base, sizeof(Cpp_Token)*shift_size); @@ -1461,7 +1512,7 @@ is dead.) #include API_EXPORT FCPP_LINK Cpp_Token_Array -cpp_make_token_array(int32_t starting_max)/* +cpp_make_token_array(i32_4tech starting_max)/* DOC_PARAM(starting_max, The number of tokens to initialize the array with.) DOC_RETURN(An empty Cpp_Token_Array with memory malloc'd for storing tokens.) DOC(This call allocates a Cpp_Token_Array with malloc for use in other @@ -1485,7 +1536,7 @@ DOC_SEE(cpp_make_token_array) } API_EXPORT FCPP_LINK void -cpp_resize_token_array(Cpp_Token_Array *token_array, int32_t new_max)/* +cpp_resize_token_array(Cpp_Token_Array *token_array, i32_4tech new_max)/* DOC_PARAM(token_array, An array previously allocated by cpp_make_token_array.) DOC_PARAM(new_max, The new maximum size the array should support. If this is not greater than the current size of the array the operation is ignored.) @@ -1506,7 +1557,7 @@ DOC_SEE(cpp_make_token_array) } API_EXPORT FCPP_LINK void -cpp_lex_file(char *data, int32_t size, Cpp_Token_Array *token_array_out)/* +cpp_lex_file(char *data, i32_4tech size, Cpp_Token_Array *token_array_out)/* DOC_PARAM(data, The file data to be lexed in a single contiguous block.) DOC_PARAM(size, The number of bytes in data.) DOC_PARAM(token_array_out, The token array where the output tokens will be pushed. @@ -1531,13 +1582,13 @@ return(array); DOC_SEE(cpp_make_token_array) */{ Cpp_Lex_Data S = cpp_lex_data_init(); - int32_t quit = 0; + i32_4tech quit = 0; char empty = 0; token_array_out->count = 0; for (;!quit;){ - int32_t result = cpp_lex_step(&S, data, size, HAS_NULL_TERM, token_array_out, NO_OUT_LIMIT); + i32_4tech result = cpp_lex_step(&S, data, size, HAS_NULL_TERM, token_array_out, NO_OUT_LIMIT); switch (result){ case LexResult_Finished: { @@ -1560,7 +1611,7 @@ DOC_SEE(cpp_make_token_array) // NOTE(allen): We told the system to use all of the output memory // but we ran out anyway, so allocate more memory. We hereby assume // the stack was allocated using cpp_make_token_array. - int32_t new_max = 2*token_array_out->max_count + 1; + i32_4tech new_max = 2*token_array_out->max_count + 1; cpp_resize_token_array(token_array_out, new_max); }break; } @@ -1569,6 +1620,12 @@ DOC_SEE(cpp_make_token_array) #endif + +#undef DfrYield +#undef DfrReturn +#undef DfrCase + + #endif // BOTTOM diff --git a/4cpp_lexer_tables.c b/4cpp/4cpp_lexer_tables.c similarity index 100% rename from 4cpp_lexer_tables.c rename to 4cpp/4cpp_lexer_tables.c diff --git a/4cpp_lexer_types.h b/4cpp/4cpp_lexer_types.h similarity index 100% rename from 4cpp_lexer_types.h rename to 4cpp/4cpp_lexer_types.h diff --git a/4ed.cpp b/4ed.cpp index 4abb91ac..cc42e158 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -304,22 +304,6 @@ COMMAND_DECL(redo){ Assert(file->state.undo.undo.size >= 0); } -COMMAND_DECL(history_backward){ - USE_MODELS(models); - REQ_OPEN_VIEW(view); - REQ_FILE_HISTORY(file, view); - - view_history_step(system, models, view, hist_backward); -} - -COMMAND_DECL(history_forward){ - USE_MODELS(models); - REQ_OPEN_VIEW(view); - REQ_FILE_HISTORY(file, view); - - view_history_step(system, models, view, hist_backward); -} - COMMAND_DECL(interactive_new){ USE_VIEW(view); @@ -466,7 +450,6 @@ COMMAND_DECL(toggle_line_wrap){ Assert(view->edit_pos); - // TODO(allen): WHAT TO DO HERE??? Relative_Scrolling scrolling = view_get_relative_scrolling(view); if (file->settings.unwrapped_lines){ file->settings.unwrapped_lines = 0; @@ -495,7 +478,9 @@ COMMAND_DECL(toggle_tokens){ internal void case_change_range(System_Functions *system, Mem_Options *mem, View *view, Editing_File *file, u8 a, u8 z, u8 char_delta){ - Range range = make_range(view->edit_pos->cursor.pos, view->edit_pos->mark); + Range range = {0}; + range.min = Min(view->edit_pos->cursor.pos, view->edit_pos->mark); + range.max = Max(view->edit_pos->cursor.pos, view->edit_pos->mark); if (range.start < range.end){ Edit_Step step = {}; step.type = ED_NORMAL; @@ -522,175 +507,6 @@ case_change_range(System_Functions *system, Mem_Options *mem, View *view, Editin } } -COMMAND_DECL(open_panel_vsplit){ - USE_VARS(vars); - USE_MODELS(models); - USE_PANEL(panel); - - if (models->layout.panel_count < models->layout.panel_max_count){ - Split_Result split = layout_split_panel(&models->layout, panel, 1); - - Panel *panel1 = panel; - Panel *panel2 = split.panel; - - panel2->screen_region = panel1->screen_region; - - i32 x_pos = ROUND32(lerp((f32)panel1->full.x0, - split.divider->pos, - (f32)panel1->full.x1) - ); - - panel2->full.x0 = x_pos; - panel2->full.x1 = panel1->full.x1; - panel1->full.x1 = x_pos; - - panel_fix_internal_area(panel1); - panel_fix_internal_area(panel2); - panel2->prev_inner = panel2->inner; - - models->layout.active_panel = (i32)(panel2 - models->layout.panels); - panel_make_empty(system, vars, panel2); - } -} - -COMMAND_DECL(open_panel_hsplit){ - USE_VARS(vars); - USE_MODELS(models); - USE_PANEL(panel); - - if (models->layout.panel_count < models->layout.panel_max_count){ - Split_Result split = layout_split_panel(&models->layout, panel, 0); - - Panel *panel1 = panel; - Panel *panel2 = split.panel; - - panel2->screen_region = panel1->screen_region; - - i32 y_pos = ROUND32(lerp((f32)panel1->full.y0, - split.divider->pos, - (f32)panel1->full.y1) - ); - - panel2->full.y0 = y_pos; - panel2->full.y1 = panel1->full.y1; - panel1->full.y1 = y_pos; - - panel_fix_internal_area(panel1); - panel_fix_internal_area(panel2); - panel2->prev_inner = panel2->inner; - - models->layout.active_panel = (i32)(panel2 - models->layout.panels); - panel_make_empty(system, vars, panel2); - } -} - -COMMAND_DECL(close_panel){ - USE_MODELS(models); - USE_PANEL(panel); - USE_VIEW(view); - - Panel *panel_ptr, *used_panels; - Divider_And_ID div, parent_div, child_div; - i32 child; - i32 parent; - i32 which_child; - i32 active; - - if (models->layout.panel_count > 1){ - live_set_free_view(command->live_set, view); - panel->view = 0; - - div = layout_get_divider(&models->layout, panel->parent); - - // This divider cannot have two child dividers. - Assert(div.divider->child1 == -1 || div.divider->child2 == -1); - - // Get the child who needs to fill in this node's spot - child = div.divider->child1; - if (child == -1) child = div.divider->child2; - - parent = div.divider->parent; - which_child = div.divider->which_child; - - // Fill the child in the slot this node use to hold - if (parent == -1){ - Assert(models->layout.root == div.id); - models->layout.root = child; - } - else{ - parent_div = layout_get_divider(&models->layout, parent); - if (which_child == -1){ - parent_div.divider->child1 = child; - } - else{ - parent_div.divider->child2 = child; - } - } - - // If there was a child divider, give it information about it's new parent. - if (child != -1){ - child_div = layout_get_divider(&models->layout, child); - child_div.divider->parent = parent; - child_div.divider->which_child = div.divider->which_child; - } - - // What is the new active panel? - active = -1; - if (child == -1){ - used_panels = &models->layout.used_sentinel; - for (dll_items(panel_ptr, used_panels)){ - if (panel_ptr != panel && panel_ptr->parent == div.id){ - panel_ptr->parent = parent; - panel_ptr->which_child = which_child; - active = (i32)(panel_ptr - models->layout.panels); - break; - } - } - } - else{ - panel_ptr = panel->next; - if (panel_ptr == &models->layout.used_sentinel){ - panel_ptr = panel_ptr->next; - } - Assert(panel_ptr != panel); - active = (i32)(panel_ptr - models->layout.panels); - } - - Assert(active != -1 && panel != models->layout.panels + active); - models->layout.active_panel = active; - - layout_free_divider(&models->layout, div.divider); - layout_free_panel(&models->layout, panel); - layout_fix_all_panels(&models->layout); - } -} - -COMMAND_DECL(page_down){ - REQ_READABLE_VIEW(view); - - Assert(view->edit_pos); - - i32 height = CEIL32(view_file_height(view)); - f32 y = view_get_cursor_y(view); - f32 x = view->edit_pos->preferred_x; - - Full_Cursor cursor = view_compute_cursor_from_xy(view, x, y+height); - view_set_cursor(view, cursor, false, view->file_data.file->settings.unwrapped_lines); -} - -COMMAND_DECL(page_up){ - REQ_READABLE_VIEW(view); - - Assert(view->edit_pos); - - i32 height = CEIL32(view_file_height(view)); - f32 y = view_get_cursor_y(view); - f32 x = view->edit_pos->preferred_x; - - Full_Cursor cursor = view_compute_cursor_from_xy(view, x, y-height); - view_set_cursor(view, cursor, false, view->file_data.file->settings.unwrapped_lines); -} - COMMAND_DECL(open_color_tweaker){ USE_VIEW(view); view_show_theme(view); @@ -717,7 +533,7 @@ COMMAND_DECL(user_callback){ if (binding.custom) binding.custom(&models->app_links); } -globalvar Command_Function command_table[cmdid_count]; +global Command_Function command_table[cmdid_count]; #include "4ed_api_implementation.cpp" @@ -749,13 +565,6 @@ command_caller(Coroutine *coroutine){ } } -internal void -view_caller(Coroutine *coroutine){ - View *view = (View*)coroutine->in; - View_Persistent *persistent = &view->persistent; - persistent->view_routine(&persistent->models->app_links, persistent->id); -} - internal void app_links_init(System_Functions *system, Application_Links *app_links, void *data, i32 size){ app_links->memory = data; @@ -805,8 +614,6 @@ setup_command_table(){ SET(undo); SET(redo); - SET(history_backward); - SET(history_forward); SET(interactive_new); SET(interactive_open); @@ -1429,16 +1236,10 @@ App_Init_Sig(app_init){ persistent = &view->persistent; persistent->id = i; persistent->models = models; - persistent->view_routine = models->config_api.view_routine; } } { - Command_Map *global = 0; - i32 wanted_size = 0; - b32 did_top = 0; - b32 did_file = 0; - models->scroll_rule = fallback_scroll_rule; models->hook_open_file = 0; models->hook_new_file = 0; @@ -1446,11 +1247,13 @@ App_Init_Sig(app_init){ setup_command_table(); - global = &models->map_top; + Command_Map *global_map = &models->map_top; Assert(models->config_api.get_bindings != 0); - wanted_size = models->config_api.get_bindings(models->app_links.memory, models->app_links.memory_size); + i32 wanted_size = models->config_api.get_bindings(models->app_links.memory, models->app_links.memory_size); + b32 did_top = false; + b32 did_file = false; if (wanted_size <= models->app_links.memory_size){ Command_Map *map_ptr = 0; Binding_Unit *unit, *end; @@ -1497,21 +1300,23 @@ App_Init_Sig(app_init){ i32 table_max = count * 3 / 2; if (mapid == mapid_global){ map_ptr = &models->map_top; - map_init(map_ptr, &models->mem.part, table_max, global); - did_top = 1; + map_init(map_ptr, &models->mem.part, table_max, global_map); + did_top = true; } else if (mapid == mapid_file){ map_ptr = &models->map_file; - map_init(map_ptr, &models->mem.part, table_max, global); - did_file = 1; + map_init(map_ptr, &models->mem.part, table_max, global_map); + did_file = true; } else if (mapid < mapid_global){ i32 index = get_or_add_map_index(models, mapid); Assert(index < user_map_count); map_ptr = models->user_maps + index; - map_init(map_ptr, &models->mem.part, table_max, global); + map_init(map_ptr, &models->mem.part, table_max, global_map); + } + else{ + map_ptr = 0; } - else map_ptr = 0; if (map_ptr && unit->map_begin.replace){ map_clear(map_ptr); @@ -1574,27 +1379,27 @@ App_Init_Sig(app_init){ } else{ switch (hook_id){ - case _hook_open_file: + case special_hook_open_file: models->hook_open_file = (Open_File_Hook_Function*)unit->hook.func; break; - case _hook_new_file: + case special_hook_new_file: models->hook_new_file = (Open_File_Hook_Function*)unit->hook.func; break; - case _hook_save_file: + case special_hook_save_file: models->hook_save_file = (Open_File_Hook_Function*)unit->hook.func; break; - case _hook_command_caller: + case special_hook_command_caller: models->command_caller = (Command_Caller_Hook_Function*)unit->hook.func; break; - case _hook_scroll_rule: + case special_hook_scroll_rule: models->scroll_rule = (Scroll_Rule_Function*)unit->hook.func; break; - case _hook_input_filter: + case special_hook_input_filter: models->input_filter = (Input_Filter_Function*)unit->hook.func; break; } @@ -1607,10 +1412,10 @@ App_Init_Sig(app_init){ } memset(models->app_links.memory, 0, wanted_size); - if (!did_top) setup_top_commands(&models->map_top, &models->mem.part, global); - if (!did_file) setup_file_commands(&models->map_file, &models->mem.part, global); + if (!did_top) setup_top_commands(&models->map_top, &models->mem.part, global_map); + if (!did_file) setup_file_commands(&models->map_file, &models->mem.part, global_map); - setup_ui_commands(&models->map_ui, &models->mem.part, global); + setup_ui_commands(&models->map_ui, &models->mem.part, global_map); } // NOTE(allen): font setup @@ -2008,7 +1813,7 @@ App_Step_Sig(app_step){ // NOTE(allen): update child processes if (input->dt > 0){ Temp_Memory temp = begin_temp_memory(&models->mem.part); - u32 max = Kbytes(128); + u32 max = KB(128); char *dest = push_array(&models->mem.part, char, max); i32 count = vars->cli_processes.count; diff --git a/4ed.h b/4ed.h index c8a92680..8776af83 100644 --- a/4ed.h +++ b/4ed.h @@ -84,14 +84,13 @@ Command_Line_Parameters clparams) typedef App_Read_Command_Line_Sig(App_Read_Command_Line); +struct Custom_API{ + Get_Binding_Data_Function *get_bindings; + _Get_Version_Function *get_alpha_4coder_version; +}; -#define App_Init_Sig(name) void \ -name(System_Functions *system, \ -Render_Target *target, \ -Application_Memory *memory, \ -String clipboard, \ -String current_directory, \ -Custom_API api) +#define App_Init_Sig(name) \ +void name(System_Functions *system, Render_Target *target, Application_Memory *memory, String clipboard, String current_directory, Custom_API api) typedef App_Init_Sig(App_Init); diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 179a0974..26aec44a 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -1367,18 +1367,14 @@ DOC_SEE(View_Split_Position) split.panel->screen_region = panel->screen_region; if (vsplit){ - i32 x_pos = ROUND32(lerp((f32)lsrpanel->full.x0, - split.divider->pos, - (f32)lsrpanel->full.x1)); + i32 x_pos = round32(lerp((f32)lsrpanel->full.x0, split.divider->pos, (f32)lsrpanel->full.x1)); grtpanel->full.x0 = x_pos; grtpanel->full.x1 = lsrpanel->full.x1; lsrpanel->full.x1 = x_pos; } else{ - i32 y_pos = ROUND32(lerp((f32)lsrpanel->full.y0, - split.divider->pos, - (f32)lsrpanel->full.y1)); + i32 y_pos = round32(lerp((f32)lsrpanel->full.y0, split.divider->pos, (f32)lsrpanel->full.y1)); grtpanel->full.y0 = y_pos; grtpanel->full.y1 = lsrpanel->full.y1; @@ -2156,20 +2152,6 @@ directories controlled on the custom side. return(hot->string.size); } -// TODO(allen): Replace this with an autogenerated file -#define Memory_Allocate system->memory_allocate -#define Memory_Set_Protection system->memory_set_protection -#define Memory_Free system->memory_free - -#define Get_4ed_Path system->get_4ed_path -#define File_Exists system->file_exists -#define Directory_CD system->directory_cd -#define Show_Mouse_Cursor system->show_mouse_cursor - -#define Toggle_Fullscreen system->toggle_fullscreen -#define Is_Fullscreen system->is_fullscreen -#define Send_Exit_Signal system->send_exit_signal - API_EXPORT File_List Get_File_List(Application_Links *app, char *dir, int32_t len) /* @@ -2213,5 +2195,149 @@ DOC(This is a temporary ad-hoc solution to allow some customization of the behav models->user_down_key = down_key; } +API_EXPORT void* +Memory_Allocate(Application_Links *app, int32_t size) +/* +DOC_PARAM(size, The size in bytes of the block that should be returned.) +DOC(This calls to a low level OS allocator which means it is best used for infrequent, large allocations. The size of the block must be remembered if it will be freed or if it's mem protection status will be changed.) +DOC_SEE(memory_free) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + void *result = system->memory_allocate(size); + return(result); +} + +API_EXPORT bool32 +Memory_Set_Protection(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags) +/* +DOC_PARAM(ptr, The base of the block on which to set memory protection flags.) +DOC_PARAM(size, The size that was originally used to allocate this block.) +DOC_PARAM(flags, The new memory protection flags.) +DOC(This call sets the memory protection flags of a block of memory that was previously allocate by memory_allocate.) +DOC_SEE(memory_allocate) +DOC_SEE(Memory_Protect_Flags) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + bool32 result = system->memory_set_protection(ptr, size, flags); + return(result); +} + +API_EXPORT void +Memory_Free(Application_Links *app, void *ptr, int32_t size) +/* +DOC_PARAM(mem, The base of a block to free.) +DOC_PARAM(size, The size that was originally used to allocate this block.) +DOC(This call frees a block of memory that was previously allocated by memory_allocate.) +DOC_SEE(memory_allocate) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + system->memory_free(ptr, size); +} + +API_EXPORT bool32 +File_Exists(Application_Links *app, char *filename, int32_t len) +/* +DOC_PARAM(filename, This parameter specifies the full path to a file; it need not be null terminated.) +DOC_PARAM(len, This parameter specifies the length of the filename string.) +DOC_RETURN(This call returns non-zero if and only if the file exists.) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + bool32 result = system->file_exists(filename, len); + return(result); +} + +API_EXPORT bool32 +Directory_CD(Application_Links *app, char *dir, int32_t *len, int32_t capacity, char *rel_path, int32_t rel_len) +/* +DOC_PARAM(dir, This parameter provides a character buffer that stores a directory; it need not be null terminated.) +DOC_PARAM(len, This parameter specifies the length of the dir string.) +DOC_PARAM(capacity, This parameter specifies the maximum size of the dir string.) +DOC_PARAM(rel_path, This parameter specifies the path to change to, may include '.' or '..'; it need not be null terminated.) +DOC_PARAM(rel_len, This parameter specifies the length of the rel_path string.) +DOC_RETURN(This call returns non-zero if the call succeeds.) +DOC( +This call succeeds if the new directory exists and the it fits inside the dir buffer. If the call succeeds the dir buffer is filled with the new directory and len is overwritten with the length of the new string in the buffer. + +For instance if dir contains "C:/Users/MySelf" and rel is "Documents" the buffer will contain "C:/Users/MySelf/Documents" and len will contain the length of that string. This call can also be used with rel set to ".." to traverse to parent folders. +)*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + bool32 result = system->directory_cd(dir, len, capacity, rel_path, rel_len); + return(result); +} + +API_EXPORT int32_t +Get_4ed_Path(Application_Links *app, char *out, int32_t capacity) +/* +DOC_PARAM(out, This parameter provides a character buffer that receives the path to the 4ed executable file.) +DOC_PARAM(capacity, This parameter specifies the maximum capacity of the out buffer.) +DOC_RETURN(This call returns non-zero on success.) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + int32_t result = system->get_4ed_path(out, capacity); + return(result); +} + +// TODO(allen): add a "shown but auto-hides on timer" setting here. +API_EXPORT void +Show_Mouse_Cursor(Application_Links *app, Mouse_Cursor_Show_Type show) +/* +DOC_PARAM(show, This parameter specifies the new state of the mouse cursor.) +DOC_SEE(Mouse_Cursor_Show_Type) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + system->show_mouse_cursor(show); +} + +API_EXPORT void +Toggle_Fullscreen(Application_Links *app) +/* +DOC(This call tells 4coder to switch into or out of full screen mode. +The changes of full screen mode do not take effect until the end of the current frame. +On Windows this call will not work unless 4coder was started in "stream mode". +Stream mode can be enabled with -S or -F flags on the command line to 4ed.) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + if (!system->toggle_fullscreen()){ + char msg[] = + "ERROR: Failed to go fullscreen.\n" + "You can try using 'stream mode' by launching with the -S flag.\n"; + print_message(app, literal(msg)); + } +} + +API_EXPORT bool32 +Is_Fullscreen(Application_Links *app) +/* +DOC(This call returns true if the 4coder is in full screen mode. This call +takes toggles that have already occured this frame into account. So it may return +true even though the frame has not ended and actually put 4coder into full screen. If +it returns true though, 4coder will definitely be full screen by the beginning of the next +frame if the state is not changed.) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + bool32 result = system->is_fullscreen(); + return(result); +} + +API_EXPORT void +Send_Exit_Signal(Application_Links *app) +/* +DOC(This call sends a signal to 4coder to attempt to exit. If there are unsaved +files this triggers a dialogue ensuring you're okay with closing.) +*/{ + Command_Data *cmd = (Command_Data*)app->cmd_context; + System_Functions *system = cmd->system; + system->send_exit_signal(); +} + // BOTTOM diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index f2ff8a56..5b711e6f 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -9,34 +9,34 @@ // TOP -// TODO(allen): can I get away from this one? +// TODO(allen): get away from assert.h +// TODO(allen): get away from string.h #include -#include "common/4coder_defines.h" +#include + +#include "4tech_defines.h" + +#include "4coder_API/custom.h" + +#include "4ed_math.h" +#include "4ed_system.h" + +//#define USE_DEBUG_MEMORY #define FSTRING_IMPLEMENTATION #define FSTRING_C -#include "4coder_string.h" - -#include "4coder_custom.h" - -#include "4ed_math.h" - -#include "4ed_system.h" -#include "4ed_rendering.h" - -#include "4ed.h" - -# include "4coder_mem.h" - -//#define USE_DEBUG_MEMORY +#include "4coder_lib/4coder_string.h" +#include "4coder_lib/4coder_mem.h" +#include "4coder_lib/4coder_table.h" #if defined(USE_DEBUG_MEMORY) # include "4ed_debug_mem.h" #endif -#define FCPP_FORBID_MALLOC -#include "4cpp_lexer.h" +#include "4ed_rendering.h" +#include "4ed.h" -#include "4coder_table.cpp" +#define FCPP_FORBID_MALLOC +#include "4cpp/4cpp_lexer.h" #include "4ed_doubly_linked_list.cpp" @@ -53,6 +53,7 @@ #include "file/4coder_working_set.cpp" #include "file/4coder_hot_directory.cpp" +#include "4ed_gui.h" #include "4ed_gui.cpp" #include "4ed_layout.cpp" #include "4ed_app_models.h" diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index a40b07a8..b73e6753 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -175,7 +175,6 @@ context_eq(Scroll_Context a, Scroll_Context b){ struct View_Persistent{ i32 id; - View_Routine_Function *view_routine; Coroutine *coroutine; Event_Message message_passing_slot; @@ -477,7 +476,7 @@ inline i32 view_compute_max_target_y(i32 lowest_line, i32 line_height, f32 view_height){ f32 max_target_y = ((lowest_line+.5f)*line_height) - view_height*.5f; max_target_y = clamp_bottom(0.f, max_target_y); - return(CEIL32(max_target_y)); + return(ceil32(max_target_y)); } internal i32 @@ -521,28 +520,28 @@ view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll, b32 center_view){ if (cursor_y > target_y + limits.max){ if (center_view){ - target_y = ROUND32(cursor_y - limits.max*.5f); + target_y = round32(cursor_y - limits.max*.5f); } else{ - target_y = CEIL32(cursor_y - limits.max + limits.delta); + target_y = ceil32(cursor_y - limits.max + limits.delta); } } if (cursor_y < target_y + limits.min){ if (center_view){ - target_y = ROUND32(cursor_y - limits.max*.5f); + target_y = round32(cursor_y - limits.max*.5f); } else{ - target_y = FLOOR32(cursor_y - limits.delta - limits.min); + target_y = floor32(cursor_y - limits.delta - limits.min); } } target_y = clamp(0, target_y, max_y); if (cursor_x >= target_x + max_x){ - target_x = CEIL32(cursor_x - max_x/2); + target_x = ceil32(cursor_x - max_x/2); } else if (cursor_x < target_x){ - target_x = FLOOR32(Max(0, cursor_x - max_x/2)); + target_x = floor32(Max(0, cursor_x - max_x/2)); } if (target_x != scroll_vars.target_x || target_y != scroll_vars.target_y){ @@ -854,7 +853,7 @@ file_grow_starts_as_needed(General_Memory *general, Gap_Buffer *buffer, i32 addi i32 target_lines = count + additional_lines; if (target_lines > max || max == 0){ - max = l_round_up_i32(target_lines + max, Kbytes(1)); + max = l_round_up(target_lines + max, KB(1)); i32 *new_lines = (i32*)general_memory_reallocate(general, buffer->line_starts, sizeof(i32)*count, sizeof(f32)*max); @@ -896,7 +895,7 @@ file_update_cursor_positions(Models *models, Editing_File *file){ internal void file_measure_starts(General_Memory *general, Gap_Buffer *buffer){ if (!buffer->line_starts){ - i32 max = buffer->line_max = Kbytes(1); + i32 max = buffer->line_max = KB(1); buffer->line_starts = (i32*)general_memory_allocate(general, max*sizeof(i32)); TentativeAssert(buffer->line_starts); // TODO(allen): when unable to allocate? @@ -977,7 +976,7 @@ struct Code_Wrap_X{ i32 paren_safe_top; i32 paren_top; }; -globalvar Code_Wrap_X null_wrap_x = {0}; +global Code_Wrap_X null_wrap_x = {0}; struct Code_Wrap_State{ Cpp_Token_Array token_array; @@ -1462,7 +1461,7 @@ file_measure_wraps(Models *models, Editing_File *file, f32 font_height, f32 *adv wrap_state_init(&wrap_state, file, adv); use_tokens = 1; - potential_marks = push_array(part, Potential_Wrap_Indent_Pair, FLOOR32(width)); + potential_marks = push_array(part, Potential_Wrap_Indent_Pair, floor32(width)); max_wrap_indent_mark = partition_remaining(part)/sizeof(Wrap_Indent_Pair); wrap_indent_marks = push_array(part, Wrap_Indent_Pair, max_wrap_indent_mark); @@ -1905,8 +1904,10 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File * Gap_Buffer_Init init = buffer_begin_init(&file->state.buffer, val.str, val.size); for (; buffer_init_need_more(&init); ){ i32 page_size = buffer_init_page_size(&init); - page_size = l_round_up_i32(page_size, Kbytes(4)); - if (page_size < Kbytes(4)) page_size = Kbytes(4); + page_size = l_round_up(page_size, KB(4)); + if (page_size < KB(4)){ + page_size = KB(4); + } void *data = general_memory_allocate(general, page_size); buffer_init_provide_page(&init, data, page_size); } @@ -1937,7 +1938,7 @@ file_create_from_string(System_Functions *system, Models *models, Editing_File * file->settings.read_only = read_only; if (!read_only){ // TODO(allen): Redo undo system (if you don't mind the pun) - i32 request_size = Kbytes(64); + i32 request_size = KB(64); file->state.undo.undo.max = request_size; file->state.undo.undo.strings = (u8*)general_memory_allocate(general, request_size); file->state.undo.undo.edit_max = request_size / sizeof(Edit_Step); @@ -2079,7 +2080,7 @@ Job_Callback_Sig(job_full_lex){ } } while (still_lexing); - i32 new_max = l_round_up_i32(tokens.count+1, Kbytes(1)); + i32 new_max = l_round_up(tokens.count+1, KB(1)); system->acquire_lock(FRAME_LOCK); { @@ -2206,7 +2207,7 @@ file_first_lex_serial(Mem_Options *mem, Editing_File *file){ } } while (still_lexing); - i32 new_max = l_round_up_i32(tokens.count+1, Kbytes(1)); + i32 new_max = l_round_up(tokens.count+1, KB(1)); { Assert(file->state.swap_array.tokens == 0); @@ -2320,7 +2321,7 @@ file_relex_parallel(System_Functions *system, Mem_Options *mem, Editing_File *fi if (inline_lex){ i32 new_count = cpp_relex_get_new_count(&state, array->count, &relex_array); if (new_count > array->max_count){ - i32 new_max = l_round_up_i32(new_count, Kbytes(1)); + i32 new_max = l_round_up(new_count, KB(1)); array->tokens = (Cpp_Token*) general_memory_reallocate(general, array->tokens, array->count*sizeof(Cpp_Token), new_max*sizeof(Cpp_Token)); array->max_count = new_max; @@ -2435,9 +2436,8 @@ file_relex_serial(Mem_Options *mem, Editing_File *file, i32 start_i, i32 end_i, i32 new_count = cpp_relex_get_new_count(&state, array->count, &relex_array); if (new_count > array->max_count){ - i32 new_max = l_round_up_i32(new_count, Kbytes(1)); - array->tokens = (Cpp_Token*) - general_memory_reallocate(general, array->tokens, array->count*sizeof(Cpp_Token), new_max*sizeof(Cpp_Token)); + i32 new_max = l_round_up(new_count, KB(1)); + array->tokens = (Cpp_Token*)general_memory_reallocate(general, array->tokens, array->count*sizeof(Cpp_Token), new_max*sizeof(Cpp_Token)); array->max_count = new_max; } @@ -2658,7 +2658,7 @@ file_post_history(General_Memory *general, Editing_File *file, Edit_Step step, b Edit_Stack *history = &file->state.undo.history; Edit_Step *result = 0; - persist Edit_Type reverse_types[4]; + local_persist Edit_Type reverse_types[4]; if (reverse_types[ED_UNDO] == 0){ reverse_types[ED_NORMAL] = ED_REVERSE_NORMAL; reverse_types[ED_REVERSE_NORMAL] = ED_NORMAL; @@ -2816,7 +2816,7 @@ view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){ if (view->edit_pos){ view->edit_pos->scroll.scroll_y = cursor_y - scrolling.scroll_y; - view->edit_pos->scroll.target_y = ROUND32(clamp_bottom(0.f, cursor_y - scrolling.target_y)); + view->edit_pos->scroll.target_y = round32(clamp_bottom(0.f, cursor_y - scrolling.target_y)); } } @@ -3088,8 +3088,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, } y_position += y_offset; - scroll.target_y += - ROUND32(y_position - scroll.scroll_y); + scroll.target_y += round32(y_position - scroll.scroll_y); scroll.scroll_y = y_position; } @@ -4165,10 +4164,10 @@ view_reinit_scrolling(View *view){ h = view_file_height(view); if (cursor_x >= target_x + w){ - target_x = ROUND32(cursor_x - w*.35f); + target_x = round32(cursor_x - w*.35f); } - target_y = clamp_bottom(0, FLOOR32(cursor_y - h*.5f)); + target_y = clamp_bottom(0, floor32(cursor_y - h*.5f)); } GUI_Scroll_Vars scroll = {0}; @@ -4254,9 +4253,9 @@ begin_exhaustive_loop(Exhaustive_File_Loop *loop, Hot_Directory *hdir){ internal Exhaustive_File_Info get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhaustive_File_Loop *loop, i32 i){ - persist String message_loaded = make_lit_string(" LOADED"); - persist String message_unsaved = make_lit_string(" LOADED *"); - persist String message_unsynced = make_lit_string(" LOADED !"); + local_persist String message_loaded = make_lit_string(" LOADED"); + local_persist String message_unsaved = make_lit_string(" LOADED *"); + local_persist String message_unsynced = make_lit_string(" LOADED !"); Exhaustive_File_Info result = {0}; Editing_File *file = 0; @@ -5029,8 +5028,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su case IInt_Live_File_List: { - persist String message_unsaved = make_lit_string(" *"); - persist String message_unsynced = make_lit_string(" !"); + local_persist String message_unsaved = make_lit_string(" *"); + local_persist String message_unsynced = make_lit_string(" !"); String message = {0}; switch (view->action){ @@ -5805,7 +5804,7 @@ do_step_file_view(System_Functions *system, v = unlerp(gui_session.scroll_top, (f32)my, gui_session.scroll_bottom); v = clamp(0.f, v, 1.f); - result.vars.target_y = ROUND32(lerp(0.f, v, (f32)max_y)); + result.vars.target_y = round32(lerp(0.f, v, (f32)max_y)); gui_activate_scrolling(target); result.is_animating = 1; @@ -6146,7 +6145,7 @@ draw_text_field(Render_Target *target, View *view, i16 font_id, if (target){ draw_rectangle(target, rect, back_color); - x = CEIL32(draw_string(target, font_id, p, x, y, text2_color)); + x = ceil32(draw_string(target, font_id, p, x, y, text2_color)); draw_string(target, font_id, t, x, y, text1_color); } } @@ -6178,19 +6177,19 @@ draw_text_with_cursor(Render_Target *target, View *view, i16 font_id, part3 = substr(s, pos+1, s.size-pos-1); - x = draw_string(target, font_id, part1, FLOOR32(x), y, text_color); + x = draw_string(target, font_id, part1, floor32(x), y, text_color); - cursor_rect.x0 = FLOOR32(x); - cursor_rect.x1 = FLOOR32(x) + CEIL32(font->advance_data[s.str[pos]]); + cursor_rect.x0 = floor32(x); + cursor_rect.x1 = floor32(x) + ceil32(font->advance_data[s.str[pos]]); cursor_rect.y0 = y; cursor_rect.y1 = y + view->line_height; draw_rectangle(target, cursor_rect, cursor_color); - x = draw_string(target, font_id, part2, FLOOR32(x), y, at_cursor_color); + x = draw_string(target, font_id, part2, floor32(x), y, at_cursor_color); - draw_string(target, font_id, part3, FLOOR32(x), y, text_color); + draw_string(target, font_id, part3, floor32(x), y, text_color); } else{ - draw_string(target, font_id, s, FLOOR32(x), y, text_color); + draw_string(target, font_id, s, floor32(x), y, text_color); } } } @@ -6254,13 +6253,13 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re switch (file_get_sync(file)){ case DirtyState_UnloadedChanges: { - persist String out_of_sync = make_lit_string(" !"); + local_persist String out_of_sync = make_lit_string(" !"); intbar_draw_string(target, &bar, out_of_sync, pop2_color); }break; case DirtyState_UnsavedChanges: { - persist String out_of_sync = make_lit_string(" *"); + local_persist String out_of_sync = make_lit_string(" *"); intbar_draw_string(target, &bar, out_of_sync, pop2_color); }break; } @@ -6358,13 +6357,12 @@ draw_fat_option_block(GUI_Target *gui_target, Render_Target *target, View *view, x = checkbox_rect.x1 + 3; } - x = CEIL32(draw_string(target, font_id, text, x, y, text_color)); + x = ceil32(draw_string(target, font_id, text, x, y, text_color)); draw_string(target, font_id, pop, x, y, pop_color); } internal void -draw_button(GUI_Target *gui_target, Render_Target *target, View *view, - i16 font_id, i32_Rect rect, GUI_id id, String text){ +draw_button(GUI_Target *gui_target, Render_Target *target, View *view, i16 font_id, i32_Rect rect, GUI_id id, String text){ Models *models = view->persistent.models; Style *style = main_style(models); @@ -6410,7 +6408,7 @@ draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, i32 y = inner.y0; i32 x = inner.x0; - x = CEIL32(draw_string(target, font_id, style->name.str, x, y, text_color)); + x = ceil32(draw_string(target, font_id, style->name.str, x, y, text_color)); i32 font_x = (i32)(inner.x1 - font_string_width(target, font_id, info->name.str)); if (font_x > x + 10){ draw_string(target, font_id, info->name.str, font_x, y, text_color); @@ -6418,13 +6416,13 @@ draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, x = inner.x0; y += info->height; - x = CEIL32(draw_string(target, font_id, "if", x, y, keyword_color)); - x = CEIL32(draw_string(target, font_id, "(x < ", x, y, text_color)); - x = CEIL32(draw_string(target, font_id, "0", x, y, int_constant_color)); - x = CEIL32(draw_string(target, font_id, ") { x = ", x, y, text_color)); - x = CEIL32(draw_string(target, font_id, "0", x, y, int_constant_color)); - x = CEIL32(draw_string(target, font_id, "; } ", x, y, text_color)); - x = CEIL32(draw_string(target, font_id, "// comment", x, y, comment_color)); + x = ceil32(draw_string(target, font_id, "if", x, y, keyword_color)); + x = ceil32(draw_string(target, font_id, "(x < ", x, y, text_color)); + x = ceil32(draw_string(target, font_id, "0", x, y, int_constant_color)); + x = ceil32(draw_string(target, font_id, ") { x = ", x, y, text_color)); + x = ceil32(draw_string(target, font_id, "0", x, y, int_constant_color)); + x = ceil32(draw_string(target, font_id, "; } ", x, y, text_color)); + x = ceil32(draw_string(target, font_id, "// comment", x, y, comment_color)); x = inner.x0; y += info->height; @@ -6680,7 +6678,7 @@ live_set_alloc_view(Live_Views *live_set, Panel *panel, Models *models){ init_query_set(&result.view->query_set); { - i32 gui_mem_size = Kbytes(512); + i32 gui_mem_size = KB(512); void *gui_mem = general_memory_allocate(&models->mem.general, gui_mem_size + 8); result.view->gui_mem = gui_mem; gui_mem = advance_to_alignment(gui_mem); diff --git a/4ed_gui.cpp b/4ed_gui.cpp index db53c229..f21be2c2 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -213,14 +213,14 @@ gui_active_level(GUI_Target *target, GUI_id id){ i32 level = 0; if (gui_id_eq(target->active, id)){ level = 4; - } + } else if (gui_id_eq(target->auto_hot, id)){ level = 3; } else if (gui_id_eq(target->mouse_hot, id)){ if (gui_id_eq(target->hover, id)){ level = 3; - } + } else{ level = 2; } @@ -305,7 +305,7 @@ gui_push_aligned_item(GUI_Target *target, GUI_Header *h, void *item, i32 size){ char *ptr = (char*)partition_allocate(&target->push, size); if (ptr && item){ memcpy(ptr, item, size); - } + } gui_align(target, h); return(ptr); } @@ -316,7 +316,7 @@ gui_push_item(GUI_Target *target, GUI_Header *h, void *item, i32 size){ ptr = (char*)partition_allocate(&target->push, size); if (ptr && item){ memcpy(ptr, item, size); - } + } h->size += size; return(ptr); } @@ -445,7 +445,7 @@ gui_do_color_button(GUI_Target *target, GUI_id id, u32 fore, u32 back, String te if (gui_id_eq(id, target->active)){ result = 1; target->animating = 1; - } + } return(result); } @@ -462,7 +462,7 @@ gui_do_font_button(GUI_Target *target, GUI_id id, i16 font_id, String text){ if (gui_id_eq(id, target->active)){ result = 1; target->animating = 1; - } + } return(result); } @@ -485,7 +485,7 @@ gui_begin_list(GUI_Target *target, GUI_id id, i32 list_i, if (gui_id_eq(id, target->active)){ active = 1; result = 1; - } + } if (snap_into_view){ if (target->list_view_min > list_min){ @@ -543,7 +543,7 @@ gui_do_file_option(GUI_Target *target, GUI_id id, String filename, if (gui_id_eq(id, target->active)){ result = 1; target->animating = 1; - } + } return(result); } @@ -559,7 +559,7 @@ gui_do_button(GUI_Target *target, GUI_id id, String message){ if (gui_id_eq(id, target->active)){ result = 1; target->animating = 1; - } + } return(result); } @@ -576,7 +576,7 @@ gui_do_fixed_option(GUI_Target *target, GUI_id id, String message, char key){ if (gui_id_eq(id, target->active)){ result = 1; target->animating = 1; - } + } return(result); } @@ -594,7 +594,7 @@ gui_do_fixed_option_checkbox(GUI_Target *target, GUI_id id, String message, char if (gui_id_eq(id, target->active)){ result = 1; target->animating = 1; - } + } return(result); } @@ -610,7 +610,7 @@ gui_do_style_preview(GUI_Target *target, GUI_id id, i32 style_index){ if (gui_id_eq(id, target->active)){ result = 1; target->animating = 1; - } + } return(result); } @@ -821,7 +821,7 @@ gui_layout_top_bottom(GUI_Session *session, i32 y0, i32 y1){ if (session->is_scrollable){ rect.x0 = session->scroll_region.x0; rect.x1 = session->scroll_region.x1; - } + } return(rect); } @@ -968,10 +968,10 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, y = section->v; if (!session->is_scrollable) scroll_v = 0; - + switch (h->type){ case guicom_null: Assert(0); break; - + case guicom_begin_serial: ++session->t; Assert(session->t < ArrayCount(session->sections)); @@ -980,21 +980,21 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, new_section->max_v = y; new_section->top_v = y; break; - + case guicom_end_serial: Assert(session->t > 0); prev_section = &session->sections[--session->t]; end_v = section->max_v; end_section = prev_section; break; - + case guicom_top_bar: give_to_user = 1; rect = gui_layout_fixed_h(session, y, session->line_height + 2); end_v = rect.y1; end_section = section; break; - + case guicom_file: give_to_user = 1; rect = gui_layout_top_bottom(session, y, session->full_rect.y1); @@ -1002,7 +1002,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, end_section = section; scroll_v = 0; break; - + case guicom_text_with_cursor: case guicom_text_field: give_to_user = 1; @@ -1010,7 +1010,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, end_v = rect.y1; end_section = section; break; - + case guicom_color_button: case guicom_font_button: give_to_user = 1; @@ -1018,7 +1018,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, end_v = rect.y1; end_section = section; break; - + case guicom_begin_list: { GUI_Interactive *b = (GUI_Interactive*)h; @@ -1164,9 +1164,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, case guicom_end_scrollable_section: always_give_to_user = 1; - session->suggested_max_y = - CEIL32(session->scrollable_items_bottom - - (session->full_rect.y0 + session->full_rect.y1)*.5f); + session->suggested_max_y = ceil32(session->scrollable_items_bottom - (session->full_rect.y0 + session->full_rect.y1)*.5f); if (session->suggested_max_y < 0){ session->suggested_max_y = 0; } diff --git a/4coder_gui.h b/4ed_gui.h similarity index 100% rename from 4coder_gui.h rename to 4ed_gui.h diff --git a/4ed_layout.cpp b/4ed_layout.cpp index 3e9acf1d..11cdb68f 100644 --- a/4ed_layout.cpp +++ b/4ed_layout.cpp @@ -73,8 +73,8 @@ panel_init(Panel *panel){ panel->view = 0; panel->parent = -1; panel->which_child = 0; - panel->screen_region.full = i32_rect_zero(); - panel->screen_region.inner = i32_rect_zero(); + panel->screen_region.full = null_i32_rect; + panel->screen_region.inner = null_i32_rect; panel->l_margin = 3; panel->r_margin = 3; panel->t_margin = 3; @@ -233,18 +233,18 @@ layout_get_rect(Editing_Layout *layout, i32 id, i32 which_child){ Panel_Divider *div = dividers + divider_chain[i]; if (div->v_divider){ if (div->child1 == divider_chain[i-1]){ - r.x1 = ROUND32(lerp((f32)r.x0, div->pos, (f32)r.x1)); + r.x1 = round32(lerp((f32)r.x0, div->pos, (f32)r.x1)); } else{ - r.x0 = ROUND32(lerp((f32)r.x0, div->pos, (f32)r.x1)); + r.x0 = round32(lerp((f32)r.x0, div->pos, (f32)r.x1)); } } else{ if (div->child1 == divider_chain[i-1]){ - r.y1 = ROUND32(lerp((f32)r.y0, div->pos, (f32)r.y1)); + r.y1 = round32(lerp((f32)r.y0, div->pos, (f32)r.y1)); } else{ - r.y0 = ROUND32(lerp((f32)r.y0, div->pos, (f32)r.y1)); + r.y0 = round32(lerp((f32)r.y0, div->pos, (f32)r.y1)); } } } @@ -253,20 +253,20 @@ layout_get_rect(Editing_Layout *layout, i32 id, i32 which_child){ case 1: { if (original_div->v_divider){ - r.x0 = ROUND32(lerp((f32)r.x0, original_div->pos, (f32)r.x1)); + r.x0 = round32(lerp((f32)r.x0, original_div->pos, (f32)r.x1)); } else{ - r.y0 = ROUND32(lerp((f32)r.y0, original_div->pos, (f32)r.y1)); + r.y0 = round32(lerp((f32)r.y0, original_div->pos, (f32)r.y1)); } }break; case -1: { if (original_div->v_divider){ - r.x1 = ROUND32(lerp((f32)r.x0, original_div->pos, (f32)r.x1)); + r.x1 = round32(lerp((f32)r.x0, original_div->pos, (f32)r.x1)); } else{ - r.y1 = ROUND32(lerp((f32)r.y0, original_div->pos, (f32)r.y1)); + r.y1 = round32(lerp((f32)r.y0, original_div->pos, (f32)r.y1)); } }break; } diff --git a/4ed_math.h b/4ed_math.h index d610c66a..57f41c23 100644 --- a/4ed_math.h +++ b/4ed_math.h @@ -60,10 +60,10 @@ COS(f32 x_degrees){ struct Vec2{ union{ struct{ - real32 x, y; + f32 x, y; }; struct{ - real32 v[2]; + f32 v[2]; }; }; }; @@ -71,21 +71,21 @@ struct Vec2{ struct Vec3{ union{ struct{ - real32 x, y, z; + f32 x, y, z; }; struct{ - real32 r, g, b; + f32 r, g, b; }; struct{ Vec2 xy; - real32 _z; + f32 _z; }; struct{ - real32 _x; + f32 _x; Vec2 yz; }; struct{ - real32 v[3]; + f32 v[3]; }; }; }; @@ -93,35 +93,35 @@ struct Vec3{ struct Vec4{ union{ struct{ - real32 r, g, b, a; + f32 r, g, b, a; }; struct{ - real32 h, s, l, __a; + f32 h, s, l, __a; }; struct{ - real32 x, y, z, w; + f32 x, y, z, w; }; struct{ Vec3 rgb; - real32 _a; + f32 _a; }; struct{ Vec3 xyz; - real32 _w; + f32 _w; }; struct{ - real32 _x; + f32 _x; Vec3 yzw; }; struct{ - real32 v[4]; + f32 v[4]; }; }; }; inline internal Vec2 -V2(real32 x, real32 y){ +V2(f32 x, f32 y){ Vec2 result; result.x = x; result.y = y; @@ -129,7 +129,7 @@ V2(real32 x, real32 y){ } inline internal Vec3 -V3(real32 x, real32 y, real32 z){ +V3(f32 x, f32 y, f32 z){ Vec3 result; result.x = x; result.y = y; @@ -138,7 +138,7 @@ V3(real32 x, real32 y, real32 z){ } inline internal Vec4 -V4(real32 x, real32 y, real32 z, real32 w){ +V4(f32 x, f32 y, f32 z, f32 w){ Vec4 result; result.x = x; result.y = y; @@ -202,7 +202,7 @@ operator-(Vec4 a, Vec4 b){ } inline internal Vec2 -operator*(Vec2 a, real32 k){ +operator*(Vec2 a, f32 k){ Vec2 result; result.x = a.x * k; result.y = a.y * k; @@ -210,7 +210,7 @@ operator*(Vec2 a, real32 k){ } inline internal Vec3 -operator*(Vec3 a, real32 k){ +operator*(Vec3 a, f32 k){ Vec3 result; result.x = a.x * k; result.y = a.y * k; @@ -219,7 +219,7 @@ operator*(Vec3 a, real32 k){ } inline internal Vec4 -operator*(Vec4 a, real32 k){ +operator*(Vec4 a, f32 k){ Vec4 result; result.x = a.x * k; result.y = a.y * k; @@ -229,7 +229,7 @@ operator*(Vec4 a, real32 k){ } inline internal Vec2 -operator*(real32 k, Vec2 a){ +operator*(f32 k, Vec2 a){ Vec2 result; result.x = a.x * k; result.y = a.y * k; @@ -237,7 +237,7 @@ operator*(real32 k, Vec2 a){ } inline internal Vec3 -operator*(real32 k, Vec3 a){ +operator*(f32 k, Vec3 a){ Vec3 result; result.x = a.x * k; result.y = a.y * k; @@ -246,7 +246,7 @@ operator*(real32 k, Vec3 a){ } inline internal Vec4 -operator*(real32 k, Vec4 a){ +operator*(f32 k, Vec4 a){ Vec4 result; result.x = a.x * k; result.y = a.y * k; @@ -292,40 +292,40 @@ operator-=(Vec4 &a, Vec4 b){ } inline internal Vec2& -operator*=(Vec2 &a, real32 k){ +operator*=(Vec2 &a, f32 k){ a = (a * k); return a; } inline internal Vec3& -operator*=(Vec3 &a, real32 k){ +operator*=(Vec3 &a, f32 k){ a = (a * k); return a; } inline internal Vec4& -operator*=(Vec4 &a, real32 k){ +operator*=(Vec4 &a, f32 k){ a = (a * k); return a; } -inline internal real32 +inline internal f32 dot(Vec2 a, Vec2 b){ - real32 result; + f32 result; result = a.x*b.x + a.y*b.y; return result; } -inline internal real32 +inline internal f32 dot(Vec3 a, Vec3 b){ - real32 result; + f32 result; result = a.x*b.x + a.y*b.y + a.z*b.z; return result; } -inline internal real32 +inline internal f32 dot(Vec4 a, Vec4 b){ - real32 result; + f32 result; result = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; return result; } @@ -375,7 +375,7 @@ perp(Vec2 v){ } inline Vec2 -polar_to_cartesian(real32 theta_degrees, real32 length){ +polar_to_cartesian(f32 theta_degrees, f32 length){ Vec2 result; result.x = COS(theta_degrees)*length; result.y = SIN(theta_degrees)*length; @@ -383,9 +383,9 @@ polar_to_cartesian(real32 theta_degrees, real32 length){ } inline Vec2 -rotate(Vec2 v, real32 theta_degrees){ +rotate(Vec2 v, f32 theta_degrees){ Vec2 result; - real32 c, s; + f32 c, s; c = COS(theta_degrees); s = SIN(theta_degrees); result.x = v.x*c - v.y*s; @@ -475,7 +475,7 @@ clamp(i32 a, i32 n, i32 z){ // TODO(allen): Convert colors to Vec4 inline u32 -color_blend(u32 a, real32 t, u32 b){ +color_blend(u32 a, f32 t, u32 b){ union{ u8 byte[4]; u32 comp; @@ -524,7 +524,7 @@ pack_color4(Vec4 color){ internal Vec4 rgba_to_hsla(Vec4 rgba){ Vec4 hsla = {}; - real32 max, min, delta; + f32 max, min, delta; i32 maxc; hsla.a = rgba.a; max = rgba.r; min = rgba.r; @@ -580,43 +580,80 @@ rgba_to_hsla(Vec4 rgba){ internal Vec4 hsla_to_rgba(Vec4 hsla){ if (hsla.h >= 1.f) hsla.h = 0.f; - Vec4 rgba = {}; - real32 C, X, m; - i32 H; + Vec4 rgba = {0}; + f32 C = (1.f - ABS(2*hsla.z - 1.f)) * hsla.y; + f32 X = C * (1.f-ABS(MOD(hsla.x*6.f, 2)-1.f)); + f32 m = hsla.z - C*.5f; + i32 H = floor32(hsla.x * 6.f); rgba.a = hsla.a; - C = (1.f - ABS(2*hsla.z - 1.f)) * hsla.y; - X = C * (1.f-ABS(MOD(hsla.x*6.f, 2)-1.f)); - m = hsla.z - C*.5f; - H = FLOOR32(hsla.x * 6.f); switch (H){ - case 0: - rgba.r = C; rgba.g = X; rgba.b = 0; - break; - - case 1: - rgba.r = X; rgba.g = C; rgba.b = 0; - break; - - case 2: - rgba.r = 0; rgba.g = C; rgba.b = X; - break; - - case 3: - rgba.r = 0; rgba.g = X; rgba.b = C; - break; - - case 4: - rgba.r = X; rgba.g = 0; rgba.b = C; - break; - - case 5: - rgba.r = C; rgba.g = 0; rgba.b = X; - break; + case 0: rgba.r = C; rgba.g = X; rgba.b = 0; break; + case 1: rgba.r = X; rgba.g = C; rgba.b = 0; break; + case 2: rgba.r = 0; rgba.g = C; rgba.b = X; break; + case 3: rgba.r = 0; rgba.g = X; rgba.b = C; break; + case 4: rgba.r = X; rgba.g = 0; rgba.b = C; break; + case 5: rgba.r = C; rgba.g = 0; rgba.b = X; break; } rgba.r += m; rgba.g += m; rgba.b += m; - return rgba; + return(rgba); +} + +// +// Rectangle Operations +// + +inline i32_Rect +i32R(int32_t l, int32_t t, int32_t r, int32_t b){ + i32_Rect rect; + rect.x0 = l; rect.y0 = t; + rect.x1 = r; rect.y1 = b; + return(rect); +} + +inline f32_Rect +f32R(float l, float t, float r, float b){ + f32_Rect rect; + rect.x0 = l; rect.y0 = t; + rect.x1 = r; rect.y1 = b; + return(rect); +} + +inline f32_Rect +f32R(i32_Rect r){ + f32_Rect rect; + rect.x0 = (float)r.x0; + rect.y0 = (float)r.y0; + rect.x1 = (float)r.x1; + rect.y1 = (float)r.y1; + return(rect); +} + +inline int32_t +rect_equal(i32_Rect r1, i32_Rect r2){ + int32_t result = (r1.x0 == r2.x0 && r1.y0 == r2.y0 && r1.x1 == r2.x1 && r1.y1 == r2.y1); + return(result); +} + +inline int32_t +hit_check(int32_t x, int32_t y, int32_t x0, int32_t y0, int32_t x1, int32_t y1){ + return (x >= x0 && x < x1 && y >= y0 && y < y1); +} + +inline int32_t +hit_check(int32_t x, int32_t y, i32_Rect rect){ + return (hit_check(x, y, rect.x0, rect.y0, rect.x1, rect.y1)); +} + +inline i32_Rect +get_inner_rect(i32_Rect outer, int32_t margin){ + i32_Rect r; + r.x0 = outer.x0 + margin; + r.y0 = outer.y0 + margin; + r.x1 = outer.x1 - margin; + r.y1 = outer.y1 - margin; + return r; } // BOTTOM diff --git a/4ed_os_custom_api.h b/4ed_os_custom_api.h index 8af9b79e..ddcd7561 100644 --- a/4ed_os_custom_api.h +++ b/4ed_os_custom_api.h @@ -1,20 +1 @@ -#define MEMORY_ALLOCATE_SIG(n) void* n(Application_Links *app, int32_t size) -#define MEMORY_SET_PROTECTION_SIG(n) bool32 n(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags) -#define MEMORY_FREE_SIG(n) void n(Application_Links *app, void *ptr, int32_t size) -#define FILE_EXISTS_SIG(n) bool32 n(Application_Links *app, char *filename, int32_t len) -#define DIRECTORY_CD_SIG(n) bool32 n(Application_Links *app, char *dir, int32_t *len, int32_t capacity, char *rel_path, int32_t rel_len) -#define GET_4ED_PATH_SIG(n) int32_t n(Application_Links *app, char *out, int32_t capacity) -#define SHOW_MOUSE_CURSOR_SIG(n) void n(Application_Links *app, Mouse_Cursor_Show_Type show) -#define TOGGLE_FULLSCREEN_SIG(n) void n(Application_Links *app) -#define IS_FULLSCREEN_SIG(n) bool32 n(Application_Links *app) -#define SEND_EXIT_SIGNAL_SIG(n) void n(Application_Links *app) -typedef MEMORY_ALLOCATE_SIG(Memory_Allocate_Function); -typedef MEMORY_SET_PROTECTION_SIG(Memory_Set_Protection_Function); -typedef MEMORY_FREE_SIG(Memory_Free_Function); -typedef FILE_EXISTS_SIG(File_Exists_Function); -typedef DIRECTORY_CD_SIG(Directory_CD_Function); -typedef GET_4ED_PATH_SIG(Get_4ed_Path_Function); -typedef SHOW_MOUSE_CURSOR_SIG(Show_Mouse_Cursor_Function); -typedef TOGGLE_FULLSCREEN_SIG(Toggle_Fullscreen_Function); -typedef IS_FULLSCREEN_SIG(Is_Fullscreen_Function); -typedef SEND_EXIT_SIGNAL_SIG(Send_Exit_Signal_Function); +struct Application_Links; diff --git a/4ed_rendering.h b/4ed_rendering.h index eadb253f..bae1a73e 100644 --- a/4ed_rendering.h +++ b/4ed_rendering.h @@ -30,9 +30,9 @@ struct Render_Font{ // TODO(allen): Have our own type here instead // of stbtt_packedchar, and have both stb fonts // and OS fonts go to our type. - Glyph_Data glyphs[256]; + Glyph_Data glyphs[256]; f32 advance_data[256]; - i32 height, ascent, descent, line_skip; + i32 height, ascent, descent, line_skip; i32 advance; u32 tex; i32 tex_width, tex_height; @@ -174,7 +174,12 @@ struct Render_Target{ inline i32_Rect rect_from_target(Render_Target *target){ - return i32R(0, 0, target->width, target->height); + i32_Rect r; + r.x0 = 0; + r.y0 = 0; + r.x1 = target->width; + r.y1 = target->height; + return(r); } inline Font_Info* diff --git a/4ed_rendering_helper.cpp b/4ed_rendering_helper.cpp index 9c30d292..4836b146 100644 --- a/4ed_rendering_helper.cpp +++ b/4ed_rendering_helper.cpp @@ -9,6 +9,20 @@ // TOP +#if 0 +inline i32_Rect +i32_rect_zero(){ + i32_Rect rect={0}; + return(rect); +} + +inline f32_Rect +f32_rect_zero(){ + f32_Rect rect={0}; + return(rect); +} +#endif + inline void draw_push_clip(Render_Target *target, i32_Rect clip_box){ target->push_clip(target, clip_box); diff --git a/4ed_site.ctm b/4ed_site.ctm index 0d02ed612c9c63da55bc5e9659c599b07f8ec7a4..354cc4e313167a70641924d0f5033610a68e8767 100644 GIT binary patch delta 507 zcmZ3&JcWJ362|&4_sq`V;!BK-3=9k+oD2+;<1;6~_+A_g4D~CzCWH9QK=}V6|Grd>FqSXkjD!vI8JK z$ij<23)D-NoqP`En*jNz8E5yufbv~{eAS*7miJJ;F_6#1<0=T_2Lbs{El$fal|no? zqZnvGg7I}ln1BqBAK;Ln3gbrr`F8@jv_O2213*Dq>XB{14mCiS2^eAyx;8LANWZdk Vm>rA{3Nc>3&rTpdNWUpiKLE46eQ5vy delta 7 OcmbQjzJz(h5=H= outer.x0 && rect.x1 <= outer.x1 && + rect.y0 >= outer.y0 && rect.y1 <= outer.y1); +} + internal void draw_push_clip(Render_Target *target, i32_Rect clip_box){ Assert(target->clip_top == -1 || @@ -472,8 +478,7 @@ private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, } inline void -private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, - real32 x, real32 y, u32 color){ +private_draw_glyph_mono(Render_Target *target, Render_Font *font, u8 character, f32 x, f32 y, u32 color){ private_draw_glyph_mono(target, font, character, x, y, (f32)font->advance, color); } @@ -656,7 +661,7 @@ stb_font_load(Partition *part, f32 *advance_data = font_out->advance_data; Glyph_Data *glyphs = font_out->glyphs; for (u8 code_point = 0; code_point < 128; ++code_point){ - advance_data[code_point] = (f32)(CEIL32(chardata[code_point].xadvance)); + advance_data[code_point] = (f32)(ceil32(chardata[code_point].xadvance)); glyphs[code_point].x0 = chardata[code_point].x0; glyphs[code_point].y0 = chardata[code_point].y0; glyphs[code_point].x1 = chardata[code_point].x1; @@ -680,7 +685,7 @@ stb_font_load(Partition *part, for (u8 code_point = 0; code_point < 128; ++code_point){ if (stbtt_FindGlyphIndex(&font, code_point) != 0){ font_out->glyphs[code_point].exists = 1; - i32 advance = CEIL32(advance_data[code_point]); + i32 advance = ceil32(advance_data[code_point]); if (max_advance < advance){ max_advance = advance; } @@ -758,10 +763,10 @@ font_load_freetype(Partition *part, FT_Request_Size(face, &size); rf->loaded = 1; - rf->ascent = CEIL32 (face->size->metrics.ascender / 64.0f); - rf->descent = FLOOR32 (face->size->metrics.descender / 64.0f); - rf->advance = CEIL32 (face->size->metrics.max_advance / 64.0f); - rf->height = CEIL32 (face->size->metrics.height / 64.0f); + rf->ascent = ceil32 (face->size->metrics.ascender / 64.0f); + rf->descent = floor32 (face->size->metrics.descender / 64.0f); + rf->advance = ceil32 (face->size->metrics.max_advance / 64.0f); + rf->height = ceil32 (face->size->metrics.height / 64.0f); rf->line_skip = rf->height - (rf->ascent - rf->descent); rf->height -= rf->line_skip; @@ -777,7 +782,7 @@ font_load_freetype(Partition *part, tex_width *= 2; float glyphs_per_row = ceilf(tex_width / (float) max_glyph_w); float rows = ceilf(NUM_GLYPHS / glyphs_per_row); - tex_height = CEIL32(rows * (max_glyph_h + 2)); + tex_height = ceil32(rows * (max_glyph_h + 2)); } while(tex_height > tex_width); tex_height = next_pow_of_2(tex_height); @@ -836,7 +841,7 @@ font_load_freetype(Partition *part, // TODO(allen): maybe advance data should be integers for a while... // I require the actual values to be integers anyway... hmm... - rf->advance_data[i] = (f32)CEIL32(face->glyph->advance.x / 64.0f); + rf->advance_data[i] = (f32)ceil32(face->glyph->advance.x / 64.0f); rf->glyphs[i].exists = 1; @@ -872,7 +877,7 @@ font_load_freetype(Partition *part, } } - pen_x = CEIL32(c->x1 + 1); + pen_x = ceil32(c->x1 + 1); } // TODO(allen): advance data is still too stupid. diff --git a/4ed_system_shared.h b/4ed_system_shared.h index ae8bd992..108f23b4 100644 --- a/4ed_system_shared.h +++ b/4ed_system_shared.h @@ -19,7 +19,7 @@ struct File_Data{ u32 size; b32 got_file; }; -globalvar File_Data null_file_data = {0}; +global File_Data null_file_data = {0}; #define Sys_Get_Memory_Sig(name) void* name(i32 size, i32 line_number, char *file_name) #define Sys_Free_Memory_Sig(name) void name(void *block) diff --git a/4tech_defines.h b/4tech_defines.h new file mode 100644 index 00000000..a30a4842 --- /dev/null +++ b/4tech_defines.h @@ -0,0 +1,146 @@ +/* +4tech_defines.h - Standard defines across all 4tech projects. +By Allen Webster +Created 21.01.2017 (dd.mm.yyyy) +*/ + +// TOP + +#if !defined(FTECH_DEFINES) +#define FTECH_DEFINES +#include + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef i8 b8; +typedef i32 b32; + +// TODO(allen): Find a real way to detect 32 bit ness. +#if defined(FTECH_32_BIT) +typedef u32 umem; +typedef i32 imem; +#else +typedef u64 umem; +typedef i64 imem; +#endif + +typedef float f32; +typedef double f64; + +#define internal static +#define local_persist static +#define global static +#define local_const static const +#define global_const static const + +#define ArrayCount(a) ((sizeof(a))/(sizeof(*a))) +#define ExpandArray(a) (a), (ArrayCount(a)) +#define AllowLocal(c) (void)(c) + +#if defined(Assert) +# undef Assert +#endif + +#define Assert(c) do { if (!(c)) *((i32*)0) = 0xA11E; } while(0) +#define TentativeAssert(c) Assert(c) +#define InvalidCodePath Assert(!"Invalid Code Path!") +#define NotImplemented Assert(!"Not Implemented!") + +#define Swap(t,a,b) do { t x = a; a = b; b = x; } while(0) + +#define Max(a,b) (((a)>(b))?(a):(b)) +#define Min(a,b) (((a)<(b))?(a):(b)) + +#define ceil32(v) (((v)>0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)+1.f)) ):( ((i32)(v)) )) + +#define floor32(v) (((v)<0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)-1.f)) ):( ((i32)(v)) )) + +#define round32(v) (floor32(v + 0.5f)) + +#define trunc32(v) (i32)(v) + +#define div_ceil(n,d) ( ((n) % (d) != 0) + ((n) / (d)) ) + +#define l_round_up(x,b) ( ((x)+(b)-1) - (((x)+(b)-1)%(b)) ) + +#define STR__(s) #s +#define STR_(s) STR__(s) + +#define DrCase(PC) case PC: goto resumespot_##PC +#define DrYield(PC, n) { *S_ptr = S; S_ptr->__pc__ = PC; return(n); resumespot_##PC:; } +#define DrReturn(n) { *S_ptr = S; S_ptr->__pc__ = -1; return(n); } + +#define Bytes(x) ((umem)x) +#define KB(x) (((umem)x) << 10) +#define MB(x) (((umem)x) << 20) +#define GB(x) (((umem)x) << 30) +#define TB(x) (((umem)x) << 40) + +#define max_i8 ((i8)0x7F) +#define max_i16 ((i16)0x7FFF) +#define max_i32 ((i32)0x7FFFFFFF) +#define max_i64 ((i64)0x7FFFFFFFFFFFFFFF) + +#define min_i8 ((i8)0x80) +#define min_i16 ((i16)0x8000) +#define min_i32 ((i32)0x80000000) +#define min_i64 ((i64)0x8000000000000000) + +#define max_u8 ((u8)0xFF) +#define max_u16 ((u16)0xFFFF) +#define max_u32 ((u32)0xFFFFFFFF) +#define max_u64 ((u64)0xFFFFFFFFFFFFFFFF) + +#define min_u8 ((u8)0) +#define min_u16 ((u16)0) +#define min_u32 ((u32)0) +#define min_u64 ((u64)0) + +#define Bit_0 (1 << 0) +#define Bit_1 (1 << 1) +#define Bit_2 (1 << 2) +#define Bit_3 (1 << 3) +#define Bit_4 (1 << 4) +#define Bit_5 (1 << 5) +#define Bit_6 (1 << 6) +#define Bit_7 (1 << 7) + +#define Bit_8 (1 << 8) +#define Bit_9 (1 << 9) +#define Bit_10 (1 << 10) +#define Bit_11 (1 << 11) +#define Bit_12 (1 << 12) +#define Bit_13 (1 << 13) +#define Bit_14 (1 << 14) +#define Bit_15 (1 << 15) + +#define Bit_16 (1 << 16) +#define Bit_17 (1 << 17) +#define Bit_18 (1 << 18) +#define Bit_19 (1 << 19) +#define Bit_20 (1 << 20) +#define Bit_21 (1 << 21) +#define Bit_22 (1 << 22) +#define Bit_23 (1 << 23) + +#define Bit_24 (1 << 24) +#define Bit_25 (1 << 25) +#define Bit_26 (1 << 26) +#define Bit_27 (1 << 27) +#define Bit_28 (1 << 28) +#define Bit_29 (1 << 29) +#define Bit_30 (1 << 30) +#define Bit_31 (1 << 31) + +#endif + +// BOTTOM + diff --git a/_4coder_string.ctm b/_4coder_string.ctm new file mode 100644 index 0000000000000000000000000000000000000000..5fc766549eafd78cac6801829d44116741916d2b GIT binary patch literal 324 zcmcC7j5~F99c#$Fl1q#XK;RI{!jQnh-U#Cx)vz+m-cryC<15c(Wl(c7{t4qB=;vVI zc(FX_K2$&FEiQ(x)0!J${0vuK215?d-!Q(aHa|n@{z}FNQ1!cl`56p&7gxjhp(R2L zd&J|G!T8}l!VG%6g6!T7h;MHuGyzdHcq7g~uhuwR*e9K>e^`sXea z1H(cWKlz7H`@Ss^W7xU-y%vnG{85a-Lc`u2#^1O~oT0v2#}CFAyCKeSHj=R%#D|&3 OtYlvUljmTQWB>pvuwiQe literal 0 HcmV?d00001 diff --git a/build.bat b/build.bat index 013c3706..b8fbfe56 100644 --- a/build.bat +++ b/build.bat @@ -25,5 +25,5 @@ call "print_size.bat" 4ed_app.dll call "print_size.bat" 4ed.exe popd -::END +:END call "ctime" -end 4ed_data.ctm %FirstError% diff --git a/buildsuper.bat b/buildsuper.bat index b9945780..a4af85a4 100644 --- a/buildsuper.bat +++ b/buildsuper.bat @@ -17,7 +17,7 @@ REM default files no matter where you store your code. REM And no matter how you call buildsuper.bat. SET CODE_HOME=%~dp0 -cl /I%CODE_HOME% %OPTS% %DEBUG% %SRC% /Fe4coder_custom %BUILD_DLL% %EXPORTS% +cl /I%CODE_HOME% %OPTS% %DEBUG% %SRC% /Fecustom_4coder %BUILD_DLL% %EXPORTS% REM file spammation preventation del *.exp diff --git a/common/4coder_defines.h b/common/4coder_defines.h deleted file mode 100644 index a55408ed..00000000 --- a/common/4coder_defines.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 12.12.2014 - * - * Meta setup for project codename "4ed" - * - */ - -// TOP - -#if !defined(FRED_DEFINES_H) -#define FRED_DEFINES_H - -#if !defined (FRED_TYPES) -#include -#define FRED_TYPES -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; - -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; - -typedef i32 bool32; -typedef i8 bool8; -typedef i32 b32; -typedef i16 b16; -typedef i8 b8; - -typedef float real32; -typedef double real64; -typedef float f32; -typedef double f64; - -#define internal static -#define globalvar static -#define persist static - -#define globalconst static const -#endif - -#define COMP_ID_(a,b,c,d) (d << 24) | (c << 16) | (b << 8) | a -#define COMPOSE_ID(a,b,c,d) (COMP_ID_((a),(b),(c),(d))) - -#define S(X) #X -#define S_(X) S(X) -#define S__LINE__ S_(__LINE__) - -#if FRED_INTERNAL || FRED_KEEP_ASSERT -# define Assert(c) assert(c) -#else -# define Assert(c) -#endif -#define TentativeAssert(c) Assert(c) -#define NotImplemented Assert(!"This is not implemented yet!") -#define InvalidCodePath Assert(!"Invalid code path!") -#define InvalidPath InvalidCodePath - -#define AllowLocal(name) (void)name -#ifndef ArrayCount -# define ArrayCount(array) (sizeof(array)/sizeof(array[0])) -#endif - -#define OffsetOfStruct(S,c) ((i64)(& ((S*)0)->c )) - -#define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0) - -#define Min(a,b) (((a)<(b))?(a):(b)) -#define Max(a,b) (((a)>(b))?(a):(b)) - -#define TMax(t,v) globalconst t max_##t = v -TMax(u8, 255); -TMax(u16, 65535); -TMax(u32, 4294967295); -TMax(u64, 18446744073709551615U); - -TMax(i8, 127); -TMax(i16, 32767); -TMax(i32, 2147483647); -TMax(i64, 9223372036854775807); -#undef TMax - -#define TMin(t) globalconst t min_##t = 0 -TMin(u8); -TMin(u16); -TMin(u32); -TMin(u64); -#undef TMin - -#define TMin(t,v) globalconst t min_##t = ((t)(v)) -TMin(i8, -127-1); -TMin(i16, -32767-1); -TMin(i32, -2147483647-1); -TMin(i64, -9223372036854775807-1); -#undef TMin - -#define Bit_0 (1 << 0) -#define Bit_1 (1 << 1) -#define Bit_2 (1 << 2) -#define Bit_3 (1 << 3) -#define Bit_4 (1 << 4) -#define Bit_5 (1 << 5) -#define Bit_6 (1 << 6) -#define Bit_7 (1 << 7) - -#define Bit_8 (1 << 8) -#define Bit_9 (1 << 9) -#define Bit_10 (1 << 10) -#define Bit_11 (1 << 11) -#define Bit_12 (1 << 12) -#define Bit_13 (1 << 13) -#define Bit_14 (1 << 14) -#define Bit_15 (1 << 15) - -#define Bit_16 (1 << 16) -#define Bit_17 (1 << 17) -#define Bit_18 (1 << 18) -#define Bit_19 (1 << 19) -#define Bit_20 (1 << 20) -#define Bit_21 (1 << 21) -#define Bit_22 (1 << 22) -#define Bit_23 (1 << 23) - -#define Bit_24 (1 << 24) -#define Bit_25 (1 << 25) -#define Bit_26 (1 << 26) -#define Bit_27 (1 << 27) -#define Bit_28 (1 << 28) -#define Bit_29 (1 << 29) -#define Bit_30 (1 << 30) -#define Bit_31 (1 << 31) - -#define bytes(n) (n) -#define Kbytes(n) ((n) << 10) -#define Mbytes(n) ((n) << 20) -#define Gbytes(n) (((u64)n) << 30) -#define Tbytes(n) (((u64)n) << 40) - -// -// Rounding -// - -internal u32 -l_round_up_u32(u32 x, u32 granularity){ - u32 new_x = x + granularity - 1; - new_x = new_x - (new_x % granularity); - return(new_x); -} - -internal i32 -l_round_up_i32(i32 x, i32 granularity){ - i32 new_x = (i32)l_round_up_u32((u32)x, (u32)granularity); - return(new_x); -} - -inline i32 -TRUNC32(real32 x) { return (i32)x; } - -inline i32 -FLOOR32(real32 x) { return (i32)(x)-((x!=(i32)(x) && x<0)?1:0); } - -inline i32 -CEIL32(real32 x) { return (i32)(x)+((x!=(i32)(x) && x>0)?1:0); } - -inline i32 -ROUND32(real32 x) { return FLOOR32(x + .5f); } - -inline i32 -DIVCEIL32(i32 n, i32 d) { - i32 q = (n/d); - return q + (q*d < n); -} - -inline real32 -FRACPART32(real32 x) { return x - (i32)x; } - -inline u32 -ROUNDPOT32(u32 v){ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; -} - -#endif - -// BOTTOM - diff --git a/file/4coder_buffer.cpp b/file/4coder_buffer.cpp index d0898246..4dd15d45 100644 --- a/file/4coder_buffer.cpp +++ b/file/4coder_buffer.cpp @@ -13,11 +13,7 @@ // Buffer low level operations // -// TODO(allen): Put 4coder_seek_types into the file directory. -// Setup a meta system for putting together a file in the custom -// code directory from the export structs and helpers. - -#include "../4coder_seek_types.h" +#include "../4coder_helper/4coder_seek_types.h" typedef struct Cursor_With_Index{ i32 pos; @@ -506,7 +502,7 @@ buffer_replace_range(Gap_Buffer *buffer, i32 start, i32 end, char *str, i32 len, assert(buffer->size1 + buffer->gap_size + buffer->size2 == buffer->max); } else{ - *request_amount = l_round_up_u32(2*(*shift_amount + size), 4 << 10); + *request_amount = l_round_up(2*(*shift_amount + size), 4 << 10); result = 1; } @@ -1201,7 +1197,7 @@ buffer_get_line_index_from_character_pos(i32 *character_starts, i32 pos, i32 l_b inline i32 buffer_get_line_index_from_wrapped_y(i32 *wrap_line_index, f32 y, f32 line_height, i32 l_bound, i32 u_bound){ - i32 wrap_index = FLOOR32(y/line_height); + i32 wrap_index = floor32(y/line_height); i32 i = binary_search(wrap_line_index, wrap_index, l_bound, u_bound); return(i); } diff --git a/file/4coder_file_tests.cpp b/file/4coder_file_tests.cpp deleted file mode 100644 index 552b5ead..00000000 --- a/file/4coder_file_tests.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 03.01.2017 - * - * File layer for 4coder - * - */ - -// TOP - -#include "../common/4ed_defines.h" - -#include "4coder_buffer.cpp" -#include "4coder_undo.cpp" - -int main(){ - return(0); -} - -// BOTTOM - diff --git a/file/run_tests.bat b/file/run_tests.bat deleted file mode 100644 index 278bfbb7..00000000 --- a/file/run_tests.bat +++ /dev/null @@ -1,11 +0,0 @@ -@echo off - -SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX -SET OPTS=%OPTS% /GR- /EHa- /nologo /FC - -pushd ..\build -cl %OPTS% ..\code\file\4coder_file_tests.cpp /Zi /Fefile_test -popd - -if %ERRORLEVEL% eq 0 (..\build\file_test) - diff --git a/linux_4ed.cpp b/linux_4ed.cpp index 9d060e75..c5623c0d 100644 --- a/linux_4ed.cpp +++ b/linux_4ed.cpp @@ -12,50 +12,23 @@ #include #include -#include "common/4coder_defines.h" -#include "common/4coder_version.h" +#include "4tech_defines.h" +#include "4coder_API/version.h" -#if FRED_SUPER +#if defined(FRED_SUPER) +# include "4coder_API/keycodes.h" +# include "4coder_API/style.h" # define FSTRING_IMPLEMENTATION # define FSTRING_C -# include "4coder_string.h" +# include "4coder_lib/4coder_string.h" +# include "4coder_lib/4coder_mem.h" -# include "4coder_keycodes.h" -# include "4coder_style.h" -# include "4coder_rect.h" - -# include "4coder_mem.h" - -// TODO(allen): This is duplicated from 4coder_custom.h -// I need to work out a way to avoid this. -#define VIEW_ROUTINE_SIG(name) void name(struct Application_Links *app, int32_t view_id) -#define GET_BINDING_DATA(name) int32_t name(void *data, int32_t size) -#define _GET_VERSION_SIG(n) int32_t n(int32_t maj, int32_t min, int32_t patch) - -typedef VIEW_ROUTINE_SIG(View_Routine_Function); -typedef GET_BINDING_DATA(Get_Binding_Data_Function); -typedef _GET_VERSION_SIG(_Get_Version_Function); - -struct Custom_API{ - View_Routine_Function *view_routine; - Get_Binding_Data_Function *get_bindings; - _Get_Version_Function *get_alpha_4coder_version; -}; - - -typedef void Custom_Command_Function; -#include "4coder_types.h" -struct Application_Links; +# include "4coder_API/types.h" # include "4ed_os_custom_api.h" #else # include "4coder_default_bindings.cpp" - -# define FSTRING_IMPLEMENTATION -# define FSTRING_C -# include "4coder_string.h" - #endif #include "4ed_math.h" @@ -252,8 +225,8 @@ struct Linux_Vars{ // Linux globals // -globalvar Linux_Vars linuxvars; -globalvar Application_Memory memory_vars; +global Linux_Vars linuxvars; +global Application_Memory memory_vars; // // Linux forward declarations @@ -601,11 +574,11 @@ Sys_Now_Time_Sig(system_now_time){ } // -// 4coder_custom.h +// custom.h // internal -MEMORY_ALLOCATE_SIG(system_memory_allocate){ +Sys_Memory_Allocate_Sig(system_memory_allocate){ // NOTE(allen): This must return the exact base of the vpage. // We will count on the user to keep track of size themselves. void *result = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -617,7 +590,7 @@ MEMORY_ALLOCATE_SIG(system_memory_allocate){ } internal -MEMORY_SET_PROTECTION_SIG(system_memory_set_protection){ +Sys_Memory_Set_Protection_Sig(system_memory_set_protection){ // NOTE(allen): // There is no such thing as "write only" in windows // so I just made write = write + read in all cases. @@ -658,13 +631,13 @@ MEMORY_SET_PROTECTION_SIG(system_memory_set_protection){ } internal -MEMORY_FREE_SIG(system_memory_free){ +Sys_Memory_Free_Sig(system_memory_free){ // NOTE(allen): This must take the exact base of the vpage. munmap(ptr, size); } internal -FILE_EXISTS_SIG(system_file_exists){ +Sys_File_Exists_Sig(system_file_exists){ int result = 0; char buff[PATH_MAX] = {}; @@ -683,8 +656,8 @@ FILE_EXISTS_SIG(system_file_exists){ } internal -DIRECTORY_CD_SIG(system_directory_cd){ - String directory = make_string_cap(dir, *len, capacity); +Sys_Directory_CD_Sig(system_directory_cd){ + String directory = make_string_cap(dir, *len, cap); b32 result = 0; i32 old_size; @@ -722,24 +695,26 @@ DIRECTORY_CD_SIG(system_directory_cd){ } internal -GET_4ED_PATH_SIG(system_get_4ed_path){ +Sys_Get_4ed_Path_Sig(system_get_4ed_path){ String str = make_string_cap(out, 0, capacity); return(system_get_binary_path(&str)); } internal -SHOW_MOUSE_CURSOR_SIG(system_show_mouse_cursor){ +Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){ linuxvars.hide_cursor = !show; XDefineCursor(linuxvars.XDisplay, linuxvars.XWindow, show ? None : linuxvars.hidden_cursor); } internal -TOGGLE_FULLSCREEN_SIG(system_toggle_fullscreen){ +Sys_Toggle_Fullscreen_Sig(system_toggle_fullscreen){ + b32 success = true; LinuxToggleFullscreen(linuxvars.XDisplay, linuxvars.XWindow); + return(success); } internal -IS_FULLSCREEN_SIG(system_is_fullscreen){ +Sys_Is_Fullscreen_Sig(system_is_fullscreen){ b32 result = 0; Atom type, *prop; @@ -765,7 +740,7 @@ IS_FULLSCREEN_SIG(system_is_fullscreen){ } internal -SEND_EXIT_SIGNAL_SIG(system_send_exit_signal){ +Sys_Send_Exit_Signal_Sig(system_send_exit_signal){ linuxvars.keep_running = 0; } @@ -1020,7 +995,7 @@ JobThreadProc(void* lpParameter){ Thread_Memory *thread_memory = linuxvars.thread_memory + thread_index; if (thread_memory->size == 0){ - i32 new_size = Kbytes(64); + i32 new_size = KB(64); thread_memory->data = LinuxGetMemory(new_size); thread_memory->size = new_size; } @@ -1285,7 +1260,7 @@ Sys_Grow_Thread_Memory_Sig(system_grow_thread_memory){ system_acquire_lock(CANCEL_LOCK0 + memory->id - 1); old_data = memory->data; old_size = memory->size; - new_size = LargeRoundUp(memory->size*2, Kbytes(4)); + new_size = l_round_up(memory->size*2, KB(4)); memory->data = system_get_memory(new_size); memory->size = new_size; if (old_data){ @@ -1358,13 +1333,13 @@ Font_Load_Sig(system_draw_font_load){ LINUX_FN_DEBUG("%s, %dpt, tab_width: %d", filename, pt_size, tab_width); if (linuxvars.font_part.base == 0){ - linuxvars.font_part = sysshared_scratch_partition(Mbytes(8)); + linuxvars.font_part = sysshared_scratch_partition(MB(8)); } i32 oversample = 2; #if SUPPORT_DPI - pt_size = ROUND32(pt_size * size_change(linuxvars.dpi_x, linuxvars.dpi_y)); + pt_size = round32(pt_size * size_change(linuxvars.dpi_x, linuxvars.dpi_y)); #endif for(; attempts < 3; ++attempts){ @@ -1444,7 +1419,7 @@ LinuxLoadSystemCode(){ // time linuxvars.system.now_time = system_now_time; - // 4coder_custom.h + // custom.h linuxvars.system.memory_allocate = system_memory_allocate; linuxvars.system.memory_set_protection = system_memory_set_protection; linuxvars.system.memory_free = system_memory_free; @@ -1911,7 +1886,7 @@ LinuxInputInit(Display *dpy, Window XWindow) // Keyboard handling funcs // -globalvar u8 keycode_lookup_table[255]; +global u8 keycode_lookup_table[255]; internal void LinuxKeycodeInit(Display* dpy){ @@ -2979,14 +2954,14 @@ main(int argc, char **argv) LinuxLoadSystemCode(); LinuxLoadRenderCode(); - memory_vars.vars_memory_size = Mbytes(2); + memory_vars.vars_memory_size = MB(2); memory_vars.vars_memory = system_get_memory(memory_vars.vars_memory_size); - memory_vars.target_memory_size = Mbytes(512); + memory_vars.target_memory_size = MB(512); memory_vars.target_memory = system_get_memory(memory_vars.target_memory_size); - memory_vars.user_memory_size = Mbytes(2); + memory_vars.user_memory_size = MB(2); memory_vars.user_memory = system_get_memory(memory_vars.user_memory_size); - linuxvars.target.max = Mbytes(1); + linuxvars.target.max = MB(1); linuxvars.target.push_buffer = (char*)system_get_memory(linuxvars.target.max); if(memory_vars.vars_memory == NULL || memory_vars.target_memory == NULL || memory_vars.user_memory == NULL || linuxvars.target.push_buffer == NULL){ @@ -3043,7 +3018,7 @@ main(int argc, char **argv) #ifdef FRED_SUPER - char *custom_file_default = "4coder_custom.so"; + char *custom_file_default = "custom_4coder.so"; sysshared_to_binary_path(&base_dir, custom_file_default); custom_file_default = base_dir.str; @@ -3067,23 +3042,21 @@ main(int argc, char **argv) if (linuxvars.custom_api.get_alpha_4coder_version == 0 || linuxvars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){ - LinuxFatalErrorMsg("Failed to load '4coder_custom.so': Version mismatch. Try rebuilding it with 'buildsuper.sh'."); + LinuxFatalErrorMsg("Failed to load 'custom_4coder.so': Version mismatch. Try rebuilding it with 'buildsuper.sh'."); exit(1); } else{ linuxvars.custom_api.get_bindings = (Get_Binding_Data_Function*) dlsym(linuxvars.custom, "get_bindings"); - linuxvars.custom_api.view_routine = (View_Routine_Function*) - dlsym(linuxvars.custom, "view_routine"); if (linuxvars.custom_api.get_bindings == 0){ - LinuxFatalErrorMsg("Failed to load '4coder_custom.so': " + LinuxFatalErrorMsg("Failed to load 'custom_4coder.so': " "It does not export the required 'get_bindings' function. " "Try rebuilding it with 'buildsuper.sh'."); exit(1); } else{ - fprintf(stderr, "Successfully loaded 4coder_custom.so\n"); + fprintf(stderr, "Successfully loaded custom_4coder.so\n"); } } } else { @@ -3091,7 +3064,7 @@ main(int argc, char **argv) const char* error = dlerror(); snprintf(buf, sizeof(buf), "Error loading custom: %s. " "Make sure this file is in the same directory as the main '4ed' executable.", - error ? error : "'4coder_custom.so' missing"); + error ? error : "'custom_4coder.so' missing"); LinuxFatalErrorMsg(buf); exit(1); } @@ -3099,14 +3072,6 @@ main(int argc, char **argv) linuxvars.custom_api.get_bindings = get_bindings; #endif - linuxvars.custom_api.view_routine = 0; - -#if 0 - if (linuxvars.custom_api.view_routine == 0){ - linuxvars.custom_api.view_routine = view_routine; - } -#endif - // // Coroutine / Thread / Semaphore / Mutex init // @@ -3116,7 +3081,7 @@ main(int argc, char **argv) linuxvars.coroutine_data[i].next = linuxvars.coroutine_data + i + 1; } - const size_t stack_size = Mbytes(2); + const size_t stack_size = MB(2); for (i32 i = 0; i < ArrayCount(linuxvars.coroutine_data); ++i){ linuxvars.coroutine_data[i].stack.ss_size = stack_size; linuxvars.coroutine_data[i].stack.ss_sp = system_get_memory(stack_size); diff --git a/meta/4ed_metagen.cpp b/meta/4ed_metagen.cpp index a9539ca1..dc6c3de5 100644 --- a/meta/4ed_metagen.cpp +++ b/meta/4ed_metagen.cpp @@ -9,21 +9,24 @@ // TOP -#include "../common/4coder_defines.h" -#include "../common/4coder_version.h" +#define KEYCODES_FILE "4coder_API/keycodes.h" +#define STYLE_FILE "4coder_API/style.h" -#if !defined(FSTRING_GUARD) -#include "../internal_4coder_string.cpp" -#endif +#define API_H "4coder_API/app_functions.h" +#define OS_API_H "4ed_os_custom_api.h" -#include "../4cpp_lexer.h" +#include "4tech_meta_defines.h" +#include "../4coder_API/version.h" + +#define FSTRING_IMPLEMENTATION +#include "../4coder_lib/4coder_string.h" +#include "../4coder_lib/4coder_mem.h" + +#include "../4cpp/4cpp_lexer.h" #include #include #include -#include - -#include "../4coder_mem.h" #include "meta_parser.cpp" #include "out_context.cpp" @@ -69,7 +72,7 @@ char *keys_that_need_codes[] = { void generate_keycode_enum(){ - char *filename_keycodes = "4coder_keycodes.h"; + char *filename_keycodes = KEYCODES_FILE; Out_Context context = {0}; int32_t i = 0, count = 0; unsigned char code = 1; @@ -196,7 +199,7 @@ make_style_tag(char *tag){ static void generate_style(){ - char filename_4coder[] = "4coder_style.h"; + char filename_4coder[] = STYLE_FILE; char filename_4ed[] = "4ed_style.h"; char *tag = 0; int32_t count = 0, i = 0; @@ -377,9 +380,7 @@ allocate_app_api(Partition *part, int32_t count){ static void generate_custom_headers(){ -#define API_H "4coder_custom_api.h" -#define OS_API_H "4ed_os_custom_api.h" -#define STRING_H "4coder_string.h" + META_BEGIN(); int32_t size = (512 << 20); void *mem = malloc(size); @@ -401,24 +402,12 @@ generate_custom_headers(){ #define ExpandArray(a) (a), (ArrayCount(a)) - // NOTE(allen): Parse the internal string file. - static char *string_files[] = { - "internal_4coder_string.cpp", - 0 - }; - - Meta_Unit string_unit = compile_meta_unit(part, ".", string_files, ExpandArray(meta_keywords)); - - // NOTE(allen): Parse the customization API files - static char *functions_files[] = { - "4ed_api_implementation.cpp", - "win32_api_impl.cpp", - 0 - }; - + static char *functions_files[] = { "4ed_api_implementation.cpp", 0 }; Meta_Unit unit_custom = compile_meta_unit(part, ".", functions_files, ExpandArray(meta_keywords)); - + if (unit_custom.parse == 0){ + Assert(!"Missing one or more input files!"); + } // NOTE(allen): Compute and store variations of the function names App_API func_4ed_names = allocate_app_api(part, unit_custom.set.count); @@ -446,6 +435,8 @@ generate_custom_headers(){ if (begin_file_out(&context, OS_API_H, &out)){ int32_t main_api_count = unit_custom.parse[0].item_count; int32_t os_api_count = unit_custom.parse[1].item_count; + append_sc(&out, "struct Application_Links;\n"); + for (int32_t i = main_api_count; i < os_api_count; ++i){ append_sc(&out, "#define "); append_ss(&out, func_4ed_names.names[i].macro); @@ -471,6 +462,8 @@ generate_custom_headers(){ } if (begin_file_out(&context, API_H, &out)){ + append_sc(&out, "struct Application_Links;\n"); + for (int32_t i = 0; i < unit_custom.set.count; ++i){ append_sc(&out, "#define "); append_ss(&out, func_4ed_names.names[i].macro); @@ -586,212 +579,7 @@ generate_custom_headers(){ // TODO(allen): warning } - // NOTE(allen): String Library - if (begin_file_out(&context, STRING_H, &out)){ - Cpp_Token *token = 0; - int32_t start = 0; - - Parse parse = string_unit.parse[0]; - Parse_Context pcontext = setup_parse_context(parse); - - for (; (token = get_token(&pcontext)) != 0; get_next_token(&pcontext)){ - if (!(token->flags & CPP_TFLAG_PP_BODY) && - token->type == CPP_TOKEN_IDENTIFIER){ - String lexeme = get_lexeme(*token, pcontext.data); - if (match_ss(lexeme, make_lit_string("FSTRING_BEGIN"))){ - start = token->start + token->size; - break; - } - } - } - - String pstr = {0}; - int32_t do_whitespace_print = true; - - for(;(token = get_next_token(&pcontext)) != 0;){ - if (do_whitespace_print){ - pstr = str_start_end(pcontext.data, start, token->start); - append_ss(&out, pstr); - } - else{ - do_whitespace_print = true; - } - - String lexeme = get_lexeme(*token, pcontext.data); - - int32_t do_print = true; - if (match_ss(lexeme, make_lit_string("FSTRING_DECLS"))){ - append_sc(&out, "#if !defined(FCODER_STRING_H)\n#define FCODER_STRING_H\n\n"); - do_print = false; - - static int32_t SIG_PADDING = 35; - - for (int32_t j = 0; j < string_unit.set.count; ++j){ - char line_[2048]; - String line = make_fixed_width_string(line_); - Item_Node *item = string_unit.set.items + j; - - if (item->t == Item_Function){ - //append_ss (&line, item->marker); - //append_padding (&line, ' ', RETURN_PADDING); - append_ss (&line, item->ret); - append_padding (&line, ' ', SIG_PADDING); - append_ss (&line, item->name); - append_ss (&line, item->args); - append_sc (&line, ";\n"); - } - else if (item->t == Item_Macro){ - append_ss (&line, make_lit_string("#ifndef ")); - append_padding (&line, ' ', 10); - append_ss (&line, item->name); - append_s_char (&line, '\n'); - - append_ss (&line, make_lit_string("# define ")); - append_padding (&line, ' ', 10); - append_ss (&line, item->name); - append_ss (&line, item->args); - append_s_char (&line, ' '); - append_ss (&line, item->body); - append_s_char (&line, '\n'); - - append_ss (&line, make_lit_string("#endif")); - append_s_char (&line, '\n'); - } - else{ - InvalidPath; - } - - append_ss(&out, line); - } - - append_sc(&out, "\n#endif\n"); - - // NOTE(allen): C++ overload definitions - append_sc(&out, "\n#if !defined(FSTRING_C) && !defined(FSTRING_GUARD)\n\n"); - - for (int32_t j = 0; j < string_unit.set.count; ++j){ - char line_space[2048]; - String line = make_fixed_width_string(line_space); - - Item_Node *item = &string_unit.set.items[j]; - - if (item->t == Item_Function){ - String cpp_name = item->cpp_name; - if (cpp_name.str != 0){ - Argument_Breakdown breakdown = item->breakdown; - - append_ss (&line, item->ret); - append_padding(&line, ' ', SIG_PADDING); - append_ss (&line, cpp_name); - append_ss (&line, item->args); - if (match_ss(item->ret, make_lit_string("void"))){ - append_ss(&line, make_lit_string("{(")); - } - else{ - append_ss(&line, make_lit_string("{return(")); - } - append_ss (&line, item->name); - append_s_char(&line, '('); - - if (breakdown.count > 0){ - for (int32_t i = 0; i < breakdown.count; ++i){ - if (i != 0){ - append_s_char(&line, ','); - } - append_ss(&line, breakdown.args[i].param_name); - } - } - else{ - append_ss(&line, make_lit_string("void")); - } - - append_ss(&line, make_lit_string("));}\n")); - - append_ss(&out, line); - } - } - } - - append_sc(&out, "\n#endif\n"); - } - - else if (match_ss(lexeme, make_lit_string("API_EXPORT_MACRO"))){ - token = get_next_token(&pcontext); - if (token && token->type == CPP_TOKEN_COMMENT){ - token = get_next_token(&pcontext); - if (token && token->type == CPP_PP_DEFINE){ - for (;(token = get_next_token(&pcontext)) != 0;){ - if (!(token->flags & CPP_TFLAG_PP_BODY)){ - break; - } - } - if (token != 0){ - get_prev_token(&pcontext); - } - do_print = false; - do_whitespace_print = false; - } - } - } - - else if (match_ss(lexeme, make_lit_string("API_EXPORT")) || - match_ss(lexeme, make_lit_string("API_EXPORT_INLINE"))){ - if (!(token->flags & CPP_TFLAG_PP_BODY)){ - if (match_ss(lexeme, make_lit_string("API_EXPORT_INLINE"))){ - append_sc(&out, "#if !defined(FSTRING_GUARD)\n"); - } - else{ - append_sc(&out, "#if defined(FSTRING_IMPLEMENTATION)\n"); - } - print_function_body_code(&out, &pcontext, start); - append_sc(&out, "\n#endif"); - do_print = false; - } - } - - else if (match_ss(lexeme, make_lit_string("CPP_NAME"))){ - Cpp_Token *token_start = token; - int32_t has_cpp_name = false; - - token = get_next_token(&pcontext); - if (token && token->type == CPP_TOKEN_PARENTHESE_OPEN){ - token = get_next_token(&pcontext); - if (token && token->type == CPP_TOKEN_IDENTIFIER){ - token = get_next_token(&pcontext); - if (token && token->type == CPP_TOKEN_PARENTHESE_CLOSE){ - has_cpp_name = true; - do_print = false; - } - } - } - - if (!has_cpp_name){ - token = set_token(&pcontext, token_start); - } - } - - else if (token->type == CPP_TOKEN_COMMENT){ - if (check_and_fix_docs(&lexeme)){ - do_print = false; - } - } - - if ((token = get_token(&pcontext)) != 0){ - if (do_print){ - pstr = get_lexeme(*token, pcontext.data); - append_ss(&out, pstr); - } - start = token->start + token->size; - } - } - pstr = str_start_end(pcontext.data, start, parse.code.size); - append_ss(&out, pstr); - - end_file_out(context); - } - else{ - // TODO(allen): warning - } + META_FINISH(); } int main(int argc, char **argv){ diff --git a/meta/4tech_file_moving.h b/meta/4tech_file_moving.h new file mode 100644 index 00000000..c83c7d3a --- /dev/null +++ b/meta/4tech_file_moving.h @@ -0,0 +1,439 @@ +/* +4tech_file_moving.h - Code for moving files around on the file system. +By Allen Webster +21.01.2017 (dd.mm.yyyy) +*/ + +// TOP + +#if !defined(FTECH_FILE_MOVING_H) +#define FTECH_FILE_MOVING_H + +#include // include system for windows +#include // include system for linux (YAY!) + +// NOTE(allen): Compiler/OS cracking. +#if defined(_MSC_VER) + +# define IS_CL +# define snprintf _snprintf + +# if defined(_WIN32) +# define IS_WINDOWS +# pragma comment(lib, "Kernel32.lib") +# else +# error This compiler/platform combo is not supported yet +# endif + +#elif defined(__GNUC__) || defined(__GNUG__) + +# define IS_GCC + +# if defined(__gnu_linux__) +# define IS_LINUX +# else +# error This compiler/platform combo is not supported yet +# endif + +#else +#error This compiler is not supported yet +#endif + + +#if defined(IS_WINDOWS) +# define ONLY_WINDOWS(x) x +# define ONLY_LINUX(x) (void)0 + +#define SLASH "\\" +static char platform_correct_slash = '\\'; + +#elif defined(IS_LINUX) +# define ONLY_WINDOWS(x) (void)0 +# define ONLY_LINUX(x) x + +#define SLASH "/" +static char platform_correct_slash = '/'; + +#else +# define ONLY_WINDOWS(x) (void)0 +# define ONLY_LINUX(x) (void)0 + +#define SLASH "/" +static char platform_correct_slash = '/'; + +#endif + + +static char cmd[4096]; +static i32 error_state = 0; +static i32 prev_error = 0; + +#define systemf(...) do{ \ + int32_t n = snprintf(cmd, sizeof(cmd), __VA_ARGS__); \ + AllowLocal(n); \ + Assert(n < sizeof(cmd)); \ + prev_error = system(cmd); \ + if (prev_error != 0) error_state = 1; \ +}while(0) + +static void init_time_system(); +static u64 get_time(); +static i32 get_current_directory(char *buffer, i32 max); +static void execute_in_dir(char *dir, char *str, char *args); + +static void make_folder_if_missing(char *dir, char *folder); +static void clear_folder(char *folder); +static void delete_file(char *file); +static void copy_file(char *path, char *file, char *folder1, char *folder2, char *newname); +static void copy_all(char *source, char *tag, char *folder); +static void zip(char *parent, char *folder, char *dest); + +static void slash_fix(char *path); +#define DECL_STR(n,s) char n[] = s; slash_fix(n) + +typedef struct Temp_Dir{ + char dir[512]; +} Temp_Dir; + +static Temp_Dir pushdir(char *dir); +static void popdir(Temp_Dir temp); + +#endif + +#if defined(FTECH_FILE_MOVING_IMPLEMENTATION) && !defined(FTECH_FILE_MOVING_IMPL_GUARD) +#define FTECH_FILE_MOVING_IMPL_GUARD + +#if defined(IS_WINDOWS) + +typedef uint32_t DWORD; +typedef int32_t LONG; +typedef int64_t LONGLONG; +typedef char* LPTSTR; +typedef char* LPCTSTR; +typedef int32_t BOOL; +typedef void* LPSECURITY_ATTRIBUTES; +typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + }; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; +} LARGE_INTEGER, *PLARGE_INTEGER; + +#define WINAPI + +extern "C"{ + DWORD WINAPI GetCurrentDirectoryA(_In_ DWORD nBufferLength, _Out_ LPTSTR lpBuffer); + BOOL WINAPI SetCurrentDirectoryA(_In_ LPCTSTR lpPathName); + + BOOL WINAPI QueryPerformanceCounter(_Out_ LARGE_INTEGER *lpPerformanceCount); + + BOOL WINAPI QueryPerformanceFrequency(_Out_ LARGE_INTEGER *lpFrequency); + + BOOL WINAPI CreateDirectoryA(_In_ LPCTSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes); + + BOOL WINAPI CopyFileA(_In_ LPCTSTR lpExistingFileName, _In_ LPCTSTR lpNewFileName, _In_ BOOL bFailIfExists); +} + +static uint64_t perf_frequency; + +static Temp_Dir +pushdir(char *dir){ + Temp_Dir temp = {0}; + GetCurrentDirectoryA(sizeof(temp.dir), temp.dir); + SetCurrentDirectoryA(dir); + return(temp); +} + +static void +popdir(Temp_Dir temp){ + SetCurrentDirectoryA(temp.dir); +} + +static void +init_time_system(){ + LARGE_INTEGER lint; + if (QueryPerformanceFrequency(&lint)){ + perf_frequency = lint.QuadPart; + } +} + +static uint64_t +get_time(){ + uint64_t time = 0; + LARGE_INTEGER lint; + if (QueryPerformanceCounter(&lint)){ + time = lint.QuadPart; + time = (time * 1000000) / perf_frequency; + } + return(time); +} + +static int32_t +get_current_directory(char *buffer, int32_t max){ + int32_t result = GetCurrentDirectoryA(max, buffer); + return(result); +} + +static void +execute_in_dir(char *dir, char *str, char *args){ + if (dir){ + Temp_Dir temp = pushdir(dir); + if (args){ + systemf("call \"%s\" %s", str, args); + } + else{ + systemf("call \"%s\"", str); + } + popdir(temp); + } + else{ + if (args){ + systemf("call \"%s\" %s", str, args); + } + else{ + systemf("call \"%s\"", str); + } + } +} + +static void +slash_fix(char *path){ + if (path){ + for (int32_t i = 0; path[i]; ++i){ + if (path[i] == '/') path[i] = '\\'; + } + } +} + +static void +make_folder_if_missing(char *dir, char *folder){ + char space[1024]; + String path = make_fixed_width_string(space); + append_sc(&path, dir); + if (folder){ + append_sc(&path, "\\"); + append_sc(&path, folder); + } + terminate_with_null(&path); + + char *p = path.str; + for (; *p; ++p){ + if (*p == '\\'){ + *p = 0; + CreateDirectoryA(path.str, 0); + *p = '\\'; + } + } + CreateDirectoryA(path.str, 0); +} + +static void +clear_folder(char *folder){ + systemf("del /S /Q /F %s\\* & rmdir /S /Q %s & mkdir %s", + folder, folder, folder); +} + +static void +delete_file(char *file){ + systemf("del %s", file); +} + +static void +copy_file(char *path, char *file, char *folder1, char *folder2, char *newname){ + char src[256], dst[256]; + String b = make_fixed_width_string(src); + if (path){ + append_sc(&b, path); + append_sc(&b, "\\"); + } + append_sc(&b, file); + terminate_with_null(&b); + + b = make_fixed_width_string(dst); + append_sc(&b, folder1); + append_sc(&b, "\\"); + if (folder2){ + append_sc(&b, folder2); + append_sc(&b, "\\"); + } + if (newname){ + append_sc(&b, newname); + } + else{ + append_sc(&b, file); + } + terminate_with_null(&b); + + CopyFileA(src, dst, 0); +} + +static void +copy_all(char *source, char *tag, char *folder){ + if (source){ + systemf("copy %s\\%s %s\\*", source, tag, folder); + } + else{ + systemf("copy %s %s\\*", tag, folder); + } +} + +static void +zip(char *parent, char *folder, char *dest){ + char cdir[512]; + get_current_directory(cdir, sizeof(cdir)); + + Temp_Dir temp = pushdir(parent); + systemf("%s\\zip %s\\4tech_gobble.zip", cdir, cdir); + popdir(temp); + + systemf("copy %s\\4tech_gobble.zip %s & del %s\\4tech_gobble.zip", cdir, dest, cdir); +} + +#elif defined(IS_LINUX) + +#include +#include + +static Temp_Dir +pushdir(char *dir){ + Temp_Dir temp; + char *result = getcwd(temp.dir, sizeof(temp.dir)); + int32_t chresult = chdir(dir); + if (result == 0 || chresult != 0){ + printf("trying pushdir %s\n", dir); + assert(result != 0); + assert(chresult == 0); + } + return(temp); +} + +static void +popdir(Temp_Dir temp){ + chdir(temp.dir); +} + +static void +init_time_system(){ + // NOTE(allen): do nothing +} + +static uint64_t +get_time(){ + struct timespec spec; + uint64_t result; + clock_gettime(CLOCK_MONOTONIC, &spec); + result = (spec.tv_sec * (uint64_t)(1000000)) + (spec.tv_nsec / (uint64_t)(1000)); + return(result); +} + +static int32_t +get_current_directory(char *buffer, int32_t max){ + int32_t result = 0; + char *d = getcwd(buffer, max); + if (d == buffer){ + result = strlen(buffer); + } + return(result); +} + +static void +execute_in_dir(char *dir, char *str, char *args){ + if (dir){ + if (args){ + Temp_Dir temp = pushdir(dir); + systemf("%s %s", str, args); + popdir(temp); + } + else{ + Temp_Dir temp = pushdir(dir); + systemf("%s", str); + popdir(temp); + } + } + else{ + if (args){ + systemf("%s %s", str, args); + } + else{ + systemf("%s", str); + } + } +} + +static void +slash_fix(char *path){} + +static void +make_folder_if_missing(char *dir, char *folder){ + if (folder){ + systemf("mkdir -p %s/%s", dir, folder); + } + else{ + systemf("mkdir -p %s", dir); + } +} + +static void +clear_folder(char *folder){ + systemf("rm -rf %s*", folder); +} + +static void +delete_file(char *file){ + systemf("rm %s", file); +} + +static void +copy_file(char *path, char *file, char *folder1, char *folder2, char *newname){ + if (!newname){ + newname = file; + } + + if (path){ + if (folder2){ + systemf("cp %s/%s %s/%s/%s", path, file, folder1, folder2, newname); + } + else{ + systemf("cp %s/%s %s/%s", path, file, folder1, newname); + } + } + else{ + if (folder2){ + systemf("cp %s %s/%s/%s", file, folder1, folder2, newname); + } + else{ + systemf("cp %s %s/%s", file, folder1, newname); + } + } +} + +static void +copy_all(char *source, char *tag, char *folder){ + if (source){ + systemf("cp -rf %s/%s %s", source, tag, folder); + } + else{ + systemf("cp -rf %s %s", tag, folder); + } +} + +static void +zip(char *parent, char *folder, char *file){ + Temp_Dir temp = pushdir(parent); + systemf("zip -r %s %s", file, folder); + popdir(temp); +} + +#else +#error This OS is not supported yet +#endif + +#endif + +// BOTTOM + diff --git a/meta/4tech_meta_defines.h b/meta/4tech_meta_defines.h new file mode 100644 index 00000000..d949b82f --- /dev/null +++ b/meta/4tech_meta_defines.h @@ -0,0 +1,49 @@ +/* +4tech_meta_defines.h - Header to setup metaprograms. +By Allen Webster +Created 21.01.2017 (dd.mm.yyyy) +*/ + +// TOP + +#if !defined(FTECH_META_DEFINES_H) +#define FTECH_META_DEFINES_H + +#include "../4tech_defines.h" + +#include +#include + +global jmp_buf META_ASSERT_ENV; +global char* META_ASSERT_MSG; + +internal void +__meta_finish__(){ + if (META_ASSERT_MSG != 0){ + printf("%s\n", META_ASSERT_MSG); + } +} + +#define META_FINISH() } __META_FINISH__: __meta_finish__() + +#define LINE_STR STR_(__LINE__) + +#if defined(Assert) +# undef Assert +#endif + +#define Assert(c) do { if (!(c)) { META_ASSERT_MSG = __FILE__":"LINE_STR": "#c; longjmp(META_ASSERT_ENV, 1); } } while(0) + +#define META_BEGIN() META_ASSERT_MSG = 0; if (setjmp(META_ASSERT_ENV) == 1){ goto __META_FINISH__; } { + +char STANDARD_DISCLAIMER[] = +"no warranty implied; use at your own risk\n" +"\n" +"This software is in the public domain. Where that dedication is not\n" +"recognized, you are granted a perpetual, irrevocable license to copy,\n" +"distribute, and modify this file as you see fit.\n\n"; + +#endif + +// BOTTOM + diff --git a/meta/build.cpp b/meta/build.cpp index 5cd7e772..632936cc 100644 --- a/meta/build.cpp +++ b/meta/build.cpp @@ -4,16 +4,16 @@ // TOP -#include // include system for windows -#include // include system for linux (YAY!) -#include +#include "../4tech_defines.h" +#include "4tech_file_moving.h" + #include #include -#include "../common/4coder_version.h" +#include "../4coder_API/version.h" -#define FSTRING_INLINE static -#include "../internal_4coder_string.cpp" +#define FSTRING_IMPLEMENTATION +#include "../4coder_lib/4coder_string.h" // // reusable @@ -21,397 +21,6 @@ #define IS_64BIT -// NOTE(allen): Compiler/OS cracking. -#if defined(_MSC_VER) - -# define IS_CL -# define snprintf _snprintf - -# if defined(_WIN32) -# define IS_WINDOWS -# pragma comment(lib, "Kernel32.lib") -# else -# error This compiler/platform combo is not supported yet -# endif - -#elif defined(__GNUC__) || defined(__GNUG__) - -# define IS_GCC - -# if defined(__gnu_linux__) -# define IS_LINUX -# else -# error This compiler/platform combo is not supported yet -# endif - -#else -#error This compiler is not supported yet -#endif - - -#if defined(IS_WINDOWS) -# define ONLY_WINDOWS(x) x -# define ONLY_LINUX(x) (void)0 -#elif defined(IS_LINUX) -# define ONLY_WINDOWS(x) (void)0 -# define ONLY_LINUX(x) x -#else -# define ONLY_WIN(x) (void)0 -# define ONLY_LINUX(x) (void)0 -#endif - - -static char cmd[4096]; -static int32_t error_state = 0; -static int32_t prev_error = 0; - -#define systemf(...) do{ \ - int32_t n = snprintf(cmd, sizeof(cmd), __VA_ARGS__); \ - assert(n < sizeof(cmd)); \ - prev_error = system(cmd); \ - if (prev_error != 0) error_state = 1; \ -}while(0) - -static void init_time_system(); -static uint64_t get_time(); -static int32_t get_current_directory(char *buffer, int32_t max); -static void execute_in_dir(char *dir, char *str, char *args); - -static void make_folder_if_missing(char *dir, char *folder); -static void clear_folder(char *folder); -static void copy_file(char *path, char *file, char *folder1, char *folder2, char *newname); -static void copy_all(char *source, char *tag, char *folder); -static void zip(char *parent, char *folder, char *dest); - -typedef struct Temp_Dir{ - char dir[512]; -} Temp_Dir; - -static Temp_Dir pushdir(char *dir); -static void popdir(Temp_Dir temp); - -#if defined(IS_WINDOWS) - -typedef uint32_t DWORD; -typedef int32_t LONG; -typedef int64_t LONGLONG; -typedef char* LPTSTR; -typedef char* LPCTSTR; -typedef int32_t BOOL; -typedef void* LPSECURITY_ATTRIBUTES; -typedef union _LARGE_INTEGER { - struct { - DWORD LowPart; - LONG HighPart; - }; - struct { - DWORD LowPart; - LONG HighPart; - } u; - LONGLONG QuadPart; -} LARGE_INTEGER, *PLARGE_INTEGER; - -#if defined(IS_64BIT) -# define WINAPI -#endif - -extern "C"{ - DWORD WINAPI GetCurrentDirectoryA(_In_ DWORD nBufferLength, _Out_ LPTSTR lpBuffer); - BOOL WINAPI SetCurrentDirectoryA(_In_ LPCTSTR lpPathName); - - BOOL WINAPI QueryPerformanceCounter(_Out_ LARGE_INTEGER *lpPerformanceCount); - - BOOL WINAPI QueryPerformanceFrequency(_Out_ LARGE_INTEGER *lpFrequency); - - BOOL WINAPI CreateDirectoryA(_In_ LPCTSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes); - - BOOL WINAPI CopyFileA(_In_ LPCTSTR lpExistingFileName, _In_ LPCTSTR lpNewFileName, _In_ BOOL bFailIfExists); -} - -static uint64_t perf_frequency; - -static Temp_Dir -pushdir(char *dir){ - Temp_Dir temp = {0}; - GetCurrentDirectoryA(sizeof(temp.dir), temp.dir); - SetCurrentDirectoryA(dir); - return(temp); -} - -static void -popdir(Temp_Dir temp){ - SetCurrentDirectoryA(temp.dir); -} - -static void -init_time_system(){ - LARGE_INTEGER lint; - if (QueryPerformanceFrequency(&lint)){ - perf_frequency = lint.QuadPart; - } -} - -static uint64_t -get_time(){ - uint64_t time = 0; - LARGE_INTEGER lint; - if (QueryPerformanceCounter(&lint)){ - time = lint.QuadPart; - time = (time * 1000000) / perf_frequency; - } - return(time); -} - -static int32_t -get_current_directory(char *buffer, int32_t max){ - int32_t result = GetCurrentDirectoryA(max, buffer); - return(result); -} - -static void -execute_in_dir(char *dir, char *str, char *args){ - if (dir){ - Temp_Dir temp = pushdir(dir); - if (args){ - systemf("call \"%s\" %s", str, args); - } - else{ - systemf("call \"%s\"", str); - } - popdir(temp); - } - else{ - if (args){ - systemf("call \"%s\" %s", str, args); - } - else{ - systemf("call \"%s\"", str); - } - } -} - -static void -slash_fix(char *path){ - if (path){ - for (int32_t i = 0; path[i]; ++i){ - if (path[i] == '/') path[i] = '\\'; - } - } -} - -static void -make_folder_if_missing(char *dir, char *folder){ - char space[1024]; - String path = make_fixed_width_string(space); - append_sc(&path, dir); - if (folder){ - append_sc(&path, "\\"); - append_sc(&path, folder); - } - terminate_with_null(&path); - - char *p = path.str; - for (; *p; ++p){ - if (*p == '\\'){ - *p = 0; - CreateDirectoryA(path.str, 0); - *p = '\\'; - } - } - CreateDirectoryA(path.str, 0); -} - -static void -clear_folder(char *folder){ - systemf("del /S /Q /F %s\\* & rmdir /S /Q %s & mkdir %s", - folder, folder, folder); -} - -static void -copy_file(char *path, char *file, char *folder1, char *folder2, char *newname){ - char src[256], dst[256]; - String b = make_fixed_width_string(src); - if (path){ - append_sc(&b, path); - append_sc(&b, "\\"); - } - append_sc(&b, file); - terminate_with_null(&b); - - b = make_fixed_width_string(dst); - append_sc(&b, folder1); - append_sc(&b, "\\"); - if (folder2){ - append_sc(&b, folder2); - append_sc(&b, "\\"); - } - if (newname){ - append_sc(&b, newname); - } - else{ - append_sc(&b, file); - } - terminate_with_null(&b); - - CopyFileA(src, dst, 0); -} - -static void -copy_all(char *source, char *tag, char *folder){ - if (source){ - systemf("copy %s\\%s %s\\*", source, tag, folder); - } - else{ - systemf("copy %s %s\\*", tag, folder); - } -} - -static void -zip(char *parent, char *folder, char *dest){ - char cdir[512]; - get_current_directory(cdir, sizeof(cdir)); - - Temp_Dir temp = pushdir(parent); - systemf("%s\\zip %s\\4tech_gobble.zip", cdir, cdir); - popdir(temp); - - systemf("copy %s\\4tech_gobble.zip %s & del %s\\4tech_gobble.zip", cdir, dest, cdir); -} - -#elif defined(IS_LINUX) - -#include -#include - -static Temp_Dir -pushdir(char *dir){ - Temp_Dir temp; - char *result = getcwd(temp.dir, sizeof(temp.dir)); - int32_t chresult = chdir(dir); - if (result == 0 || chresult != 0){ - printf("trying pushdir %s\n", dir); - assert(result != 0); - assert(chresult == 0); - } - return(temp); -} - -static void -popdir(Temp_Dir temp){ - chdir(temp.dir); -} - -static void -init_time_system(){ - // NOTE(allen): do nothing -} - -static uint64_t -get_time(){ - struct timespec spec; - uint64_t result; - clock_gettime(CLOCK_MONOTONIC, &spec); - result = (spec.tv_sec * (uint64_t)(1000000)) + (spec.tv_nsec / (uint64_t)(1000)); - return(result); -} - -static int32_t -get_current_directory(char *buffer, int32_t max){ - int32_t result = 0; - char *d = getcwd(buffer, max); - if (d == buffer){ - result = strlen(buffer); - } - return(result); -} - -static void -execute_in_dir(char *dir, char *str, char *args){ - if (dir){ - if (args){ - Temp_Dir temp = pushdir(dir); - systemf("%s %s", str, args); - popdir(temp); - } - else{ - Temp_Dir temp = pushdir(dir); - systemf("%s", str); - popdir(temp); - } - } - else{ - if (args){ - systemf("%s %s", str, args); - } - else{ - systemf("%s", str); - } - } -} - -static void -slash_fix(char *path){} - -static void -make_folder_if_missing(char *dir, char *folder){ - if (folder){ - systemf("mkdir -p %s/%s", dir, folder); - } - else{ - systemf("mkdir -p %s", dir); - } -} - -static void -clear_folder(char *folder){ - systemf("rm -rf %s*", folder); -} - -static void -copy_file(char *path, char *file, char *folder1, char *folder2, char *newname){ - if (!newname){ - newname = file; - } - - if (path){ - if (folder2){ - systemf("cp %s/%s %s/%s/%s", path, file, folder1, folder2, newname); - } - else{ - systemf("cp %s/%s %s/%s", path, file, folder1, newname); - } - } - else{ - if (folder2){ - systemf("cp %s %s/%s/%s", file, folder1, folder2, newname); - } - else{ - systemf("cp %s %s/%s", file, folder1, newname); - } - } -} - -static void -copy_all(char *source, char *tag, char *folder){ - if (source){ - systemf("cp -rf %s/%s %s", source, tag, folder); - } - else{ - systemf("cp -rf %s %s", tag, folder); - } -} - -static void -zip(char *parent, char *folder, char *file){ - Temp_Dir temp = pushdir(parent); - systemf("zip -r %s %s", file, folder); - popdir(temp); -} - -#else -#error This OS is not supported yet -#endif - #define BEGIN_TIME_SECTION() uint64_t start = get_time() #define END_TIME_SECTION(n) uint64_t total = get_time() - start; printf("%-20s: %.2lu.%.6lu\n", (n), total/1000000, total%1000000); @@ -480,7 +89,7 @@ typedef struct Build_Line{ char build_optionsB[BUILD_LINE_MAX]; char *build_options; char *build_options_prev; - int32_t build_max; + i32 build_max; } Build_Line; static void @@ -504,21 +113,18 @@ init_build_line(Build_Line *line){ #elif defined(IS_GCC) -#define build_ap(line, str, ...) do{ \ - snprintf(line.build_options, \ - line.build_max, "%s "str, \ - line.build_options_prev, ##__VA_ARGS__);\ - swap_ptr(&line.build_options, \ - &line.build_options_prev); \ +#define build_ap(line, str, ...) do{ \ + snprintf(line.build_options, line.build_max, "%s "str, \ + line.build_options_prev, ##__VA_ARGS__); \ + swap_ptr(&line.build_options, &line.build_options_prev); \ }while(0) #endif - #define CL_OPTS \ -"/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 " \ -"/wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX " \ -"/GR- /EHa- /nologo /FC" +"-W4 -wd4310 -wd4100 -wd4201 -wd4505 -wd4996 " \ +"-wd4127 -wd4510 -wd4512 -wd4610 -wd4390 " \ +"-wd4611 -WX -GR- -EHa- -nologo -FC" #define CL_INCLUDES "/I..\\foreign /I..\\foreign\\freetype2" @@ -531,7 +137,7 @@ init_build_line(Build_Line *line){ #define CL_ICON "..\\res\\icon.res" static void -build_cl(uint32_t flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){ +build_cl(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){ Build_Line line; init_build_line(&line); @@ -609,7 +215,7 @@ build_cl(uint32_t flags, char *code_path, char *code_file, char *out_path, char "-lGL -ldl -lXfixes -lfreetype -lfontconfig" static void -build_gcc(uint32_t flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){ +build_gcc(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){ Build_Line line; init_build_line(&line); @@ -620,7 +226,7 @@ build_gcc(uint32_t flags, char *code_path, char *code_file, char *out_path, char if (flags & INCLUDES){ // TODO(allen): Abstract this out. #if defined(IS_LINUX) - int32_t size = 0; + i32 size = 0; char freetype_include[512]; FILE *file = popen("pkg-config --cflags freetype2", "r"); if (file != 0){ @@ -676,7 +282,7 @@ build_gcc(uint32_t flags, char *code_path, char *code_file, char *out_path, char } static void -build(uint32_t flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){ +build(u32 flags, char *code_path, char *code_file, char *out_path, char *out_file, char *exports){ #if defined(IS_CL) build_cl(flags, code_path, code_file, out_path, out_file, exports); #elif defined(IS_GCC) @@ -728,8 +334,6 @@ buildsuper(char *code_path, char *out_path, char *filename){ #error No platform layer defined for this OS. #endif -#define DECL_STR(n,s) char n[] = s; slash_fix(n) - static void fsm_generator(char *cdir){ { @@ -777,7 +381,7 @@ enum{ }; static void -do_buildsuper(char *cdir, int32_t custom_option){ +do_buildsuper(char *cdir, i32 custom_option){ char space[1024]; String str = make_fixed_width_string(space); @@ -818,7 +422,7 @@ do_buildsuper(char *cdir, int32_t custom_option){ } static void -build_main(char *cdir, uint32_t flags){ +build_main(char *cdir, u32 flags){ DECL_STR(dir, BUILD_DIR); { DECL_STR(file, "4ed_app_target.cpp"); @@ -835,7 +439,9 @@ build_main(char *cdir, uint32_t flags){ } static void -standard_build(char *cdir, uint32_t flags){ +standard_build(char *cdir, u32 flags){ + //run_update("4coder_string.h"); + //run_update("4cpp/4cpp_lexer.h 4cpp/4cpp_lexer.h 4cpp/4cpp_lexer.h"); fsm_generator(cdir); metagen(cdir); do_buildsuper(cdir, Custom_Experiments); @@ -844,7 +450,7 @@ standard_build(char *cdir, uint32_t flags){ } static void -site_build(char *cdir, uint32_t flags){ +site_build(char *cdir, u32 flags){ { DECL_STR(file, "site/sitegen.cpp"); DECL_STR(dir, BUILD_DIR"/site"); @@ -857,14 +463,14 @@ site_build(char *cdir, uint32_t flags){ BEGIN_TIME_SECTION(); DECL_STR(cmd, "../build/site/sitegen . ../site_resources site/source_material ../site"); - systemf(cmd); + systemf("%s", cmd); END_TIME_SECTION("run sitegen"); } } static void -get_4coder_dist_name(String *zip_file, int32_t OS_specific, char *tier, char *ext){ +get_4coder_dist_name(String *zip_file, i32 OS_specific, char *tier, char *ext){ zip_file->size = 0; append_sc(zip_file, PACK_DIR"/"); @@ -927,13 +533,13 @@ package(char *cdir){ make_folder_if_missing(pack_alpha_dir, "3rdparty"); make_folder_if_missing(pack_dir, "alpha"); copy_file(build_dir, "4ed"EXE, pack_alpha_dir, 0, 0); - ONLY_WINDOWS(copy_file(build_dir, "4ed"PDB, pack_alpha_dir, 0, 0)); + //ONLY_WINDOWS(copy_file(build_dir, "4ed"PDB, pack_alpha_dir, 0, 0)); copy_file(build_dir, "4ed_app"DLL, pack_alpha_dir, 0, 0); - ONLY_WINDOWS(copy_file(build_dir, "4ed_app"PDB, pack_alpha_dir, 0, 0)); + //ONLY_WINDOWS(copy_file(build_dir, "4ed_app"PDB, pack_alpha_dir, 0, 0)); copy_all (pack_data_dir, "*", pack_alpha_dir); copy_file(0, "README.txt", pack_alpha_dir, 0, 0); copy_file(0, "TODO.txt", pack_alpha_dir, 0, 0); - copy_file(DATA_DIR, "release-config.4coder", pack_alpha_dir, 0, "config.4coder"); + copy_file(data_dir, "release-config.4coder", pack_alpha_dir, 0, "config.4coder"); get_4coder_dist_name(&str, 1, "alpha", "zip"); zip(pack_alpha_par_dir, "4coder", str.str); @@ -948,22 +554,47 @@ package(char *cdir){ make_folder_if_missing(pack_dir, "super-docs"); copy_file(build_dir, "4ed"EXE, pack_super_dir, 0, 0); - ONLY_WINDOWS(copy_file(build_dir, "4ed"PDB, pack_super_dir, 0, 0)); + //ONLY_WINDOWS(copy_file(build_dir, "4ed"PDB, pack_super_dir, 0, 0)); copy_file(build_dir, "4ed_app"DLL, pack_super_dir, 0, 0); - ONLY_WINDOWS(copy_file(build_dir, "4ed_app"PDB, pack_super_dir, 0, 0)); - copy_file(build_dir, "4coder_custom"DLL, pack_super_dir, 0, 0); + //ONLY_WINDOWS(copy_file(build_dir, "4ed_app"PDB, pack_super_dir, 0, 0)); + copy_file(build_dir, "custom_4coder"DLL, pack_super_dir, 0, 0); copy_all (pack_data_dir, "*", pack_super_dir); copy_file(0, "README.txt", pack_super_dir, 0, 0); copy_file(0, "TODO.txt", pack_super_dir, 0, 0); copy_file(data_dir, "release-config.4coder", pack_super_dir, 0, "config.4coder"); - copy_all (0, "4coder_*.h", pack_super_dir); - copy_all (0, "4coder_*.cpp", pack_super_dir); - copy_all (0, "4cpp_*.h", pack_super_dir); - copy_all (0, "4cpp_*.c", pack_super_dir); + copy_all(0, "4coder_*", pack_super_dir); + copy_file(0, "buildsuper"BAT, pack_super_dir, 0, 0); + DECL_STR(custom_dir, "4coder_API"); + DECL_STR(custom_helper_dir, "4coder_helper"); + DECL_STR(custom_lib_dir, "4coder_lib"); + DECL_STR(fcpp_dir, "4cpp"); + + char *dir_array[] = { + custom_dir, + custom_helper_dir, + custom_lib_dir, + fcpp_dir, + }; + i32 dir_count = ArrayCount(dir_array); + + for (i32 i = 0; i < dir_count; ++i){ + char *d = dir_array[i]; + make_folder_if_missing(pack_super_dir, d); + + char space[256]; + String str = make_fixed_width_string(space); + append_sc(&str, pack_super_dir); + append_s_char(&str, platform_correct_slash); + append_sc(&str, d); + terminate_with_null(&str); + + copy_all(d, "*", str.str); + } + get_4coder_dist_name(&str, 0, "API", "html"); str2 = front_of_directory(str); copy_file(site_dir, "custom_docs.html", pack_dir, "super-docs", str2.str); @@ -989,7 +620,7 @@ int main(int argc, char **argv){ char cdir[256]; BEGIN_TIME_SECTION(); - int32_t n = get_current_directory(cdir, sizeof(cdir)); + i32 n = get_current_directory(cdir, sizeof(cdir)); assert(n < sizeof(cdir)); END_TIME_SECTION("current directory"); @@ -1002,12 +633,11 @@ int main(int argc, char **argv){ int main(int argc, char **argv){ init_time_system(); - init_global_strings(); char cdir[256]; BEGIN_TIME_SECTION(); - int32_t n = get_current_directory(cdir, sizeof(cdir)); + i32 n = get_current_directory(cdir, sizeof(cdir)); assert(n < sizeof(cdir)); END_TIME_SECTION("current directory"); @@ -1024,7 +654,7 @@ int main(int argc, char **argv){ char cdir[256]; BEGIN_TIME_SECTION(); - int32_t n = get_current_directory(cdir, sizeof(cdir)); + i32 n = get_current_directory(cdir, sizeof(cdir)); assert(n < sizeof(cdir)); END_TIME_SECTION("current directory"); @@ -1037,4 +667,9 @@ int main(int argc, char **argv){ #error No build type specified #endif +#define FTECH_FILE_MOVING_IMPLEMENTATION +#include "4tech_file_moving.h" + // BOTTOM + + diff --git a/meta/fsm_table_generator.cpp b/meta/fsm_table_generator.cpp index 05bf6219..a9b28de3 100644 --- a/meta/fsm_table_generator.cpp +++ b/meta/fsm_table_generator.cpp @@ -14,7 +14,9 @@ #define Assert(n) do{ if (!(n)) { *(int*)0 = 0xA11E; } }while(0) #define ArrayCount(a) (sizeof(a)/sizeof(*a)) -#include "../4cpp_lexer_types.h" +#define LEXER_TABLE_FILE "4cpp/4cpp_lexer_tables.c" + +#include "../4cpp/4cpp_lexer_types.h" #include "../4ed_mem_ansi.c" typedef struct Whitespace_FSM{ @@ -700,7 +702,7 @@ static PP_Names pp_names[] = { int main(){ FILE *file; - file = fopen("4cpp_lexer_tables.c", "wb"); + file = fopen(LEXER_TABLE_FILE, "wb"); FSM_Tables wtables = generate_whitespace_skip_table(); render_fsm_table(file, wtables, "whitespace_fsm"); diff --git a/meta/meta_parser.cpp b/meta/meta_parser.cpp index 5fe55e8b..df139e8e 100644 --- a/meta/meta_parser.cpp +++ b/meta/meta_parser.cpp @@ -9,21 +9,8 @@ // TOP -#if !defined(META_PARSER_CPP_4CODER) -#define META_PARSER_CPP_4CODER - -#if !defined(FSTRING_GUARD) -#include "internal_4coder_string.cpp" -#endif - -#include "../4cpp_lexer.h" - -#include -#include -#include -#include - -#include "../4coder_mem.h" +#if !defined(META_PARSER_CPP) +#define META_PARSER_CPP typedef struct Parse_Context{ Cpp_Token *token_s; @@ -241,8 +228,10 @@ static Parse meta_lex(char *filename){ Parse result = {0}; result.code = file_dump(filename); - result.tokens = cpp_make_token_array(1024); - cpp_lex_file(result.code.str, result.code.size, &result.tokens); + if (result.code.str != 0){ + result.tokens = cpp_make_token_array(1024); + cpp_lex_file(result.code.str, result.code.size, &result.tokens); + } return(result); } @@ -261,7 +250,7 @@ get_next_line(String source, String line){ int32_t start = 0; if (pos < source.size){ - assert(source.str[pos] == '\n'); + Assert(source.str[pos] == '\n'); start = pos + 1; if (start < source.size){ @@ -369,7 +358,7 @@ static String doc_parse_note_string(String source, int32_t *pos){ String result = {0}; - assert(source.str[*pos] == '('); + Assert(source.str[*pos] == '('); int32_t p = *pos + 1; int32_t start = p; @@ -498,7 +487,7 @@ perform_doc_parse(Partition *part, String doc_string, Documentation *doc){ switch (doc_note_type){ case DOC_PARAM: { - assert(param_index < param_count); + Assert(param_index < param_count); int32_t param_pos = 0; String param_name = doc_parse_parameter(doc_note_string, ¶m_pos); String param_docs = doc_parse_last_parameter(doc_note_string, ¶m_pos); @@ -519,7 +508,7 @@ perform_doc_parse(Partition *part, String doc_string, Documentation *doc){ case DOC_SEE: { - assert(see_index < see_count); + Assert(see_index < see_count); doc->see_also[see_index++] = doc_note_string; }break; } @@ -613,7 +602,7 @@ struct_parse_next_member(Partition *part, Parse_Context *context){ break; } else{ - assert(!"unhandled error"); + Assert(!"unhandled error"); } } else if (match_ss(lexeme, make_lit_string("UNION"))){ @@ -623,7 +612,7 @@ struct_parse_next_member(Partition *part, Parse_Context *context){ break; } else{ - assert(!"unhandled error"); + Assert(!"unhandled error"); } } else{ @@ -633,7 +622,7 @@ struct_parse_next_member(Partition *part, Parse_Context *context){ break; } else{ - assert(!"unhandled error"); + Assert(!"unhandled error"); } } } @@ -1210,6 +1199,7 @@ compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keyw unit.count = file_count; unit.parse = push_array(part, Parse, file_count); + b32 all_files_lexed = true; int32_t i = 0; for (char **file_ptr = files; *file_ptr; ++file_ptr, ++i){ char str_space[512]; @@ -1224,143 +1214,151 @@ compile_meta_unit(Partition *part, char *code_directory, char **files, Meta_Keyw terminate_with_null(&name); unit.parse[i] = meta_lex(name.str); + if (unit.parse[i].code.str == 0){ + all_files_lexed = false; + break; + } } - // TODO(allen): This stage counts nested structs - // and unions which is not correct. Luckily it only - // means we over allocate by a few items, but fixing it - // to be exactly correct would be nice. - for (int32_t J = 0; J < unit.count; ++J){ - Cpp_Token *token = 0; - Parse_Context context_ = setup_parse_context(unit.parse[J]); - Parse_Context *context = &context_; - - for (; (token = get_token(context)) != 0; get_next_token(context)){ - if (!(token->flags & CPP_TFLAG_PP_BODY)){ - - String lexeme = get_lexeme(*token, context->data); - int32_t match_index = 0; - if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ - Item_Type type = keywords[match_index].type; + + if (all_files_lexed){ + // TODO(allen): This stage counts nested structs and unions which is not correct. Luckily it only means we over allocate by a few items, but fixing it to be exactly correct would be nice. + for (int32_t J = 0; J < unit.count; ++J){ + Cpp_Token *token = 0; + Parse_Context context_ = setup_parse_context(unit.parse[J]); + Parse_Context *context = &context_; + + for (; (token = get_token(context)) != 0; get_next_token(context)){ + if (!(token->flags & CPP_TFLAG_PP_BODY)){ - if (type > Item_Null && type < Item_Type_Count){ - ++unit.set.count; - } - else{ - // TODO(allen): Warning + String lexeme = get_lexeme(*token, context->data); + int32_t match_index = 0; + if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ + Item_Type type = keywords[match_index].type; + + if (type > Item_Null && type < Item_Type_Count){ + ++unit.set.count; + } + else{ + // TODO(allen): Warning + } } } } } - } - - if (unit.set.count > 0){ - unit.set = allocate_item_set(part, unit.set.count); - } - - int32_t index = 0; - - for (int32_t J = 0; J < unit.count; ++J){ - Cpp_Token *token = 0; - Parse_Context context_ = setup_parse_context(unit.parse[J]); - Parse_Context *context = &context_; - String cpp_name = {0}; - int32_t has_cpp_name = 0; - - for (; (token = get_token(context)) != 0; get_next_token(context)){ - if (!(token->flags & CPP_TFLAG_PP_BODY)){ - - String lexeme = get_lexeme(*token, context->data); - int32_t match_index = 0; - if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ - Item_Type type = keywords[match_index].type; - - switch (type){ - case Item_Function: - { - if (function_parse(part, context, unit.set.items + index, cpp_name)){ - Assert(unit.set.items[index].t == Item_Function); - ++index; - } - else{ - fprintf(stderr, "warning: invalid function signature\n"); - } - }break; - - case Item_CppName: - { - if (cpp_name_parse(context, &cpp_name)){ - has_cpp_name = 1; - } - else{ - // TODO(allen): warning message - } - }break; - - case Item_Macro: - { - if (macro_parse(part, context, unit.set.items + index)){ - Assert(unit.set.items[index].t == Item_Macro); - ++index; - } - else{ - // TODO(allen): warning message - } - }break; - - case Item_Typedef: //typedef - { - if (typedef_parse(context, unit.set.items + index)){ - Assert(unit.set.items[index].t == Item_Typedef); - ++index; - } - else{ - // TODO(allen): warning message - } - }break; - - case Item_Struct: case Item_Union: //struct/union - { - if (struct_parse(part, (type == Item_Struct), context, unit.set.items + index)){ - Assert(unit.set.items[index].t == Item_Struct || - unit.set.items[index].t == Item_Union); - ++index; - } - else{ - // TODO(allen): warning message - } - }break; - - case Item_Enum: //ENUM - { - if (enum_parse(part, context, unit.set.items + index)){ - Assert(unit.set.items[index].t == Item_Enum); - ++index; - } - else{ - // TODO(allen): warning message - } - }break; - - } - } - } - - if (has_cpp_name){ - has_cpp_name = 0; - } - else{ - cpp_name = null_string; - } - - unit.parse[J].item_count = index; + if (unit.set.count > 0){ + unit.set = allocate_item_set(part, unit.set.count); } - // NOTE(allen): This is necessary for now because - // the original count is slightly overestimated thanks - // to nested structs and unions. - unit.set.count = index; + int32_t index = 0; + + for (int32_t J = 0; J < unit.count; ++J){ + Cpp_Token *token = 0; + Parse_Context context_ = setup_parse_context(unit.parse[J]); + Parse_Context *context = &context_; + + String cpp_name = {0}; + int32_t has_cpp_name = 0; + + for (; (token = get_token(context)) != 0; get_next_token(context)){ + if (!(token->flags & CPP_TFLAG_PP_BODY)){ + + String lexeme = get_lexeme(*token, context->data); + int32_t match_index = 0; + if (string_set_match_table(keywords, sizeof(*keywords), key_count, lexeme, &match_index)){ + Item_Type type = keywords[match_index].type; + + switch (type){ + case Item_Function: + { + if (function_parse(part, context, unit.set.items + index, cpp_name)){ + Assert(unit.set.items[index].t == Item_Function); + ++index; + } + else{ + fprintf(stderr, "warning: invalid function signature\n"); + } + }break; + + case Item_CppName: + { + if (cpp_name_parse(context, &cpp_name)){ + has_cpp_name = 1; + } + else{ + // TODO(allen): warning message + } + }break; + + case Item_Macro: + { + if (macro_parse(part, context, unit.set.items + index)){ + Assert(unit.set.items[index].t == Item_Macro); + ++index; + } + else{ + // TODO(allen): warning message + } + }break; + + case Item_Typedef: //typedef + { + if (typedef_parse(context, unit.set.items + index)){ + Assert(unit.set.items[index].t == Item_Typedef); + ++index; + } + else{ + // TODO(allen): warning message + } + }break; + + case Item_Struct: case Item_Union: //struct/union + { + if (struct_parse(part, (type == Item_Struct), context, unit.set.items + index)){ + Assert(unit.set.items[index].t == Item_Struct || + unit.set.items[index].t == Item_Union); + ++index; + } + else{ + // TODO(allen): warning message + } + }break; + + case Item_Enum: //ENUM + { + if (enum_parse(part, context, unit.set.items + index)){ + Assert(unit.set.items[index].t == Item_Enum); + ++index; + } + else{ + // TODO(allen): warning message + } + }break; + + } + } + } + + if (has_cpp_name){ + has_cpp_name = 0; + } + else{ + cpp_name = null_string; + } + + unit.parse[J].item_count = index; + } + + // NOTE(allen): This is necessary for now because + // the original count is slightly overestimated thanks + // to nested structs and unions. + unit.set.count = index; + } + } + else{ + unit.parse = 0; + unit.count = 0; } return(unit); diff --git a/not_shipping_4coder_default_view.cpp b/not_shipping_4coder_default_view.cpp deleted file mode 100644 index b8112091..00000000 --- a/not_shipping_4coder_default_view.cpp +++ /dev/null @@ -1,89 +0,0 @@ - -struct Custom_Vars{ - int32_t initialized; - Partition part; -}; - -enum View_Mode{ - ViewMode_File, -}; - -struct View_Vars{ - int32_t id; - View_Mode mode; - - GUI_Scroll_Vars scroll; - i32_Rect scroll_region; - - int32_t buffer_id; -}; -inline View_Vars -view_vars_zero(){ - View_Vars vars = {0}; - return(vars); -} - -extern "C" void -view_routine(Application_Links *app, int32_t view_id){ - Custom_Vars *vars = (Custom_Vars*)app->memory; - View_Vars view = {0}; - view.id = view_id; - - int32_t show_scrollbar = 1; - - if (!vars->initialized){ - vars->initialized = 1; - vars->part = make_part(app->memory, app->memory_size); - push_struct(&vars->part, Custom_Vars); - } - - for(;;){ - Event_Message message = {0}; - message = app->get_event_message(app); - - switch (message.type){ - case EM_Open_View: - { - view = view_vars_zero(); - view.id = view_id; - }break; - - case EM_Frame: - { - GUI_Functions *guifn = app->get_gui_functions(app); - GUI *gui = app->get_gui(app, view_id); - - guifn->begin(gui); - guifn->top_bar(gui); - - switch (view.mode){ - case ViewMode_File: - // TODO(allen): Overlapped widget - GUI_id scroll_id; - scroll_id.id[1] = view.mode; - scroll_id.id[0] = view.buffer_id; - - guifn->get_scroll_vars(gui, scroll_id, &view.scroll, - &view.scroll_region); - guifn->begin_scrollable(gui, scroll_id, view.scroll, - 144.f, show_scrollbar); - guifn->file(gui, view.buffer_id); - guifn->end_scrollable(gui); - break; - } - - guifn->end(gui); - - // TODO(allen): Put this code in charge of dispatching - // to the command or command coroutine or whatever. - - // TODO(allen): Put this code in charge of when to process - // the GUI with input and retrieve new layout data. - }break; - - case EM_Close_View: - {}break; - } - } -} - diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp index cb2d37e1..dc729fb2 100644 --- a/power/4coder_experiments.cpp +++ b/power/4coder_experiments.cpp @@ -3,6 +3,8 @@ #include "4coder_default_include.cpp" +#include "4coder_function_list.cpp" + #define NO_BINDING #include "4coder_default_bindings.cpp" @@ -197,273 +199,6 @@ CUSTOM_COMMAND_SIG(multi_line_edit){ } } -// -// Declaration list -// - -static void -list_all_functions(Application_Links *app, Partition *part, Buffer_Summary *buffer){ - String search_name = make_lit_string("*decls*"); - Buffer_Summary decls_buffer = get_buffer_by_name(app, search_name.str, search_name.size, AccessAll); - if (!decls_buffer.exists){ - decls_buffer = create_buffer(app, search_name.str, search_name.size, BufferCreate_AlwaysNew); - buffer_set_setting(app, &decls_buffer, BufferSetting_Unimportant, true); - buffer_set_setting(app, &decls_buffer, BufferSetting_ReadOnly, true); - buffer_set_setting(app, &decls_buffer, BufferSetting_WrapLine, false); - } - else{ - buffer_replace_range(app, &decls_buffer, 0, decls_buffer.size, 0, 0); - } - - Temp_Memory temp = begin_temp_memory(part); - - struct Function_Positions{ - int32_t sig_start_index; - int32_t sig_end_index; - int32_t open_paren_pos; - }; - - Function_Positions *positions_array = push_array(part, Function_Positions, (4<<10)/sizeof(Function_Positions)); - int32_t positions_count = 0; - - Partition extra_memory_ = partition_sub_part(part, (4<<10)); - Partition *extra_memory = &extra_memory_; - char *str = (char*)partition_current(part); - int32_t part_size = 0; - int32_t size = 0; - - static const int32_t token_chunk_size = 512; - Cpp_Token token_chunk[token_chunk_size]; - Stream_Tokens token_stream = {0}; - - if (init_stream_tokens(&token_stream, app, buffer, 0, token_chunk, token_chunk_size)){ - Stream_Tokens start_position_stream_temp = begin_temp_stream_token(&token_stream); - - int32_t token_index = 0; - int32_t nest_level = 0; - int32_t paren_nest_level = 0; - - int32_t first_paren_index = 0; - int32_t first_paren_position = 0; - int32_t last_paren_index = 0; - - bool32 still_looping = false; - - // Look for the next token at global scope that might need to be printed. - mode1: do{ - for (; token_index < token_stream.end; ++token_index){ - Cpp_Token *token = &token_stream.tokens[token_index]; - - if (!(token->flags & CPP_TFLAG_PP_BODY)){ - switch (token->type){ - case CPP_TOKEN_BRACE_OPEN: - { - ++nest_level; - }break; - - case CPP_TOKEN_BRACE_CLOSE: - { - if (nest_level > 0){ - --nest_level; - } - }break; - - case CPP_TOKEN_PARENTHESE_OPEN: - { - if (nest_level == 0){ - first_paren_index = token_index; - first_paren_position = token->start; - goto paren_mode1; - } - }break; - } - } - } - still_looping = forward_stream_tokens(&token_stream); - }while(still_looping); - goto end; - - // Look for a closing parenthese to mark the end of a function signature. - paren_mode1: - paren_nest_level = 0; - do{ - for (; token_index < token_stream.end; ++token_index){ - Cpp_Token *token = &token_stream.tokens[token_index]; - - if (!(token->flags & CPP_TFLAG_PP_BODY)){ - switch (token->type){ - case CPP_TOKEN_PARENTHESE_OPEN: - { - ++paren_nest_level; - }break; - - case CPP_TOKEN_PARENTHESE_CLOSE: - { - --paren_nest_level; - if (paren_nest_level == 0){ - last_paren_index = token_index; - goto paren_mode2; - } - }break; - } - } - } - still_looping = forward_stream_tokens(&token_stream); - }while(still_looping); - goto end; - - // Look backwards from an open parenthese to find the start of a function signature. - paren_mode2: { - Stream_Tokens backward_stream_temp = begin_temp_stream_token(&token_stream); - int32_t local_index = first_paren_index; - int32_t signature_start_index = 0; - - do{ - for (; local_index >= token_stream.start; --local_index){ - Cpp_Token *token = &token_stream.tokens[local_index]; - if ((token->flags & CPP_TFLAG_PP_BODY) || (token->flags & CPP_TFLAG_PP_DIRECTIVE) || token->type == CPP_TOKEN_BRACE_CLOSE || token->type == CPP_TOKEN_SEMICOLON || token->type == CPP_TOKEN_PARENTHESE_CLOSE){ - ++local_index; - signature_start_index = local_index; - goto paren_mode2_done; - } - } - still_looping = backward_stream_tokens(&token_stream); - }while(still_looping); - // When this loop ends by going all the way back to the beginning set the signature start to 0 and fall through to the printing phase. - signature_start_index = 0; - - paren_mode2_done:; - { - Function_Positions positions; - positions.sig_start_index = signature_start_index; - positions.sig_end_index = last_paren_index; - positions.open_paren_pos = first_paren_position; - positions_array[positions_count++] = positions; - } - - end_temp_stream_token(&token_stream, backward_stream_temp); - goto mode1; - } - - end:; - end_temp_stream_token(&token_stream, start_position_stream_temp); - // Print the results - String buffer_name = make_string(buffer->buffer_name, buffer->buffer_name_len); - for (int32_t i = 0; i < positions_count; ++i){ - Function_Positions *positions = &positions_array[i]; - Temp_Memory extra_temp = begin_temp_memory(extra_memory); - - int32_t local_index = positions->sig_start_index; - int32_t end_index = positions->sig_end_index; - int32_t open_paren_pos = positions->open_paren_pos; - - do{ - for (; local_index < token_stream.end; ++local_index){ - Cpp_Token *token = &token_stream.tokens[local_index]; - if (!(token->flags & CPP_TFLAG_PP_BODY)){ - if (token->type != CPP_TOKEN_COMMENT){ - bool32 delete_space_before = false; - bool32 space_after = false; - - switch (token->type){ - case CPP_TOKEN_COMMA: - case CPP_TOKEN_PARENTHESE_OPEN: - case CPP_TOKEN_PARENTHESE_CLOSE: - { - delete_space_before = true; - }break; - } - - switch (token->type){ - case CPP_TOKEN_IDENTIFIER: - case CPP_TOKEN_COMMA: - case CPP_TOKEN_STAR: - { - space_after = true; - }break; - } - if (token->flags & CPP_TFLAG_IS_KEYWORD){ - space_after = true; - } - - if (delete_space_before){ - int32_t pos = extra_memory->pos - 1; - char *base = ((char*)(extra_memory->base)); - if (pos >= 0 && base[pos] == ' '){ - extra_memory->pos = pos; - } - } - - char *token_str = push_array(extra_memory, char, token->size + space_after); - - buffer_read_range(app, buffer, token->start, token->start + token->size, token_str); - if (space_after){ - token_str[token->size] = ' '; - } - } - } - - if (local_index == end_index){ - goto finish_print; - } - } - still_looping = forward_stream_tokens(&token_stream); - }while(still_looping); - - finish_print:; - { - int32_t sig_size = extra_memory->pos; - String sig = make_string(extra_memory->base, sig_size); - - int32_t line_number = buffer_get_line_index(app, buffer, open_paren_pos); - int32_t line_number_len = int_to_str_size(line_number); - - int32_t append_len = buffer_name.size + 1 + line_number_len + 1 + 1 + sig_size + 1; - - char *out_space = push_array(part, char, append_len); - if (out_space == 0){ - buffer_replace_range(app, &decls_buffer, size, size, str, part_size); - size += part_size; - - end_temp_memory(temp); - temp = begin_temp_memory(part); - - part_size = 0; - out_space = push_array(part, char, append_len); - } - - part_size += append_len; - String out = make_string(out_space, 0, append_len); - append(&out, buffer_name); - append(&out, ':'); - append_int_to_str(&out, line_number); - append(&out, ':'); - append(&out, ' '); - append(&out, sig); - append(&out, '\n'); - } - - end_temp_memory(extra_temp); - } - - buffer_replace_range(app, &decls_buffer, size, size, str, part_size); - - View_Summary view = get_active_view(app, AccessAll); - view_set_buffer(app, &view, decls_buffer.buffer_id, 0); - - lock_jump_buffer(search_name.str, search_name.size); - - end_temp_memory(temp); - } -} - -CUSTOM_COMMAND_SIG(list_all_functions_current_buffer){ - uint32_t access = AccessProtected; - View_Summary view = get_active_view(app, access); - Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); - list_all_functions(app, &global_part, &buffer); -} - // // Scope-Smart Editing Basics // diff --git a/power/4coder_function_list.cpp b/power/4coder_function_list.cpp new file mode 100644 index 00000000..0fc79e4f --- /dev/null +++ b/power/4coder_function_list.cpp @@ -0,0 +1,282 @@ + +// TOP + +// NOTE(allen|a4.0.14): This turned out to be a nasty little routine. There might +// be a better way to do it with just tokens that I didn't see the first time +// through. Once I build a real parser this should become almost just as easy as +// iterating tokens is now. +// +// This version can be dropped anywhere underneath 4coder_default_include.cpp and +// will then provide the "list_all_functions_current_buffer" command. +// + + +// +// Declaration list +// + +static void +list_all_functions(Application_Links *app, Partition *part, Buffer_Summary *buffer){ + String search_name = make_lit_string("*decls*"); + Buffer_Summary decls_buffer = get_buffer_by_name(app, search_name.str, search_name.size, AccessAll); + if (!decls_buffer.exists){ + decls_buffer = create_buffer(app, search_name.str, search_name.size, BufferCreate_AlwaysNew); + buffer_set_setting(app, &decls_buffer, BufferSetting_Unimportant, true); + buffer_set_setting(app, &decls_buffer, BufferSetting_ReadOnly, true); + buffer_set_setting(app, &decls_buffer, BufferSetting_WrapLine, false); + } + else{ + buffer_replace_range(app, &decls_buffer, 0, decls_buffer.size, 0, 0); + } + + Temp_Memory temp = begin_temp_memory(part); + + struct Function_Positions{ + int32_t sig_start_index; + int32_t sig_end_index; + int32_t open_paren_pos; + }; + + Function_Positions *positions_array = push_array(part, Function_Positions, (4<<10)/sizeof(Function_Positions)); + int32_t positions_count = 0; + + Partition extra_memory_ = partition_sub_part(part, (4<<10)); + Partition *extra_memory = &extra_memory_; + char *str = (char*)partition_current(part); + int32_t part_size = 0; + int32_t size = 0; + + static const int32_t token_chunk_size = 512; + Cpp_Token token_chunk[token_chunk_size]; + Stream_Tokens token_stream = {0}; + + if (init_stream_tokens(&token_stream, app, buffer, 0, token_chunk, token_chunk_size)){ + Stream_Tokens start_position_stream_temp = begin_temp_stream_token(&token_stream); + + int32_t token_index = 0; + int32_t nest_level = 0; + int32_t paren_nest_level = 0; + + int32_t first_paren_index = 0; + int32_t first_paren_position = 0; + int32_t last_paren_index = 0; + + bool32 still_looping = false; + + // Look for the next token at global scope that might need to be printed. + mode1: do{ + for (; token_index < token_stream.end; ++token_index){ + Cpp_Token *token = &token_stream.tokens[token_index]; + + if (!(token->flags & CPP_TFLAG_PP_BODY)){ + switch (token->type){ + case CPP_TOKEN_BRACE_OPEN: + { + ++nest_level; + }break; + + case CPP_TOKEN_BRACE_CLOSE: + { + if (nest_level > 0){ + --nest_level; + } + }break; + + case CPP_TOKEN_PARENTHESE_OPEN: + { + if (nest_level == 0){ + first_paren_index = token_index; + first_paren_position = token->start; + goto paren_mode1; + } + }break; + } + } + } + still_looping = forward_stream_tokens(&token_stream); + }while(still_looping); + goto end; + + // Look for a closing parenthese to mark the end of a function signature. + paren_mode1: + paren_nest_level = 0; + do{ + for (; token_index < token_stream.end; ++token_index){ + Cpp_Token *token = &token_stream.tokens[token_index]; + + if (!(token->flags & CPP_TFLAG_PP_BODY)){ + switch (token->type){ + case CPP_TOKEN_PARENTHESE_OPEN: + { + ++paren_nest_level; + }break; + + case CPP_TOKEN_PARENTHESE_CLOSE: + { + --paren_nest_level; + if (paren_nest_level == 0){ + last_paren_index = token_index; + goto paren_mode2; + } + }break; + } + } + } + still_looping = forward_stream_tokens(&token_stream); + }while(still_looping); + goto end; + + // Look backwards from an open parenthese to find the start of a function signature. + paren_mode2: { + Stream_Tokens backward_stream_temp = begin_temp_stream_token(&token_stream); + int32_t local_index = first_paren_index; + int32_t signature_start_index = 0; + + do{ + for (; local_index >= token_stream.start; --local_index){ + Cpp_Token *token = &token_stream.tokens[local_index]; + if ((token->flags & CPP_TFLAG_PP_BODY) || (token->flags & CPP_TFLAG_PP_DIRECTIVE) || token->type == CPP_TOKEN_BRACE_CLOSE || token->type == CPP_TOKEN_SEMICOLON || token->type == CPP_TOKEN_PARENTHESE_CLOSE){ + ++local_index; + signature_start_index = local_index; + goto paren_mode2_done; + } + } + still_looping = backward_stream_tokens(&token_stream); + }while(still_looping); + // When this loop ends by going all the way back to the beginning set the signature start to 0 and fall through to the printing phase. + signature_start_index = 0; + + paren_mode2_done:; + { + Function_Positions positions; + positions.sig_start_index = signature_start_index; + positions.sig_end_index = last_paren_index; + positions.open_paren_pos = first_paren_position; + positions_array[positions_count++] = positions; + } + + end_temp_stream_token(&token_stream, backward_stream_temp); + goto mode1; + } + + end:; + end_temp_stream_token(&token_stream, start_position_stream_temp); + // Print the results + String buffer_name = make_string(buffer->buffer_name, buffer->buffer_name_len); + for (int32_t i = 0; i < positions_count; ++i){ + Function_Positions *positions = &positions_array[i]; + Temp_Memory extra_temp = begin_temp_memory(extra_memory); + + int32_t local_index = positions->sig_start_index; + int32_t end_index = positions->sig_end_index; + int32_t open_paren_pos = positions->open_paren_pos; + + do{ + for (; local_index < token_stream.end; ++local_index){ + Cpp_Token *token = &token_stream.tokens[local_index]; + if (!(token->flags & CPP_TFLAG_PP_BODY)){ + if (token->type != CPP_TOKEN_COMMENT){ + bool32 delete_space_before = false; + bool32 space_after = false; + + switch (token->type){ + case CPP_TOKEN_COMMA: + case CPP_TOKEN_PARENTHESE_OPEN: + case CPP_TOKEN_PARENTHESE_CLOSE: + { + delete_space_before = true; + }break; + } + + switch (token->type){ + case CPP_TOKEN_IDENTIFIER: + case CPP_TOKEN_COMMA: + case CPP_TOKEN_STAR: + { + space_after = true; + }break; + } + if (token->flags & CPP_TFLAG_IS_KEYWORD){ + space_after = true; + } + + if (delete_space_before){ + int32_t pos = extra_memory->pos - 1; + char *base = ((char*)(extra_memory->base)); + if (pos >= 0 && base[pos] == ' '){ + extra_memory->pos = pos; + } + } + + char *token_str = push_array(extra_memory, char, token->size + space_after); + + buffer_read_range(app, buffer, token->start, token->start + token->size, token_str); + if (space_after){ + token_str[token->size] = ' '; + } + } + } + + if (local_index == end_index){ + goto finish_print; + } + } + still_looping = forward_stream_tokens(&token_stream); + }while(still_looping); + + finish_print:; + { + int32_t sig_size = extra_memory->pos; + String sig = make_string(extra_memory->base, sig_size); + + int32_t line_number = buffer_get_line_index(app, buffer, open_paren_pos); + int32_t line_number_len = int_to_str_size(line_number); + + int32_t append_len = buffer_name.size + 1 + line_number_len + 1 + 1 + sig_size + 1; + + char *out_space = push_array(part, char, append_len); + if (out_space == 0){ + buffer_replace_range(app, &decls_buffer, size, size, str, part_size); + size += part_size; + + end_temp_memory(temp); + temp = begin_temp_memory(part); + + part_size = 0; + out_space = push_array(part, char, append_len); + } + + part_size += append_len; + String out = make_string(out_space, 0, append_len); + append(&out, buffer_name); + append(&out, ':'); + append_int_to_str(&out, line_number); + append(&out, ':'); + append(&out, ' '); + append(&out, sig); + append(&out, '\n'); + } + + end_temp_memory(extra_temp); + } + + buffer_replace_range(app, &decls_buffer, size, size, str, part_size); + + View_Summary view = get_active_view(app, AccessAll); + view_set_buffer(app, &view, decls_buffer.buffer_id, 0); + + lock_jump_buffer(search_name.str, search_name.size); + + end_temp_memory(temp); + } +} + +CUSTOM_COMMAND_SIG(list_all_functions_current_buffer){ + uint32_t access = AccessProtected; + View_Summary view = get_active_view(app, access); + Buffer_Summary buffer = get_buffer(app, view.buffer_id, access); + list_all_functions(app, &global_part, &buffer); +} + +// BOTTOM + diff --git a/project.4coder b/project.4coder index eeb321fb..39cda7cd 100644 --- a/project.4coder +++ b/project.4coder @@ -2,7 +2,7 @@ extensions=".c.cpp.h.hpp.bat.sh"; fkey_command_win[1] = {"build.bat", "*compilation*", true}; fkey_command_win[2] = {"site\\build.bat", "*compilation*", true}; -fkey_command_win[3] = {"file\\run_tests.bat", "*tests*", true}; +fkey_command_win[3] = {"string\\build.bat", "*compilation*", true}; fkey_command_win[4] = {0, 0}; fkey_command_win[5] = {"..\\misc\\run.bat", "*run*"}; fkey_command_win[6] = {0, 0}; diff --git a/site/abstract_document.cpp b/site/abstract_document.cpp index 77056780..8db35149 100644 --- a/site/abstract_document.cpp +++ b/site/abstract_document.cpp @@ -831,7 +831,7 @@ write_enriched_text_html(String *out, Partition *part, Enriched_Text *text, Docu Abstract_Item *img_lookup = get_item_by_name(doc_system->img_list, img_name); if (img_lookup){ - pixel_height = CEIL32(pixel_width*img_lookup->h_w_ratio); + pixel_height = ceil32(pixel_width*img_lookup->h_w_ratio); append_sc(out, "= 'A' && c <= 'Z'); } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_lower(char c) /* DOC(If c is a lower letter this call returns true.) */{ return (c >= 'a' && c <= 'z'); @@ -99,43 +81,43 @@ char_to_lower(char c) return (c >= 'A' && c <= 'Z') ? c - (char)('A' - 'a') : c; } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_whitespace(char c) /* DOC(This call returns non-zero if c is whitespace.) */{ return (c == ' ' || c == '\n' || c == '\r' || c == '\t'); } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_alpha_numeric(char c) /* DOC(This call returns non-zero if c is any alphanumeric character including underscore.) */{ return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_'); } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_alpha_numeric_true(char c) /* DOC(This call returns non-zero if c is any alphanumeric character no including underscore.) */{ return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'); } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_alpha(char c) /* DOC(This call returns non-zero if c is any alphabetic character including underscore.) */{ return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'); } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_alpha_true(char c) /* DOC(This call returns non-zero if c is any alphabetic character.) */{ return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'); } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_hex(char c) /* DOC(This call returns non-zero if c is any valid hexadecimal digit.) */{ return (c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f'); } -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech char_is_numeric(char c) /* DOC(This call returns non-zero if c is any valid decimal digit.) */{ return (c >= '0' && c <= '9'); @@ -148,7 +130,7 @@ char_is_numeric(char c) CPP_NAME(make_string) API_EXPORT_INLINE FSTRING_INLINE String -make_string_cap(void *str, int32_t size, int32_t mem_size)/* +make_string_cap(void *str, i32_4tech size, i32_4tech mem_size)/* DOC_PARAM(str, The str parameter provides the of memory with which the string shall operate.) DOC_PARAM(size, The size parameter expresses the initial size of the string. If the memory does not already contain a useful string this should be zero.) @@ -163,7 +145,7 @@ DOC(This call returns the String created from the parameters.) } API_EXPORT_INLINE FSTRING_INLINE String -make_string(void *str, int32_t size)/* +make_string(void *str, i32_4tech size)/* DOC_PARAM(str, The str parameter provides the of memory with which the string shall operate.) DOC_PARAM(size, The size parameter expresses the initial size of the string. If the memory does not already contain a useful string this should be zero. Since this version @@ -190,10 +172,10 @@ API_EXPORT_MACRO /* DOC(This macro is a helper for any calls that take a char*,integer pair to specify a string. This macro expands to both of those parameters from one String struct.) */ #define expand_str(s) ((s).str), ((s).size) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech str_size(char *str) /* DOC(This call returns the number of bytes before a null terminator starting at str.) */{ - int32_t i = 0; + i32_4tech i = 0; while (str[i]) ++i; return(i); } @@ -210,7 +192,7 @@ make_string_slowly(void *str) CPP_NAME(substr) API_EXPORT_INLINE FSTRING_INLINE String -substr_tail(String str, int32_t start) +substr_tail(String str, i32_4tech start) /* DOC(This call creates a substring of str that starts with an offset from str's base. The new string uses the same underlying memory so both strings will see changes. Usually strings created this way should only go through immutable calls.) */{ @@ -222,7 +204,7 @@ Usually strings created this way should only go through immutable calls.) */{ } API_EXPORT_INLINE FSTRING_INLINE String -substr(String str, int32_t start, int32_t size) +substr(String str, i32_4tech start, i32_4tech size) /* DOC(This call creates a substring of str that starts with an offset from str's base, and has a fixed size. The new string uses the same underlying memory so both strings will see changes. Usually strings created this way should only go through immutable calls.) */{ @@ -242,7 +224,7 @@ skip_whitespace(String str) Like other substr calls, the new string uses the underlying memory and so should usually be considered immutable.) DOC_SEE(substr) */{ String result = {0}; - int32_t i = 0; + i32_4tech i = 0; for (; i < str.size && char_is_whitespace(str.str[i]); ++i); result = substr(str, i, str.size - i); return(result); @@ -254,7 +236,7 @@ chop_whitespace(String str) Like other substr calls, the new string uses the underlying memory and so should usually be considered immutable.) DOC_SEE(substr) */{ String result = {0}; - int32_t i = str.size; + i32_4tech i = str.size; for (; i > 0 && char_is_whitespace(str.str[i-1]); --i); result = substr(str, 0, i); return(result); @@ -286,9 +268,9 @@ the portion of str's memory that is not used.) */{ // CPP_NAME(match) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_cc(char *a, char *b)/* DOC(This call returns non-zero if a and b are equivalent.) */{ - for (int32_t i = 0;; ++i){ + for (i32_4tech i = 0;; ++i){ if (a[i] != b[i]){ return 0; } @@ -299,9 +281,9 @@ match_cc(char *a, char *b)/* DOC(This call returns non-zero if a and b are equiv } CPP_NAME(match) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_sc(String a, char *b)/* DOC(This call returns non-zero if a and b are equivalent.) */{ - int32_t i = 0; + i32_4tech i = 0; for (; i < a.size; ++i){ if (a.str[i] != b[i]){ return 0; @@ -314,18 +296,18 @@ match_sc(String a, char *b)/* DOC(This call returns non-zero if a and b are equi } CPP_NAME(match) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech match_cs(char *a, String b)/* DOC(This call returns non-zero if a and b are equivalent.) */{ return(match_sc(b,a)); } CPP_NAME(match) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_ss(String a, String b)/* DOC(This call returns non-zero if a and b are equivalent.) */{ if (a.size != b.size){ return 0; } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (a.str[i] != b.str[i]){ return 0; } @@ -334,12 +316,12 @@ match_ss(String a, String b)/* DOC(This call returns non-zero if a and b are equ } CPP_NAME(match_part) -API_EXPORT FSTRING_LINK fstr_bool -match_part_ccl(char *a, char *b, int32_t *len)/* +API_EXPORT FSTRING_LINK b32_4tech +match_part_ccl(char *a, char *b, i32_4tech *len)/* DOC_PARAM(len, If this call returns non-zero this parameter is used to output the length of b.) DOC(This call is similar to a match call, except that it is permitted for a to be longer than b. In other words this call returns non-zero if b is a prefix of a.) */{ - int32_t i; + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (a[i] != b[i]){ return 0; @@ -350,12 +332,12 @@ In other words this call returns non-zero if b is a prefix of a.) */{ } CPP_NAME(match_part) -API_EXPORT FSTRING_LINK fstr_bool -match_part_scl(String a, char *b, int32_t *len)/* +API_EXPORT FSTRING_LINK b32_4tech +match_part_scl(String a, char *b, i32_4tech *len)/* DOC_PARAM(len, If this call returns non-zero this parameter is used to output the length of b.) DOC(This call is similar to a match call, except that it is permitted for a to be longer than b. In other words this call returns non-zero if b is a prefix of a.) */{ - int32_t i; + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (a.str[i] != b[i] || i == a.size){ return 0; @@ -366,30 +348,30 @@ In other words this call returns non-zero if b is a prefix of a.) */{ } CPP_NAME(match_part) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech match_part_cc(char *a, char *b)/* DOC_PARAM(len, If this call returns non-zero this parameter is used to output the length of b.) DOC(This call is similar to a match call, except that it is permitted for a to be longer than b. In other words this call returns non-zero if b is a prefix of a.) */{ - int32_t x; + i32_4tech x; return match_part_ccl(a,b,&x); } CPP_NAME(match_part) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech match_part_sc(String a, char *b)/* DOC(This call is similar to a match call, except that it is permitted for a to be longer than b. In other words this call returns non-zero if b is a prefix of a.) */{ - int32_t x; + i32_4tech x; return match_part_scl(a,b,&x); } CPP_NAME(match_part) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_part_cs(char *a, String b)/* DOC(This call is similar to a match call, except that it is permitted for a to be longer than b. In other words this call returns non-zero if b is a prefix of a.) */{ - for (int32_t i = 0; i != b.size; ++i){ + for (i32_4tech i = 0; i != b.size; ++i){ if (a[i] != b.str[i]){ return 0; } @@ -398,14 +380,14 @@ In other words this call returns non-zero if b is a prefix of a.) */{ } CPP_NAME(match_part) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_part_ss(String a, String b)/* DOC(This call is similar to a match call, except that it is permitted for a to be longer than b. In other words this call returns non-zero if b is a prefix of a.) */{ if (a.size < b.size){ return 0; } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (a.str[i] != b.str[i]){ return 0; } @@ -414,10 +396,10 @@ In other words this call returns non-zero if b is a prefix of a.) */{ } CPP_NAME(match_insensitive) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_insensitive_cc(char *a, char *b)/* DOC(This call returns non-zero if a and b are equivalent under case insensitive comparison.) */{ - for (int32_t i = 0;; ++i){ + for (i32_4tech i = 0;; ++i){ if (char_to_upper(a[i]) != char_to_upper(b[i])){ return 0; @@ -429,10 +411,10 @@ DOC(This call returns non-zero if a and b are equivalent under case insensitive } CPP_NAME(match_insensitive) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_insensitive_sc(String a, char *b)/* DOC(This call returns non-zero if a and b are equivalent under case insensitive comparison.) */{ - int32_t i = 0; + i32_4tech i = 0; for (; i < a.size; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b[i])){ @@ -446,20 +428,20 @@ DOC(This call returns non-zero if a and b are equivalent under case insensitive } CPP_NAME(match_insensitive) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech match_insensitive_cs(char *a, String b)/* DOC(This call returns non-zero if a and b are equivalent under case insensitive comparison.) */{ return match_insensitive_sc(b,a); } CPP_NAME(match_insensitive) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_insensitive_ss(String a, String b)/* DOC(This call returns non-zero if a and b are equivalent under case insensitive comparison.) */{ if (a.size != b.size){ return 0; } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b.str[i])){ return 0; @@ -469,12 +451,12 @@ DOC(This call returns non-zero if a and b are equivalent under case insensitive } CPP_NAME(match_part_insensitive) -API_EXPORT FSTRING_LINK fstr_bool -match_part_insensitive_ccl(char *a, char *b, int32_t *len)/* +API_EXPORT FSTRING_LINK b32_4tech +match_part_insensitive_ccl(char *a, char *b, i32_4tech *len)/* DOC_PARAM(len, If this call returns non-zero this parameter is used to output the length of b.) DOC(This call performs the same partial matching rule as match_part under case insensitive comparison.) DOC_SEE(match_part) */{ - int32_t i; + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (char_to_upper(a[i]) != char_to_upper(b[i])){ return 0; @@ -485,12 +467,12 @@ DOC_SEE(match_part) */{ } CPP_NAME(match_part_insensitive) -API_EXPORT FSTRING_LINK fstr_bool -match_part_insensitive_scl(String a, char *b, int32_t *len)/* +API_EXPORT FSTRING_LINK b32_4tech +match_part_insensitive_scl(String a, char *b, i32_4tech *len)/* DOC_PARAM(len, If this call returns non-zero this parameter is used to output the length of b.) DOC(This call performs the same partial matching rule as match_part under case insensitive comparison.) DOC_SEE(match_part) */{ - int32_t i; + i32_4tech i; for (i = 0; b[i] != 0; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b[i]) || i == a.size){ @@ -502,29 +484,29 @@ DOC_SEE(match_part) */{ } CPP_NAME(match_part_insensitive) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech match_part_insensitive_cc(char *a, char *b)/* DOC(This call performs the same partial matching rule as match_part under case insensitive comparison.) DOC_SEE(match_part) */{ - int32_t x; + i32_4tech x; return match_part_insensitive_ccl(a,b,&x); } CPP_NAME(match_part_insensitive) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech match_part_insensitive_sc(String a, char *b)/* DOC(This call performs the same partial matching rule as match_part under case insensitive comparison.) DOC_SEE(match_part) */{ - int32_t x; + i32_4tech x; return match_part_insensitive_scl(a,b,&x); } CPP_NAME(match_part_insensitive) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_part_insensitive_cs(char *a, String b)/* DOC(This call performs the same partial matching rule as match_part under case insensitive comparison.) DOC_SEE(match_part) */{ - for (int32_t i = 0; i != b.size; ++i){ + for (i32_4tech i = 0; i != b.size; ++i){ if (char_to_upper(a[i]) != char_to_upper(b.str[i])){ return(0); } @@ -533,14 +515,14 @@ DOC_SEE(match_part) */{ } CPP_NAME(match_part_insensitive) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech match_part_insensitive_ss(String a, String b)/* DOC(This call performs the same partial matching rule as match_part under case insensitive comparison.) DOC_SEE(match_part) */{ if (a.size < b.size){ return(0); } - for (int32_t i = 0; i < b.size; ++i){ + for (i32_4tech i = 0; i < b.size; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b.str[i])){ return(0); } @@ -549,12 +531,12 @@ DOC_SEE(match_part) */{ } CPP_NAME(compare) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech compare_cc(char *a, char *b)/* DOC(This call returns zero if a and b are equivalent, it returns negative if a sorts before b alphabetically, and positive if a sorts after b alphabetically.) */{ - int32_t i = 0, r = 0; + i32_4tech i = 0, r = 0; while (a[i] == b[i] && a[i] != 0){ ++i; } @@ -563,12 +545,12 @@ and positive if a sorts after b alphabetically.) */{ } CPP_NAME(compare) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech compare_sc(String a, char *b)/* DOC(This call returns zero if a and b are equivalent, it returns negative if a sorts before b alphabetically, and positive if a sorts after b alphabetically.) */{ - int32_t i = 0, r = 0; + i32_4tech i = 0, r = 0; while (i < a.size && a.str[i] == b[i]){ ++i; } @@ -587,23 +569,23 @@ and positive if a sorts after b alphabetically.) */{ } CPP_NAME(compare) -API_EXPORT_INLINE FSTRING_INLINE int32_t +API_EXPORT_INLINE FSTRING_INLINE i32_4tech compare_cs(char *a, String b)/* DOC(This call returns zero if a and b are equivalent, it returns negative if a sorts before b alphabetically, and positive if a sorts after b alphabetically.) */{ - int32_t r = -compare_sc(b,a); + i32_4tech r = -compare_sc(b,a); return(r); } CPP_NAME(compare) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech compare_ss(String a, String b)/* DOC(This call returns zero if a and b are equivalent, it returns negative if a sorts before b alphabetically, and positive if a sorts after b alphabetically.) */{ - int32_t i = 0, r = 0; - int32_t m = a.size; + i32_4tech i = 0, r = 0; + i32_4tech m = a.size; if (b.size < m){ m = b.size; } @@ -626,53 +608,53 @@ and positive if a sorts after b alphabetically.) */{ // CPP_NAME(find) -API_EXPORT FSTRING_LINK int32_t -find_c_char(char *str, int32_t start, char character)/* +API_EXPORT FSTRING_LINK i32_4tech +find_c_char(char *str, i32_4tech start, char character)/* DOC_PARAM(str, The str parameter provides a null terminated string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(character, The character parameter provides the character for which to search.) DOC(This call returns the index of the first occurance of character, or the size of the string if the character is not found.) */{ - int32_t i = start; + i32_4tech i = start; while (str[i] != character && str[i] != 0) ++i; return(i); } CPP_NAME(find) -API_EXPORT FSTRING_LINK int32_t -find_s_char(String str, int32_t start, char character)/* +API_EXPORT FSTRING_LINK i32_4tech +find_s_char(String str, i32_4tech start, char character)/* DOC_PARAM(str, The str parameter provides a string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(character, The character parameter provides the character for which to search.) DOC(This call returns the index of the first occurance of character, or the size of the string if the character is not found.) */{ - int32_t i = start; + i32_4tech i = start; while (i < str.size && str.str[i] != character) ++i; return(i); } CPP_NAME(rfind) -API_EXPORT FSTRING_LINK int32_t -rfind_s_char(String str, int32_t start, char character)/* +API_EXPORT FSTRING_LINK i32_4tech +rfind_s_char(String str, i32_4tech start, char character)/* DOC_PARAM(str, The str parameter provides a string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(character, The character parameter provides the character for which to search.) DOC(This call looks for the largest index less than or equal to the start position where the given character occurs. If the index is found it is returned otherwise -1 is returned.) */{ - int32_t i = start; + i32_4tech i = start; while (i >= 0 && str.str[i] != character) --i; return(i); } CPP_NAME(find) -API_EXPORT FSTRING_LINK int32_t -find_c_chars(char *str, int32_t start, char *characters)/* +API_EXPORT FSTRING_LINK i32_4tech +find_c_chars(char *str, i32_4tech start, char *characters)/* DOC_PARAM(str, The str parameter provides a null terminated string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(character, The characters parameter provides a null terminated array of characters for which to search.) DOC(This call returns the index of the first occurance of a character in the characters array, or the size of the string if no such character is not found.) */{ - int32_t i = start, j; + i32_4tech i = start, j; while (str[i] != 0){ for (j = 0; characters[j]; ++j){ if (str[i] == characters[j]){ @@ -685,14 +667,14 @@ or the size of the string if no such character is not found.) */{ } CPP_NAME(find) -API_EXPORT FSTRING_LINK int32_t -find_s_chars(String str, int32_t start, char *characters)/* +API_EXPORT FSTRING_LINK i32_4tech +find_s_chars(String str, i32_4tech start, char *characters)/* DOC_PARAM(str, The str parameter provides a string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(character, The characters parameter provides a null terminated array of characters for which to search.) DOC(This call returns the index of the first occurance of a character in the characters array, or the size of the string if no such character is not found.) */{ - int32_t i = start, j; + i32_4tech i = start, j; while (i < str.size){ for (j = 0; characters[j]; ++j){ if (str.str[i] == characters[j]){ @@ -705,15 +687,15 @@ or the size of the string if no such character is not found.) */{ } CPP_NAME(find_substr) -API_EXPORT FSTRING_LINK int32_t -find_substr_c(char *str, int32_t start, String seek)/* +API_EXPORT FSTRING_LINK i32_4tech +find_substr_c(char *str, i32_4tech start, String seek)/* DOC_PARAM(str, The str parameter provides a null terminated string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(seek, The seek parameter provides a string to find in str.) DOC(This call returns the index of the first occurance of the seek substring in str or the size of str if no such substring in str is found.) */{ - int32_t i, j, k; - fstr_bool hit; + i32_4tech i, j, k; + b32_4tech hit; if (seek.size == 0){ i = str_size(str); @@ -737,15 +719,15 @@ size of str if no such substring in str is found.) */{ } CPP_NAME(find_substr) -API_EXPORT FSTRING_LINK int32_t -find_substr_s(String str, int32_t start, String seek)/* +API_EXPORT FSTRING_LINK i32_4tech +find_substr_s(String str, i32_4tech start, String seek)/* DOC_PARAM(str, The str parameter provides a string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(seek, The seek parameter provides a string to find in str.) DOC(This call returns the index of the first occurance of the seek substring in str or the size of str if no such substring in str is found.) */{ - int32_t stop_at, i, j, k; - fstr_bool hit; + i32_4tech stop_at, i, j, k; + b32_4tech hit; if (seek.size == 0){ return str.size; @@ -769,15 +751,15 @@ size of str if no such substring in str is found.) */{ } CPP_NAME(rfind_substr) -API_EXPORT FSTRING_LINK int32_t -rfind_substr_s(String str, int32_t start, String seek)/* +API_EXPORT FSTRING_LINK i32_4tech +rfind_substr_s(String str, i32_4tech start, String seek)/* DOC_PARAM(str, The str parameter provides a string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(seek, The seek parameter provides a string to find in str.) DOC(This call returns the index of the last occurance of the seek substring in str or -1 if no such substring in str is found.) */{ - int32_t i, j, k; - fstr_bool hit; + i32_4tech i, j, k; + b32_4tech hit; if (seek.size == 0){ return -1; @@ -803,15 +785,15 @@ or -1 if no such substring in str is found.) */{ } CPP_NAME(find_substr_insensitive) -API_EXPORT FSTRING_LINK int32_t -find_substr_insensitive_c(char *str, int32_t start, String seek)/* +API_EXPORT FSTRING_LINK i32_4tech +find_substr_insensitive_c(char *str, i32_4tech start, String seek)/* DOC_PARAM(str, The str parameter provides a null terminated string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(seek, The seek parameter provides a string to find in str.) DOC(This call acts as find_substr under case insensitive comparison.) DOC_SEE(find_substr)*/{ - int32_t i, j, k; - fstr_bool hit; + i32_4tech i, j, k; + b32_4tech hit; char a_upper, b_upper; if (seek.size == 0){ @@ -837,16 +819,16 @@ DOC_SEE(find_substr)*/{ } CPP_NAME(find_substr_insensitive) -API_EXPORT FSTRING_LINK int32_t -find_substr_insensitive_s(String str, int32_t start, String seek)/* +API_EXPORT FSTRING_LINK i32_4tech +find_substr_insensitive_s(String str, i32_4tech start, String seek)/* DOC_PARAM(str, The str parameter provides a string to search.) DOC_PARAM(start, The start parameter provides the index of the first character in str to search.) DOC_PARAM(seek, The seek parameter provides a string to find in str.) DOC(This call acts as find_substr under case insensitive comparison.) DOC_SEE(find_substr)*/{ - int32_t i, j, k; - int32_t stop_at; - fstr_bool hit; + i32_4tech i, j, k; + i32_4tech stop_at; + b32_4tech hit; char a_upper, b_upper; if (seek.size == 0){ @@ -873,21 +855,21 @@ DOC_SEE(find_substr)*/{ } CPP_NAME(has_substr) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech has_substr_c(char *s, String seek)/* DOC(This call returns non-zero if the string s contains a substring equivalent to seek.) */{ return (s[find_substr_c(s, 0, seek)] != 0); } CPP_NAME(has_substr) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech has_substr_s(String s, String seek)/* DOC(This call returns non-zero if the string s contains a substring equivalent to seek.) */{ return (find_substr_s(s, 0, seek) < s.size); } CPP_NAME(has_substr_insensitive) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech has_substr_insensitive_c(char *s, String seek)/* DOC(This call returns non-zero if the string s contains a substring equivalent to seek under case insensitive comparison.) */{ @@ -895,7 +877,7 @@ under case insensitive comparison.) */{ } CPP_NAME(has_substr_insensitive) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech has_substr_insensitive_s(String s, String seek)/* DOC(This call returns non-zero if the string s contains a substring equivalent to seek under case insensitive comparison.) */{ @@ -907,7 +889,7 @@ under case insensitive comparison.) */{ // CPP_NAME(copy_fast_unsafe) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech copy_fast_unsafe_cc(char *dest, char *src)/* DOC(This call performs a copy from the src buffer to the dest buffer. The copy does not stop until a null terminator is found in src. There @@ -920,18 +902,18 @@ of bytes coppied to dest.) */{ ++dest; ++src; } - return (int32_t)(dest - start); + return (i32_4tech)(dest - start); } CPP_NAME(copy_fast_unsafe) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech copy_fast_unsafe_cs(char *dest, String src)/* DOC(This call performs a copy from the src string to the dest buffer. The copy does not stop until src.size characters are coppied. There is no safety against overrun so dest must be large enough to contain src. The null terminator is not written to dest. This call returns the number of bytes coppied to dest.) */{ - int32_t i = 0; + i32_4tech i = 0; while (i != src.size){ dest[i] = src.str[i]; ++i; @@ -940,13 +922,13 @@ of bytes coppied to dest.) */{ } CPP_NAME(copy_checked) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech copy_checked_ss(String *dest, String src)/* DOC(This call performs a copy from the src string to the dest string. The memory_size of dest is checked before any coppying is done. This call returns non-zero on a successful copy.) */{ char *dest_str; - int32_t i; + i32_4tech i; if (dest->memory_size < src.size){ return 0; } @@ -959,14 +941,14 @@ This call returns non-zero on a successful copy.) */{ } CPP_NAME(copy_partial) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech copy_partial_sc(String *dest, char *src)/* DOC(This call performs a copy from the src buffer to the dest string. The memory_size of dest is checked if the entire copy cannot be performed, as many bytes as possible are coppied to dest. This call returns non-zero if the entire string is coppied to dest.) */{ - int32_t i = 0; - int32_t memory_size = dest->memory_size; + i32_4tech i = 0; + i32_4tech memory_size = dest->memory_size; char *dest_str = dest->str; while (src[i] != 0){ if (i >= memory_size){ @@ -980,20 +962,20 @@ if the entire string is coppied to dest.) */{ } CPP_NAME(copy_partial) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech copy_partial_ss(String *dest, String src)/* DOC(This call performs a copy from the src string to the dest string. The memory_size of dest is checked if the entire copy cannot be performed, as many bytes as possible are coppied to dest. This call returns non-zero if the entire string is coppied to dest.) */{ char *dest_str = dest->str; - int32_t memory_size = dest->memory_size; - fstr_bool result = 0; + i32_4tech memory_size = dest->memory_size; + b32_4tech result = 0; if (memory_size >= src.size){ result = 1; memory_size = src.size; } - for (int32_t i = 0; i < memory_size; ++i){ + for (i32_4tech i = 0; i < memory_size; ++i){ dest_str[i] = src.str[i]; } dest->size = memory_size; @@ -1001,7 +983,7 @@ if the entire string is coppied to dest.) */{ } CPP_NAME(copy) -API_EXPORT_INLINE FSTRING_INLINE int32_t +API_EXPORT_INLINE FSTRING_INLINE i32_4tech copy_cc(char *dest, char *src)/* DOC(This call performs a copy from src to dest equivalent to copy_fast_unsafe.) DOC_SEE(copy_fast_unsafe) */{ @@ -1025,13 +1007,13 @@ DOC_SEE(copy_partial) */{ } CPP_NAME(append_checked) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech append_checked_ss(String *dest, String src)/* DOC(This call checks if there is enough space in dest's underlying memory to append src onto dest. If there is src is appended and the call returns non-zero.) */{ String end; end = tailstr(*dest); - fstr_bool result = copy_checked_ss(&end, src); + b32_4tech result = copy_checked_ss(&end, src); // NOTE(allen): This depends on end.size still being 0 if // the check failed and no coppy occurred. dest->size += end.size; @@ -1039,33 +1021,33 @@ to append src onto dest. If there is src is appended and the call returns non-ze } CPP_NAME(append_partial) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech append_partial_sc(String *dest, char *src)/* DOC(This call attemps to append as much of src into the space in dest's underlying memory as possible. If the entire string is appended the call returns non-zero.) */{ String end = tailstr(*dest); - fstr_bool result = copy_partial_sc(&end, src); + b32_4tech result = copy_partial_sc(&end, src); dest->size += end.size; return result; } CPP_NAME(append_partial) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech append_partial_ss(String *dest, String src)/* DOC(This call attemps to append as much of src into the space in dest's underlying memory as possible. If the entire string is appended the call returns non-zero.) */{ String end = tailstr(*dest); - fstr_bool result = copy_partial_ss(&end, src); + b32_4tech result = copy_partial_ss(&end, src); dest->size += end.size; return result; } CPP_NAME(append) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech append_s_char(String *dest, char c)/* DOC(This call attemps to append c onto dest. If there is space left in dest's underlying memory the character is appended and the call returns non-zero.) */{ - fstr_bool result = 0; + b32_4tech result = 0; if (dest->size < dest->memory_size){ dest->str[dest->size++] = c; result = 1; @@ -1074,26 +1056,26 @@ memory the character is appended and the call returns non-zero.) */{ } CPP_NAME(append) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech append_ss(String *dest, String src)/* DOC(This call is equivalent to append_partial.) DOC_SEE(append_partial) */{ return append_partial_ss(dest, src); } CPP_NAME(append) -API_EXPORT_INLINE FSTRING_INLINE fstr_bool +API_EXPORT_INLINE FSTRING_INLINE b32_4tech append_sc(String *dest, char *src)/* DOC(This call is equivalent to append_partial.) DOC_SEE(append_partial) */{ return append_partial_sc(dest, src); } -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech terminate_with_null(String *str)/* DOC(This call attemps to append a null terminator onto str without effecting the size of str. This is usually called when the time comes to pass the the string to an API that requires a null terminator. This call returns non-zero if there was a spare byte in the strings underlying memory.) */{ - fstr_bool result = 0; + b32_4tech result = 0; if (str->size < str->memory_size){ str->str[str->size] = 0; result = 1; @@ -1101,14 +1083,14 @@ byte in the strings underlying memory.) */{ return(result); } -API_EXPORT FSTRING_LINK fstr_bool -append_padding(String *dest, char c, int32_t target_size)/* +API_EXPORT FSTRING_LINK b32_4tech +append_padding(String *dest, char c, i32_4tech target_size)/* DOC(This call pads out dest so that it has a size of target_size by appending the padding character c until the target size is achieved. This call returns non-zero if dest does not run out of space in the underlying memory.) */{ - fstr_bool result = 1; - int32_t offset = target_size - dest->size; - int32_t r = 0; + b32_4tech result = 1; + i32_4tech offset = target_size - dest->size; + i32_4tech r = 0; if (offset > 0){ for (r = 0; r < offset; ++r){ if (append_s_char(dest, c) == 0){ @@ -1132,7 +1114,7 @@ DOC_PARAM(replace, The replace character specifies which character should be rep DOC_PARAM(with, The with character specifies what to write into the positions where replacement occurs.) DOC(This call replaces all occurances of character in str with another character.) */{ char *s = str->str; - int32_t i = 0; + i32_4tech i = 0; for (i = 0; i < str->size; ++i, ++s){ if (*s == replace) *s = with; } @@ -1163,8 +1145,8 @@ DOC_PARAM(src, The source string to conver to lowercase.) DOC(Rewrites the string in src into dst. src and dst should not overlap with the exception that src and dst may be exactly equal in order to convert the string in place.) */{ - int32_t i = 0; - int32_t size = src.size; + i32_4tech i = 0; + i32_4tech size = src.size; char *c = src.str; char *d = dst->str; @@ -1182,8 +1164,8 @@ to_lower_s(String *str)/* DOC_PARAM(str, The string to be converted to all lowercase.) DOC(This version of to_lower converts str to lowercase in place.) */{ - int32_t i = 0; - int32_t size = str->size; + i32_4tech i = 0; + i32_4tech size = str->size; char *c = str->str; for (; i < size; ++c, ++i){ *c = char_to_lower(*c); @@ -1214,8 +1196,8 @@ DOC_PARAM(src, The source string to convert to uppercase.) DOC(Rewrites the string in src into dst. src and dst should not overlap with the exception that src and dst may be exactly equal in order to convert the string in place.) */{ - int32_t i = 0; - int32_t size = src.size; + i32_4tech i = 0; + i32_4tech size = src.size; char *c = src.str; char *d = dst->str; @@ -1233,8 +1215,8 @@ to_upper_s(String *str)/* DOC_PARAM(str, The string to be converted to all uppercase.) DOC(This version of to_upper converts str to uppercase in place.) */{ - int32_t i = 0; - int32_t size = str->size; + i32_4tech i = 0; + i32_4tech size = str->size; char *c = str->str; for (; i < size; ++c, ++i){ *c = char_to_upper(*c); @@ -1252,7 +1234,7 @@ with the exception that src and dst may be exactly equal in order to convert the string in place.) */{ char *c, ch; - int32_t is_first = 1; + i32_4tech is_first = 1; for (c = src; *c != 0; ++c){ ch = *c; if (char_is_alpha_numeric_true(ch)){ @@ -1277,10 +1259,10 @@ convert the string in place.) // String <-> Number Conversions // -API_EXPORT FSTRING_LINK int32_t -int_to_str_size(int32_t x)/* +API_EXPORT FSTRING_LINK i32_4tech +int_to_str_size(i32_4tech x)/* DOC(This call returns the number of bytes required to represent x as a string.) */{ - int32_t size = 1; + i32_4tech size = 1; if (x < 0){ size = 2; } @@ -1292,15 +1274,15 @@ DOC(This call returns the number of bytes required to represent x as a string.) return(size); } -API_EXPORT FSTRING_LINK fstr_bool -int_to_str(String *dest, int32_t x)/* +API_EXPORT FSTRING_LINK b32_4tech +int_to_str(String *dest, i32_4tech x)/* DOC(This call writes a string representation of x into dest. If there is enough space in dest this call returns non-zero.) */{ - fstr_bool result = 1; + b32_4tech result = 1; char *str = dest->str; - int32_t memory_size = dest->memory_size; - int32_t size, i, j; - fstr_bool negative; + i32_4tech memory_size = dest->memory_size; + i32_4tech size, i, j; + b32_4tech negative; if (x == 0){ str[0] = '0'; @@ -1324,8 +1306,7 @@ space in dest this call returns non-zero.) */{ str[size++] = (char)('0' + i); } if (result){ - // NOTE(allen): Start i = 0 if not negative, start i = 1 if is negative - // because - should not be flipped if it is negative :) + // NOTE(allen): Start i = 0 if not negative, start i = 1 if is negative because - should not be flipped if it is negative :) for (i = negative, j = size-1; i < j; ++i, --j){ char temp = str[i]; str[i] = str[j]; @@ -1340,22 +1321,22 @@ space in dest this call returns non-zero.) */{ return(result); } -API_EXPORT FSTRING_LINK fstr_bool -append_int_to_str(String *dest, int32_t x)/* +API_EXPORT FSTRING_LINK b32_4tech +append_int_to_str(String *dest, i32_4tech x)/* DOC(This call appends a string representation of x onto dest. If there is enough space in dest this call returns non-zero.) */{ String last_part = tailstr(*dest); - fstr_bool result = int_to_str(&last_part, x); + b32_4tech result = int_to_str(&last_part, x); if (result){ dest->size += last_part.size; } return(result); } -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech u64_to_str_size(uint64_t x)/* DOC(This call returns the number of bytes required to represent x as a string.) */{ - int32_t size; + i32_4tech size; if (x < 0){ size = 0; } @@ -1370,14 +1351,14 @@ DOC(This call returns the number of bytes required to represent x as a string.) return(size); } -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech u64_to_str(String *dest, uint64_t x)/* DOC(This call writes a string representation of x into dest. If there is enough space in dest this call returns non-zero.) */{ - fstr_bool result = 1; + b32_4tech result = 1; char *str = dest->str; - int32_t memory_size = dest->memory_size; - int32_t size, i, j; + i32_4tech memory_size = dest->memory_size; + i32_4tech size, i, j; if (x == 0){ str[0] = '0'; @@ -1409,23 +1390,23 @@ space in dest this call returns non-zero.) */{ return(result); } -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech append_u64_to_str(String *dest, uint64_t x)/* DOC(This call appends a string representation of x onto dest. If there is enough space in dest this call returns non-zero.) */{ String last_part = tailstr(*dest); - fstr_bool result = u64_to_str(&last_part, x); + b32_4tech result = u64_to_str(&last_part, x); if (result){ dest->size += last_part.size; } return(result); } -#ifndef FSTRING_GUARD +#if !defined(FSTRING_GUARD) typedef struct Float_To_Str_Variables{ - fstr_bool negative; - int32_t int_part; - int32_t dec_part; + b32_4tech negative; + i32_4tech int_part; + i32_4tech dec_part; } Float_To_Str_Variables; static Float_To_Str_Variables @@ -1437,27 +1418,25 @@ get_float_vars(float x){ x = -x; } - vars.int_part = (int32_t)(x); - vars.dec_part = (int32_t)((x - vars.int_part) * 1000); + vars.int_part = (i32_4tech)(x); + vars.dec_part = (i32_4tech)((x - vars.int_part) * 1000); return(vars); } #endif -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech float_to_str_size(float x)/* DOC(This call returns the number of bytes required to represent x as a string.) */{ Float_To_Str_Variables vars = get_float_vars(x); - int32_t size = - vars.negative + int_to_str_size(vars.int_part) + 1 + int_to_str_size(vars.dec_part); + i32_4tech size = vars.negative + int_to_str_size(vars.int_part) + 1 + int_to_str_size(vars.dec_part); return(size); } -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech append_float_to_str(String *dest, float x)/* -DOC(This call writes a string representation of x into dest. If there is enough -space in dest this call returns non-zero.) */{ - fstr_bool result = 1; +DOC(This call writes a string representation of x into dest. If there is enough space in dest this call returns non-zero.) */{ + b32_4tech result = 1; Float_To_Str_Variables vars = get_float_vars(x); if (vars.negative){ @@ -1471,21 +1450,20 @@ space in dest this call returns non-zero.) */{ return(result); } -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech float_to_str(String *dest, float x)/* -DOC(This call appends a string representation of x onto dest. If there is enough -space in dest this call returns non-zero.) */{ - fstr_bool result = 1; +DOC(This call appends a string representation of x onto dest. If there is enough space in dest this call returns non-zero.) */{ + b32_4tech result = 1; dest->size = 0; append_float_to_str(dest, x); return(result); } CPP_NAME(str_is_int) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech str_is_int_c(char *str)/* DOC(If str is a valid string representation of an integer, this call returns non-zero) */{ - fstr_bool result = 1; + b32_4tech result = 1; for (; *str; ++str){ if (!char_is_numeric(*str)){ result = 0; @@ -1496,11 +1474,11 @@ DOC(If str is a valid string representation of an integer, this call returns non } CPP_NAME(str_is_int) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech str_is_int_s(String str)/* DOC(If str is a valid string representation of an integer, this call returns non-zero.) */{ - fstr_bool result = 1; - for (int32_t i = 0; i < str.size; ++i){ + b32_4tech result = 1; + for (i32_4tech i = 0; i < str.size; ++i){ if (!char_is_numeric(str.str[i])){ result = 0; break; @@ -1510,11 +1488,11 @@ DOC(If str is a valid string representation of an integer, this call returns non } CPP_NAME(str_to_int) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech str_to_int_c(char *str)/* DOC(If str is a valid string representation of an integer, this call will return the integer represented by the string. Otherwise this call returns zero.) */{ - int32_t x = 0; + i32_4tech x = 0; for (; *str; ++str){ if (*str >= '0' && *str <= '9'){ x *= 10; @@ -1529,11 +1507,11 @@ the integer represented by the string. Otherwise this call returns zero.) */{ } CPP_NAME(str_to_int) -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech str_to_int_s(String str)/* DOC(If str represents a valid string representation of an integer, this call will return the integer represented by the string. Otherwise this call returns zero.) */{ - int32_t x, i; + i32_4tech x, i; if (str.size == 0){ x = 0; } @@ -1547,11 +1525,11 @@ the integer represented by the string. Otherwise this call returns zero.) */{ return(x); } -API_EXPORT FSTRING_LINK int32_t +API_EXPORT FSTRING_LINK i32_4tech hexchar_to_int(char c)/* DOC(If c is a valid hexadecimal digit [0-9a-fA-F] this call returns the value of the integer value of the digit. Otherwise the return is some nonsense value.) */{ - int32_t x = 0; + i32_4tech x = 0; if (c >= '0' && c <= '9'){ x = c-'0'; } @@ -1565,18 +1543,18 @@ the integer value of the digit. Otherwise the return is some nonsense value.) */ } API_EXPORT FSTRING_LINK char -int_to_hexchar(int32_t x)/* +int_to_hexchar(i32_4tech x)/* DOC(If x is in the range [0,15] this call returns the equivalent lowercase hexadecimal digit. Otherwise the return is some nonsense value.) */{ return (x<10)?((char)x+'0'):((char)x+'a'-10); } -API_EXPORT FSTRING_LINK uint32_t +API_EXPORT FSTRING_LINK u32_4tech hexstr_to_int(String str)/* DOC(This call interprets str has a hexadecimal representation of an integer and returns the represented integer value.) */{ - uint32_t x; - int32_t i; + u32_4tech x; + i32_4tech i; if (str.size == 0){ x = 0; } @@ -1590,12 +1568,12 @@ the represented integer value.) */{ return(x); } -API_EXPORT FSTRING_LINK fstr_bool -color_to_hexstr(String *s, uint32_t color)/* +API_EXPORT FSTRING_LINK b32_4tech +color_to_hexstr(String *s, u32_4tech color)/* DOC(This call fills s with the hexadecimal representation of the color. If there is enough memory in s to represent the color this call returns non-zero.) */{ - fstr_bool result = 0; - int32_t i; + b32_4tech result = 0; + i32_4tech i; if (s->memory_size == 7 || s->memory_size == 8){ result = 1; @@ -1619,20 +1597,20 @@ If there is enough memory in s to represent the color this call returns non-zero return(result); } -API_EXPORT FSTRING_LINK fstr_bool -hexstr_to_color(String s, uint32_t *out)/* +API_EXPORT FSTRING_LINK b32_4tech +hexstr_to_color(String s, u32_4tech *out)/* DOC(This call interprets s as a color and writes the 32-bit integer representation into out.) */{ - fstr_bool result = 0; - uint32_t color = 0; + b32_4tech result = 0; + u32_4tech color = 0; if (s.size == 6){ result = 1; - color = (uint32_t)hexstr_to_int(s); + color = (u32_4tech)hexstr_to_int(s); color |= (0xFF << 24); *out = color; } else if (s.size == 8){ result = 1; - color = (uint32_t)hexstr_to_int(s); + color = (u32_4tech)hexstr_to_int(s); *out = color; } return(result); @@ -1643,17 +1621,17 @@ DOC(This call interprets s as a color and writes the 32-bit integer representati // CPP_NAME(reverse_seek_slash) -API_EXPORT FSTRING_LINK int32_t -reverse_seek_slash_pos(String str, int32_t pos)/* +API_EXPORT FSTRING_LINK i32_4tech +reverse_seek_slash_pos(String str, i32_4tech pos)/* DOC(This call searches for a slash in str by starting pos bytes from the end and going backwards.) */{ - int32_t i = str.size - 1 - pos; + i32_4tech i = str.size - 1 - pos; while (i >= 0 && !char_is_slash(str.str[i])){ --i; } return i; } -API_EXPORT_INLINE FSTRING_INLINE int32_t +API_EXPORT_INLINE FSTRING_INLINE i32_4tech reverse_seek_slash(String str)/* DOC(This call searches for a slash in str by starting at the end and going backwards.) */{ return(reverse_seek_slash_pos(str, 0)); @@ -1674,7 +1652,7 @@ for the final file or folder name.) DOC_SEE(substr) */{ } CPP_NAME(set_last_folder) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech set_last_folder_sc(String *dir, char *folder_name, char slash)/* DOC_PARAM(dir, The dir parameter is the directory string in which to set the last folder in the directory.) DOC_PARAM(folder_name, The folder_name parameter is a null terminated string specifying the name to set @@ -1682,8 +1660,8 @@ at the end of the directory.) DOC_PARAM(slash, The slash parameter specifies what slash to use between names in the directory.) DOC(This call deletes the last file name or folder name in the dir string and appends the new provided one. If there is enough memory in dir this call returns non-zero.) */{ - fstr_bool result = 0; - int32_t size = reverse_seek_slash(*dir) + 1; + b32_4tech result = 0; + i32_4tech size = reverse_seek_slash(*dir) + 1; dir->size = size; if (append_sc(dir, folder_name)){ if (append_s_char(dir, slash)){ @@ -1697,15 +1675,15 @@ If there is enough memory in dir this call returns non-zero.) */{ } CPP_NAME(set_last_folder) -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech set_last_folder_ss(String *dir, String folder_name, char slash)/* DOC_PARAM(dir, The dir parameter is the directory string in which to set the last folder in the directory.) DOC_PARAM(folder_name, The folder_name parameter is a string specifying the name to set at the end of the directory.) DOC_PARAM(slash, The slash parameter specifies what slash to use between names in the directory.) DOC(This call deletes the last file name or folder name in the dir string and appends the new provided one. If there is enough memory in dir this call returns non-zero.) */{ - fstr_bool result = 0; - int32_t size = reverse_seek_slash(*dir) + 1; + b32_4tech result = 0; + i32_4tech size = reverse_seek_slash(*dir) + 1; dir->size = size; if (append_ss(dir, folder_name)){ if (append_s_char(dir, slash)){ @@ -1722,7 +1700,7 @@ API_EXPORT FSTRING_LINK String file_extension(String str)/* DOC(This call returns a substring containing only the file extension of the provided filename.) DOC_SEE(substr) */{ - int32_t i; + i32_4tech i; for (i = str.size - 1; i >= 0; --i){ if (str.str[i] == '.') break; } @@ -1730,12 +1708,12 @@ DOC_SEE(substr) */{ return(make_string(str.str+i, str.size-i)); } -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech remove_extension(String *str)/* DOC(This call attemps to delete a file extension off the end of a filename. This call returns non-zero on success.) */{ - fstr_bool result = 0; - int32_t i; + b32_4tech result = 0; + i32_4tech i; for (i = str->size - 1; i >= 0; --i){ if (str->str[i] == '.') break; } @@ -1746,12 +1724,12 @@ This call returns non-zero on success.) */{ return(result); } -API_EXPORT FSTRING_LINK fstr_bool +API_EXPORT FSTRING_LINK b32_4tech remove_last_folder(String *str)/* DOC(This call attemps to delete a folder or filename off the end of a path string. This call returns non-zero on success.) */{ - fstr_bool result = 0; - int32_t end = reverse_seek_slash_pos(*str, 1); + b32_4tech result = 0; + i32_4tech end = reverse_seek_slash_pos(*str, 1); if (end >= 0){ result = 1; str->size = end + 1; @@ -1761,8 +1739,8 @@ This call returns non-zero on success.) */{ // TODO(allen): Add hash-table extension to string sets. CPP_NAME(string_set_match) -API_EXPORT FSTRING_LINK fstr_bool -string_set_match_table(void *str_set, int32_t item_size, int32_t count, String str, int32_t *match_index)/* +API_EXPORT FSTRING_LINK b32_4tech +string_set_match_table(void *str_set, i32_4tech item_size, i32_4tech count, String str, i32_4tech *match_index)/* DOC_PARAM(str_set, The str_set parameter may be an array of any type. It should point at the String in the first element of the array.) DOC_PARAM(count, The item_size parameter should describe the "stride" from one String to the next, in other words it should be the size of one element of the array.) DOC_PARAM(count, The count parameter specifies the number of elements in the str_set array.) @@ -1770,8 +1748,8 @@ DOC_PARAM(str, The str parameter specifies the string to match against the str_s DOC_PARAM(match_index, If this call succeeds match_index is filled with the index into str_set where the match occurred.) DOC(This call tries to see if str matches any of the strings in str_set. If there is a match the call succeeds and returns non-zero. The matching rule is equivalent to the matching rule for match.) DOC_SEE(match) */{ - fstr_bool result = 0; - int32_t i = 0; + b32_4tech result = 0; + i32_4tech i = 0; uint8_t *ptr = (uint8_t*)str_set; for (; i < count; ++i, ptr += item_size){ if (match_ss(*(String*)ptr, str)){ @@ -1783,15 +1761,15 @@ DOC_SEE(match) */{ return(result); } -API_EXPORT FSTRING_LINK fstr_bool -string_set_match(String *str_set, int32_t count, String str, int32_t *match_index)/* +API_EXPORT FSTRING_LINK b32_4tech +string_set_match(String *str_set, i32_4tech count, String str, i32_4tech *match_index)/* DOC_PARAM(str_set, The str_set parameter is an array of String structs specifying matchable strings.) DOC_PARAM(count, The count parameter specifies the number of String structs in the str_set array.) DOC_PARAM(str, The str parameter specifies the string to match against the str_set.) DOC_PARAM(match_index, If this call succeeds match_index is filled with the index into str_set where the match occurred.) DOC(This call tries to see if str matches any of the strings in str_set. If there is a match the call succeeds and returns non-zero. The matching rule is equivalent to the matching rule for match.) DOC_SEE(match) */{ - fstr_bool result = string_set_match_table(str_set, sizeof(String), count, str, match_index); + b32_4tech result = string_set_match_table(str_set, sizeof(String), count, str, match_index); return(result); } @@ -1803,8 +1781,8 @@ DOC(A 'double line' is a string of characters delimited by two new line characte DOC_SEE(get_next_double_line) */{ String line = {0}; - int32_t pos0 = find_substr_s(source, 0, make_lit_string("\n\n")); - int32_t pos1 = find_substr_s(source, 0, make_lit_string("\r\n\r\n")); + i32_4tech pos0 = find_substr_s(source, 0, make_lit_string("\n\n")); + i32_4tech pos1 = find_substr_s(source, 0, make_lit_string("\r\n\r\n")); if (pos1 < pos0){ pos0 = pos1; } @@ -1820,8 +1798,8 @@ DOC_RETURN(The returned value is the first 'double line' in the source string.) DOC_SEE(get_first_double_line) */{ String next = {0}; - int32_t pos = (int32_t)(line.str - source.str) + line.size; - int32_t start = 0, pos0 = 0, pos1 = 0; + i32_4tech pos = (i32_4tech)(line.str - source.str) + line.size; + i32_4tech start = 0, pos0 = 0, pos1 = 0; if (pos < source.size){ //Assert(source.str[pos] == '\n' || source.str[pos] == '\r'); @@ -1849,8 +1827,8 @@ DOC_SEE(get_first_word) */{ String word = {0}; - int32_t pos0 = (int32_t)(prev_word.str - source.str) + prev_word.size; - int32_t pos1 = 0; + i32_4tech pos0 = (i32_4tech)(prev_word.str - source.str) + prev_word.size; + i32_4tech pos1 = 0; char c = 0; for (; pos0 < source.size; ++pos0){ @@ -1886,40 +1864,37 @@ DOC_SEE(get_next_word) return(word); } +// TODO(allen): eliminate this. #ifndef FSTRING_EXPERIMENTAL #define FSTRING_EXPERIMENTAL // NOTE(allen): experimental section, things below here are // not promoted to public API level yet. -#ifndef ArrayCount -# define ArrayCount(a) ((sizeof(a))/sizeof(*a)) -#endif - typedef struct Absolutes{ String a[8]; - int32_t count; + i32_4tech count; } Absolutes; static void -get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){ +get_absolutes(String name, Absolutes *absolutes, b32_4tech implicit_first, b32_4tech implicit_last){ if (name.size != 0){ - int32_t count = 0; - int32_t max = ArrayCount(absolutes->a) - 1; + i32_4tech count = 0; + i32_4tech max = ArrayCount(absolutes->a) - 1; if (implicit_last) --max; String str; str.str = name.str; str.size = 0; str.memory_size = 0; - fstr_bool prev_was_wild = 0; + b32_4tech prev_was_wild = 0; if (implicit_first){ absolutes->a[count++] = str; prev_was_wild = 1; } - int32_t i; + i32_4tech i; for (i = 0; i < name.size; ++i){ if (name.str[i] == '*' && count < max){ if (!prev_was_wild){ @@ -1952,15 +1927,15 @@ get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_ } } -static fstr_bool -wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){ - fstr_bool r = 1; +static b32_4tech +wildcard_match_c(Absolutes *absolutes, char *x, i32_4tech case_sensitive){ + b32_4tech r = 1; if (absolutes->count > 0){ String *a = absolutes->a; - fstr_bool (*match_func)(char*, String); - fstr_bool (*match_part_func)(char*, String); + b32_4tech (*match_func)(char*, String); + b32_4tech (*match_part_func)(char*, String); if (case_sensitive){ match_func = match_cs; @@ -2013,8 +1988,8 @@ wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){ return(r); } -static fstr_bool -wildcard_match_s(Absolutes *absolutes, String x, int32_t case_sensitive){ +static b32_4tech +wildcard_match_s(Absolutes *absolutes, String x, i32_4tech case_sensitive){ terminate_with_null(&x); return(wildcard_match_c(absolutes, x.str, case_sensitive)); } @@ -2023,6 +1998,7 @@ wildcard_match_s(Absolutes *absolutes, String x, int32_t case_sensitive){ #if defined(FSTRING_IMPLEMENTATION) #undef FSTRING_IMPLEMENTATION +#define FSTRING_IMPL_GUARD #endif #if !defined(FSTRING_GUARD) diff --git a/string/string_builder.cpp b/string/string_builder.cpp new file mode 100644 index 00000000..f589d8ab --- /dev/null +++ b/string/string_builder.cpp @@ -0,0 +1,487 @@ +/* +Builder for the 4coder_string.h header. +By Allen Webster +Created 21.01.2017 (dd.mm.yyyy) +*/ + +// TOP + +#include "../4cpp/4cpp_lexer.h" +// TODO(allen): Make sure to only publish the 4coder_string.h if it builds and passes a series of tests. +#define FSTRING_IMPLEMENTATION +#include "../4coder_lib/4coder_string.h" + +#include "../4tech_defines.h" +#include "../meta/4tech_meta_defines.h" +#include "../meta/4tech_file_moving.h" + + +#define BUILD_NUMBER_FILE "4coder_string_build_num.txt" + +#define GENERATED_FILE "4coder_string.h" +#define INTERNAL_STRING "internal_4coder_string.cpp" + +#define BACKUP_FOLDER ".." SLASH ".." SLASH "string_backup" +#define PUBLISH_FOLDER ".." SLASH "4coder_helper" + + +#include +#include +#include + +#include "../4coder_lib/4coder_mem.h" + +#define V_MAJ_NUM 1 +#define V_MIN_NUM 0 + +#define V_MAJ STR_(V_MAJ_NUM) +#define V_MIN STR_(V_MIN_NUM) + +#include "../meta/meta_parser.cpp" + +static b32 +parse_build_number(char *file_name, i32 *major_out, i32 *minor_out, i32 *build_out){ + b32 result = false; + String file = file_dump(file_name); + + if (file.str != 0){ + char *end_str = file.str + file.size; + char *major_str = file.str; + char *minor_str = major_str; + for (; minor_str < end_str && *minor_str != '\n'; ++minor_str); + ++minor_str; + + *major_out = 0; + *minor_out = 0; + *build_out = 0; + + if (major_str < end_str){ + char *build_str = minor_str; + for (; build_str < end_str && *build_str != '\n'; ++build_str); + ++build_str; + + if (build_str < end_str){ + char *ender = build_str; + for (; ender < end_str && *ender != '\n'; ++ender); + + if (ender < end_str){ + *ender = 0; + } + + minor_str[-1] = 0; + build_str[-1] = 0; + + *major_out = str_to_int_c(major_str); + *minor_out = str_to_int_c(minor_str); + *build_out = str_to_int_c(build_str); + + result = true; + } + } + + free(file.str); + } + + return(result); +} + +static void +save_build_number(char *file_name, i32 major, i32 minor, i32 build){ + FILE *out = fopen(file_name, "wb"); + fprintf(out, "%d\n", major); + fprintf(out, "%d\n", minor); + fprintf(out, "%d\n\n\n", build); + fclose(out); +} + +/////////////////////////////// + +#include "../meta/out_context.cpp" + +// +// Meta Parse Rules +// + +static void +print_function_body_code(String *out, Parse_Context *context, int32_t start){ + String pstr = {0}, lexeme = {0}; + Cpp_Token *token = 0; + + int32_t do_print = 0; + int32_t nest_level = 0; + int32_t finish = false; + int32_t do_whitespace_print = false; + int32_t is_first = true; + + for (; (token = get_token(context)) != 0; get_next_token(context)){ + if (do_whitespace_print){ + pstr = str_start_end(context->data, start, token->start); + append_ss(out, pstr); + } + else{ + do_whitespace_print = true; + } + + do_print = true; + if (token->type == CPP_TOKEN_COMMENT){ + lexeme = get_lexeme(*token, context->data); + if (check_and_fix_docs(&lexeme)){ + do_print = false; + } + } + else if (token->type == CPP_TOKEN_BRACE_OPEN){ + ++nest_level; + } + else if (token->type == CPP_TOKEN_BRACE_CLOSE){ + --nest_level; + if (nest_level == 0){ + finish = true; + } + } + if (is_first){ + do_print = false; + is_first = false; + } + + if (do_print){ + pstr = get_lexeme(*token, context->data); + append_ss(out, pstr); + } + + start = token->start + token->size; + + if (finish){ + break; + } + } +} + +internal void +file_move(char *path, char *file_name){ + copy_file(0, file_name, path, 0, file_name); +} + +int main(){ + META_BEGIN(); + + i32 size = (512 << 20); + void *mem = malloc(size); + memset(mem, 0, size); + + Partition part_ = make_part(mem, size); + Partition *part = &part_; + + static Meta_Keywords meta_keywords[] = { + {make_lit_string("API_EXPORT") , Item_Function } , + {make_lit_string("API_EXPORT_INLINE") , Item_Function } , + {make_lit_string("API_EXPORT_MACRO") , Item_Macro } , + {make_lit_string("CPP_NAME") , Item_CppName } , + {make_lit_string("TYPEDEF") , Item_Typedef } , + {make_lit_string("STRUCT") , Item_Struct } , + {make_lit_string("UNION") , Item_Union } , + {make_lit_string("ENUM") , Item_Enum } , + }; + + // NOTE(allen): Parse the internal string file. + char *string_files[] = { INTERNAL_STRING, 0 }; + Meta_Unit string_unit = compile_meta_unit(part, ".", string_files, ExpandArray(meta_keywords)); + + if (string_unit.parse == 0){ + Assert(!"Missing one or more input files!"); + } + + // NOTE(allen): Parse the version counter file + i32 major_number = 0; + i32 minor_number = 0; + i32 build_number = 0; + b32 parsed_version_counter = parse_build_number(BUILD_NUMBER_FILE, &major_number, &minor_number, &build_number); + Assert(parsed_version_counter); + + if (V_MAJ_NUM < major_number){ + Assert(!"major version mismatch"); + } + else if (V_MAJ_NUM > major_number){ + major_number = V_MAJ_NUM; + minor_number = V_MIN_NUM; + build_number = 0; + } + else{ + if (V_MIN_NUM < minor_number){ + Assert(!"minor version mismatch"); + } + else if (V_MIN_NUM > minor_number){ + minor_number = V_MIN_NUM; + build_number = 0; + } + } + + // NOTE(allen): Output + String out = str_alloc(part, 10 << 20); + Out_Context context = {0}; + + // NOTE(allen): String Library + if (begin_file_out(&context, GENERATED_FILE, &out)){ + Cpp_Token *token = 0; + int32_t start = 0; + + Parse parse = string_unit.parse[0]; + Parse_Context pcontext = setup_parse_context(parse); + + for (; (token = get_token(&pcontext)) != 0; get_next_token(&pcontext)){ + if (!(token->flags & CPP_TFLAG_PP_BODY) && + token->type == CPP_TOKEN_IDENTIFIER){ + String lexeme = get_lexeme(*token, pcontext.data); + if (match_ss(lexeme, make_lit_string("FSTRING_BEGIN"))){ + start = token->start + token->size; + break; + } + } + } + + append_sc(&out, "/*\n"); + + append_sc(&out, GENERATED_FILE " - Version "V_MAJ"."V_MIN"."); + append_int_to_str(&out, build_number); + append_sc(&out, "\n"); + + append_sc(&out, STANDARD_DISCLAIMER); + append_sc(&out, + "To include implementation: #define FSTRING_IMPLEMENTATION\n" + "To use in C mode: #define FSTRING_C\n"); + + append_sc(&out, "*/\n"); + + String pstr = {0}; + int32_t do_whitespace_print = true; + + for(;(token = get_next_token(&pcontext)) != 0;){ + if (do_whitespace_print){ + pstr = str_start_end(pcontext.data, start, token->start); + append_ss(&out, pstr); + } + else{ + do_whitespace_print = true; + } + + String lexeme = get_lexeme(*token, pcontext.data); + + int32_t do_print = true; + if (match_ss(lexeme, make_lit_string("FSTRING_DECLS"))){ + append_sc(&out, "#if !defined(FCODER_STRING_H)\n#define FCODER_STRING_H\n\n"); + do_print = false; + + static int32_t RETURN_PADDING = 16; + static int32_t SIG_PADDING = 35; + + for (int32_t j = 0; j < string_unit.set.count; ++j){ + char line_[2048]; + String line = make_fixed_width_string(line_); + Item_Node *item = string_unit.set.items + j; + + if (item->t == Item_Function){ + //append_ss (&line, item->marker); + //append_padding (&line, ' ', RETURN_PADDING); + append_ss (&line, item->ret); + append_padding (&line, ' ', SIG_PADDING); + append_ss (&line, item->name); + append_ss (&line, item->args); + append_sc (&line, ";\n"); + } + else if (item->t == Item_Macro){ + append_ss (&line, make_lit_string("#ifndef ")); + append_padding (&line, ' ', 10); + append_ss (&line, item->name); + append_s_char (&line, '\n'); + + append_ss (&line, make_lit_string("# define ")); + append_padding (&line, ' ', 10); + append_ss (&line, item->name); + append_ss (&line, item->args); + append_s_char (&line, ' '); + append_ss (&line, item->body); + append_s_char (&line, '\n'); + + append_ss (&line, make_lit_string("#endif")); + append_s_char (&line, '\n'); + } + else{ + InvalidCodePath; + } + + append_ss(&out, line); + } + + append_sc(&out, "\n#endif\n"); + + // NOTE(allen): C++ overload definitions + append_sc(&out, "\n#if !defined(FSTRING_C) && !defined(FSTRING_GUARD)\n\n"); + + for (int32_t j = 0; j < string_unit.set.count; ++j){ + char line_space[2048]; + String line = make_fixed_width_string(line_space); + + Item_Node *item = &string_unit.set.items[j]; + + if (item->t == Item_Function){ + String cpp_name = item->cpp_name; + if (cpp_name.str != 0){ + Argument_Breakdown breakdown = item->breakdown; + + append_ss (&line, item->ret); + append_padding(&line, ' ', SIG_PADDING); + append_ss (&line, cpp_name); + append_ss (&line, item->args); + if (match_ss(item->ret, make_lit_string("void"))){ + append_ss(&line, make_lit_string("{(")); + } + else{ + append_ss(&line, make_lit_string("{return(")); + } + append_ss (&line, item->name); + append_s_char(&line, '('); + + if (breakdown.count > 0){ + for (int32_t i = 0; i < breakdown.count; ++i){ + if (i != 0){ + append_s_char(&line, ','); + } + append_ss(&line, breakdown.args[i].param_name); + } + } + else{ + append_ss(&line, make_lit_string("void")); + } + + append_ss(&line, make_lit_string("));}\n")); + + append_ss(&out, line); + } + } + } + + append_sc(&out, "\n#endif\n"); + } + + else if (match_ss(lexeme, make_lit_string("API_EXPORT_MACRO"))){ + token = get_next_token(&pcontext); + if (token && token->type == CPP_TOKEN_COMMENT){ + token = get_next_token(&pcontext); + if (token && token->type == CPP_PP_DEFINE){ + for (;(token = get_next_token(&pcontext)) != 0;){ + if (!(token->flags & CPP_TFLAG_PP_BODY)){ + break; + } + } + if (token != 0){ + get_prev_token(&pcontext); + } + do_print = false; + do_whitespace_print = false; + } + } + } + + else if (match_ss(lexeme, make_lit_string("API_EXPORT")) || + match_ss(lexeme, make_lit_string("API_EXPORT_INLINE"))){ + if (!(token->flags & CPP_TFLAG_PP_BODY)){ + if (match_ss(lexeme, make_lit_string("API_EXPORT_INLINE"))){ + append_sc(&out, "#if !defined(FSTRING_GUARD)\n"); + } + else{ + append_sc(&out, "#if defined(FSTRING_IMPLEMENTATION)\n"); + } + print_function_body_code(&out, &pcontext, start); + append_sc(&out, "\n#endif"); + do_print = false; + } + } + + else if (match_ss(lexeme, make_lit_string("CPP_NAME"))){ + Cpp_Token *token_start = token; + int32_t has_cpp_name = false; + + token = get_next_token(&pcontext); + if (token && token->type == CPP_TOKEN_PARENTHESE_OPEN){ + token = get_next_token(&pcontext); + if (token && token->type == CPP_TOKEN_IDENTIFIER){ + token = get_next_token(&pcontext); + if (token && token->type == CPP_TOKEN_PARENTHESE_CLOSE){ + has_cpp_name = true; + do_print = false; + } + } + } + + if (!has_cpp_name){ + token = set_token(&pcontext, token_start); + } + } + + else if (token->type == CPP_TOKEN_COMMENT){ + if (check_and_fix_docs(&lexeme)){ + do_print = false; + } + } + + else if (token->type == CPP_PP_INCLUDE){ + token = get_next_token(&pcontext); + + if (token && token->type == CPP_PP_INCLUDE_FILE){ + lexeme = get_lexeme(*token, pcontext.data);; + lexeme.size -= 2; + lexeme.str += 1; + + char space[512]; + String str = make_fixed_width_string(space); + append_ss(&str, lexeme); + terminate_with_null(&str); + String dump = file_dump(str.str); + if (dump.str){ + append_ss(&out, dump); + } + else{ + lexeme.size += 2; + lexeme.str -= 1; + append_sc(&out, "#error Could not find "); + append_ss(&out, lexeme); + append_sc(&out, "\n"); + } + free(dump.str); + } + + do_print = false; + } + + if ((token = get_token(&pcontext)) != 0){ + if (do_print){ + pstr = get_lexeme(*token, pcontext.data); + append_ss(&out, pstr); + } + start = token->start + token->size; + } + } + pstr = str_start_end(pcontext.data, start, parse.code.size); + append_ss(&out, pstr); + + end_file_out(context); + } + + // NOTE(allen): Publish the new file. (Would like to be able to automatically test the result before publishing). + { + make_folder_if_missing(BACKUP_FOLDER SLASH V_MAJ SLASH V_MIN, 0); + file_move(BACKUP_FOLDER SLASH V_MAJ SLASH V_MIN, INTERNAL_STRING); + file_move(BACKUP_FOLDER SLASH V_MAJ SLASH V_MIN, GENERATED_FILE); + //file_move(PUBLISH_FOLDER, GENERATED_FILE); + delete_file(GENERATED_FILE); + printf("published "GENERATED_FILE": v%d.%d.%d\n", major_number, minor_number, build_number); + save_build_number(BUILD_NUMBER_FILE, major_number, minor_number, build_number + 1); + } + + META_FINISH(); +} + +#define FTECH_FILE_MOVING_IMPLEMENTATION +#include "..\meta\4tech_file_moving.h" + +// BOTTOM + diff --git a/win32_4ed.cpp b/win32_4ed.cpp index dba8a8fb..c041ce13 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -11,50 +11,23 @@ #include #include -#include "common/4coder_defines.h" -#include "common/4coder_version.h" +#include "4tech_defines.h" +#include "4coder_API/version.h" #if defined(FRED_SUPER) +# include "4coder_API/keycodes.h" +# include "4coder_API/style.h" # define FSTRING_IMPLEMENTATION # define FSTRING_C -# include "4coder_string.h" +# include "4coder_lib/4coder_string.h" +# include "4coder_lib/4coder_mem.h" -# include "4coder_keycodes.h" -# include "4coder_style.h" -# include "4coder_rect.h" -# include "4coder_mem.h" -# include "4cpp_lexer.h" - -// TODO(allen): This is duplicated from 4coder_custom.h -// I need to work out a way to avoid this. -#define VIEW_ROUTINE_SIG(name) void name(struct Application_Links *app, int32_t view_id) -#define GET_BINDING_DATA(name) int32_t name(void *data, int32_t size) -#define _GET_VERSION_SIG(n) int32_t n(int32_t maj, int32_t min, int32_t patch) - -typedef VIEW_ROUTINE_SIG(View_Routine_Function); -typedef GET_BINDING_DATA(Get_Binding_Data_Function); -typedef _GET_VERSION_SIG(_Get_Version_Function); - -struct Custom_API{ - View_Routine_Function *view_routine; - Get_Binding_Data_Function *get_bindings; - _Get_Version_Function *get_alpha_4coder_version; -}; - - -typedef void Custom_Command_Function; -#include "4coder_types.h" -struct Application_Links; -# include "4coder_custom_api.h" +# include "4coder_API/types.h" +# include "4ed_os_custom_api.h" #else # include "4coder_default_bindings.cpp" - -# define FSTRING_IMPLEMENTATION -# define FSTRING_C -# include "4coder_string.h" - #endif #include "4ed_math.h" @@ -203,8 +176,8 @@ typedef struct Win32_Vars{ } Win32_Vars; -globalvar Win32_Vars win32vars; -globalvar Application_Memory memory_vars; +global Win32_Vars win32vars; +global Application_Memory memory_vars; // @@ -245,6 +218,48 @@ Win32Ptr(void *h){ // Memory (not exposed to application, but needed in system_shared.cpp) // +internal +Sys_Memory_Allocate_Sig(system_memory_allocate){ + void *result = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + return(result); +} + +internal +Sys_Memory_Set_Protection_Sig(system_memory_set_protection){ + bool32 result = false; + DWORD old_protect = 0; + DWORD protect = 0; + + flags = flags & 0x7; + + switch (flags){ + case 0: protect = PAGE_NOACCESS; break; + + case MemProtect_Read: protect = PAGE_READONLY; break; + + case MemProtect_Write: + case MemProtect_Read|MemProtect_Write: + protect = PAGE_READWRITE; break; + + case MemProtect_Execute: protect = PAGE_EXECUTE; break; + + case MemProtect_Execute|MemProtect_Read: protect = PAGE_EXECUTE_READ; break; + + case MemProtect_Execute|MemProtect_Write: + case MemProtect_Execute|MemProtect_Write|MemProtect_Read: + protect = PAGE_EXECUTE_READWRITE; break; + } + + VirtualProtect(ptr, size, protect, &old_protect); + return(result); +} + +internal +Sys_Memory_Free_Sig(system_memory_free){ + VirtualFree(ptr, 0, MEM_RELEASE); +} + +// TODO(allen): delete internal Sys_Get_Memory_Sig(system_get_memory_){ void *ptr = 0; @@ -254,6 +269,7 @@ Sys_Get_Memory_Sig(system_get_memory_){ return(ptr); } +// TODO(allen): delete internal Sys_Free_Memory_Sig(system_free_memory){ if (block){ @@ -317,7 +333,7 @@ JobThreadProc(LPVOID lpParameter){ Thread_Memory *thread_memory = win32vars.thread_memory + thread_index; if (thread_memory->size == 0){ - i32 new_size = Kbytes(64); + i32 new_size = KB(64); thread_memory->data = Win32GetMemory(new_size); thread_memory->size = new_size; } @@ -575,13 +591,10 @@ Sys_Check_Cancel_Sig(system_check_cancel){ internal Sys_Grow_Thread_Memory_Sig(system_grow_thread_memory){ - void *old_data; - i32 old_size, new_size; - system_acquire_lock(CANCEL_LOCK0 + memory->id - 1); - old_data = memory->data; - old_size = memory->size; - new_size = l_round_up_i32(memory->size*2, Kbytes(4)); + void *old_data = memory->data; + i32 old_size = memory->size; + i32 new_size = l_round_up(memory->size*2, KB(4)); memory->data = system_get_memory(new_size); memory->size = new_size; if (old_data){ @@ -593,13 +606,15 @@ Sys_Grow_Thread_Memory_Sig(system_grow_thread_memory){ #if FRED_INTERNAL internal void -INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){ +INTERNAL_get_thread_states(Thread_Group_ID id, b8 *running, i32 *pending){ Thread_Group *group = win32vars.groups + id; Unbounded_Work_Queue *source_queue = &group->queue; Work_Queue *queue = win32vars.queues + id; u32 write = queue->write_position; u32 read = queue->read_position; - if (write < read) write += QUEUE_WRAP; + if (write < read){ + write += QUEUE_WRAP; + } *pending = (i32)(write - read) + source_queue->count - source_queue->skip; for (i32 i = 0; i < group->count; ++i){ @@ -996,6 +1011,76 @@ Sys_Get_Binary_Path_Sig(system_get_binary_path){ return(result); } +internal +Sys_File_Exists_Sig(system_file_exists){ + char full_filename_space[1024]; + String full_filename; + HANDLE file; + b32 result = 0; + + if (len < sizeof(full_filename_space)){ + full_filename = make_fixed_width_string(full_filename_space); + copy_ss(&full_filename, make_string(filename, len)); + terminate_with_null(&full_filename); + + file = CreateFile(full_filename.str, GENERIC_READ, 0, 0, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + + if (file != INVALID_HANDLE_VALUE){ + CloseHandle(file); + result = 1; + } + } + + return(result); +} + +internal +Sys_Directory_CD_Sig(system_directory_cd){ + String directory = make_string_cap(dir, *len, cap); + b32 result = 0; + i32 old_size; + + char rel_path_space[1024]; + String rel_path_string = make_fixed_width_string(rel_path_space); + copy_ss(&rel_path_string, make_string(rel_path, rel_len)); + terminate_with_null(&rel_path_string); + + if (rel_path[0] != 0){ + if (rel_path[0] == '.' && rel_path[1] == 0){ + result = 1; + } + else if (rel_path[0] == '.' && rel_path[1] == '.' && rel_path[2] == 0){ + result = remove_last_folder(&directory); + terminate_with_null(&directory); + } + else{ + if (directory.size + rel_len + 1 > directory.memory_size){ + old_size = directory.size; + append_partial_sc(&directory, rel_path); + append_s_char(&directory, '\\'); + if (Win32DirectoryExists(directory.str)){ + result = 1; + } + else{ + directory.size = old_size; + } + } + } + } + + *len = directory.size; + + return(result); +} + +internal +Sys_Get_4ed_Path_Sig(system_get_4ed_path){ + String str = make_string_cap(out, 0, capacity); + int32_t size = system_get_binary_path(&str); + return(size); +} + /* NOTE(casey): This follows Raymond Chen's prescription @@ -1031,8 +1116,6 @@ Win32ToggleFullscreen(void){ } } -#include "win32_api_impl.cpp" - // // Clipboard // @@ -1206,10 +1289,12 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ DWORD result = 0; if (WaitForSingleObject(proc, 0) == WAIT_OBJECT_0){ - if (GetExitCodeProcess(proc, &result) == 0) + if (GetExitCodeProcess(proc, &result) == 0){ cli->exit = -1; - else + } + else{ cli->exit = (i32)result; + } close_me = 1; CloseHandle(*(HANDLE*)&cli->proc); @@ -1221,6 +1306,59 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ return(close_me); } +// +// Appearence Settings +// + +// TODO(allen): add a "shown but auto-hides on timer" setting here. +internal +Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){ + switch (show){ + case MouseCursorShow_Never: + ShowCursor(false); + break; + + case MouseCursorShow_Always: + ShowCursor(true); + break; + + // TODO(allen): MouseCursor_HideWhenStill + } +} + +internal +Sys_Toggle_Fullscreen_Sig(system_toggle_fullscreen){ + /* NOTE(allen): Don't actually change window size now! + Tell the platform layer to do the toggle (or to cancel the toggle) + later when the app.step function isn't running. If the size changes + mid step, it messes up the rendering rules and stuff. */ + + b32 success = false; + + // NOTE(allen): On windows we must be in stream mode to go fullscreen. + if (win32vars.settings.stream_mode){ + win32vars.do_toggle = !win32vars.do_toggle; + success = true; + } + + return(success); +} + +internal +Sys_Is_Fullscreen_Sig(system_is_fullscreen){ + /* NOTE(allen): This is a fancy way to say 'full_screen XOR do_toggle' + This way this function can always report the state the fullscreen + will have when the next frame runs, given the number of toggles + that have occurred this frame and the original value. */ + bool32 result = (win32vars.full_screen + win32vars.do_toggle) & 1; + return(result); +} + +internal +Sys_Send_Exit_Signal_Sig(system_send_exit_signal){ + win32vars.send_exit_signal = 1; +} + #include "4ed_system_shared.cpp" #if USE_FT_FONTS @@ -1239,14 +1377,14 @@ size_change(i32 dpi_x, i32 dpi_y){ internal Font_Load_Sig(system_draw_font_load){ if (win32vars.font_part.base == 0){ - win32vars.font_part = Win32ScratchPartition(Mbytes(8)); + win32vars.font_part = Win32ScratchPartition(MB(8)); } i32 oversample = 2; AllowLocal(oversample); #if SUPPORT_DPI - pt_size = ROUND32(pt_size * size_change(win32vars.dpi_x, win32vars.dpi_y)); + pt_size = round32(pt_size * size_change(win32vars.dpi_x, win32vars.dpi_y)); #endif for (b32 success = 0; success == 0;){ @@ -1331,19 +1469,6 @@ Win32LoadSystemCode(){ win32vars.system.now_time = system_now_time; - win32vars.system.memory_allocate = Memory_Allocate; - win32vars.system.memory_set_protection = Memory_Set_Protection; - win32vars.system.memory_free = Memory_Free; - - win32vars.system.file_exists = File_Exists; - win32vars.system.directory_cd = Directory_CD; - win32vars.system.get_4ed_path = Get_4ed_Path; - win32vars.system.show_mouse_cursor = Show_Mouse_Cursor; - - win32vars.system.toggle_fullscreen = Toggle_Fullscreen; - win32vars.system.is_fullscreen = Is_Fullscreen; - win32vars.system.send_exit_signal = Send_Exit_Signal; - win32vars.system.post_clipboard = system_post_clipboard; win32vars.system.create_coroutine = system_create_coroutine; @@ -1363,6 +1488,17 @@ Win32LoadSystemCode(){ win32vars.system.acquire_lock = system_acquire_lock; win32vars.system.release_lock = system_release_lock; + win32vars.system.memory_allocate = system_memory_allocate; + win32vars.system.memory_set_protection = system_memory_set_protection; + win32vars.system.memory_free = system_memory_free; + win32vars.system.file_exists = system_file_exists; + win32vars.system.directory_cd = system_directory_cd; + win32vars.system.get_4ed_path = system_get_4ed_path; + win32vars.system.toggle_fullscreen = system_toggle_fullscreen; + win32vars.system.is_fullscreen = system_is_fullscreen;win32vars.system.show_mouse_cursor = system_show_mouse_cursor; + win32vars.system.send_exit_signal = system_send_exit_signal; + + #if FRED_INTERNAL win32vars.system.internal_get_thread_states = INTERNAL_get_thread_states; #endif @@ -1382,7 +1518,7 @@ Win32LoadRenderCode(){ // Helpers // -globalvar u8 keycode_lookup_table[255]; +global u8 keycode_lookup_table[255]; internal void Win32KeycodeInit(){ @@ -1855,37 +1991,31 @@ WinMain(HINSTANCE hInstance, LPVOID base; #if FRED_INTERNAL - base = (LPVOID)Tbytes(1); + base = (LPVOID)TB(1); #else base = (LPVOID)0; #endif - memory_vars.vars_memory_size = Mbytes(2); - memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size, - MEM_COMMIT | MEM_RESERVE, - PAGE_READWRITE); + memory_vars.vars_memory_size = MB(2); + memory_vars.vars_memory = VirtualAlloc(base, memory_vars.vars_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); #if FRED_INTERNAL - base = (LPVOID)Tbytes(2); + base = (LPVOID)TB(2); #else base = (LPVOID)0; #endif - memory_vars.target_memory_size = Mbytes(512); - memory_vars.target_memory = - VirtualAlloc(base, memory_vars.target_memory_size, - MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + memory_vars.target_memory_size = MB(512); + memory_vars.target_memory = VirtualAlloc(base, memory_vars.target_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); base = (LPVOID)0; - memory_vars.user_memory_size = Mbytes(2); - memory_vars.user_memory = - VirtualAlloc(base, memory_vars.target_memory_size, - MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + memory_vars.user_memory_size = MB(2); + memory_vars.user_memory = VirtualAlloc(base, memory_vars.target_memory_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!memory_vars.vars_memory){ exit(1); } - win32vars.target.max = Mbytes(1); + win32vars.target.max = MB(1); win32vars.target.push_buffer = (char*)system_get_memory(win32vars.target.max); @@ -1943,7 +2073,7 @@ WinMain(HINSTANCE hInstance, // #if defined(FRED_SUPER) - char *custom_file_default = "4coder_custom.dll"; + char *custom_file_default = "custom_4coder.dll"; char *custom_file = 0; if (win32vars.settings.custom_dll) custom_file = win32vars.settings.custom_dll; else custom_file = custom_file_default; @@ -1966,13 +2096,6 @@ WinMain(HINSTANCE hInstance, } win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*) GetProcAddress(win32vars.custom, "get_bindings"); - - // NOTE(allen): I am temporarily taking the view routine - // back out, it will be back soon. -#if 0 - win32vars.custom_api.view_routine = (View_Routine_Function*) - GetProcAddress(win32vars.custom, "view_routine"); -#endif } if (win32vars.custom_api.get_bindings == 0){ @@ -1984,15 +2107,6 @@ WinMain(HINSTANCE hInstance, win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings; #endif - win32vars.custom_api.view_routine = (View_Routine_Function*)0; - -#if 0 - if (win32vars.custom_api.view_routine == 0){ - win32vars.custom_api.view_routine = (View_Routine_Function*)view_routine; - } -#endif - - // // Window and GL Initialization // @@ -2232,10 +2346,21 @@ WinMain(HINSTANCE hInstance, if (GetCursorPos(&mouse_point) && ScreenToClient(win32vars.window_handle, &mouse_point)){ - i32_Rect screen = - i32R(0, 0, win32vars.target.width, win32vars.target.height); + i32_Rect screen; + screen.x0 = 0; + screen.y0 = 0; + screen.x1 = win32vars.target.width; + screen.y1 = win32vars.target.height; - if (!hit_check(mouse_point.x, mouse_point.y, screen)){ + i32 mx = mouse_point.x; + i32 my = mouse_point.y; + + b32 is_hit = false; + if (mx >= screen.x0 && mx < screen.x1 && my >= screen.y0 && my < screen.y1){ + is_hit = true; + } + + if (!is_hit){ win32vars.input_chunk.trans.out_of_window = 1; } diff --git a/win32_api_impl.cpp b/win32_api_impl.cpp deleted file mode 100644 index d59b5545..00000000 --- a/win32_api_impl.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/* -Implementation of system level functions that get exposed straight -into the 4coder custom API. This file need not be split on other platforms, -as this is the only one that will be used for generating headers and docs. --Allen - -27.06.2016 (dd.mm.yyyy) -*/ - -// TOP - -#define API_EXPORT - -API_EXPORT void* -Memory_Allocate(Application_Links *app, int32_t size) -/* -DOC_PARAM(size, The size in bytes of the block that should be returned.) -DOC(This calls to a low level OS allocator which means it is best used -for infrequent, large allocations. The size of the block must be remembered -if it will be freed or if it's mem protection status will be changed.) -DOC_SEE(memory_free) -*/{ - void *result = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - return(result); -} - -API_EXPORT bool32 -Memory_Set_Protection(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags) -/* -DOC_PARAM(ptr, The base of the block on which to set memory protection flags.) -DOC_PARAM(size, The size that was originally used to allocate this block.) -DOC_PARAM(flags, The new memory protection flags.) -DOC(This call sets the memory protection flags of a block of memory that was previously -allocate by memory_allocate.) -DOC_SEE(memory_allocate) -DOC_SEE(Memory_Protect_Flags) -*/{ - bool32 result = false; - DWORD old_protect = 0; - DWORD protect = 0; - - flags = flags & 0x7; - - switch (flags){ - case 0: protect = PAGE_NOACCESS; break; - - case MemProtect_Read: protect = PAGE_READONLY; break; - - case MemProtect_Write: - case MemProtect_Read|MemProtect_Write: - protect = PAGE_READWRITE; break; - - case MemProtect_Execute: protect = PAGE_EXECUTE; break; - - case MemProtect_Execute|MemProtect_Read: protect = PAGE_EXECUTE_READ; break; - - case MemProtect_Execute|MemProtect_Write: - case MemProtect_Execute|MemProtect_Write|MemProtect_Read: - protect = PAGE_EXECUTE_READWRITE; break; - } - - VirtualProtect(ptr, size, protect, &old_protect); - return(result); -} - -API_EXPORT void -Memory_Free(Application_Links *app, void *ptr, int32_t size)/* -DOC_PARAM(mem, The base of a block to free.) -DOC_PARAM(size, The size that was originally used to allocate this block.) -DOC(This call frees a block of memory that was previously allocated by -memory_allocate.) -DOC_SEE(memory_allocate) -*/{ - VirtualFree(ptr, 0, MEM_RELEASE); -} - -API_EXPORT bool32 -File_Exists(Application_Links *app, char *filename, int32_t len)/* -DOC_PARAM(filename, This parameter specifies the full path to a file; it need not be null terminated.) -DOC_PARAM(len, This parameter specifies the length of the filename string.) -DOC_RETURN(This call returns non-zero if and only if the file exists.) -*/{ - char full_filename_space[1024]; - String full_filename; - HANDLE file; - b32 result = 0; - - if (len < sizeof(full_filename_space)){ - full_filename = make_fixed_width_string(full_filename_space); - copy_ss(&full_filename, make_string(filename, len)); - terminate_with_null(&full_filename); - - file = CreateFile(full_filename.str, GENERIC_READ, 0, 0, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - - if (file != INVALID_HANDLE_VALUE){ - CloseHandle(file); - result = 1; - } - } - - return(result); -} - -API_EXPORT bool32 -Directory_CD(Application_Links *app, char *dir, int32_t *len, int32_t capacity, char *rel_path, int32_t rel_len)/* -DOC_PARAM(dir, This parameter provides a character buffer that stores a directory; it need not be null terminated.) -DOC_PARAM(len, This parameter specifies the length of the dir string.) -DOC_PARAM(capacity, This parameter specifies the maximum size of the dir string.) -DOC_PARAM(rel_path, This parameter specifies the path to change to, may include '.' or '..'; it need not be null terminated.) -DOC_PARAM(rel_len, This parameter specifies the length of the rel_path string.) -DOC_RETURN(This call returns non-zero if the call succeeds.) -DOC -( -This call succeeds if the new directory exists and the it fits inside the -dir buffer. If the call succeeds the dir buffer is filled with the new -directory and len is overwritten with the length of the new string in the buffer. - -For instance if dir contains "C:/Users/MySelf" and rel is "Documents" the buffer -will contain "C:/Users/MySelf/Documents" and len will contain the length of that -string. This call can also be used with rel set to ".." to traverse to parent -folders. -) -*/{ - String directory = make_string_cap(dir, *len, capacity); - b32 result = 0; - i32 old_size; - - char rel_path_space[1024]; - String rel_path_string = make_fixed_width_string(rel_path_space); - copy_ss(&rel_path_string, make_string(rel_path, rel_len)); - terminate_with_null(&rel_path_string); - - if (rel_path[0] != 0){ - if (rel_path[0] == '.' && rel_path[1] == 0){ - result = 1; - } - else if (rel_path[0] == '.' && rel_path[1] == '.' && rel_path[2] == 0){ - result = remove_last_folder(&directory); - terminate_with_null(&directory); - } - else{ - if (directory.size + rel_len + 1 > directory.memory_size){ - old_size = directory.size; - append_partial_sc(&directory, rel_path); - append_s_char(&directory, '\\'); - if (Win32DirectoryExists(directory.str)){ - result = 1; - } - else{ - directory.size = old_size; - } - } - } - } - - *len = directory.size; - - return(result); -} - -API_EXPORT int32_t -Get_4ed_Path(Application_Links *app, char *out, int32_t capacity) -/* -DOC_PARAM(out, This parameter provides a character buffer that receives the path to the 4ed executable file.) -DOC_PARAM(capacity, This parameter specifies the maximum capacity of the out buffer.) -DOC_RETURN(This call returns non-zero on success.) -*/{ - String str = make_string_cap(out, 0, capacity); - int32_t size = system_get_binary_path(&str); - return(size); -} - -// TODO(allen): add a "shown but auto-hides on timer" setting here. -API_EXPORT void -Show_Mouse_Cursor(Application_Links *app, Mouse_Cursor_Show_Type show) -/* -DOC_PARAM(show, This parameter specifies the new state of the mouse cursor.) -DOC_SEE(Mouse_Cursor_Show_Type) -*/{ - switch (show){ - case MouseCursorShow_Never: - ShowCursor(false); - break; - - case MouseCursorShow_Always: - ShowCursor(true); - break; - - // TODO(allen): MouseCursor_HideWhenStill - } -} - -API_EXPORT void -Toggle_Fullscreen(Application_Links *app) -/* -DOC(This call tells 4coder to switch into or out of full screen mode. -The changes of full screen mode do not take effect until the end of the current frame. -On Windows this call will not work unless 4coder was started in "stream mode". -Stream mode can be enabled with -S or -F flags on the command line to 4ed.) -*/{ - /* NOTE(allen): Don't actually change window size now! - Tell the platform layer to do the toggle (or to cancel the toggle) - later when the app.step function isn't running. If the size changes - mid step, it messes up the rendering rules and stuff. */ - - // NOTE(allen): On windows we must be in stream mode to go fullscreen. - if (win32vars.settings.stream_mode){ - win32vars.do_toggle = !win32vars.do_toggle; - } - else{ - print_message(app, literal("WARNING: Cannot go full screen unless 4coder is in stream mode\n Use the flag -S to put 4coder in stream mode.\n")); - } -} - -API_EXPORT bool32 -Is_Fullscreen(Application_Links *app) -/* -DOC(This call returns true if the 4coder is in full screen mode. This call -takes toggles that have already occured this frame into account. So it may return -true even though the frame has not ended and actually put 4coder into full screen. If -it returns true though, 4coder will definitely be full screen by the beginning of the next -frame if the state is not changed.) -*/{ - /* NOTE(allen): This is a fancy way to say 'full_screen XOR do_toggle' - This way this function can always report the state the fullscreen - will have when the next frame runs, given the number of toggles - that have occurred this frame and the original value. */ - bool32 result = (win32vars.full_screen + win32vars.do_toggle) & 1; - return(result); -} - -API_EXPORT void -Send_Exit_Signal(Application_Links *app) -/* -DOC(This call sends a signal to 4coder to attempt to exit. If there are unsaved -files this triggers a dialogue ensuring you're okay with closing.) -*/{ - win32vars.send_exit_signal = 1; -} - -// BOTTOM -