diff --git a/4coder_custom.h b/4coder_custom.h index 84e1b96e..54fd2f4a 100644 --- a/4coder_custom.h +++ b/4coder_custom.h @@ -172,55 +172,57 @@ typedef struct File_List{ enum Command_ID{ cmdid_null, - cmdid_write_character, + cmdid_seek_left, cmdid_seek_right, - cmdid_seek_whitespace_up, - cmdid_seek_whitespace_down, + cmdid_center_view, + cmdid_word_complete, - cmdid_set_mark, + cmdid_copy, cmdid_cut, cmdid_paste, cmdid_paste_next, - cmdid_delete_range, + cmdid_undo, cmdid_redo, cmdid_history_backward, cmdid_history_forward, + cmdid_interactive_new, cmdid_interactive_open, cmdid_reopen, cmdid_save, - cmdid_change_active_panel, cmdid_interactive_switch_buffer, cmdid_interactive_kill_buffer, cmdid_kill_buffer, - cmdid_toggle_line_wrap, - cmdid_toggle_endline_mode, + + cmdid_change_active_panel, + cmdid_to_uppercase, cmdid_to_lowercase, + + cmdid_toggle_line_wrap, cmdid_toggle_show_whitespace, - cmdid_clean_all_lines, + cmdid_eol_dosify, cmdid_eol_nixify, + + cmdid_clean_all_lines, cmdid_auto_tab_range, + cmdid_open_panel_vsplit, cmdid_open_panel_hsplit, cmdid_close_panel, - cmdid_move_left, - cmdid_move_right, - cmdid_delete, - cmdid_backspace, - cmdid_move_up, - cmdid_move_down, + cmdid_seek_end_of_line, cmdid_seek_beginning_of_line, cmdid_page_up, cmdid_page_down, - cmdid_open_color_tweaker, cmdid_cursor_mark_swap, + + cmdid_open_color_tweaker, cmdid_open_menu, cmdid_hide_scrollbar, cmdid_show_scrollbar, @@ -240,6 +242,7 @@ enum Param_ID{ par_lex_as_cpp_file, par_wrap_lines, par_key_mapid, + par_show_whitespace, par_cli_path, par_cli_command, par_clear_blank_lines, @@ -270,9 +273,9 @@ enum Special_Hook_ID{ _hook_scroll_rule = hook_type_count, }; -// NOTE(allen): None of the members of *_Summary structs nor any of the -// data pointed to by the members should be modified, I would have made -// them all const... but that causes a lot problems for C++ reasons. +// None of the members of *_Summary structs nor any of the data pointed +// to by the members should be modified, I would have made them all +// const... but that causes a lot problems for C++ reasons. struct Buffer_Summary{ int exists; int ready; @@ -305,8 +308,9 @@ struct View_Summary{ Full_Cursor cursor; Full_Cursor mark; float preferred_x; - int line_height; + float line_height; int unwrapped_lines; + int show_whitespace; }; inline View_Summary view_summary_zero(){ diff --git a/4coder_custom_api.h b/4coder_custom_api.h index 5903c3df..aa9a839c 100644 --- a/4coder_custom_api.h +++ b/4coder_custom_api.h @@ -11,12 +11,8 @@ #define GET_BUFFER_FIRST_SIG(n) Buffer_Summary n(Application_Links *app) #define GET_BUFFER_NEXT_SIG(n) void n(Application_Links *app, Buffer_Summary *buffer) #define GET_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int index) -#define GET_ACTIVE_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app) #define GET_PARAMETER_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int param_index) #define GET_BUFFER_BY_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *filename, int len) -#define BUFFER_SEEK_DELIMITER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out) -#define BUFFER_SEEK_STRING_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out) -#define BUFFER_SEEK_STRING_INSENSITIVE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out) #define REFRESH_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer) #define BUFFER_READ_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out) #define BUFFER_REPLACE_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len) @@ -56,12 +52,8 @@ extern "C"{ typedef GET_BUFFER_FIRST_SIG(Get_Buffer_First_Function); typedef GET_BUFFER_NEXT_SIG(Get_Buffer_Next_Function); typedef GET_BUFFER_SIG(Get_Buffer_Function); - typedef GET_ACTIVE_BUFFER_SIG(Get_Active_Buffer_Function); typedef GET_PARAMETER_BUFFER_SIG(Get_Parameter_Buffer_Function); typedef GET_BUFFER_BY_NAME_SIG(Get_Buffer_By_Name_Function); - typedef BUFFER_SEEK_DELIMITER_SIG(Buffer_Seek_Delimiter_Function); - typedef BUFFER_SEEK_STRING_SIG(Buffer_Seek_String_Function); - typedef BUFFER_SEEK_STRING_INSENSITIVE_SIG(Buffer_Seek_String_Insensitive_Function); typedef REFRESH_BUFFER_SIG(Refresh_Buffer_Function); typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function); typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function); @@ -104,12 +96,8 @@ struct Application_Links{ Get_Buffer_First_Function *get_buffer_first; Get_Buffer_Next_Function *get_buffer_next; Get_Buffer_Function *get_buffer; - Get_Active_Buffer_Function *get_active_buffer; Get_Parameter_Buffer_Function *get_parameter_buffer; Get_Buffer_By_Name_Function *get_buffer_by_name; - Buffer_Seek_Delimiter_Function *buffer_seek_delimiter; - Buffer_Seek_String_Function *buffer_seek_string; - Buffer_Seek_String_Insensitive_Function *buffer_seek_string_insensitive; Refresh_Buffer_Function *refresh_buffer; Buffer_Read_Range_Function *buffer_read_range; Buffer_Replace_Range_Function *buffer_replace_range; diff --git a/4coder_default_bindings.cpp b/4coder_default_bindings.cpp index 0ca989ed..da15c181 100644 --- a/4coder_default_bindings.cpp +++ b/4coder_default_bindings.cpp @@ -49,44 +49,6 @@ CUSTOM_COMMAND_SIG(switch_to_compilation){ app->view_set_buffer(app, &view, buffer.buffer_id); } -CUSTOM_COMMAND_SIG(move_up_10){ - View_Summary view; - float x, y; - - view = app->get_active_view(app); - x = view.preferred_x; - - if (view.unwrapped_lines){ - y = view.cursor.unwrapped_y; - } - else{ - y = view.cursor.wrapped_y; - } - - y -= 10*view.line_height; - - app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0); -} - -CUSTOM_COMMAND_SIG(move_down_10){ - View_Summary view; - float x, y; - - view = app->get_active_view(app); - x = view.preferred_x; - - if (view.unwrapped_lines){ - y = view.cursor.unwrapped_y; - } - else{ - y = view.cursor.wrapped_y; - } - - y += 10*view.line_height; - - app->view_set_cursor(app, &view, seek_xy(x, y, 0, view.unwrapped_lines), 0); -} - CUSTOM_COMMAND_SIG(rewrite_as_single_caps){ View_Summary view; Buffer_Summary buffer; @@ -141,22 +103,24 @@ CUSTOM_COMMAND_SIG(open_my_files){ // any circumstance. push_parameter(app, par_name, literal("w:/4ed/data/test/basic.cpp")); exec_command(app, cmdid_interactive_open); - + +#if 0 exec_command(app, cmdid_change_active_panel); - + char my_file[256]; int my_file_len; - + my_file_len = sizeof("w:/4ed/data/test/basic.txt") - 1; for (int i = 0; i < my_file_len; ++i){ my_file[i] = ("w:/4ed/data/test/basic.txt")[i]; } - + // NOTE(allen|a3.1): null terminators are not needed for strings. push_parameter(app, par_name, my_file, my_file_len); exec_command(app, cmdid_interactive_open); - + exec_command(app, cmdid_change_active_panel); +#endif } CUSTOM_COMMAND_SIG(build_at_launch_location){ @@ -262,7 +226,7 @@ HOOK_SIG(my_file_settings){ push_parameter(app, par_wrap_lines, wrap_lines); push_parameter(app, par_key_mapid, (treat_as_code)?((int)my_code_map):((int)mapid_file)); exec_command(app, cmdid_set_settings); - + // no meaning for return return(0); } @@ -270,7 +234,7 @@ HOOK_SIG(my_file_settings){ void default_keys(Bind_Helper *context){ begin_map(context, mapid_global); - + bind(context, 'p', MDFR_CTRL, cmdid_open_panel_vsplit); bind(context, '_', MDFR_CTRL, cmdid_open_panel_hsplit); bind(context, 'P', MDFR_CTRL, cmdid_close_panel); @@ -282,40 +246,40 @@ default_keys(Bind_Helper *context){ bind(context, 'c', MDFR_ALT, cmdid_open_color_tweaker); bind(context, 'o', MDFR_ALT, open_in_other); bind(context, 'w', MDFR_CTRL, save_as); - + bind(context, 'm', MDFR_ALT, build_search); bind(context, 'x', MDFR_ALT, execute_arbitrary_command); bind(context, 'z', MDFR_ALT, execute_any_cli); bind(context, 'Z', MDFR_ALT, execute_previous_cli); - + // NOTE(allen): These callbacks may not actually be useful to you, but // go look at them and see what they do. bind(context, 'M', MDFR_ALT | MDFR_CTRL, open_my_files); bind(context, 'M', MDFR_ALT, build_at_launch_location); - + end_map(context); begin_map(context, my_empty_map1); inherit_map(context, mapid_nomap); end_map(context); - + begin_map(context, my_empty_map2); inherit_map(context, mapid_nomap); end_map(context); - + begin_map(context, my_code_map); - + // NOTE(allen|a3.1): Set this map (my_code_map == mapid_user_custom) to // inherit from mapid_file. When searching if a key is bound // in this map, if it is not found here it will then search mapid_file. // // If this is not set, it defaults to mapid_global. inherit_map(context, mapid_file); - + // NOTE(allen|a3.1): Children can override parent's bindings. bind(context, key_right, MDFR_CTRL, seek_alphanumeric_or_camel_right); bind(context, key_left, MDFR_CTRL, seek_alphanumeric_or_camel_left); - + // NOTE(allen|a3.2): Specific keys can override vanilla keys, // and write character writes whichever character corresponds // to the key that triggered the command. @@ -325,11 +289,11 @@ default_keys(Bind_Helper *context){ bind(context, ']', MDFR_NONE, write_and_auto_tab); bind(context, ';', MDFR_NONE, write_and_auto_tab); bind(context, '#', MDFR_NONE, write_and_auto_tab); - + bind(context, '\t', MDFR_NONE, cmdid_word_complete); bind(context, '\t', MDFR_CTRL, cmdid_auto_tab_range); bind(context, '\t', MDFR_SHIFT, auto_tab_line_at_cursor); - + bind(context, '=', MDFR_CTRL, write_increment); bind(context, 't', MDFR_ALT, write_allen_todo); bind(context, 'n', MDFR_ALT, write_allen_note); @@ -339,54 +303,53 @@ default_keys(Bind_Helper *context){ bind(context, 'i', MDFR_ALT, if0_off); bind(context, '1', MDFR_ALT, open_file_in_quotes); bind(context, '0', MDFR_CTRL, write_zero_struct); - + end_map(context); - - + + begin_map(context, mapid_file); - + // NOTE(allen|a3.4.4): Binding this essentially binds // all key combos that would normally insert a character // into a buffer. If the code for the key is not an enum // value such as key_left or key_back then it is a vanilla key. // It is possible to override this binding for individual keys. - bind_vanilla_keys(context, cmdid_write_character); - - bind(context, key_left, MDFR_NONE, cmdid_move_left); - bind(context, key_right, MDFR_NONE, cmdid_move_right); - bind(context, key_del, MDFR_NONE, cmdid_delete); - bind(context, key_back, MDFR_NONE, cmdid_backspace); - bind(context, key_up, MDFR_NONE, cmdid_move_up); - bind(context, key_down, MDFR_NONE, cmdid_move_down); + bind_vanilla_keys(context, write_character); + + bind(context, key_left, MDFR_NONE, move_left); + bind(context, key_right, MDFR_NONE, move_right); + bind(context, key_del, MDFR_NONE, delete_char); + bind(context, key_back, MDFR_NONE, backspace_char); + bind(context, key_up, MDFR_NONE, move_up); + bind(context, key_down, MDFR_NONE, move_down); bind(context, key_end, MDFR_NONE, cmdid_seek_end_of_line); bind(context, key_home, MDFR_NONE, cmdid_seek_beginning_of_line); bind(context, key_page_up, MDFR_NONE, cmdid_page_up); bind(context, key_page_down, MDFR_NONE, cmdid_page_down); - + bind(context, key_right, MDFR_CTRL, seek_whitespace_right); bind(context, key_left, MDFR_CTRL, seek_whitespace_left); - bind(context, key_up, MDFR_CTRL, cmdid_seek_whitespace_up); - bind(context, key_down, MDFR_CTRL, cmdid_seek_whitespace_down); - + bind(context, key_up, MDFR_CTRL, seek_whitespace_up); + bind(context, key_down, MDFR_CTRL, seek_whitespace_down); + bind(context, key_up, MDFR_ALT, move_up_10); bind(context, key_down, MDFR_ALT, move_down_10); - + bind(context, key_back, MDFR_CTRL, backspace_word); bind(context, key_back, MDFR_ALT, snipe_token_or_word); - - bind(context, ' ', MDFR_CTRL, cmdid_set_mark); + + bind(context, ' ', MDFR_CTRL, set_mark); bind(context, 'a', MDFR_CTRL, replace_in_range); bind(context, 'c', MDFR_CTRL, cmdid_copy); - bind(context, 'd', MDFR_CTRL, cmdid_delete_range); + bind(context, 'd', MDFR_CTRL, delete_range); bind(context, 'e', MDFR_CTRL, cmdid_center_view); bind(context, 'f', MDFR_CTRL, search); 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, 'l', MDFR_CTRL, cmdid_toggle_line_wrap); bind(context, 'j', MDFR_CTRL, cmdid_to_lowercase); bind(context, 'K', MDFR_CTRL, cmdid_kill_buffer); - bind(context, 'L', MDFR_CTRL, cmdid_toggle_endline_mode); + bind(context, 'l', MDFR_CTRL, cmdid_toggle_line_wrap); bind(context, 'm', MDFR_CTRL, cmdid_cursor_mark_swap); bind(context, 'O', MDFR_CTRL, cmdid_reopen); bind(context, 'q', MDFR_CTRL, query_replace); @@ -409,7 +372,7 @@ default_keys(Bind_Helper *context){ bind(context, '~', MDFR_CTRL, cmdid_clean_all_lines); bind(context, '!', MDFR_CTRL, cmdid_eol_nixify); bind(context, '\n', MDFR_SHIFT, write_and_auto_tab); - bind(context, ' ', MDFR_SHIFT, cmdid_write_character); + bind(context, ' ', MDFR_SHIFT, write_character); end_map(context); } @@ -425,7 +388,7 @@ get_bindings(void *data, int size){ // and once set they always apply, regardless of what map is active. set_hook(context, hook_start, my_start); set_hook(context, hook_open_file, my_file_settings); - + set_scroll_rule(context, smooth_scroll_rule); default_keys(context); @@ -434,94 +397,6 @@ get_bindings(void *data, int size){ return(result); } -struct Custom_Vars{ - int initialized; - Partition part; -}; - -enum View_Mode{ - ViewMode_File, -}; - -struct View_Vars{ - int id; - View_Mode mode; - - GUI_Scroll_Vars scroll; - i32_Rect scroll_region; - - int buffer_id; -}; -inline View_Vars -view_vars_zero(){ - View_Vars vars = {0}; - return(vars); -} - -extern "C" void -view_routine(Application_Links *app, int view_id){ - Custom_Vars *vars = (Custom_Vars*)app->memory; - View_Vars view = {0}; - view.id = view_id; - - int 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; - } - } -} - #endif // BOTTOM diff --git a/4coder_default_include.cpp b/4coder_default_include.cpp index 72efbe6c..a5f49440 100644 --- a/4coder_default_include.cpp +++ b/4coder_default_include.cpp @@ -4,19 +4,293 @@ #define FCPP_STRING_IMPLEMENTATION #include "4coder_string.h" -#define UseInterfacesThatArePhasingOut 0 #include "4coder_helper.h" #include -static void -write_string(Application_Links *app, String string){ - Buffer_Summary buffer = app->get_active_buffer(app); - app->buffer_replace_range(app, &buffer, buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, string.str, string.size); +inline float +get_view_y(View_Summary view){ + float y; + if (view.unwrapped_lines){ + y = view.cursor.unwrapped_y; + } + else{ + y = view.cursor.wrapped_y; + } + return(y); } -CUSTOM_COMMAND_SIG(write_increment){ - write_string(app, make_lit_string("++")); +inline float +get_view_x(View_Summary view){ + float x; + if (view.unwrapped_lines){ + x = view.cursor.unwrapped_x; + } + else{ + x = view.cursor.wrapped_x; + } + return(x); +} + +// +// Fundamental Editing +// + +CUSTOM_COMMAND_SIG(write_character){ + View_Summary view = app->get_active_view(app); + + User_Input in = app->get_command_input(app); + char character = 0; + + if (in.type == UserInputKey){ + character = in.key.character; + } + + if (character != 0){ + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + int pos = view.cursor.pos; + int next_pos = pos + 1; + app->buffer_replace_range(app, &buffer, + pos, pos, &character, 1); + app->view_set_cursor(app, &view, seek_pos(next_pos), true); + } +} + +CUSTOM_COMMAND_SIG(delete_char){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + int pos = view.cursor.pos; + if (0 < buffer.size && pos < buffer.size){ + app->buffer_replace_range(app, &buffer, + pos, pos+1, 0, 0); + } +} + +CUSTOM_COMMAND_SIG(backspace_char){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + int pos = view.cursor.pos; + if (0 < pos && pos <= buffer.size){ + app->buffer_replace_range(app, &buffer, + pos-1, pos, 0, 0); + + app->view_set_cursor(app, &view, seek_pos(pos-1), true); + } +} + +CUSTOM_COMMAND_SIG(set_mark){ + View_Summary view = app->get_active_view(app); + + app->view_set_mark(app, &view, seek_pos(view.cursor.pos)); +} + +CUSTOM_COMMAND_SIG(delete_range){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + + Range range = get_range(&view); + + app->buffer_replace_range(app, &buffer, + range.min, range.max, + 0, 0); +} + +// +// Basic Navigation +// + +inline void +move_vertical(Application_Links *app, float line_multiplier){ + View_Summary view = app->get_active_view(app); + + float new_y = get_view_y(view) + line_multiplier*view.line_height; + float x = view.preferred_x; + + app->view_set_cursor(app, &view, + seek_xy(x, new_y, false, view.unwrapped_lines), + false); +} + +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); +} + + +CUSTOM_COMMAND_SIG(move_left){ + View_Summary view = app->get_active_view(app); + int new_pos = view.cursor.pos - 1; + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); +} + +CUSTOM_COMMAND_SIG(move_right){ + View_Summary view = app->get_active_view(app); + int new_pos = view.cursor.pos + 1; + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); +} + +// +// Various Forms of Seek +// + +static int +buffer_seek_whitespace_up(Application_Links *app, Buffer_Summary *buffer, int pos){ + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + int no_hard; + int still_looping; + 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. + still_looping = true; + do{ + 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); + } while(still_looping); + 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' + 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 int +buffer_seek_whitespace_down(Application_Links *app, Buffer_Summary *buffer, int pos){ + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + int no_hard; + int prev_endline; + int 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){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id); + + int new_pos = buffer_seek_whitespace_up(app, &buffer, view.cursor.pos); + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); +} + +CUSTOM_COMMAND_SIG(seek_whitespace_down){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.locked_buffer_id); + + int new_pos = buffer_seek_whitespace_down(app, &buffer, view.cursor.pos); + app->view_set_cursor(app, &view, + seek_pos(new_pos), + true); } static void @@ -39,6 +313,23 @@ SEEK_COMMAND(alphanumeric, left, BoundryAlphanumeric) SEEK_COMMAND(alphanumeric_or_camel, right, BoundryAlphanumeric | BoundryCamelCase) SEEK_COMMAND(alphanumeric_or_camel, left, BoundryAlphanumeric | BoundryCamelCase) + +// +// Special string writing commands +// + +static void +write_string(Application_Links *app, String string){ + Buffer_Summary buffer = get_active_buffer(app); + app->buffer_replace_range(app, &buffer, + buffer.buffer_cursor_pos, buffer.buffer_cursor_pos, + string.str, string.size); +} + +CUSTOM_COMMAND_SIG(write_increment){ + write_string(app, make_lit_string("++")); +} + static void long_braces(Application_Links *app, char *text, int size){ View_Summary view; @@ -92,7 +383,7 @@ CUSTOM_COMMAND_SIG(if0_off){ int pos; view = app->get_active_view(app); - buffer = app->get_active_buffer(app); + buffer = app->get_buffer(app, view.buffer_id); range = get_range(&view); pos = range.min; @@ -161,8 +452,8 @@ CUSTOM_COMMAND_SIG(open_file_in_quotes){ view = app->get_active_view(app); buffer = app->get_buffer(app, view.buffer_id); pos = view.cursor.pos; - app->buffer_seek_delimiter(app, &buffer, pos, '"', 1, &end); - app->buffer_seek_delimiter(app, &buffer, pos, '"', 0, &start); + buffer_seek_delimiter_forward(app, &buffer, pos, '"', &end); + buffer_seek_delimiter_backward(app, &buffer, pos, '"', &start); ++start; size = end - start; @@ -213,39 +504,39 @@ isearch(Application_Links *app, int start_reversed){ Buffer_Summary buffer; User_Input in; Query_Bar bar; - + view = app->get_active_view(app); buffer = app->get_buffer(app, view.locked_buffer_id); if (!buffer.exists) return; if (app->start_query_bar(app, &bar, 0) == 0) return; - + Range match; int reverse = start_reversed; int pos; pos = view.cursor.pos; match = make_range(pos, pos); - + char bar_string_space[256]; bar.string = make_fixed_width_string(bar_string_space); - + String isearch = make_lit_string("I-Search: "); String rsearch = make_lit_string("Reverse-I-Search: "); - + while (1){ // NOTE(allen): Change the bar's prompt to match the current direction. if (reverse) bar.prompt = rsearch; else bar.prompt = isearch; - + in = app->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); - + int made_change = 0; if (in.key.keycode == '\n' || in.key.keycode == '\t'){ break; @@ -260,15 +551,15 @@ isearch(Application_Links *app, int start_reversed){ made_change = 1; } } - + int step_forward = 0; int step_backward = 0; - + if (CommandEqual(in.command, search) || - in.key.keycode == key_page_down || in.key.keycode == key_down) step_forward = 1; + in.key.keycode == key_page_down || in.key.keycode == key_down) step_forward = 1; if (CommandEqual(in.command, reverse_search) || - in.key.keycode == key_page_up || in.key.keycode == key_up) step_backward = 1; - + in.key.keycode == key_page_up || in.key.keycode == key_up) step_backward = 1; + int start_pos = pos; if (step_forward && reverse){ start_pos = match.start + 1; @@ -282,17 +573,18 @@ isearch(Application_Links *app, int start_reversed){ reverse = 1; step_backward = 0; } - + if (in.key.keycode != key_back){ int new_pos; if (reverse){ - // TODO(allen): Need a good way to allow users to implement seeks for themselves. - app->buffer_seek_string_insensitive(app, &buffer, start_pos - 1, bar.string.str, bar.string.size, 0, &new_pos); + buffer_seek_string_insensitive_backward(app, &buffer, start_pos - 1, + bar.string.str, bar.string.size, &new_pos); if (new_pos >= 0){ if (step_backward){ pos = new_pos; start_pos = new_pos; - app->buffer_seek_string_insensitive(app, &buffer, start_pos - 1, bar.string.str, bar.string.size, 0, &new_pos); + buffer_seek_string_insensitive_backward(app, &buffer, start_pos - 1, + bar.string.str, bar.string.size, &new_pos); if (new_pos < 0) new_pos = start_pos; } match.start = new_pos; @@ -300,12 +592,14 @@ isearch(Application_Links *app, int start_reversed){ } } else{ - app->buffer_seek_string_insensitive(app, &buffer, start_pos + 1, bar.string.str, bar.string.size, 1, &new_pos); + buffer_seek_string_insensitive_forward(app, &buffer, start_pos + 1, + bar.string.str, bar.string.size, &new_pos); if (new_pos < buffer.size){ if (step_forward){ pos = new_pos; start_pos = new_pos; - app->buffer_seek_string_insensitive(app, &buffer, start_pos + 1, bar.string.str, bar.string.size, 1, &new_pos); + buffer_seek_string_insensitive_forward(app, &buffer, start_pos + 1, + bar.string.str, bar.string.size, &new_pos); if (new_pos >= buffer.size) new_pos = start_pos; } match.start = new_pos; @@ -318,12 +612,12 @@ isearch(Application_Links *app, int start_reversed){ match.end = match.start + bar.string.size; } } - + app->view_set_highlight(app, &view, match.start, match.end, 1); } app->view_set_highlight(app, &view, 0, 0, 0); if (in.abort) return; - + app->view_set_cursor(app, &view, seek_pos(match.min), 1); } @@ -365,14 +659,14 @@ CUSTOM_COMMAND_SIG(replace_in_range){ int pos, new_pos; pos = range.min; - app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); + buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos); while (new_pos + r.size <= range.end){ app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size); app->refresh_view(app, &view); range = get_range(&view); pos = new_pos + w.size; - app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); + buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos); } } @@ -410,7 +704,7 @@ CUSTOM_COMMAND_SIG(query_replace){ buffer = app->get_buffer(app, view.buffer_id); pos = view.cursor.pos; - app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); + buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos); User_Input in = {0}; while (new_pos < buffer.size){ @@ -428,7 +722,7 @@ CUSTOM_COMMAND_SIG(query_replace){ pos = match.max; } - app->buffer_seek_string(app, &buffer, pos, r.str, r.size, 1, &new_pos); + buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos); } app->view_set_highlight(app, &view, 0, 0, 0); @@ -663,14 +957,14 @@ CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor){ } CUSTOM_COMMAND_SIG(auto_tab_whole_file){ - Buffer_Summary buffer = app->get_active_buffer(app); + Buffer_Summary buffer = get_active_buffer(app); push_parameter(app, par_range_start, 0); push_parameter(app, par_range_end, buffer.size); exec_command(app, cmdid_auto_tab_range); } CUSTOM_COMMAND_SIG(write_and_auto_tab){ - exec_command(app, cmdid_write_character); + exec_command(app, write_character); exec_command(app, auto_tab_line_at_cursor); } diff --git a/4coder_gui.h b/4coder_gui.h index 2771b490..28ddc8ef 100644 --- a/4coder_gui.h +++ b/4coder_gui.h @@ -17,7 +17,7 @@ struct GUI_Scroll_Vars{ float scroll_y; float target_y; float prev_target_y; - float min_y, max_y; + float max_y; float scroll_x; float target_x; diff --git a/4coder_helper.h b/4coder_helper.h index ce090629..54e7960a 100644 --- a/4coder_helper.h +++ b/4coder_helper.h @@ -386,3 +386,361 @@ query_user_number(Application_Links *app, Query_Bar *bar){ } inline String empty_string() {String Result = {}; return(Result);} + +inline Buffer_Summary +get_active_buffer(Application_Links *app){ + View_Summary view = app->get_active_view(app); + Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); + return(buffer); +} + + +struct Stream_Chunk{ + Application_Links *app; + Buffer_Summary *buffer; + + char *base_data; + int start, end; + int data_size; + + char *data; +}; + +int +round_down(int x, int b){ + int r = 0; + if (x >= 0){ + r = x - (x % b); + } + return(r); +} + +int +round_up(int x, int b){ + int r = 0; + if (x >= 0){ + r = x - (x % b) + b; + } + return(r); +} + +int +init_stream_chunk(Stream_Chunk *chunk, + Application_Links *app, Buffer_Summary *buffer, + int pos, char *data, int size){ + int result = 0; + + app->refresh_buffer(app, buffer); + if (pos >= 0 && pos < buffer->size && size > 0){ + result = 1; + 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->end > buffer->size){ + chunk->end = buffer->size; + } + app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); + chunk->data = chunk->base_data - chunk->start; + } + return(result); +} + +int +forward_stream_chunk(Stream_Chunk *chunk){ + Application_Links *app = chunk->app; + Buffer_Summary *buffer = chunk->buffer; + int result = 0; + + app->refresh_buffer(app, buffer); + if (chunk->end < buffer->size){ + result = 1; + chunk->start = chunk->end; + chunk->end += chunk->data_size; + if (chunk->end > buffer->size){ + chunk->end = buffer->size; + } + app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); + chunk->data = chunk->base_data - chunk->start; + } + return(result); +} + +int +backward_stream_chunk(Stream_Chunk *chunk){ + Application_Links *app = chunk->app; + Buffer_Summary *buffer = chunk->buffer; + int result = 0; + + app->refresh_buffer(app, buffer); + if (chunk->start > 0){ + result = 1; + chunk->end = chunk->start; + chunk->start -= chunk->data_size; + if (chunk->start < 0){ + chunk->start = 0; + } + app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); + chunk->data = chunk->base_data - chunk->start; + } + return(result); +} + +void +buffer_seek_delimiter_forward(Application_Links *app, Buffer_Summary *buffer, + int pos, char delim, int *result){ + if (buffer->exists){ + char chunk[1024]; + int size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){ + int 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:; +} + +void +buffer_seek_delimiter_backward(Application_Links *app, Buffer_Summary *buffer, + int pos, char delim, int *result){ + if (buffer->exists){ + char chunk[1024]; + int size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, size)){ + int 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. +void +buffer_seek_string_forward(Application_Links *app, Buffer_Summary *buffer, + int pos, char *str, int size, int *result){ + char read_buffer[512]; + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (size <= 0){ + *result = pos; + } + else if (size > sizeof(read_buffer)){ + *result = pos; + } + else{ + 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; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + int still_looping = 1; + do{ + for(; pos < stream.end; ++pos){ + char at_pos = stream.data[pos]; + if (at_pos == first_char){ + app->buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = forward_stream_chunk(&stream); + }while (still_looping); + } + } + + *result = buffer->size; + + 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. +void +buffer_seek_string_backward(Application_Links *app, Buffer_Summary *buffer, + int pos, char *str, int size, int *result){ + char read_buffer[512]; + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (size <= 0){ + *result = 0; + } + else if (size > sizeof(read_buffer)){ + *result = 0; + } + else{ + 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; + + if (init_stream_chunk(&stream, app, buffer, pos, chunk, chunk_size)){ + int still_looping = 1; + do{ + for(; pos >= stream.start; --pos){ + char at_pos = stream.data[pos]; + if (at_pos == first_char){ + app->buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = backward_stream_chunk(&stream); + }while (still_looping); + } + } + + *result = 0; + + 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. +void +buffer_seek_string_insensitive_forward(Application_Links *app, Buffer_Summary *buffer, + int pos, char *str, int size, int *result){ + char read_buffer[512]; + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (size <= 0){ + *result = pos; + } + else if (size > sizeof(read_buffer)){ + *result = pos; + } + else{ + 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)){ + int still_looping = 1; + do{ + for(; pos < stream.end; ++pos){ + char at_pos = char_to_upper(stream.data[pos]); + if (at_pos == first_char){ + app->buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match_insensitive(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = forward_stream_chunk(&stream); + }while (still_looping); + } + } + + *result = buffer->size; + + 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. +void +buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary *buffer, + int pos, char *str, int size, int *result){ + char read_buffer[512]; + char chunk[1024]; + int chunk_size = sizeof(chunk); + Stream_Chunk stream = {0}; + + if (size <= 0){ + *result = -1; + } + else if (size > sizeof(read_buffer)){ + *result = -1; + } + else{ + 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)){ + int still_looping = 1; + do{ + for(; pos >= stream.start; --pos){ + char at_pos = char_to_upper(stream.data[pos]); + if (at_pos == first_char){ + app->buffer_read_range(app, buffer, pos, pos+size, read_buffer); + if (match_insensitive(needle_str, read_str)){ + *result = pos; + goto finished; + } + } + } + still_looping = backward_stream_chunk(&stream); + }while (still_looping); + } + } + + *result = -1; + + finished:; + } +} + + diff --git a/4coder_string.h b/4coder_string.h index c1958cc0..c51c82bc 100644 --- a/4coder_string.h +++ b/4coder_string.h @@ -102,17 +102,17 @@ FSTRING_INLINE bool match_part(String a, char *b) { int x; return match_part FSTRING_LINK bool match_part(char *a, String b); FSTRING_LINK bool match_part(String a, String b); -FSTRING_LINK bool match_unsensitive(char *a, char *b); -FSTRING_LINK bool match_unsensitive(String a, char *b); -FSTRING_INLINE bool match_unsensitive(char *a, String b) { return match_unsensitive(b,a); } -FSTRING_LINK bool match_unsensitive(String a, String b); +FSTRING_LINK bool match_insensitive(char *a, char *b); +FSTRING_LINK bool match_insensitive(String a, char *b); +FSTRING_INLINE bool match_insensitive(char *a, String b) { return match_insensitive(b,a); } +FSTRING_LINK bool match_insensitive(String a, String b); -FSTRING_LINK bool match_part_unsensitive(char *a, char *b, int *len); -FSTRING_LINK bool match_part_unsensitive(String a, char *b, int *len); -FSTRING_INLINE bool match_part_unsensitive(char *a, char *b) { int x; return match_part(a,b,&x); } -FSTRING_INLINE bool match_part_unsensitive(String a, char *b) { int x; return match_part(a,b,&x); } -FSTRING_LINK bool match_part_unsensitive(char *a, String b); -FSTRING_LINK bool match_part_unsensitive(String a, String b); +FSTRING_LINK bool match_part_insensitive(char *a, char *b, int *len); +FSTRING_LINK bool match_part_insensitive(String a, char *b, int *len); +FSTRING_INLINE bool match_part_insensitive(char *a, char *b) { int x; return match_part(a,b,&x); } +FSTRING_INLINE bool match_part_insensitive(String a, char *b) { int x; return match_part(a,b,&x); } +FSTRING_LINK bool match_part_insensitive(char *a, String b); +FSTRING_LINK bool match_part_insensitive(String a, String b); FSTRING_LINK int find(char *s, int start, char c); FSTRING_LINK int find(String s, int start, char c); @@ -123,14 +123,14 @@ FSTRING_LINK int find_substr(char *s, int start, String seek); FSTRING_LINK int find_substr(String s, int start, String seek); FSTRING_LINK int rfind_substr(String s, int start, String seek); -FSTRING_LINK int find_substr_unsensitive(char *s, int start, String seek); -FSTRING_LINK int find_substr_unsensitive(String s, int start, String seek); +FSTRING_LINK int find_substr_insensitive(char *s, int start, String seek); +FSTRING_LINK int find_substr_insensitive(String s, int start, String seek); FSTRING_INLINE bool has_substr(char *s, String seek) { return (s[find_substr(s, 0, seek)] != 0); } FSTRING_INLINE bool has_substr(String s, String seek) { return (find_substr(s, 0, seek) < s.size); } -FSTRING_INLINE bool has_substr_unsensitive(char *s, String seek) { return (s[find_substr_unsensitive(s, 0, seek)] != 0); } -FSTRING_INLINE bool has_substr_unsensitive(String s, String seek) { return (find_substr_unsensitive(s, 0, seek) < s.size); } +FSTRING_INLINE bool has_substr_insensitive(char *s, String seek) { return (s[find_substr_insensitive(s, 0, seek)] != 0); } +FSTRING_INLINE bool has_substr_insensitive(String s, String seek) { return (find_substr_insensitive(s, 0, seek) < s.size); } FSTRING_LINK int int_to_str_size(int x); FSTRING_LINK int int_to_str(int x, char *s_out); @@ -391,7 +391,7 @@ match_part(String a, String b){ } FSTRING_LINK bool -match_unsensitive(char *a, char *b){ +match_insensitive(char *a, char *b){ for (int i = 0;; ++i){ if (char_to_upper(a[i]) != char_to_upper(b[i])){ @@ -404,7 +404,7 @@ match_unsensitive(char *a, char *b){ } FSTRING_LINK bool -match_unsensitive(String a, char *b){ +match_insensitive(String a, char *b){ int i = 0; for (; i < a.size; ++i){ if (char_to_upper(a.str[i]) != @@ -419,7 +419,7 @@ match_unsensitive(String a, char *b){ } FSTRING_LINK bool -match_unsensitive(String a, String b){ +match_insensitive(String a, String b){ if (a.size != b.size){ return 0; } @@ -433,7 +433,7 @@ match_unsensitive(String a, String b){ } FSTRING_LINK bool -match_part_unsensitive(char *a, char *b, int *len){ +match_part_insensitive(char *a, char *b, int *len){ int i; for (i = 0; b[i] != 0; ++i){ if (char_to_upper(a[i]) != char_to_upper(b[i])){ @@ -445,7 +445,7 @@ match_part_unsensitive(char *a, char *b, int *len){ } FSTRING_LINK bool -match_part_unsensitive(String a, char *b, int *len){ +match_part_insensitive(String a, char *b, int *len){ int i; for (i = 0; b[i] != 0; ++i){ if (char_to_upper(a.str[i]) != char_to_upper(b[i]) || @@ -458,7 +458,7 @@ match_part_unsensitive(String a, char *b, int *len){ } FSTRING_LINK bool -match_part_unsensitive(char *a, String b){ +match_part_insensitive(char *a, String b){ for (int i = 0; i != b.size; ++i){ if (char_to_upper(a[i]) != char_to_upper(b.str[i])){ return 0; @@ -468,7 +468,7 @@ match_part_unsensitive(char *a, String b){ } FSTRING_LINK bool -match_part_unsensitive(String a, String b){ +match_part_insensitive(String a, String b){ if (a.size < b.size){ return 0; } @@ -602,7 +602,7 @@ rfind_substr(String str, int start, String seek){ } FSTRING_LINK int -find_substr_unsensitive(char *str, int start, String seek){ +find_substr_insensitive(char *str, int start, String seek){ int i, j, k; bool hit; char a_upper, b_upper; @@ -630,7 +630,7 @@ find_substr_unsensitive(char *str, int start, String seek){ } FSTRING_LINK int -find_substr_unsensitive(String str, int start, String seek){ +find_substr_insensitive(String str, int start, String seek){ int i, j, k; int stop_at; bool hit; @@ -1217,8 +1217,8 @@ wildcard_match(Absolutes *absolutes, char *x, int case_sensitive){ match_part_func = match_part; } else{ - match_func = match_unsensitive; - match_part_func = match_part_unsensitive; + match_func = match_insensitive; + match_part_func = match_part_insensitive; } if (absolutes->count == 1){ diff --git a/4coder_version.h b/4coder_version.h index a73750ef..1baec73c 100644 --- a/4coder_version.h +++ b/4coder_version.h @@ -1,6 +1,6 @@ #define MAJOR 4 #define MINOR 0 -#define PATCH 6 +#define PATCH 7 #define VN__(a,b,c) #a"."#b"."#c #define VN_(a,b,c) VN__(a,b,c) diff --git a/4cpp_lexer.h b/4cpp_lexer.h index cfd3bf84..3f86a2ff 100644 --- a/4cpp_lexer.h +++ b/4cpp_lexer.h @@ -65,6 +65,19 @@ NOTES ON USE: #include "4cpp_lexer_types.h" +struct Cpp_Lex_Data{ + Cpp_Preprocessor_State pp_state; + int pos; + int complete; +}; + +struct Cpp_Read_Result{ + Cpp_Token token; + int pos; + char newline; + char has_result; +}; + Cpp_File data_as_cpp_file(Data data){ Cpp_File result; @@ -140,7 +153,6 @@ FCPP_LINK bool cpp_push_token_no_merge(Cpp_Token_Stack *stack, Cpp_Token token); FCPP_LINK bool cpp_push_token_nonalloc(Cpp_Token_Stack *stack, Cpp_Token token); inline Cpp_Lex_Data cpp_lex_data_zero() { Cpp_Lex_Data data = {(Cpp_Preprocessor_State)0}; return(data); } -inline Cpp_Token_Stack cpp_token_stack_zero() { Cpp_Token_Stack stack={0}; return(stack); } FCPP_LINK Cpp_Read_Result cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex); @@ -1266,10 +1278,10 @@ cpp_lex_step(Cpp_File file, Cpp_Lex_Data *lex_data){ } } } - + result.token.state_flags = state_flags; result.has_result = has_result; - + *lex_data = lex; return result; } diff --git a/4cpp_lexer_types.h b/4cpp_lexer_types.h index a33bd3c3..b25a6d1a 100644 --- a/4cpp_lexer_types.h +++ b/4cpp_lexer_types.h @@ -209,23 +209,15 @@ enum Cpp_Preprocessor_State{ CPP_LEX_PP_COUNT }; -struct Cpp_Lex_Data{ - Cpp_Preprocessor_State pp_state; - int pos; - int complete; -}; - -struct Cpp_Read_Result{ - Cpp_Token token; - int pos; - char newline; - char has_result; -}; - struct Cpp_Token_Stack{ Cpp_Token *tokens; int count, max_count; }; +inline Cpp_Token_Stack +cpp_token_stack_zero(){ + Cpp_Token_Stack stack={0}; + return(stack); +} struct Cpp_Token_Merge{ Cpp_Token new_token; diff --git a/4ed.cpp b/4ed.cpp index 931eb63b..f6d36dd2 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -33,9 +33,6 @@ struct CLI_List{ i32 count, max; }; -#define SysAppCreateView 0x1 -#define SysAppCreateNewBuffer 0x2 - struct Complete_State{ Search_Set set; Search_Iter iter; @@ -49,29 +46,28 @@ struct Command_Data{ Models *models; struct App_Vars *vars; System_Functions *system; - Exchange *exchange; Live_Views *live_set; - + Panel *panel; View *view; - + i32 screen_width, screen_height; Key_Event_Data key; - + Partition part; }; struct App_Vars{ Models models; - + CLI_List cli_processes; - + Live_Views live_set; - + App_State state; App_State_Resizing resizing; Complete_State complete_state; - + Command_Data command_data; }; @@ -105,10 +101,7 @@ app_launch_coroutine(System_Functions *system, Application_Links *app, Coroutine app->current_coroutine = co; app->type_coroutine = type; - { - result = system->launch_coroutine(co, in, out); - } - + result = system->launch_coroutine(co, in, out); restore_state(app, prev_state); return(result); @@ -123,10 +116,7 @@ app_resume_coroutine(System_Functions *system, Application_Links *app, Coroutine app->current_coroutine = co; app->type_coroutine = type; - { - result = system->resume_coroutine(co, in, out); - } - + result = system->resume_coroutine(co, in, out); restore_state(app, prev_state); return(result); @@ -145,7 +135,7 @@ output_file_append(System_Functions *system, Models *models, Editing_File *file, inline void do_feedback_message(System_Functions *system, Models *models, String value){ Editing_File *file = models->message_buffer; - + if (file){ output_file_append(system, models, file, value, 1); i32 pos = buffer_size(&file->state.buffer); @@ -159,15 +149,11 @@ do_feedback_message(System_Functions *system, Models *models, String value){ // Commands -// TODO(allen): MOVE THIS TO models -//globalvar Application_Links app_links; - #define USE_MODELS(n) Models *n = command->models #define USE_VARS(n) App_Vars *n = command->vars #define USE_PANEL(n) Panel *n = command->panel #define USE_VIEW(n) View *n = command->view #define USE_FILE(n,v) Editing_File *n = (v)->file_data.file -#define USE_EXCHANGE(n) Exchange *n = command->exchange #define REQ_OPEN_VIEW(n) View *n = command->panel->view; if (view_lock_level(n) > LockLevel_Open) return #define REQ_READABLE_VIEW(n) View *n = command->panel->view; if (view_lock_level(n) > LockLevel_NoWrite) return @@ -219,15 +205,15 @@ param_stack_end(Partition *part){ } internal View* -panel_make_empty(System_Functions *system, Exchange *exchange, App_Vars *vars, Panel *panel){ +panel_make_empty(System_Functions *system, App_Vars *vars, Panel *panel){ Models *models = &vars->models; View_And_ID new_view; - + Assert(panel->view == 0); new_view = live_set_alloc_view(&vars->live_set, panel, models); view_set_file(new_view.view, 0, models); new_view.view->map = get_map(models, mapid_global); - + return(new_view.view); } @@ -235,36 +221,18 @@ COMMAND_DECL(null){ AllowLocal(command); } -COMMAND_DECL(write_character){ - - USE_MODELS(models); - REQ_OPEN_VIEW(view); - REQ_FILE(file, view); - - char character; - i32 pos, next_cursor_pos; - - character = command->key.character; - if (character != 0){ - pos = view->recent->cursor.pos; - next_cursor_pos = view->recent->cursor.pos + 1; - view_replace_range(system, models, view, pos, pos, &character, 1, next_cursor_pos); - view_cursor_move(view, next_cursor_pos); - } -} - internal i32 seek_token_left(Cpp_Token_Stack *tokens, i32 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; } @@ -277,18 +245,17 @@ seek_token_right(Cpp_Token_Stack *tokens, i32 pos){ 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; } COMMAND_DECL(seek_left){ - REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + u32 flags = BoundryWhitespace; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -299,13 +266,13 @@ COMMAND_DECL(seek_left){ break; } } - + i32 pos[4] = {0}; - + if (flags & (1)){ pos[0] = buffer_seek_whitespace_left(&file->state.buffer, view->recent->cursor.pos); } - + if (flags & (1 << 1)){ if (file->state.tokens_complete){ pos[1] = seek_token_left(&file->state.token_stack, view->recent->cursor.pos); @@ -314,7 +281,7 @@ COMMAND_DECL(seek_left){ pos[1] = buffer_seek_whitespace_left(&file->state.buffer, view->recent->cursor.pos); } } - + if (flags & (1 << 2)){ pos[2] = buffer_seek_alphanumeric_left(&file->state.buffer, view->recent->cursor.pos); if (flags & (1 << 3)){ @@ -326,22 +293,21 @@ COMMAND_DECL(seek_left){ pos[3] = buffer_seek_alphanumeric_or_camel_left(&file->state.buffer, view->recent->cursor.pos); } } - + i32 new_pos = 0; for (i32 i = 0; i < ArrayCount(pos); ++i){ if (pos[i] > new_pos) new_pos = pos[i]; } - + view_cursor_move(view, new_pos); } COMMAND_DECL(seek_right){ - REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + u32 flags = BoundryWhitespace; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -352,15 +318,15 @@ COMMAND_DECL(seek_right){ break; } } - + i32 size = buffer_size(&file->state.buffer); i32 pos[4]; for (i32 i = 0; i < ArrayCount(pos); ++i) pos[i] = size; - + if (flags & (1)){ pos[0] = buffer_seek_whitespace_right(&file->state.buffer, view->recent->cursor.pos); } - + if (flags & (1 << 1)){ if (file->state.tokens_complete){ pos[1] = seek_token_right(&file->state.token_stack, view->recent->cursor.pos); @@ -369,7 +335,7 @@ COMMAND_DECL(seek_right){ pos[1] = buffer_seek_whitespace_right(&file->state.buffer, view->recent->cursor.pos); } } - + if (flags & (1 << 2)){ pos[2] = buffer_seek_alphanumeric_right(&file->state.buffer, view->recent->cursor.pos); if (flags & (1 << 3)){ @@ -381,38 +347,19 @@ COMMAND_DECL(seek_right){ pos[3] = buffer_seek_alphanumeric_or_camel_right(&file->state.buffer, view->recent->cursor.pos); } } - + i32 new_pos = size; for (i32 i = 0; i < ArrayCount(pos); ++i){ if (pos[i] < new_pos) new_pos = pos[i]; } - + view_cursor_move(view, new_pos); } -COMMAND_DECL(seek_whitespace_up){ - - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - i32 pos = buffer_seek_whitespace_up(&file->state.buffer, view->recent->cursor.pos); - view_cursor_move(view, pos); -} - -COMMAND_DECL(seek_whitespace_down){ - - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - i32 pos = buffer_seek_whitespace_down(&file->state.buffer, view->recent->cursor.pos); - view_cursor_move(view, pos); -} - COMMAND_DECL(center_view){ - - USE_VIEW(view); + REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + f32 y, h; if (view->file_data.unwrapped_lines){ y = view->recent->cursor.unwrapped_y; @@ -420,66 +367,64 @@ COMMAND_DECL(center_view){ else{ y = view->recent->cursor.wrapped_y; } - + h = view_file_height(view); - y -= h * .5f; - if (y < view->recent->scroll.min_y) y = view->recent->scroll.min_y; - + y = clamp_bottom(0.f, y - h*.5f); + view->recent->scroll.target_y = y; } COMMAND_DECL(word_complete){ - USE_MODELS(models); USE_VARS(vars); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + Partition *part = &models->mem.part; General_Memory *general = &models->mem.general; Working_Set *working_set = &models->working_set; Complete_State *complete_state = &vars->complete_state; Search_Range *ranges; Search_Match match; - + Temp_Memory temp; - + Buffer_Type *buffer; Buffer_Backify_Type loop; char *data; i32 end; i32 size_of_buffer; - + i32 cursor_pos, word_start, word_end; char c; - + char *spare; i32 size; - + i32 match_size; b32 do_init = 0; - + buffer = &file->state.buffer; size_of_buffer = buffer_size(buffer); - + if (view->mode.rewrite != 2){ do_init = 1; } view->next_mode.rewrite = 2; - + if (complete_state->initialized == 0){ do_init = 1; } - + if (do_init){ word_end = view->recent->cursor.pos; word_start = word_end; cursor_pos = word_end - 1; - + // TODO(allen): macros for these buffer loops and some method of breaking out of them. for (loop = buffer_backify_loop(buffer, cursor_pos, 0); - buffer_backify_good(&loop); - buffer_backify_next(&loop)){ + buffer_backify_good(&loop); + buffer_backify_next(&loop)){ end = loop.absolute_pos; data = loop.data - loop.absolute_pos; for (; cursor_pos >= end; --cursor_pos){ @@ -493,35 +438,35 @@ COMMAND_DECL(word_complete){ } } double_break:; - + size = word_end - word_start; - + if (size == 0){ complete_state->initialized = 0; return; } - + complete_state->initialized = 1; search_iter_init(general, &complete_state->iter, size); buffer_stringify(buffer, word_start, word_end, complete_state->iter.word.str); complete_state->iter.word.size = size; - + { File_Node *node, *used_nodes; Editing_File *file_ptr; i32 buffer_count, j; - + buffer_count = working_set->file_count; search_set_init(general, &complete_state->set, buffer_count + 1); ranges = complete_state->set.ranges; ranges[0].buffer = buffer; ranges[0].start = 0; ranges[0].size = word_start; - + ranges[1].buffer = buffer; ranges[1].start = word_end; ranges[1].size = size_of_buffer - word_end; - + used_nodes = &working_set->used_sentinel; j = 2; for (dll_items(node, used_nodes)){ @@ -535,11 +480,11 @@ COMMAND_DECL(word_complete){ } complete_state->set.count = j; } - + search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4)); search_hit_add(general, &complete_state->hits, &complete_state->str, - complete_state->iter.word.str, complete_state->iter.word.size); - + complete_state->iter.word.str, complete_state->iter.word.size); + complete_state->word_start = word_start; complete_state->word_end = word_end; } @@ -548,20 +493,20 @@ COMMAND_DECL(word_complete){ word_end = complete_state->word_end; size = complete_state->iter.word.size; } - + if (size > 0){ for (;;){ match = search_next_match(part, &complete_state->set, &complete_state->iter); - + if (match.found_match){ temp = begin_temp_memory(part); match_size = match.end - match.start; spare = (char*)push_array(part, char, match_size); buffer_stringify(match.buffer, match.start, match.end, spare); - + if (search_hit_add(general, &complete_state->hits, &complete_state->str, spare, match_size)){ view_replace_range(system, models, view, word_start, word_end, spare, match_size, word_end); - + complete_state->word_end = word_start + match_size; complete_state->set.ranges[1].start = word_start + match_size; break; @@ -571,15 +516,15 @@ COMMAND_DECL(word_complete){ else{ complete_state->iter.pos = 0; complete_state->iter.i = 0; - + search_hits_init(general, &complete_state->hits, &complete_state->str, 100, Kbytes(4)); search_hit_add(general, &complete_state->hits, &complete_state->str, - complete_state->iter.word.str, complete_state->iter.word.size); - + complete_state->iter.word.str, complete_state->iter.word.size); + match_size = complete_state->iter.word.size; view_replace_range(system, models, view, word_start, word_end, - complete_state->iter.word.str, match_size, word_end); - + complete_state->iter.word.str, match_size, word_end); + complete_state->word_end = word_start + match_size; complete_state->set.ranges[1].start = word_start + match_size; break; @@ -588,22 +533,15 @@ COMMAND_DECL(word_complete){ } } -COMMAND_DECL(set_mark){ - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - view->recent->mark = (i32)view->recent->cursor.pos; -} - COMMAND_DECL(copy){ USE_MODELS(models); REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + // TODO(allen): deduplicate int r_start = 0, r_end = 0; int start_set = 0, end_set = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -613,14 +551,14 @@ COMMAND_DECL(copy){ start_set = 1; r_start = dynamic_to_int(¶m->param.value); break; - + case par_range_end: end_set = 1; r_end = dynamic_to_int(¶m->param.value); break; } } - + Range range = make_range(view->recent->cursor.pos, view->recent->mark); if (start_set) range.start = r_start; if (end_set) range.end = r_end; @@ -633,11 +571,11 @@ COMMAND_DECL(cut){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + // TODO(allen): deduplicate int r_start = 0, r_end = 0; int start_set = 0, end_set = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -647,23 +585,23 @@ COMMAND_DECL(cut){ start_set = 1; r_start = dynamic_to_int(¶m->param.value); break; - + case par_range_end: end_set = 1; r_end = dynamic_to_int(¶m->param.value); break; } } - + Range range = make_range(view->recent->cursor.pos, view->recent->mark); if (start_set) range.start = r_start; if (end_set) range.end = r_end; if (range.start < range.end){ i32 next_cursor_pos = range.start; - + clipboard_copy(system, &models->mem.general, &models->working_set, range, file); view_replace_range(system, models, view, range.start, range.end, 0, 0, next_cursor_pos); - + view->recent->mark = range.start; view_cursor_move(view, next_cursor_pos); } @@ -674,28 +612,28 @@ COMMAND_DECL(paste){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + View_Iter iter; String *src; i32 pos_left, next_cursor_pos; - + if (models->working_set.clipboard_size > 0){ view->next_mode.rewrite = 1; - + src = working_set_clipboard_head(&models->working_set); pos_left = view->recent->cursor.pos; - + next_cursor_pos = pos_left+src->size; view_replace_range(system, models, view, pos_left, pos_left, src->str, src->size, next_cursor_pos); - + view_cursor_move(view, next_cursor_pos); view->recent->mark = pos_left; - + Style *style = main_style(models); u32 paste_color = style->main.paste_color; for (iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ view_post_paste_effect(iter.view, 20, pos_left, src->size, paste_color); } } @@ -705,30 +643,30 @@ COMMAND_DECL(paste_next){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + View_Iter iter; Range range; String *src; i32 next_cursor_pos; - + if (models->working_set.clipboard_size > 0 && view->mode.rewrite == 1){ view->next_mode.rewrite = 1; - + range = make_range(view->recent->mark, view->recent->cursor.pos); src = working_set_clipboard_roll_down(&models->working_set); next_cursor_pos = range.start+src->size; view_replace_range(system, - models, view, range.start, range.end, - src->str, src->size, next_cursor_pos); - + models, view, range.start, range.end, + src->str, src->size, next_cursor_pos); + view_cursor_move(view, next_cursor_pos); view->recent->mark = range.start; - + Style *style = main_style(models); u32 paste_color = style->main.paste_color; for (iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ view_post_paste_effect(iter.view, 20, range.start, src->size, paste_color); } } @@ -737,40 +675,21 @@ COMMAND_DECL(paste_next){ } } -COMMAND_DECL(delete_range){ - USE_MODELS(models); - REQ_OPEN_VIEW(view); - REQ_FILE(file, view); - - Range range; - i32 next_cursor_pos; - - range = make_range(view->recent->cursor.pos, view->recent->mark); - if (range.start < range.end){ - next_cursor_pos = range.start; - Assert(range.end <= buffer_size(&file->state.buffer)); - view_replace_range(system, models, view, range.start, range.end, 0, 0, next_cursor_pos); - view_cursor_move(view, next_cursor_pos); - view->recent->mark = range.start; - } -} - COMMAND_DECL(undo){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE_HISTORY(file, view); - + view_undo(system, models, view); Assert(file->state.undo.undo.size >= 0); - } COMMAND_DECL(redo){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE_HISTORY(file, view); - + view_redo(system, models, view); Assert(file->state.undo.undo.size >= 0); @@ -780,7 +699,7 @@ COMMAND_DECL(history_backward){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE_HISTORY(file, view); - + view_history_step(system, models, view, hist_backward); } @@ -788,36 +707,32 @@ 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_MODELS(models); USE_VIEW(view); - + view_show_interactive(system, view, &models->map_ui, - IAct_New, IInt_Sys_File_List, make_lit_string("New: ")); + IAct_New, IInt_Sys_File_List, make_lit_string("New: ")); } COMMAND_DECL(interactive_open){ - USE_MODELS(models); - USE_PANEL(panel); USE_VIEW(view); - - Delay *delay = &models->delay1; - + char *filename = 0; int filename_len = 0; int do_in_background = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ if (param->param.param.type == dynamic_type_int){ if (param->param.param.int_value == par_name && - param->param.value.type == dynamic_type_string){ + param->param.value.type == dynamic_type_string){ filename = param->param.value.str_value; filename_len = param->param.value.str_len; } @@ -826,73 +741,19 @@ COMMAND_DECL(interactive_open){ } } } - + if (filename){ String string = make_string(filename, filename_len); if (do_in_background){ - delayed_open_background(delay, string); + view_open_file(system, models, 0, string); } else{ - // TODO(allen): Change the behavior of all delayed_open/background - // calls so that they still allocate the buffer right away. This way - // it's still possible to get at the buffer if so wished in the API. - // The switch for this view doesn't need to happen until the file is ready. - // - // Alternatively... fuck all delayed actions. Please make them go away. - delayed_open(delay, string, panel); + view_open_file(system, models, view, string); } } else{ view_show_interactive(system, view, &models->map_ui, - IAct_Open, IInt_Sys_File_List, make_lit_string("Open: ")); - } -} - -internal void -view_file_in_panel(Command_Data *cmd, Panel *panel, Editing_File *file){ - Models *models = cmd->models; - - Partition old_part; - Temp_Memory temp; - View *old_view; - Partition *part; - - old_view = cmd->view; - old_part = cmd->part; - - cmd->view = panel->view; - part = &models->mem.part; - temp = begin_temp_memory(part); - cmd->part = partition_sub_part(part, Kbytes(16)); - - View *view = panel->view; - view_set_file(view, file, models); - view_show_file(view); - - cmd->part = old_part; - end_temp_memory(temp); - cmd->view = old_view; - - panel->view->map = get_map(models, file->settings.base_map_id); -} - -internal void -init_normal_file(System_Functions *system, Models *models, Editing_File *file, - char *buffer, i32 size){ - - General_Memory *general = &models->mem.general; - - String val = make_string(buffer, size); - file_create_from_string(system, models, file, file->name.source_path.str, val); - - if (file->settings.tokens_exist){ - file_first_lex_parallel(system, general, file); - } - - for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ - view_measure_wraps(general, iter.view); + IAct_Open, IInt_Sys_File_List, make_lit_string("Open: ")); } } @@ -930,14 +791,12 @@ COMMAND_DECL(save){ USE_MODELS(models); USE_VIEW(view); USE_FILE(file, view); - - Delay *delay = &models->delay1; char *filename = 0; int filename_len = 0; int buffer_id = -1; int update_names = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -950,34 +809,34 @@ COMMAND_DECL(save){ buffer_id = dynamic_to_int(¶m->param.value); } else if (v == par_save_update_name){ - update_names = dynamic_to_bool(¶m->param.value); - } + update_names = dynamic_to_bool(¶m->param.value); + } } - + if (buffer_id != -1){ file = working_set_get_active_file(&models->working_set, buffer_id); - } + } if (update_names){ String name = {}; if (filename){ name = make_string(filename, filename_len); } - + if (file){ if (name.str){ - if (!file->state.is_dummy && file_is_ready(file)){ - delayed_save_as(delay, name, file); + if (!file->is_dummy && file_is_ready(file)){ + view_save_file(system, models, file, 0, name, 1); } } else{ view_show_interactive(system, view, &models->map_ui, - IAct_Save_As, IInt_Sys_File_List, make_lit_string("Save As: ")); + IAct_Save_As, IInt_Sys_File_List, make_lit_string("Save As: ")); } } } else{ - String name = {}; + String name = {0}; if (filename){ name = make_string(filename, filename_len); } @@ -987,12 +846,12 @@ COMMAND_DECL(save){ if (name.size != 0){ if (file){ - if (!file->state.is_dummy && file_is_ready(file)){ - delayed_save(delay, name, file); + if (!file->is_dummy && file_is_ready(file)){ + view_save_file(system, models, file, 0, name, 0); } } else{ - delayed_save(delay, name); + view_save_file(system, models, 0, 0, name, 0); } } } @@ -1002,7 +861,7 @@ COMMAND_DECL(change_active_panel){ USE_MODELS(models); USE_PANEL(panel); - + panel = panel->next; if (panel == &models->layout.used_sentinel){ panel = panel->next; @@ -1014,29 +873,27 @@ COMMAND_DECL(interactive_switch_buffer){ USE_VIEW(view); USE_MODELS(models); - + view_show_interactive(system, view, &models->map_ui, - IAct_Switch, IInt_Live_File_List, make_lit_string("Switch Buffer: ")); + IAct_Switch, IInt_Live_File_List, make_lit_string("Switch Buffer: ")); } COMMAND_DECL(interactive_kill_buffer){ USE_VIEW(view); USE_MODELS(models); - + view_show_interactive(system, view, &models->map_ui, - IAct_Kill, IInt_Live_File_List, make_lit_string("Kill Buffer: ")); + IAct_Kill, IInt_Live_File_List, make_lit_string("Kill Buffer: ")); } COMMAND_DECL(kill_buffer){ - USE_MODELS(models); USE_VIEW(view); USE_FILE(file, view); - - Delay *delay = &models->delay1; + int buffer_id = 0; - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -1045,29 +902,30 @@ COMMAND_DECL(kill_buffer){ buffer_id = dynamic_to_int(¶m->param.value); } } - + if (buffer_id != 0){ file = working_set_get_active_file(&models->working_set, buffer_id); if (file){ - delayed_kill(delay, file); + kill_file(system, models, file, string_zero()); } } else if (file){ - delayed_try_kill(delay, file, view->panel); + try_kill_file(system, models, + file, view, string_zero()); } } COMMAND_DECL(toggle_line_wrap){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + Relative_Scrolling scrolling = view_get_relative_scrolling(view); if (view->file_data.unwrapped_lines){ view->file_data.unwrapped_lines = 0; file->settings.unwrapped_lines = 0; view->recent->scroll.target_x = 0; - view->recent->cursor =view_compute_cursor_from_pos( - view, view->recent->cursor.pos); + view->recent->cursor = view_compute_cursor_from_pos( + view, view->recent->cursor.pos); view->recent->preferred_x = view->recent->cursor.wrapped_x; } else{ @@ -1090,7 +948,7 @@ COMMAND_DECL(toggle_tokens){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + if (file->settings.tokens_exist){ file_kill_tokens(system, &models->mem.general, file); } @@ -1102,8 +960,8 @@ 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){ + Mem_Options *mem, View *view, Editing_File *file, + u8 a, u8 z, u8 char_delta){ #if BUFFER_EXPERIMENT_SCALPEL <= 0 Range range = make_range(view->recent->cursor.pos, view->recent->mark); if (range.start < range.end){ @@ -1112,19 +970,19 @@ case_change_range(System_Functions *system, step.edit.start = range.start; step.edit.end = range.end; step.edit.len = range.end - range.start; - + if (file->state.still_lexing) system->cancel_job(BACKGROUND_THREADS, file->state.lex_job); - + file_update_history_before_edit(mem, file, step, 0, hist_normal); - + u8 *data = (u8*)file->state.buffer.data; for (i32 i = range.start; i < range.end; ++i){ if (data[i] >= a && data[i] <= z){ data[i] += char_delta; } } - + if (file->state.token_stack.tokens) file_relex_parallel(system, mem, file, range.start, range.end, 0); } @@ -1148,44 +1006,41 @@ COMMAND_DECL(to_lowercase){ } COMMAND_DECL(clean_all_lines){ - USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + view_clean_whitespace(system, models, view); } COMMAND_DECL(eol_dosify){ - REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + file->settings.dos_write_mode = 1; - file->state.last_4ed_edit_time = system->time(); + file->state.last_4ed_edit_time = system->now_time_stamp(); } COMMAND_DECL(eol_nixify){ - REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + file->settings.dos_write_mode = 0; - file->state.last_4ed_edit_time = system->time(); + file->state.last_4ed_edit_time = system->now_time_stamp(); } COMMAND_DECL(auto_tab_range){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + int r_start = 0, r_end = 0; int start_set = 0, end_set = 0; Indent_Options opts; opts.empty_blank_lines = 0; opts.use_tabs = 0; opts.tab_width = 4; - + // TODO(allen): deduplicate Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); @@ -1196,12 +1051,12 @@ COMMAND_DECL(auto_tab_range){ start_set = 1; r_start = dynamic_to_int(¶m->param.value); break; - + case par_range_end: end_set = 1; r_end = dynamic_to_int(¶m->param.value); break; - + case par_clear_blank_lines: opts.empty_blank_lines = dynamic_to_bool(¶m->param.value); break; @@ -1211,7 +1066,7 @@ COMMAND_DECL(auto_tab_range){ break; } } - + if (file->state.token_stack.tokens && file->state.tokens_complete && !file->state.still_lexing){ Range range = make_range(view->recent->cursor.pos, view->recent->mark); if (start_set) range.start = r_start; @@ -1224,87 +1079,82 @@ COMMAND_DECL(open_panel_vsplit){ USE_VARS(vars); USE_MODELS(models); USE_PANEL(panel); - USE_EXCHANGE(exchange); - + 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; - + panel2->full.x0 = split.divider->pos; panel2->full.x1 = panel1->full.x1; panel1->full.x1 = split.divider->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, exchange, vars, panel2); + panel_make_empty(system, vars, panel2); } } COMMAND_DECL(open_panel_hsplit){ - USE_VARS(vars); USE_MODELS(models); USE_PANEL(panel); - USE_EXCHANGE(exchange); - + 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; - + panel2->full.y0 = split.divider->pos; panel2->full.y1 = panel1->full.y1; panel1->full.y1 = split.divider->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, exchange, vars, panel2); + panel_make_empty(system, vars, panel2); } } COMMAND_DECL(close_panel){ - USE_MODELS(models); USE_PANEL(panel); USE_VIEW(view); - USE_EXCHANGE(exchange); - + 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(system, exchange, command->live_set, view); + live_set_free_view(system, 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); @@ -1319,14 +1169,14 @@ COMMAND_DECL(close_panel){ 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){ @@ -1346,21 +1196,22 @@ COMMAND_DECL(close_panel){ 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); } } +#if 0 COMMAND_DECL(move_left){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + i32 pos = view->recent->cursor.pos; if (pos > 0) --pos; view_cursor_move(view, pos); @@ -1369,7 +1220,7 @@ COMMAND_DECL(move_left){ COMMAND_DECL(move_right){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + i32 size = buffer_size(&file->state.buffer); i32 pos = view->recent->cursor.pos; if (pos < size) ++pos; @@ -1380,18 +1231,17 @@ COMMAND_DECL(delete){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + i32 size = buffer_size(&file->state.buffer); i32 cursor_pos = view->recent->cursor.pos; if (0 < size && cursor_pos < size){ i32 start, end; start = cursor_pos; end = cursor_pos+1; - - Assert(end - start > 0); - + i32 next_cursor_pos = start; - view_replace_range(system, models, view, start, end, 0, 0, next_cursor_pos); + view_replace_range(system, models, view, + start, end, 0, 0, next_cursor_pos); view_cursor_move(view, next_cursor_pos); } } @@ -1400,54 +1250,25 @@ COMMAND_DECL(backspace){ USE_MODELS(models); REQ_OPEN_VIEW(view); REQ_FILE(file, view); - + i32 size = buffer_size(&file->state.buffer); i32 cursor_pos = view->recent->cursor.pos; if (cursor_pos > 0 && cursor_pos <= size){ i32 start, end; end = cursor_pos; start = cursor_pos-1; - - i32 shift = (end - start); - Assert(shift > 0); - - i32 next_cursor_pos = view->recent->cursor.pos - shift; + + i32 next_cursor_pos = view->recent->cursor.pos - 1; view_replace_range(system, models, view, start, end, 0, 0, next_cursor_pos); view_cursor_move(view, next_cursor_pos); } } - -COMMAND_DECL(move_up){ - USE_MODELS(models); - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - f32 font_height = (f32)get_font_info(models->font_set, models->global_font.font_id)->height; - f32 cy = view_get_cursor_y(view)-font_height; - f32 px = view->recent->preferred_x; - if (cy >= 0){ - view->recent->cursor = view_compute_cursor_from_xy(view, px, cy); - file->state.cursor_pos = view->recent->cursor.pos; - } -} - -COMMAND_DECL(move_down){ - - USE_MODELS(models); - REQ_READABLE_VIEW(view); - REQ_FILE(file, view); - - f32 font_height = (f32)get_font_info(models->font_set, models->global_font.font_id)->height; - f32 cy = view_get_cursor_y(view)+font_height; - f32 px = view->recent->preferred_x; - view->recent->cursor = view_compute_cursor_from_xy(view, px, cy); - file->state.cursor_pos = view->recent->cursor.pos; -} +#endif COMMAND_DECL(seek_end_of_line){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + i32 pos = view_find_end_of_line(view, view->recent->cursor.pos); view_cursor_move(view, pos); } @@ -1455,55 +1276,54 @@ COMMAND_DECL(seek_end_of_line){ COMMAND_DECL(seek_beginning_of_line){ REQ_READABLE_VIEW(view); REQ_FILE(file, view); - + i32 pos = view_find_beginning_of_line(view, view->recent->cursor.pos); view_cursor_move(view, pos); } COMMAND_DECL(page_down){ REQ_READABLE_VIEW(view); - + f32 height = view_file_height(view); f32 max_target_y = view->recent->scroll.max_y; - - view->recent->scroll.target_y += height; - if (view->recent->scroll.target_y > max_target_y) view->recent->scroll.target_y = max_target_y; - - view->recent->cursor = view_compute_cursor_from_xy( - view, 0, view->recent->scroll.target_y + (height - view->font_height)*.5f); + + view->recent->scroll.target_y = + clamp_top(view->recent->scroll.target_y + height, max_target_y); + + view->recent->cursor = + view_compute_cursor_from_xy(view, 0, view->recent->scroll.target_y + (height - view->line_height)*.5f); } COMMAND_DECL(page_up){ REQ_READABLE_VIEW(view); - + f32 height = view_file_height(view); - f32 min_target_y = view->recent->scroll.min_y; - - view->recent->scroll.target_y -= height; - if (view->recent->scroll.target_y < min_target_y) view->recent->scroll.target_y = min_target_y; - - view->recent->cursor = view_compute_cursor_from_xy( - view, 0, view->recent->scroll.target_y + (height - view->font_height)*.5f); + + view->recent->scroll.target_y = + clamp_bottom(0.f, view->recent->scroll.target_y - height); + + view->recent->cursor = + view_compute_cursor_from_xy(view, 0, view->recent->scroll.target_y + (height - view->line_height)*.5f); } COMMAND_DECL(open_color_tweaker){ USE_VIEW(view); USE_MODELS(models); - + view_show_theme(view, &models->map_ui); } COMMAND_DECL(open_config){ USE_VIEW(view); USE_MODELS(models); - + view_show_config(view, &models->map_ui); } COMMAND_DECL(open_menu){ USE_VIEW(view); USE_MODELS(models); - + view_show_menu(view, &models->map_ui); } @@ -1514,7 +1334,7 @@ COMMAND_DECL(close_minor_view){ COMMAND_DECL(cursor_mark_swap){ REQ_READABLE_VIEW(view); - + i32 pos = view->recent->cursor.pos; view_cursor_move(view, view->recent->mark); view->recent->mark = pos; @@ -1541,6 +1361,8 @@ COMMAND_DECL(set_settings){ Editing_File *file = 0; b32 set_mapid = 0; i32 new_mapid = 0; + b32 set_show_whitespace = 0; + b32 show_whitespace = 0; Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); @@ -1575,7 +1397,7 @@ COMMAND_DECL(set_settings){ file->settings.unwrapped_lines = !v; } }break; - + case par_key_mapid: { if (file){ @@ -1590,31 +1412,35 @@ COMMAND_DECL(set_settings){ } } }break; + + case par_show_whitespace: + { + set_show_whitespace = 1; + show_whitespace = dynamic_to_bool(¶m->param.value); + }break; } } if (set_mapid){ for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ iter.view->map = get_map(models, file->settings.base_map_id); } } } COMMAND_DECL(command_line){ - USE_VARS(vars); USE_MODELS(models); - USE_PANEL(panel); USE_VIEW(view); - + Partition *part = &models->mem.part; - + char *buffer_name = 0; char *path = 0; char *script = 0; - + i32 buffer_id = 0; i32 buffer_name_len = 0; i32 path_len = 0; @@ -1624,7 +1450,7 @@ COMMAND_DECL(command_line){ char feedback_space[256]; String feedback_str = make_fixed_width_string(feedback_space); - + Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); for (; param < end; param = param_next(param, end)){ @@ -1637,17 +1463,17 @@ COMMAND_DECL(command_line){ buffer_name = new_buffer_name; } }break; - + case par_buffer_id: { buffer_id = dynamic_to_int(¶m->param.value); }break; - + case par_do_in_background: { do_in_background = 1; }break; - + case par_cli_path: { char *new_cli_path = dynamic_to_string(¶m->param.value, &path_len); @@ -1655,7 +1481,7 @@ COMMAND_DECL(command_line){ path = new_cli_path; } }break; - + case par_cli_command: { char *new_command = dynamic_to_string(¶m->param.value, &script_len); @@ -1663,21 +1489,21 @@ COMMAND_DECL(command_line){ script = new_command; } }break; - + case par_flags: { flags = (u32)dynamic_to_int(¶m->param.value); }break; } } - + { Working_Set *working_set = &models->working_set; CLI_Process *procs = vars->cli_processes.procs, *proc = 0; Editing_File *file = 0; b32 bind_to_new_view = !do_in_background; General_Memory *general = &models->mem.general; - + if (vars->cli_processes.count < vars->cli_processes.max){ if (buffer_id){ file = working_set_get_active_file(working_set, buffer_id); @@ -1725,12 +1551,12 @@ COMMAND_DECL(command_line){ working_set_add(system, working_set, file, general); } } - + if (file){ i32 proc_count = vars->cli_processes.count; View_Iter iter; i32 i; - + for (i = 0; i < proc_count; ++i){ if (procs[i].out_file == file){ if (flags & CLI_OverlapWithConflict) @@ -1740,11 +1566,11 @@ COMMAND_DECL(command_line){ break; } } - + if (file){ file_clear(system, models, file, 1); file->settings.unimportant = 1; - + if (!(flags & CLI_AlwaysBindToView)){ iter = file_view_iter_init(&models->layout, file, 0); if (file_view_iter_good(iter)){ @@ -1758,18 +1584,18 @@ COMMAND_DECL(command_line){ return; } } - + if (!path){ path = models->hot_directory.string.str; terminate_with_null(&models->hot_directory.string); } - + { Temp_Memory temp; Range range; Editing_File *file2; i32 size; - + temp = begin_temp_memory(part); if (!script){ file2 = view->file_data.file; @@ -1784,14 +1610,14 @@ COMMAND_DECL(command_line){ script = " echo no script specified"; } } - + if (bind_to_new_view){ - view_file_in_panel(command, panel, file); + view_set_file(view, file, models); } - + proc = procs + vars->cli_processes.count++; proc->out_file = file; - + if (!system->cli_call(path, script, &proc->cli)){ --vars->cli_processes.count; } @@ -1817,20 +1643,20 @@ globalvar Command_Function command_table[cmdid_count]; internal void fill_buffer_summary(Buffer_Summary *buffer, Editing_File *file, Working_Set *working_set){ *buffer = buffer_summary_zero(); - if (!file->state.is_dummy){ + if (!file->is_dummy){ buffer->exists = 1; buffer->ready = file_is_ready(file); - + buffer->is_lexed = file->settings.tokens_exist; buffer->buffer_id = file->id.id; buffer->size = file->state.buffer.size; buffer->buffer_cursor_pos = file->state.cursor_pos; - + buffer->file_name_len = file->name.source_path.size; buffer->buffer_name_len = file->name.live_name.size; buffer->file_name = file->name.source_path.str; buffer->buffer_name = file->name.live_name.str; - + buffer->map_id = file->settings.base_map_id; } } @@ -1840,38 +1666,40 @@ fill_view_summary(View_Summary *view, View *vptr, Live_Views *live_set, Working_ i32 lock_level; int buffer_id; *view = view_summary_zero(); - + if (vptr->in_use){ view->exists = 1; view->view_id = (int)(vptr - live_set->views) + 1; - view->line_height = vptr->font_height; + view->line_height = (float)(vptr->line_height); view->unwrapped_lines = vptr->file_data.unwrapped_lines; - + view->show_whitespace = vptr->file_data.show_whitespace; + + if (vptr->file_data.file){ lock_level = view_lock_level(vptr); buffer_id = vptr->file_data.file->id.id; - + if (lock_level <= 0){ view->buffer_id = buffer_id; } else{ view->buffer_id = 0; } - + if (lock_level <= 1){ view->locked_buffer_id = buffer_id; } else{ view->locked_buffer_id = 0; } - + if (lock_level <= 2){ view->hidden_buffer_id = buffer_id; } else{ view->hidden_buffer_id = 0; } - + view->mark = view_compute_cursor_from_pos(vptr, vptr->recent->mark); view->cursor = vptr->recent->cursor; view->preferred_x = vptr->recent->preferred_x; @@ -1886,10 +1714,10 @@ extern "C"{ Command_Binding binding = {}; binding.function = function; if (function) function(cmd->system, cmd, binding); - + update_command_data(cmd->vars, cmd); } - + PUSH_PARAMETER_SIG(external_push_parameter){ Command_Data *cmd = (Command_Data*)app->cmd_context; Partition *part = &cmd->part; @@ -1898,7 +1726,7 @@ extern "C"{ cmd_param->param.param = param; cmd_param->param.value = value; } - + PUSH_MEMORY_SIG(external_push_memory){ Command_Data *cmd = (Command_Data*)app->cmd_context; Partition *part = &cmd->part; @@ -1912,12 +1740,12 @@ extern "C"{ base->inline_string.len = len; return(result); } - + CLEAR_PARAMETERS_SIG(external_clear_parameters){ Command_Data *cmd = (Command_Data*)app->cmd_context; cmd->part.pos = 0; } - + DIRECTORY_GET_HOT_SIG(external_directory_get_hot){ Command_Data *cmd = (Command_Data*)app->cmd_context; Hot_Directory *hot = &cmd->models->hot_directory; @@ -1929,7 +1757,7 @@ extern "C"{ out[copy_max] = 0; return(hot->string.size); } - + GET_FILE_LIST_SIG(external_get_file_list){ Command_Data *cmd = (Command_Data*)app->cmd_context; System_Functions *system = cmd->system; @@ -1937,13 +1765,13 @@ extern "C"{ system->set_file_list(&result, make_string(dir, len)); return(result); } - + FREE_FILE_LIST_SIG(external_free_file_list){ Command_Data *cmd = (Command_Data*)app->cmd_context; System_Functions *system = cmd->system; system->set_file_list(&list, make_string(0, 0)); } - + GET_BUFFER_FIRST_SIG(external_get_buffer_first){ Command_Data *cmd = (Command_Data*)app->cmd_context; Working_Set *working_set = &cmd->models->working_set; @@ -1953,12 +1781,12 @@ extern "C"{ } return(result); } - + GET_BUFFER_NEXT_SIG(external_get_buffer_next){ Command_Data *cmd = (Command_Data*)app->cmd_context; Working_Set *working_set = &cmd->models->working_set; Editing_File *file; - + file = working_set_get_active_file(working_set, buffer->buffer_id); if (file){ file = (Editing_File*)file->node.next; @@ -1968,174 +1796,45 @@ extern "C"{ *buffer = buffer_summary_zero(); } } - + GET_BUFFER_SIG(external_get_buffer){ Command_Data *cmd = (Command_Data*)app->cmd_context; Working_Set *working_set = &cmd->models->working_set; Buffer_Summary buffer = {}; Editing_File *file; - + file = working_set_get_active_file(working_set, index); if (file){ fill_buffer_summary(&buffer, file, working_set); } - - return(buffer); - } - - GET_ACTIVE_BUFFER_SIG(external_get_active_buffer){ - Command_Data *cmd = (Command_Data*)app->cmd_context; - Buffer_Summary buffer = {}; - View *view = cmd->view; - Editing_File *file; - - if (view_lock_level(view) <= LockLevel_Open){ - file = view->file_data.file; - if (file){ - fill_buffer_summary(&buffer, file, &cmd->models->working_set); - } - } - - return(buffer); - } - - GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){ - Command_Data *cmd = (Command_Data*)app->cmd_context; - Models *models = cmd->models; - Buffer_Summary buffer = {}; - - if (param_index >= 0 && param_index < models->buffer_param_count){ - buffer = external_get_buffer(app, models->buffer_param_indices[param_index]); - } - - return(buffer); - } - - GET_BUFFER_BY_NAME_SIG(external_get_buffer_by_name){ - Command_Data *cmd = (Command_Data*)app->cmd_context; - Buffer_Summary buffer = {}; - Editing_File *file; - Working_Set *working_set = &cmd->models->working_set; - - file = working_set_contains(cmd->system, working_set, make_string(filename, len)); - if (file && !file->state.is_dummy){ - fill_buffer_summary(&buffer, file, working_set); - } return(buffer); } - - BUFFER_SEEK_DELIMITER_SIG(external_buffer_seek_delimiter){ + + GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){ Command_Data *cmd = (Command_Data*)app->cmd_context; - Editing_File *file; - Working_Set *working_set; - int result = 0; - int size; - - if (buffer->exists){ - working_set = &cmd->models->working_set; - file = working_set_get_active_file(working_set, buffer->buffer_id); - if (file && file_is_ready(file)){ - size = buffer_size(&file->state.buffer); - result = 1; - - if (start < 0 && !seek_forward) *out = start; - else if (start >= size && seek_forward) *out = start; - else{ - if (seek_forward){ - *out = buffer_seek_delimiter(&file->state.buffer, start, delim); - } - else{ - *out = buffer_reverse_seek_delimiter(&file->state.buffer, start, delim); - } - } - - fill_buffer_summary(buffer, file, working_set); - } + Models *models = cmd->models; + Buffer_Summary buffer = {}; + + if (param_index >= 0 && param_index < models->buffer_param_count){ + buffer = external_get_buffer(app, models->buffer_param_indices[param_index]); } - - return(result); - } - - BUFFER_SEEK_STRING_SIG(external_buffer_seek_string){ - Command_Data *cmd = (Command_Data*)app->cmd_context; - Models *models; - Editing_File *file; - Working_Set *working_set; - Partition *part; - Temp_Memory temp; - char *spare; - int result = 0; - int size; - - if (buffer->exists){ - models = cmd->models; - working_set = &models->working_set; - file = working_set_get_active_file(working_set, buffer->buffer_id); - if (file && file_is_ready(file)){ - size = buffer_size(&file->state.buffer); - - if (start < 0 && !seek_forward) *out = start; - else if (start >= size && seek_forward) *out = start; - else{ - part = &models->mem.part; - temp = begin_temp_memory(part); - spare = push_array(part, char, len); - result = 1; - if (seek_forward){ - *out = buffer_find_string(&file->state.buffer, start, size, str, len, spare); - } - else{ - *out = buffer_rfind_string(&file->state.buffer, start, str, len, spare); - } - end_temp_memory(temp); - } - fill_buffer_summary(buffer, file, working_set); - } - } - - return(result); + + return(buffer); } - // TODO(allen): Reduce duplication between this and external_buffer_seek_string - BUFFER_SEEK_STRING_SIG(external_buffer_seek_string_insensitive){ + GET_BUFFER_BY_NAME_SIG(external_get_buffer_by_name){ Command_Data *cmd = (Command_Data*)app->cmd_context; - Models *models; + Buffer_Summary buffer = {}; Editing_File *file; - Working_Set *working_set; - Partition *part; - Temp_Memory temp; - char *spare; - int result = 0; - int size; - - if (buffer->exists){ - models = cmd->models; - working_set = &models->working_set; - file = working_set_get_active_file(working_set, buffer->buffer_id); - if (file && file_is_ready(file)){ - size = buffer_size(&file->state.buffer); - - if (start < 0 && !seek_forward) *out = start; - else if (start >= size && seek_forward) *out = start; - else{ - part = &models->mem.part; - temp = begin_temp_memory(part); - spare = push_array(part, char, len); - result = 1; - if (seek_forward){ - *out = buffer_find_string_insensitive(&file->state.buffer, start, size, str, len, spare); - } - else{ - *out = buffer_rfind_string_insensitive(&file->state.buffer, start, str, len, spare); - } - end_temp_memory(temp); - } - fill_buffer_summary(buffer, file, working_set); - } + Working_Set *working_set = &cmd->models->working_set; + + file = working_set_contains(cmd->system, working_set, make_string(filename, len)); + if (file && !file->is_dummy){ + fill_buffer_summary(&buffer, file, working_set); } - - return(result); + + return(buffer); } REFRESH_BUFFER_SIG(external_refresh_buffer){ @@ -2144,14 +1843,14 @@ extern "C"{ result = buffer->exists; return(result); } - + BUFFER_READ_RANGE_SIG(external_buffer_read_range){ Command_Data *cmd = (Command_Data*)app->cmd_context; Editing_File *file; Working_Set *working_set; int result = 0; int size; - + if (buffer->exists){ working_set = &cmd->models->working_set; file = working_set_get_active_file(working_set, buffer->buffer_id); @@ -2164,21 +1863,21 @@ extern "C"{ fill_buffer_summary(buffer, file, working_set); } } - + return(result); } - + BUFFER_REPLACE_RANGE_SIG(external_buffer_replace_range){ Command_Data *cmd = (Command_Data*)app->cmd_context; Editing_File *file; Working_Set *working_set; - + Models *models; - + int result = 0; int size; int next_cursor, pos; - + if (buffer->exists){ models = cmd->models; working_set = &models->working_set; @@ -2187,29 +1886,29 @@ extern "C"{ size = buffer_size(&file->state.buffer); if (0 <= start && start <= end && end <= size){ result = 1; - + pos = file->state.cursor_pos; if (pos < start) next_cursor = pos; else if (pos < end) next_cursor = start; else next_cursor = pos + end - start - len; - + file_replace_range(cmd->system, models, file, start, end, str, len, next_cursor); } fill_buffer_summary(buffer, file, working_set); } } - + return(result); } - + BUFFER_SET_POS_SIG(external_buffer_set_pos){ Command_Data *cmd = (Command_Data*)app->cmd_context; Editing_File *file; Working_Set *working_set; - + int result = 0; int size; - + if (buffer->exists){ working_set = &cmd->models->working_set; file = working_set_get_active_file(working_set, buffer->buffer_id); @@ -2222,23 +1921,23 @@ extern "C"{ fill_buffer_summary(buffer, file, working_set); } } - + return(result); } - + GET_VIEW_FIRST_SIG(external_get_view_first){ Command_Data *cmd = (Command_Data*)app->cmd_context; Editing_Layout *layout = &cmd->models->layout; View_Summary view = {}; - + Panel *panel = layout->used_sentinel.next; - + Assert(panel != &layout->used_sentinel); fill_view_summary(&view, panel->view, &cmd->vars->live_set, &cmd->models->working_set); - + return(view); } - + GET_VIEW_NEXT_SIG(external_get_view_next){ Command_Data *cmd = (Command_Data*)app->cmd_context; Editing_Layout *layout = &cmd->models->layout; @@ -2246,7 +1945,7 @@ extern "C"{ View *vptr; Panel *panel; int index = view->view_id - 1; - + if (index >= 0 && index < live_set->max){ vptr = live_set->views + index; panel = vptr->panel; @@ -2262,30 +1961,30 @@ extern "C"{ *view = view_summary_zero(); } } - + GET_VIEW_SIG(external_get_view){ Command_Data *cmd = (Command_Data*)app->cmd_context; View_Summary view = {}; Live_Views *live_set = cmd->live_set; int max = live_set->max; View *vptr; - + index -= 1; if (index >= 0 && index < max){ vptr = live_set->views + index; fill_view_summary(&view, vptr, live_set, &cmd->models->working_set); } - + return(view); } - + GET_ACTIVE_VIEW_SIG(external_get_active_view){ Command_Data *cmd = (Command_Data*)app->cmd_context; View_Summary view = {}; fill_view_summary(&view, cmd->view, &cmd->vars->live_set, &cmd->models->working_set); return(view); } - + REFRESH_VIEW_SIG(external_refresh_view){ int result; *view = external_get_view(app, view->view_id); @@ -2307,7 +2006,7 @@ extern "C"{ if (view_id >= 0 && view_id < live_set->max){ vptr = live_set->views + view_id; file = vptr->file_data.file; - if (file && !file->state.is_loading){ + if (file && !file->is_loading){ if (seek.type == buffer_seek_line_char && seek.character <= 0){ seek.character = 1; } @@ -2327,14 +2026,14 @@ extern "C"{ Editing_File *file; int result = 0; int view_id; - + if (view->exists){ live_set = cmd->live_set; view_id = view->view_id - 1; if (view_id >= 0 && view_id < live_set->max){ vptr = live_set->views + view_id; file = vptr->file_data.file; - if (file && !file->state.is_loading){ + if (file && !file->is_loading){ result = 1; if (seek.type == buffer_seek_line_char && seek.character <= 0){ seek.character = 1; @@ -2348,10 +2047,10 @@ extern "C"{ } } } - + return(result); } - + VIEW_SET_MARK_SIG(external_view_set_mark){ Command_Data *cmd = (Command_Data*)app->cmd_context; Live_Views *live_set; @@ -2359,7 +2058,7 @@ extern "C"{ Full_Cursor cursor; int result = 0; int view_id; - + if (view->exists){ live_set = cmd->live_set; view_id = view->view_id - 1; @@ -2376,7 +2075,7 @@ extern "C"{ fill_view_summary(view, vptr, live_set, &cmd->models->working_set); } } - + return(result); } @@ -2557,7 +2256,7 @@ extern "C"{ Theme_Color *theme_color; u32 *color; i32 i; - + theme_color = colors; for (i = 0; i < count; ++i, ++theme_color){ color = style_index_by_tag(&style->main, theme_color->tag); @@ -2576,7 +2275,7 @@ command_caller(Coroutine *coroutine){ Command_In *cmd_in = (Command_In*)coroutine->in; Command_Data *cmd = cmd_in->cmd; View *view = cmd->view; - + // TODO(allen): this isn't really super awesome, could have issues if // the file view get's change out under us. view->next_mode = view_mode_zero(); @@ -2588,7 +2287,6 @@ 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); } @@ -2613,14 +2311,11 @@ app_links_init(System_Functions *system, Application_Links *app_links, void *dat app_links->get_buffer_next = external_get_buffer_next; app_links->get_buffer = external_get_buffer; - app_links->get_active_buffer = external_get_active_buffer; app_links->get_parameter_buffer = external_get_parameter_buffer; app_links->get_buffer_by_name = external_get_buffer_by_name; app_links->refresh_buffer = external_refresh_buffer; - app_links->buffer_seek_delimiter = external_buffer_seek_delimiter; - app_links->buffer_seek_string = external_buffer_seek_string; - app_links->buffer_seek_string_insensitive = external_buffer_seek_string_insensitive; + app_links->buffer_read_range = external_buffer_read_range; app_links->buffer_replace_range = external_buffer_replace_range; @@ -2658,9 +2353,9 @@ app_links_init(System_Functions *system, Application_Links *app_links, void *dat internal void setup_ui_commands(Command_Map *commands, Partition *part, Command_Map *parent){ map_init(commands, part, 32, parent); - + commands->vanilla_keyboard_default.function = command_null; - + // TODO(allen): This is hacky, when the new UI stuff happens, let's fix it, // and by that I mean actually fix it, don't just say you fixed it with // something stupid again. @@ -2690,21 +2385,15 @@ setup_top_commands(Command_Map *commands, Partition *part, Command_Map *parent){ internal void setup_command_table(){ #define SET(n) command_table[cmdid_##n] = command_##n - SET(null); - SET(write_character); SET(seek_left); SET(seek_right); - SET(seek_whitespace_up); - SET(seek_whitespace_down); SET(center_view); SET(word_complete); - SET(set_mark); SET(copy); SET(cut); SET(paste); SET(paste_next); - SET(delete_range); SET(undo); SET(redo); SET(history_backward); @@ -2713,14 +2402,13 @@ setup_command_table(){ SET(interactive_open); SET(reopen); SET(save); - //SET(interactive_save_as); SET(change_active_panel); SET(interactive_switch_buffer); SET(interactive_kill_buffer); SET(kill_buffer); - SET(toggle_line_wrap); SET(to_uppercase); SET(to_lowercase); + SET(toggle_line_wrap); SET(toggle_show_whitespace); SET(clean_all_lines); SET(eol_dosify); @@ -2729,12 +2417,7 @@ setup_command_table(){ SET(open_panel_vsplit); SET(open_panel_hsplit); SET(close_panel); - SET(move_left); - SET(move_right); - SET(delete); - SET(backspace); - SET(move_up); - SET(move_down); + SET(seek_end_of_line); SET(seek_beginning_of_line); SET(page_up); @@ -2746,7 +2429,7 @@ setup_command_table(){ SET(show_scrollbar); SET(set_settings); SET(command_line); - + #undef SET } @@ -2758,14 +2441,14 @@ app_hardcode_styles(Models *models){ Style *styles, *style; styles = models->styles.styles; style = styles + 1; - + i16 fonts = 1; models->global_font.font_id = fonts + 0; models->global_font.font_changed = 0; - + ///////////////// style_set_name(style, make_lit_string("4coder")); - + style->main.back_color = 0xFF0C0C0C; style->main.margin_color = 0xFF181818; style->main.margin_hover_color = 0xFF252525; @@ -2786,13 +2469,13 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFFDDEE00; style->main.undo_color = 0xFF00DDEE; - + style->main.highlight_junk_color = 0xff3a0000; style->main.highlight_white_color = 0xff003a3a; - + file_info_style.bar_color = 0xFF888888; file_info_style.bar_active_color = 0xFF666666; file_info_style.base_color = 0xFF000000; @@ -2800,10 +2483,10 @@ app_hardcode_styles(Models *models){ file_info_style.pop2_color = 0xFFFF0000; style->main.file_info_style = file_info_style; ++style; - + ///////////////// style_set_name(style, make_lit_string("Handmade Hero")); - + style->main.back_color = 0xFF161616; style->main.margin_color = 0xFF262626; style->main.margin_hover_color = 0xFF333333; @@ -2824,13 +2507,13 @@ app_hardcode_styles(Models *models){ style->main.include_color = 0xFF6B8E23; style->main.preproc_color = 0xFFDAB98F; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFFFFBB00; style->main.undo_color = 0xFF80005D; - + style->main.highlight_junk_color = 0xFF3A0000; style->main.highlight_white_color = 0xFF003A3A; - + file_info_style.bar_color = 0xFFCACACA; file_info_style.bar_active_color = 0xFFA8A8A8; file_info_style.base_color = 0xFF000000; @@ -2838,10 +2521,10 @@ app_hardcode_styles(Models *models){ file_info_style.pop2_color = 0xFFFF0000; style->main.file_info_style = file_info_style; ++style; - + ///////////////// style_set_name(style, make_lit_string("Twilight")); - + style->main.back_color = 0xFF090D12; style->main.margin_color = 0xFF1A2634; style->main.margin_hover_color = 0xFF2D415B; @@ -2862,13 +2545,13 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFFDDEE00; style->main.undo_color = 0xFF00DDEE; - + style->main.highlight_junk_color = 0xff3a0000; style->main.highlight_white_color = 0xFF151F2A; - + file_info_style.bar_color = 0xFF315E68; file_info_style.bar_active_color = 0xFF0F3C46; file_info_style.base_color = 0xFF000000; @@ -2876,10 +2559,10 @@ app_hardcode_styles(Models *models){ file_info_style.pop2_color = 0xFFFF200D; style->main.file_info_style = file_info_style; ++style; - + ///////////////// style_set_name(style, make_lit_string("Wolverine")); - + style->main.back_color = 0xFF070711; style->main.margin_color = 0xFF111168; style->main.margin_hover_color = 0xFF191996; @@ -2900,13 +2583,13 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFFFF0000; - + style->main.paste_color = 0xFF900090; style->main.undo_color = 0xFF606090; - + style->main.highlight_junk_color = 0xff3a0000; style->main.highlight_white_color = 0xff003a3a; - + file_info_style.bar_color = 0xFF7082F9; file_info_style.bar_active_color = 0xFF4E60D7; file_info_style.base_color = 0xFF000000; @@ -2914,10 +2597,10 @@ app_hardcode_styles(Models *models){ file_info_style.pop2_color = 0xFFD20000; style->main.file_info_style = file_info_style; ++style; - + ///////////////// style_set_name(style, make_lit_string("stb")); - + style->main.back_color = 0xFFD6D6D6; style->main.margin_color = 0xFF9E9E9E; style->main.margin_hover_color = 0xFF7E7E7E; @@ -2938,13 +2621,13 @@ app_hardcode_styles(Models *models){ style->main.include_color = style->main.str_constant_color; style->main.preproc_color = style->main.default_color; style->main.special_character_color = 0xFF9A0000; - + style->main.paste_color = 0xFF00B8B8; style->main.undo_color = 0xFFB800B8; - + style->main.highlight_junk_color = 0xFFFF7878; style->main.highlight_white_color = 0xFFBCBCBC; - + file_info_style.bar_color = 0xFF606060; file_info_style.bar_active_color = 0xFF3E3E3E; file_info_style.base_color = 0xFF000000; @@ -2952,7 +2635,7 @@ app_hardcode_styles(Models *models){ file_info_style.pop2_color = 0xFFE80505; style->main.file_info_style = file_info_style; ++style; - + models->styles.count = (i32)(style - styles); models->styles.max = ArrayCount(models->styles.styles); style_copy(main_style(models), models->styles.styles + 1); @@ -2993,7 +2676,7 @@ enum Command_Line_Action{ void init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, - Command_Line_Parameters clparams){ + Command_Line_Parameters clparams){ char *arg; Command_Line_Action action = CLAct_Nothing; i32 i,index; @@ -3011,12 +2694,12 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, switch (arg[1]){ case 'u': action = CLAct_UserFile; strict = 0; break; case 'U': action = CLAct_UserFile; strict = 1; break; - + case 'd': action = CLAct_CustomDLL; strict = 0; break; case 'D': action = CLAct_CustomDLL; strict = 1; break; - + case 'i': action = CLAct_InitialFilePosition; break; - + case 'w': action = CLAct_WindowSize; break; case 'W': action = CLAct_WindowMaximize; break; case 'p': action = CLAct_WindowPosition; break; @@ -3031,7 +2714,7 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, } } }break; - + case CLAct_UserFile: { settings->user_file_is_strict = strict; @@ -3040,7 +2723,7 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, } action = CLAct_Nothing; }break; - + case CLAct_CustomDLL: { plat_settings->custom_dll_is_strict = strict; @@ -3049,7 +2732,7 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, } action = CLAct_Nothing; }break; - + case CLAct_InitialFilePosition: { if (i < clparams.argc){ @@ -3057,33 +2740,33 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, } action = CLAct_Nothing; }break; - + case CLAct_WindowSize: { if (i + 1 < clparams.argc){ plat_settings->set_window_size = 1; plat_settings->window_w = str_to_int(clparams.argv[i]); plat_settings->window_h = str_to_int(clparams.argv[i+1]); - + ++i; } action = CLAct_Nothing; }break; - + case CLAct_WindowMaximize: { --i; plat_settings->maximize_window = 1; action = CLAct_Nothing; }break; - + case CLAct_WindowPosition: { if (i + 1 < clparams.argc){ plat_settings->set_window_pos = 1; plat_settings->window_x = str_to_int(clparams.argv[i]); plat_settings->window_y = str_to_int(clparams.argv[i+1]); - + ++i; } action = CLAct_Nothing; @@ -3095,7 +2778,7 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, settings->font_size = str_to_int(clparams.argv[i]); } action = CLAct_Nothing; - }break; + }break; } } } @@ -3113,9 +2796,9 @@ app_setup_memory(Application_Memory *memory){ Assert(vars); *vars = app_vars_zero(); vars->models.mem.part = _partition; - + general_memory_open(&vars->models.mem.general, memory->target_memory, memory->target_memory_size); - + return(vars); } @@ -3145,13 +2828,13 @@ App_Read_Command_Line_Sig(app_read_command_line){ App_Vars *vars; App_Settings *settings; i32 out_size = 0; - + if (clparams.argc > 1 && match(clparams.argv[1], "-T")){ out_size = execute_special_tool(memory->target_memory, memory->target_memory_size, clparams); } else{ vars = app_setup_memory(memory); - + settings = &vars->models.settings; *settings = app_settings_zero(); settings->font_size = 16; @@ -3163,7 +2846,7 @@ App_Read_Command_Line_Sig(app_read_command_line){ *files = vars->models.settings.init_files; *file_count = &vars->models.settings.init_files_count; } - + return(out_size); } @@ -3193,6 +2876,7 @@ App_Init_Sig(app_init){ vars = (App_Vars*)memory->vars_memory; models = &vars->models; + models->keep_playing = 1; app_links_init(system, &models->app_links, memory->user_memory, memory->user_memory_size); @@ -3480,17 +3164,6 @@ App_Init_Sig(app_init){ copy(dest, make_string((char*)clipboard.str, clipboard.size)); } - // NOTE(allen): delay setup - models->delay1.general = &models->mem.general; - models->delay1.max = 16; - models->delay1.acts = (Delayed_Action*)general_memory_allocate( - &models->mem.general, models->delay1.max*sizeof(Delayed_Action), 0); - - models->delay2.general = &models->mem.general; - models->delay2.max = 16; - models->delay2.acts = (Delayed_Action*)general_memory_allocate( - &models->mem.general, models->delay2.max*sizeof(Delayed_Action), 0); - // NOTE(allen): style setup app_hardcode_styles(models); @@ -3499,7 +3172,7 @@ App_Init_Sig(app_init){ // NOTE(allen): init first panel Panel_And_ID p = layout_alloc_panel(&models->layout); - panel_make_empty(system, exchange, vars, p.panel); + panel_make_empty(system, vars, p.panel); models->layout.active_panel = p.id; String hdbase = make_fixed_width_string(models->hot_dir_base_); @@ -3520,17 +3193,17 @@ App_Init_Sig(app_init){ internal i32 update_cli_handle_with_file(System_Functions *system, Models *models, - CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){ + CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){ i32 result = 0; u32 amount; for (system->cli_begin_update(cli); - system->cli_update_step(cli, dest, max, &amount);){ + system->cli_update_step(cli, dest, max, &amount);){ amount = eol_in_place_convert_in(dest, amount); output_file_append(system, models, file, make_string(dest, amount), cursor_at_end); result = 1; } - + if (system->cli_end_update(cli)){ char str_space[256]; String str = make_fixed_width_string(str_space); @@ -3539,16 +3212,16 @@ update_cli_handle_with_file(System_Functions *system, Models *models, output_file_append(system, models, file, str, cursor_at_end); result = -1; } - + i32 new_cursor = 0; if (cursor_at_end){ new_cursor = buffer_size(&file->state.buffer); } - + for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ view_cursor_move(iter.view, new_cursor); } @@ -3634,51 +3307,64 @@ consume_input(Available_Input *available, i32 input_type){ App_Step_Sig(app_step){ Application_Step_Result app_result = *result; app_result.animating = 0; - + App_Vars *vars = (App_Vars*)memory->vars_memory; Models *models = &vars->models; target->partition = &models->mem.part; - + // NOTE(allen): OS clipboard event handling + String clipboard = input->clipboard; + if (clipboard.str){ String *dest = working_set_next_clipboard_string(&models->mem.general, &models->working_set, clipboard.size); dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size); } - + // NOTE(allen): check files are up to date { File_Node *node, *used_nodes; Editing_File *file; u64 time_stamp; - + used_nodes = &models->working_set.used_sentinel; for (dll_items(node, used_nodes)){ file = (Editing_File*)node; - + time_stamp = system->file_time_stamp(make_c_str(file->name.source_path)); - + if (time_stamp > 0){ file->state.last_sys_write_time = time_stamp; } } } - + + // NOTE(allen): begin allowing the cursors and scroll locations + // to move around. + { + Panel *panel = 0, *used_panels = 0; + used_panels = &models->layout.used_sentinel; + for (dll_items(panel, used_panels)){ + Assert(panel->view); + view_begin_cursor_scroll_updates(panel->view); + } + } + // NOTE(allen): reorganizing panels on screen { i32 prev_width = models->layout.full_width; i32 prev_height = models->layout.full_height; i32 current_width = target->width; i32 current_height = target->height; - + Panel *panel, *used_panels; View *view; - + models->layout.full_width = current_width; models->layout.full_height = current_height; - + if (prev_width != current_width || prev_height != current_height){ layout_refit(&models->layout, prev_width, prev_height); - + used_panels = &models->layout.used_sentinel; for (dll_items(panel, used_panels)){ view = panel->view; @@ -3692,18 +3378,18 @@ App_Step_Sig(app_step){ // NOTE(allen): prepare input information Key_Summary key_summary = {0}; - for (i32 i = 0; i < input->press_count; ++i){ - key_summary.keys[key_summary.count++] = input->press[i]; + for (i32 i = 0; i < input->keys.press_count; ++i){ + key_summary.keys[key_summary.count++] = input->keys.press[i]; } - for (i32 i = 0; i < input->hold_count; ++i){ - key_summary.keys[key_summary.count++] = input->hold[i]; + for (i32 i = 0; i < input->keys.hold_count; ++i){ + key_summary.keys[key_summary.count++] = input->keys.hold[i]; } - mouse->wheel = -mouse->wheel; + input->mouse.wheel = -input->mouse.wheel; // NOTE(allen): detect mouse hover status - i32 mx = mouse->x; - i32 my = mouse->y; + i32 mx = input->mouse.x; + i32 my = input->mouse.y; b32 mouse_in_edit_area = 0; b32 mouse_in_margin_area = 0; Panel *mouse_panel, *used_panels; @@ -3719,16 +3405,16 @@ App_Step_Sig(app_step){ break; } } - + if (!(mouse_in_edit_area || mouse_in_margin_area)){ mouse_panel = 0; } - + b32 mouse_on_divider = 0; b32 mouse_divider_vertical = 0; i32 mouse_divider_id = 0; i32 mouse_divider_side = 0; - + if (mouse_in_margin_area){ Panel *panel = mouse_panel; if (mx >= panel->inner.x0 && mx < panel->inner.x1){ @@ -3749,20 +3435,20 @@ App_Step_Sig(app_step){ mouse_divider_side = 1; } } - + if (models->layout.panel_count > 1){ i32 which_child; mouse_divider_id = panel->parent; which_child = panel->which_child; for (;;){ Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id); - + if (which_child == mouse_divider_side && - div.divider->v_divider == mouse_divider_vertical){ + div.divider->v_divider == mouse_divider_vertical){ mouse_on_divider = 1; break; } - + if (mouse_divider_id == models->layout.root){ break; } @@ -3778,19 +3464,8 @@ App_Step_Sig(app_step){ } } - // NOTE(allen): begin allowing the cursors and scroll locations - // to move around. - { - Panel *panel = 0, *used_panels = 0; - used_panels = &models->layout.used_sentinel; - for (dll_items(panel, used_panels)){ - Assert(panel->view); - view_begin_cursor_scroll_updates(panel->view); - } - } - // NOTE(allen): update child processes - if (dt > 0){ + if (input->dt > 0){ Temp_Memory temp = begin_temp_memory(&models->mem.part); u32 max = Kbytes(32); char *dest = push_array(&models->mem.part, char, max); @@ -3815,16 +3490,15 @@ App_Step_Sig(app_step){ // NOTE(allen): prepare to start executing commands Command_Data *cmd = &vars->command_data; - + cmd->models = models; cmd->vars = vars; cmd->system = system; - cmd->exchange = exchange; cmd->live_set = &vars->live_set; - + cmd->panel = models->layout.panels + models->layout.active_panel; cmd->view = cmd->panel->view; - + cmd->screen_width = target->width; cmd->screen_height = target->height; @@ -3833,7 +3507,9 @@ App_Step_Sig(app_step){ Temp_Memory param_stack_temp = begin_temp_memory(&models->mem.part); cmd->part = partition_sub_part(&models->mem.part, 16 << 10); - if (first_step){ + if (input->first_step){ + +#if 0 { View *view = 0; View_Persistent *persistent = 0; @@ -3848,22 +3524,17 @@ App_Step_Sig(app_step){ persistent->coroutine = system->create_coroutine(view_caller); - models->command_coroutine = persistent->coroutine; - persistent->coroutine = app_launch_coroutine(system, &models->app_links, Co_View, - persistent->coroutine, - view, - 0); + persistent->coroutine, view, 0); if (!persistent->coroutine){ // TODO(allen): Error message and recover NotImplemented; } } - - models->command_coroutine = 0; } +#endif General_Memory *general = &models->mem.general; Editing_File *file = working_set_alloc_always(&models->working_set, general); @@ -3879,30 +3550,40 @@ App_Step_Sig(app_step){ models->hooks[hook_start](&models->app_links); cmd->part.pos = 0; } - + i32 i; - String file_name; + String filename; Panel *panel = models->layout.used_sentinel.next; - for (i = 0; i < models->settings.init_files_count; ++i, panel = panel->next){ - file_name = make_string_slowly(models->settings.init_files[i]); - + for (i = 0; + i < models->settings.init_files_count; + ++i, panel = panel->next){ + filename = make_string_slowly(models->settings.init_files[i]); + if (i < models->layout.panel_count){ - delayed_open(&models->delay1, file_name, panel); + view_open_file(system, models, panel->view, filename); + view_show_file(panel->view); +#if 0 if (i == 0){ - delayed_set_line(&models->delay1, panel, models->settings.initial_line); + if (panel->view->file_data.file){ + // TODO(allen): How to set the cursor of a file on the first frame? + view_compute_cursor_from_line_pos(panel->view, models->settings.initial_line, 1); + view_move_view_to_cursor(panel->view, &panel->view->recent->scroll); + } } +#endif } else{ - delayed_open_background(&models->delay1, file_name); + view_open_file(system, models, 0, filename); } } if (i < models->layout.panel_count){ - view_file_in_panel(cmd, panel, models->message_buffer); + view_set_file(panel->view, models->message_buffer, models); + view_show_file(panel->view); } } - // NOTE(allen): try to abort the command corroutine if we are shutting down + // NOTE(allen): respond if the user is trying to kill the application if (app_result.trying_to_kill){ b32 there_is_unsaved = 0; app_result.animating = 1; @@ -3921,15 +3602,14 @@ App_Step_Sig(app_step){ Coroutine *command_coroutine = models->command_coroutine; View *view = cmd->view; i32 i = 0; - + while (command_coroutine){ User_Input user_in = {0}; user_in.abort = 1; command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, - command_coroutine, - &user_in, + command_coroutine, &user_in, models->command_coroutine_flags); ++i; @@ -3941,33 +3621,33 @@ App_Step_Sig(app_step){ if (view != 0){ init_query_set(&view->query_set); } - + if (view == 0){ Panel *panel = models->layout.used_sentinel.next; view = panel->view; } - + view_show_interactive(system, view, &models->map_ui, - IAct_Sure_To_Close, IInt_Sure_To_Close, make_lit_string("Are you sure?")); - + IAct_Sure_To_Close, IInt_Sure_To_Close, + make_lit_string("Are you sure?")); + models->command_coroutine = command_coroutine; } else{ - app_result.perform_kill = 1; + models->keep_playing = 0; } } - // NOTE(allen): process the command_coroutine if it is unfinished - Available_Input available_input = init_available_input(&key_summary, mouse); - // NOTE(allen): Keyboard input to command coroutine. + Available_Input available_input = init_available_input(&key_summary, &input->mouse); + if (models->command_coroutine != 0){ Coroutine *command_coroutine = models->command_coroutine; u32 get_flags = models->command_coroutine_flags[0]; u32 abort_flags = models->command_coroutine_flags[1]; - + get_flags |= abort_flags; - + if ((get_flags & EventOnAnyKey) || (get_flags & EventOnEsc)){ Key_Summary key_data = get_key_data(&available_input); @@ -3976,25 +3656,25 @@ App_Step_Sig(app_step){ View *view = cmd->view; b32 pass_in = 0; cmd->key = key; - + Command_Map *map = 0; if (view) map = view->map; if (map == 0) map = &models->map_top; Command_Binding cmd_bind = map_extract_recursive(map, key); - + User_Input user_in; user_in.type = UserInputKey; user_in.key = key; user_in.command = (unsigned long long)cmd_bind.custom; user_in.abort = 0; - + if ((EventOnEsc & abort_flags) && key.keycode == key_esc){ user_in.abort = 1; } else if (EventOnAnyKey & abort_flags){ user_in.abort = 1; } - + if (EventOnAnyKey & get_flags){ pass_in = 1; consume_input(&available_input, Input_AnyKey); @@ -4005,7 +3685,7 @@ App_Step_Sig(app_step){ } consume_input(&available_input, Input_Esc); } - + if (pass_in){ models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, @@ -4014,7 +3694,7 @@ App_Step_Sig(app_step){ models->command_coroutine_flags); app_result.animating = 1; - + // TOOD(allen): Deduplicate // TODO(allen): Should I somehow allow a view to clean up however it wants after a // command finishes, or after transfering to another view mid command? @@ -4025,18 +3705,18 @@ App_Step_Sig(app_step){ } } } - + // NOTE(allen): Mouse input to command coroutine if (models->command_coroutine != 0 && (get_flags & EventOnMouse)){ View *view = cmd->view; b32 pass_in = 0; - + User_Input user_in; user_in.type = UserInputMouse; - user_in.mouse = *mouse; + user_in.mouse = input->mouse; user_in.command = 0; user_in.abort = 0; - + if (abort_flags & EventOnMouseMove){ user_in.abort = 1; } @@ -4044,8 +3724,8 @@ App_Step_Sig(app_step){ pass_in = 1; consume_input(&available_input, Input_MouseMove); } - - if (mouse->press_l || mouse->release_l || mouse->l){ + + if (input->mouse.press_l || input->mouse.release_l || input->mouse.l){ if (abort_flags & EventOnLeftButton){ user_in.abort = 1; } @@ -4054,8 +3734,8 @@ App_Step_Sig(app_step){ consume_input(&available_input, Input_MouseLeftButton); } } - - if (mouse->press_r || mouse->release_r || mouse->r){ + + if (input->mouse.press_r || input->mouse.release_r || input->mouse.r){ if (abort_flags & EventOnRightButton){ user_in.abort = 1; } @@ -4064,8 +3744,8 @@ App_Step_Sig(app_step){ consume_input(&available_input, Input_MouseRightButton); } } - - if (mouse->wheel != 0){ + + if (input->mouse.wheel != 0){ if (abort_flags & EventOnWheel){ user_in.abort = 1; } @@ -4074,7 +3754,7 @@ App_Step_Sig(app_step){ consume_input(&available_input, Input_MouseWheel); } } - + if (pass_in){ models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, @@ -4093,18 +3773,17 @@ App_Step_Sig(app_step){ } } } - + update_command_data(vars, cmd); // NOTE(allen): pass raw input to the panels - Input_Summary dead_input = {}; - dead_input.mouse.x = mouse->x; - dead_input.mouse.y = mouse->y; - + dead_input.mouse.x = input->mouse.x; + dead_input.mouse.y = input->mouse.y; + Input_Summary active_input = {}; - active_input.mouse.x = mouse->x; - active_input.mouse.y = mouse->y; + active_input.mouse.x = input->mouse.x; + active_input.mouse.y = input->mouse.y; active_input.keys = get_key_data(&available_input); @@ -4114,7 +3793,7 @@ App_Step_Sig(app_step){ Panel *panel = 0, *used_panels = 0; View *view = 0, *active_view = 0; b32 active = 0; - Input_Summary input = {0}; + Input_Summary summary = {0}; Input_Process_Result result = {0}; active_view = cmd->panel->view; @@ -4122,27 +3801,34 @@ App_Step_Sig(app_step){ for (dll_items(panel, used_panels)){ view = panel->view; active = (panel == cmd->panel); - input = (active)?(active_input):(dead_input); - if (step_file_view(system, view, active_view, input)){ + summary = (active)?(active_input):(dead_input); + + View_Step_Result result = step_file_view(system, view, active_view, summary); + if (result.animating){ app_result.animating = 1; } + if (result.consume_keys){ + consume_input(&available_input, Input_AnyKey); + } + if (result.consume_keys || result.consume_esc){ + consume_input(&available_input, Input_Esc); + } } for (dll_items(panel, used_panels)){ view = panel->view; Assert(view->current_scroll); active = (panel == cmd->panel); - input = (active)?(active_input):(dead_input); - if (panel == mouse_panel && !mouse->out_of_window){ - input.mouse = mouse_state; + summary = (active)?(active_input):(dead_input); + if (panel == mouse_panel && !input->mouse.out_of_window){ + summary.mouse = mouse_state; } - GUI_Scroll_Vars *vars = view->current_scroll; // TODO(allen): I feel like the scroll context should actually not // be allowed to change in here at all. - result = do_input_file_view(system, exchange, view, panel->inner, active, - &input, *vars, view->scroll_region); + result = do_step_file_view(system, view, panel->inner, active, + &summary, *vars, view->scroll_region); if (result.is_animating){ app_result.animating = 1; } @@ -4150,7 +3836,7 @@ App_Step_Sig(app_step){ view->scroll_region = result.region; } } - + update_command_data(vars, cmd); // NOTE(allen): command execution @@ -4161,7 +3847,7 @@ App_Step_Sig(app_step){ for (i32 key_i = 0; key_i < key_data.count; ++key_i){ if (models->command_coroutine != 0) break; - + switch (vars->state){ case APP_STATE_EDIT: { @@ -4202,7 +3888,7 @@ App_Step_Sig(app_step){ app_result.animating = 1; } }break; - + case APP_STATE_RESIZING: { if (key_data.count > 0){ @@ -4223,7 +3909,7 @@ App_Step_Sig(app_step){ update_command_data(vars, cmd); // NOTE(allen): initialize message - if (first_step){ + if (input->first_step){ String welcome = make_lit_string("Welcome to " VERSION "\n" "If you're new to 4coder there's no tutorial yet :(\n" @@ -4260,11 +3946,11 @@ App_Step_Sig(app_step){ switch (vars->state){ case APP_STATE_EDIT: { - if (mouse->press_l && mouse_on_divider){ + if (input->mouse.press_l && mouse_on_divider){ vars->state = APP_STATE_RESIZING; Divider_And_ID div = layout_get_divider(&models->layout, mouse_divider_id); vars->resizing.divider = div.divider; - + i32 min, max; { i32 mid, MIN, MAX; @@ -4279,7 +3965,7 @@ App_Step_Sig(app_step){ } min = MIN; max = MAX; - + i32 divider_id = div.id; do{ Divider_And_ID other_div = layout_get_divider(&models->layout, divider_id); @@ -4293,12 +3979,12 @@ App_Step_Sig(app_step){ } divider_id = other_div.divider->parent; }while(divider_id != -1); - + Temp_Memory temp = begin_temp_memory(&models->mem.part); i32 *divider_stack = push_array(&models->mem.part, i32, models->layout.panel_count); i32 top = 0; divider_stack[top++] = div.id; - + while (top > 0){ Divider_And_ID other_div = layout_get_divider(&models->layout, divider_stack[--top]); b32 divider_match = (other_div.divider->v_divider == mouse_divider_vertical); @@ -4316,18 +4002,18 @@ App_Step_Sig(app_step){ divider_stack[top++] = other_div.divider->child2; } } - + end_temp_memory(temp); } - + vars->resizing.min = min; vars->resizing.max = max; } }break; - + case APP_STATE_RESIZING: { - if (mouse->l){ + if (input->mouse.l){ Panel_Divider *divider = vars->resizing.divider; if (divider->v_divider){ divider->pos = mx; @@ -4335,14 +4021,14 @@ App_Step_Sig(app_step){ else{ divider->pos = my; } - + if (divider->pos < vars->resizing.min){ divider->pos = vars->resizing.min; } else if (divider->pos > vars->resizing.max){ divider->pos = vars->resizing.max - 1; } - + layout_fix_all_panels(&models->layout); } else{ @@ -4351,219 +4037,12 @@ App_Step_Sig(app_step){ }break; } - if (mouse_in_edit_area && mouse_panel != 0 && mouse->press_l){ + if (mouse_in_edit_area && mouse_panel != 0 && input->mouse.press_l){ models->layout.active_panel = (i32)(mouse_panel - models->layout.panels); } update_command_data(vars, cmd); - // NOTE(allen): process as many delayed actions as possible - if (models->delay1.count > 0){ - Working_Set *working_set = &models->working_set; - Mem_Options *mem = &models->mem; - General_Memory *general = &mem->general; - Partition *part = &mem->part; - - i32 count = models->delay1.count; - models->delay1.count = 0; - models->delay2.count = 0; - - Delayed_Action *act = models->delay1.acts; - for (i32 i = 0; i < count; ++i, ++act){ - String string = act->string; - Panel *panel = act->panel; - Editing_File *file = act->file; - i32 integer = act->integer; - - // TODO(allen): Paramter checking in each DACT case. - switch (act->type){ - case DACT_TOUCH_FILE: - { - if (file){ - touch_file(working_set, file); - } - }break; - - case DACT_OPEN: - case DACT_OPEN_BACKGROUND: - { - String filename = string; - Editing_File *file = working_set_contains(system, working_set, filename); - - if (file == 0){ - File_Loading loading = system->file_load_begin(filename.str); - - if (loading.exists){ - Temp_Memory temp = begin_temp_memory(part); - char *buffer = push_array(part, char, loading.size); - - if (system->file_load_end(loading, buffer)){ - file = working_set_alloc_always(working_set, general); - if (file){ - file_init_strings(file); - file_set_name(working_set, file, filename.str); - working_set_add(system, working_set, file, general); - - init_normal_file(system, models, file, - buffer, loading.size); - } - } - - end_temp_memory(temp); - } - } - - if (file){ - if (act->type == DACT_OPEN){ - view_file_in_panel(cmd, panel, file); - } - } - }break; - - case DACT_SET_LINE: - { - // TODO(allen): deduplicate - if (panel){ - file = panel->view->file_data.file; - } - else if (string.str && string.size > 0){ - file = working_set_lookup_file(working_set, string); - } - if (file){ - if (file->state.is_loading){ - file->preload.start_line = integer; - } - else{ - // TODO(allen): write this case - } - } - }break; - - case DACT_SAVE: - case DACT_SAVE_AS: - { - if (!file){ - if (panel){ - View *view = panel->view; - Assert(view); - file = view->file_data.file; - } - else{ - file = working_set_lookup_file(working_set, string); - } - } - - if (file && buffer_get_sync(file) != SYNC_GOOD){ - if (file_save(system, mem, file, string.str)){ - if (act->type == DACT_SAVE_AS){ - file_set_name(working_set, file, string.str); - } - } - } - }break; - - case DACT_NEW: - { - Editing_File *file = working_set_alloc_always(working_set, general); - file_create_empty(system, models, file, string.str); - working_set_add(system, working_set, file, general); - - View *view = panel->view; - - view_set_file(view, file, models); - view_show_file(view); - view->map = get_map(models, file->settings.base_map_id); - - Hook_Function *new_file_fnc = models->hooks[hook_new_file]; - if (new_file_fnc){ - models->buffer_param_indices[models->buffer_param_count++] = file->id.id; - new_file_fnc(&models->app_links); - models->buffer_param_count = 0; - file->settings.is_initialized = 1; - } - -#if BUFFER_EXPERIMENT_SCALPEL <= 0 - if (file->settings.tokens_exist) - file_first_lex_parallel(system, general, file); -#endif - }break; - - case DACT_SWITCH: - { - if (!file && string.str){ - file = working_set_lookup_file(working_set, string); - if (!file){ - file = working_set_contains(system, working_set, string); - } - } - - if (file){ - View *view = panel->view; - - view_set_file(view, file, models); - view_show_file(view); - view->map = get_map(models, file->settings.base_map_id); - } - }break; - - case DACT_KILL: - { - if (!file && string.str){ - file = working_set_lookup_file(working_set, string); - if (!file){ - file = working_set_contains(system, working_set, string); - } - } - - if (file && !file->settings.never_kill){ - working_set_remove(system, working_set, file->name.source_path); - kill_file(system, exchange, models, file); - } - }break; - - case DACT_TRY_KILL: - { - View *view = 0; - if (panel){ - view = panel->view; - } - else{ - view = (models->layout.panels + models->layout.active_panel)->view; - } - - if (!file && string.str){ - file = working_set_lookup_file(working_set, string); - if (!file){ - file = working_set_contains(system, working_set, string); - } - } - - if (file && !file->settings.never_kill){ - if (buffer_needs_save(file)){ - copy(&view->dest, file->name.live_name); - view_show_interactive(system, view, &models->map_ui, - IAct_Sure_To_Kill, IInt_Sure_To_Kill, make_lit_string("Are you sure?")); - } - else{ - working_set_remove(system, working_set, file->name.source_path); - kill_file(system, exchange, models, file); - } - } - }break; - - case DACT_CLOSE: - { - app_result.perform_kill = 1; - }break; - } - - if (string.str){ - general_memory_free(general, string.str); - } - } - Swap(Delay, models->delay1, models->delay2); - } - end_temp_memory(param_stack_temp); // NOTE(allen): send resize messages to panels that have changed size @@ -4585,19 +4064,19 @@ App_Step_Sig(app_step){ // NOTE(allen): send style change messages if the style has changed if (models->global_font.font_changed){ models->global_font.font_changed = 0; - + File_Node *node, *used_nodes; Editing_File *file; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; float *advance_data = 0; if (font) advance_data = font->advance_data; - + used_nodes = &models->working_set.used_sentinel; for (dll_items(node, used_nodes)){ file = (Editing_File*)node; file_measure_starts_widths(system, &models->mem.general, &file->state.buffer, advance_data); } - + Panel *panel, *used_panels; used_panels = &models->layout.used_sentinel; for (dll_items(panel, used_panels)){ @@ -4619,28 +4098,29 @@ App_Step_Sig(app_step){ // NOTE(allen): rendering { begin_render_section(target, system); - + target->clip_top = -1; draw_push_clip(target, rect_from_target(target)); - + // NOTE(allen): render the panels Panel *panel, *used_panels; used_panels = &models->layout.used_sentinel; for (dll_items(panel, used_panels)){ i32_Rect full = panel->full; i32_Rect inner = panel->inner; - + View *view = panel->view; Style *style = main_style(models); - + b32 active = (panel == cmd->panel); u32 back_color = style->main.back_color; draw_rectangle(target, full, back_color); - + draw_push_clip(target, panel->inner); - do_render_file_view(system, exchange, view, cmd->view, panel->inner, active, target, &dead_input); + do_render_file_view(system, view, cmd->view, + panel->inner, active, target, &dead_input); draw_pop_clip(target); - + u32 margin_color; if (active){ margin_color = style->main.margin_active_color; @@ -4656,13 +4136,13 @@ App_Step_Sig(app_step){ draw_rectangle(target, i32R(full.x0, inner.y0, inner.x0, inner.y1), margin_color); draw_rectangle(target, i32R(inner.x1, inner.y0, full.x1, inner.y1), margin_color); } - + end_render_section(target, system); } // NOTE(allen): get cursor type if (mouse_in_edit_area){ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; } else if (mouse_in_margin_area){ if (mouse_on_divider){ @@ -4680,6 +4160,8 @@ App_Step_Sig(app_step){ models->prev_mouse_panel = mouse_panel; app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; + app_result.perform_kill = !models->keep_playing; + *result = app_result; Assert(general_memory_check(&models->mem.general)); @@ -4689,11 +4171,11 @@ App_Step_Sig(app_step){ external App_Get_Functions_Sig(app_get_functions){ App_Functions result = {}; - + result.read_command_line = app_read_command_line; result.init = app_init; result.step = app_step; - + return(result); } diff --git a/4ed.h b/4ed.h index 33d14324..47b66a5b 100644 --- a/4ed.h +++ b/4ed.h @@ -81,17 +81,18 @@ struct Plat_Settings{ typedef App_Read_Command_Line_Sig(App_Read_Command_Line); + #define App_Init_Sig(name) void \ name(System_Functions *system, \ - Render_Target *target, \ - Application_Memory *memory, \ - Exchange *exchange, \ - String clipboard, \ - String current_directory, \ - Custom_API api) + Render_Target *target, \ + Application_Memory *memory, \ + String clipboard, \ + String current_directory, \ + Custom_API api) typedef App_Init_Sig(App_Init); + enum Application_Mouse_Cursor{ APP_MOUSE_CURSOR_DEFAULT, APP_MOUSE_CURSOR_ARROW, @@ -110,19 +111,24 @@ struct Application_Step_Result{ b32 animating; }; +struct Application_Step_Input{ + b32 first_step; + f32 dt; + Key_Input_Data keys; + Mouse_State mouse; + String clipboard; +}; + #define App_Step_Sig(name) void \ name(System_Functions *system, \ - Key_Input_Data *input, \ - Mouse_State *mouse, \ Render_Target *target, \ Application_Memory *memory, \ - Exchange *exchange, \ - String clipboard, \ - f32 dt, b32 first_step, \ + Application_Step_Input *input, \ Application_Step_Result *result) typedef App_Step_Sig(App_Step); + struct App_Functions{ App_Read_Command_Line *read_command_line; App_Init *init; diff --git a/4ed_app_models.h b/4ed_app_models.h index 35df15a6..0022ec49 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -58,16 +58,12 @@ struct Models{ char hot_dir_base_[256]; Hot_Directory hot_directory; - Delay delay1, delay2; - Panel *prev_mouse_panel; Custom_API config_api; Scroll_Rule_Function *scroll_rule; -#if 0 - File_Exchange files; -#endif + b32 keep_playing; }; // BOTTOM diff --git a/4ed_app_target.cpp b/4ed_app_target.cpp index dd6e8d1d..d3f4b609 100644 --- a/4ed_app_target.cpp +++ b/4ed_app_target.cpp @@ -39,12 +39,10 @@ #include "4ed_style.h" #include "4ed_style.cpp" -#include "4ed_exchange.cpp" #include "4ed_command.cpp" #include "4ed_file.cpp" #include "4ed_gui.cpp" #include "4ed_layout.cpp" -#include "4ed_delay.cpp" #include "4ed_app_models.h" #include "4ed_file_view.cpp" #include "4ed.cpp" diff --git a/4ed_delay.cpp b/4ed_delay.cpp deleted file mode 100644 index 715a1550..00000000 --- a/4ed_delay.cpp +++ /dev/null @@ -1,140 +0,0 @@ -enum Action_Type{ - DACT_OPEN, - DACT_OPEN_BACKGROUND, - DACT_SET_LINE, - DACT_SAVE_AS, - DACT_SAVE, - DACT_NEW, - DACT_SWITCH, - DACT_TRY_KILL, - DACT_KILL, - DACT_TOUCH_FILE, - DACT_CLOSE, -}; - -struct Delayed_Action{ - Action_Type type; - String string; - Panel* panel; - Editing_File* file; - i32 integer; -}; - -struct Delay{ - General_Memory* general; - Delayed_Action* acts; - i32 count; - i32 max; -}; - -internal String -str_alloc_copy(General_Memory *general, String str){ - String result; - result.memory_size = str.memory_size + 1; - result.size = str.size; - result.str = (char*)general_memory_allocate(general, result.memory_size, 0); - memcpy(result.str, str.str, str.size); - result.str[result.size] = 0; - return(result); -} - -inline Delayed_Action -delayed_action_zero(){ - Delayed_Action result = {(Action_Type)0}; - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type){ - Delayed_Action *result; - if (delay->count == delay->max){ - delay->max *= 2; - delay->acts = (Delayed_Action*)general_memory_reallocate(delay->general, delay->acts, delay->count*sizeof(Delayed_Action), delay->max*sizeof(Delayed_Action), 0); - } - result = delay->acts + delay->count++; - *result = delayed_action_zero(); - result->type = type; - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type, String string){ - Delayed_Action *result; - result = delayed_action_(delay, type); - result->string = str_alloc_copy(delay->general, string); - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type, Panel* panel){ - Delayed_Action *result; - result = delayed_action_(delay, type); - result->panel = panel; - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type, Editing_File* file){ - Delayed_Action *result; - result = delayed_action_(delay, type); - result->file = file; - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type, Editing_File* file, Panel* panel){ - Delayed_Action *result; - result = delayed_action_(delay, type); - result->file = file; - result->panel = panel; - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type, String string, Panel* panel){ - Delayed_Action *result; - result = delayed_action_(delay, type); - result->string = str_alloc_copy(delay->general, string); - result->panel = panel; - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type, String string, Editing_File* file){ - Delayed_Action *result; - result = delayed_action_(delay, type); - result->string = str_alloc_copy(delay->general, string); - result->file = file; - return(result); -} - -inline Delayed_Action* -delayed_action_(Delay *delay, Action_Type type, Panel* panel, i32 integer){ - Delayed_Action *result; - result = delayed_action_(delay, type); - result->panel = panel; - result->integer = integer; - return(result); -} - -inline Delayed_Action* -delayed_action_repush(Delay *delay, Delayed_Action *act){ - Delayed_Action *new_act = delayed_action_(delay, (Action_Type)0); - *new_act = *act; - if (act->string.str){ - new_act->string = str_alloc_copy(delay->general, act->string); - } - return(new_act); -} - -#define delayed_open(delay, ...) delayed_action_(delay, DACT_OPEN, ##__VA_ARGS__) -#define delayed_open_background(delay, ...) delayed_action_(delay, DACT_OPEN_BACKGROUND, ##__VA_ARGS__) -#define delayed_set_line(delay, ...) delayed_action_(delay, DACT_SET_LINE, ##__VA_ARGS__) -#define delayed_save_as(delay, ...) delayed_action_(delay, DACT_SAVE_AS, ##__VA_ARGS__) -#define delayed_save(delay, ...) delayed_action_(delay, DACT_SAVE, ##__VA_ARGS__) -#define delayed_new(delay, ...) delayed_action_(delay, DACT_NEW, ##__VA_ARGS__) -#define delayed_switch(delay, ...) delayed_action_(delay, DACT_SWITCH, ##__VA_ARGS__) -#define delayed_try_kill(delay, ...) delayed_action_(delay, DACT_TRY_KILL, ##__VA_ARGS__) -#define delayed_kill(delay, ...) delayed_action_(delay, DACT_KILL, ##__VA_ARGS__) -#define delayed_touch_file(delay, ...) delayed_action_(delay, DACT_TOUCH_FILE, ##__VA_ARGS__) -#define delayed_close(delay, ...) delayed_action_(delay, DACT_CLOSE, ##__VA_ARGS__) diff --git a/4ed_exchange.cpp b/4ed_exchange.cpp deleted file mode 100644 index 24b1d9ae..00000000 --- a/4ed_exchange.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 9.12.2015 - * - * Exchange stuff - * - */ - -// TOP - -// NOTE(allen): Uhhh.... is it just me or did it get awkward -// in here when I deleted all the file exchange stuff? - -internal b32 -queue_job_is_pending(Work_Queue *queue, u32 job_id){ - b32 result; - u32 job_index; - Full_Job_Data *full_job; - - job_index = job_id % QUEUE_WRAP; - full_job = queue->jobs + job_index; - - Assert(full_job->id == job_id); - - result = 0; - if (full_job->running_thread != 0){ - result = 1; - } - - return(result); -} - -// BOTTOM - diff --git a/4ed_file.cpp b/4ed_file.cpp index 123ca46d..0d03d2bc 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -111,9 +111,6 @@ struct Editing_File_Settings{ // NOTE(allen): This part of the Editing_File is cleared whenever // the contents of the file is set. struct Editing_File_State{ - b32 is_dummy; - b32 is_loading; - i16 font_id; Buffer_Type buffer; @@ -135,10 +132,6 @@ struct Editing_File_State{ u64 last_sys_write_time; }; -struct Editing_File_Preload{ - i32 start_line; -}; - struct Editing_File_Name{ char live_name_[256]; char source_path_[256]; @@ -168,9 +161,10 @@ struct Editing_File{ // NOTE(allen): node must be the first member of Editing_File! File_Node node; Editing_File_Settings settings; - union{ + struct{ + b32 is_loading; + b32 is_dummy; Editing_File_State state; - Editing_File_Preload preload; }; Editing_File_Name name; Buffer_Slot_ID id; @@ -317,7 +311,7 @@ working_set_alloc_always(Working_Set *working_set, General_Memory *general){ inline void working_set_free_file(Working_Set *working_set, Editing_File *file){ - file->state.is_dummy = 1; + file->is_dummy = 1; dll_remove(&file->node); dll_insert(&working_set->free_sentinel, &file->node); --working_set->file_count; @@ -349,7 +343,7 @@ inline Editing_File* working_set_get_active_file(Working_Set *working_set, Buffer_Slot_ID id){ Editing_File *result = 0; result = working_set_index(working_set, id); - if (result && result->state.is_dummy){ + if (result && result->is_dummy){ result = 0; } return(result); @@ -383,7 +377,7 @@ working_set_init(Working_Set *working_set, Partition *partition, General_Memory null_file = working_set_index(working_set, 0); dll_remove(&null_file->node); - null_file->state.is_dummy = 1; + null_file->is_dummy = 1; ++working_set->file_count; table_size = working_set->file_max; @@ -488,9 +482,11 @@ working_set_lookup_file(Working_Set *working_set, String string){ internal void touch_file(Working_Set *working_set, Editing_File *file){ - Assert(!file->state.is_dummy); - dll_remove(&file->node); - dll_insert(&working_set->used_sentinel, &file->node); + if (file){ + Assert(!file->is_dummy); + dll_remove(&file->node); + dll_insert(&working_set->used_sentinel, &file->node); + } } // Hot Directory @@ -586,6 +582,7 @@ filename_match(String query, Absolutes *absolutes, String filename, b32 case_sen return result; } +#if 0 internal Hot_Directory_Match hot_directory_first_match(Hot_Directory *hot_directory, String str, @@ -609,7 +606,7 @@ hot_directory_first_match(Hot_Directory *hot_directory, if (match(filename, str)) is_match = 1; } else{ - if (match_unsensitive(filename, str)) is_match = 1; + if (match_insensitive(filename, str)) is_match = 1; } } else{ @@ -625,6 +622,7 @@ hot_directory_first_match(Hot_Directory *hot_directory, return result; } +#endif inline File_Sync_State buffer_get_sync(Editing_File *file){ @@ -648,7 +646,7 @@ buffer_needs_save(Editing_File *file){ inline b32 file_is_ready(Editing_File *file){ b32 result = 0; - if (file && file->state.is_loading == 0){ + if (file && file->is_loading == 0){ result = 1; } return(result); @@ -670,7 +668,7 @@ inline void file_set_to_loading(Editing_File *file){ file->state = editing_file_state_zero(); file->settings = editing_file_settings_zero(); - file->state.is_loading = 1; + file->is_loading = 1; } // BOTTOM diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 3f444030..5571cf0f 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -121,22 +121,6 @@ view_mode_zero(){ return(mode); } -enum View_Widget_Type{ - FWIDG_NONE, - FWIDG_TIMELINES, - // never below this - FWIDG_TYPE_COUNT -}; - -struct View_Widget{ - View_Widget_Type type; - i32 height_; - struct{ - b32 undo_line; - b32 history_line; - } timeline; -}; - enum View_UI{ VUI_None, VUI_Theme, @@ -263,13 +247,13 @@ struct View{ i32 current_color_editing; i32 color_cursor; + // misc i32 font_advance; - i32 font_height; + i32 line_height; View_Mode mode, next_mode; - View_Widget widget; Query_Set query_set; - i32 scrub_max; + f32 widget_height; b32 reinit_scrolling; }; @@ -452,7 +436,13 @@ file_save(System_Functions *system, Mem_Options *mem, Editing_File *file, char * } Temp_Memory temp = begin_temp_memory(&mem->part); - data = (char*)push_array(&mem->part, char, max); + char empty = 0; + if (max == 0){ + data = ∅ + } + else{ + data = (char*)push_array(&mem->part, char, max); + } Assert(data); if (dos_write_mode){ @@ -508,18 +498,18 @@ file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *buffer, i32 count = buffer->line_count; i32 target_lines = count + additional_lines; Assert(max == buffer->widths_max); - + if (target_lines > max || max == 0){ max = LargeRoundUp(target_lines + max, Kbytes(1)); - + f32 *new_widths = (f32*)general_memory_reallocate( general, buffer->line_widths, sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS); - + i32 *new_lines = (i32*)general_memory_reallocate( general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); - + if (new_lines){ buffer->line_starts = new_lines; buffer->line_max = max; @@ -535,7 +525,7 @@ file_grow_starts_widths_as_needed(General_Memory *general, Buffer_Type *buffer, result = GROW_FAILED; } } - + return(result); } @@ -554,34 +544,34 @@ file_measure_starts_widths(System_Functions *system, General_Memory *general, TentativeAssert(buffer->line_starts); // TODO(allen): when unable to allocate? } - + Buffer_Measure_Starts state = {}; while (buffer_measure_starts_widths(&state, buffer, advance_data)){ i32 count = state.count; i32 max = buffer->line_max; max = ((max + 1) << 1); - + { i32 *new_lines = (i32*)general_memory_reallocate( general, buffer->line_starts, sizeof(i32)*count, sizeof(i32)*max, BUBBLE_STARTS); - + // TODO(allen): when unable to grow? TentativeAssert(new_lines); buffer->line_starts = new_lines; buffer->line_max = max; } - + { f32 *new_lines = (f32*) general_memory_reallocate(general, buffer->line_widths, sizeof(f32)*count, sizeof(f32)*max, BUBBLE_WIDTHS); - + // TODO(allen): when unable to grow? TentativeAssert(new_lines); buffer->line_widths = new_lines; buffer->widths_max = max; } - + } buffer->line_count = state.count; buffer->widths_count = state.count; @@ -617,11 +607,11 @@ view_compute_lowest_line(View *view){ } else{ f32 wrap_y = view->file_data.line_wrap_y[last_line]; - lowest_line = FLOOR32(wrap_y / view->font_height); + lowest_line = FLOOR32(wrap_y / view->line_height); f32 max_width = view_file_width(view); - + Editing_File *file = view->file_data.file; - Assert(!file->state.is_dummy); + Assert(!file->is_dummy); f32 width = file->state.buffer.line_widths[last_line]; i32 line_span = view_wrapped_line_span(width, max_width); lowest_line += line_span - 1; @@ -630,13 +620,29 @@ view_compute_lowest_line(View *view){ return lowest_line; } +inline f32 +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(max_target_y); +} + +inline f32 +view_compute_max_target_y(View *view){ + i32 lowest_line = view_compute_lowest_line(view); + i32 line_height = view->line_height; + f32 view_height = view_file_height(view); + f32 max_target_y = view_compute_max_target_y(lowest_line, line_height, view_height); + return(max_target_y); +} + internal void view_measure_wraps(General_Memory *general, View *view){ Buffer_Type *buffer; - + buffer = &view->file_data.file->state.buffer; i32 line_count = buffer->line_count; - + if (view->file_data.line_max < line_count){ i32 max = view->file_data.line_max = LargeRoundUp(line_count, Kbytes(1)); if (view->file_data.line_wrap_y){ @@ -648,27 +654,27 @@ view_measure_wraps(General_Memory *general, View *view){ general_memory_allocate(general, sizeof(f32)*max, BUBBLE_WRAPS); } } - - f32 line_height = (f32)view->font_height; + + f32 line_height = (f32)view->line_height; f32 max_width = view_file_width(view); buffer_measure_wrap_y(buffer, view->file_data.line_wrap_y, line_height, max_width); - + view->file_data.line_count = line_count; } internal void file_create_from_string(System_Functions *system, Models *models, Editing_File *file, char *filename, String val, b8 read_only = 0){ - + Font_Set *font_set = models->font_set; Working_Set *working_set = &models->working_set; General_Memory *general = &models->mem.general; Partition *part = &models->mem.part; Buffer_Init_Type init; i32 page_size, scratch_size, init_success; - + file->state = editing_file_state_zero(); - + init = buffer_begin_init(&file->state.buffer, val.str, val.size); for (; buffer_init_need_more(&init); ){ page_size = buffer_init_page_size(&init); @@ -677,29 +683,29 @@ file_create_from_string(System_Functions *system, Models *models, void *data = general_memory_allocate(general, page_size, BUBBLE_BUFFER); buffer_init_provide_page(&init, data, page_size); } - + scratch_size = partition_remaining(part); Assert(scratch_size > 0); init_success = buffer_end_init(&init, part->base + part->pos, scratch_size); AllowLocal(init_success); Assert(init_success); - + if (buffer_size(&file->state.buffer) < val.size){ file->settings.dos_write_mode = 1; } - + file_init_strings(file); file_set_name(working_set, file, (char*)filename); - + file->state.font_id = models->global_font.font_id; - + file_synchronize_times(system, file, filename); - + Render_Font *font = get_font_info(font_set, file->state.font_id)->font; float *advance_data = 0; if (font) advance_data = font->advance_data; file_measure_starts_widths(system, general, &file->state.buffer, advance_data); - + file->settings.read_only = read_only; if (!read_only){ // TODO(allen): Redo undo system (if you don't mind the pun) @@ -708,27 +714,27 @@ file_create_from_string(System_Functions *system, Models *models, file->state.undo.undo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING); file->state.undo.undo.edit_max = request_size / sizeof(Edit_Step); file->state.undo.undo.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO); - + file->state.undo.redo.max = request_size; file->state.undo.redo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING); file->state.undo.redo.edit_max = request_size / sizeof(Edit_Step); file->state.undo.redo.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO); - + file->state.undo.history.max = request_size; file->state.undo.history.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING); file->state.undo.history.edit_max = request_size / sizeof(Edit_Step); file->state.undo.history.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO); - + file->state.undo.children.max = request_size; file->state.undo.children.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING); file->state.undo.children.edit_max = request_size / sizeof(Buffer_Edit); file->state.undo.children.edits = (Buffer_Edit*)general_memory_allocate(general, request_size, BUBBLE_UNDO); - + file->state.undo.history_block_count = 1; file->state.undo.history_head_block = 0; file->state.undo.current_block_normal = 1; } - + Hook_Function *open_hook = models->hooks[hook_open_file]; models->buffer_param_indices[models->buffer_param_count++] = file->id.id; open_hook(&models->app_links); @@ -762,24 +768,24 @@ file_close(System_Functions *system, General_Memory *general, Editing_File *file if (file->state.token_stack.tokens){ general_memory_free(general, file->state.token_stack.tokens); } - + Buffer_Type *buffer = &file->state.buffer; if (buffer->data){ general_memory_free(general, buffer->data); general_memory_free(general, buffer->line_starts); general_memory_free(general, buffer->line_widths); } - + if (file->state.undo.undo.edits){ general_memory_free(general, file->state.undo.undo.strings); general_memory_free(general, file->state.undo.undo.edits); - + general_memory_free(general, file->state.undo.redo.strings); general_memory_free(general, file->state.undo.redo.edits); - + general_memory_free(general, file->state.undo.history.strings); general_memory_free(general, file->state.undo.history.edits); - + general_memory_free(general, file->state.undo.children.strings); general_memory_free(general, file->state.undo.children.edits); } @@ -793,27 +799,83 @@ internal Job_Callback_Sig(job_full_lex){ Editing_File *file = (Editing_File*)data[0]; General_Memory *general = (General_Memory*)data[1]; - + Cpp_File cpp_file; cpp_file.data = file->state.buffer.data; cpp_file.size = file->state.buffer.size; - + Cpp_Token_Stack tokens; tokens.tokens = (Cpp_Token*)memory->data; tokens.max_count = memory->size / sizeof(Cpp_Token); tokens.count = 0; - - Cpp_Lex_Data status = cpp_lex_file_nonalloc(cpp_file, &tokens); - - while (!status.complete){ - system->grow_thread_memory(memory); - tokens.tokens = (Cpp_Token*)memory->data; - tokens.max_count = memory->size / sizeof(Cpp_Token); - status = cpp_lex_file_nonalloc(cpp_file, &tokens, status); - } - + +#if 0 + + b32 still_lexing = 1; + + Lex_Data lex = {0}; + + do{ + i32 result = + cpp_lex_nonalloc(&lex, cpp_file.data, cpp_file.size, &tokens, 2048); + + switch (result){ + case LexNeedChunk: Assert(!"Invalid Path"); break; + + case LexNeedTokenMemory: + if (system->check_cancel(thread)){ + return; + } + system->grow_thread_memory(memory); + tokens.tokens = (Cpp_Token*)memory->data; + tokens.max_count = memory->size / sizeof(Cpp_Token); + break; + + case LexHitTokenLimit: + if (system->check_cancel(thread)){ + return; + } + break; + + case LexFinished: still_lexing = 0; break; + } + } while (still_lexing); + +#else + + Cpp_Lex_Data status = {}; + + do{ + for (i32 r = 2048; r > 0 && status.pos < cpp_file.size; --r){ + Cpp_Lex_Data prev_lex = status; + Cpp_Read_Result step_result = cpp_lex_step(cpp_file, &status); + + if (step_result.has_result){ + if (!cpp_push_token_nonalloc(&tokens, step_result.token)){ + status = prev_lex; + system->grow_thread_memory(memory); + tokens.tokens = (Cpp_Token*)memory->data; + tokens.max_count = memory->size / sizeof(Cpp_Token); + } + } + } + + if (status.pos >= cpp_file.size){ + status.complete = 1; + } + else{ + if (system->check_cancel(thread)){ + return; + } + } + } while(!status.complete); + +#endif + + + i32 new_max = LargeRoundUp(tokens.count+1, Kbytes(1)); - + system->acquire_lock(FRAME_LOCK); { Assert(file->state.swap_stack.tokens == 0); @@ -821,25 +883,25 @@ Job_Callback_Sig(job_full_lex){ general_memory_allocate(general, new_max*sizeof(Cpp_Token), BUBBLE_TOKENS); } system->release_lock(FRAME_LOCK); - + u8 *dest = (u8*)file->state.swap_stack.tokens; u8 *src = (u8*)tokens.tokens; - + memcpy(dest, src, tokens.count*sizeof(Cpp_Token)); - + system->acquire_lock(FRAME_LOCK); { - file->state.token_stack.count = tokens.count; - file->state.token_stack.max_count = new_max; - if (file->state.token_stack.tokens) - general_memory_free(general, file->state.token_stack.tokens); - file->state.token_stack.tokens = file->state.swap_stack.tokens; + Cpp_Token_Stack *file_stack = &file->state.token_stack; + file_stack->count = tokens.count; + file_stack->max_count = new_max; + if (file_stack->tokens){ + general_memory_free(general, file_stack->tokens); + } + file_stack->tokens = file->state.swap_stack.tokens; file->state.swap_stack.tokens = 0; } system->release_lock(FRAME_LOCK); - - exchange->force_redraw = 1; - + // NOTE(allen): These are outside the locked section because I don't // think getting these out of order will cause critical bugs, and I // want to minimize what's done in locked sections. @@ -871,18 +933,17 @@ internal void file_first_lex_parallel(System_Functions *system, General_Memory *general, Editing_File *file){ file->settings.tokens_exist = 1; - - if (file->state.is_loading == 0 && file->state.still_lexing == 0){ + + if (file->is_loading == 0 && file->state.still_lexing == 0){ Assert(file->state.token_stack.tokens == 0); - + file->state.tokens_complete = 0; file->state.still_lexing = 1; - + Job_Data job; job.callback = job_full_lex; job.data[0] = file; job.data[1] = general; - job.memory_request = Kbytes(64); file->state.lex_job = system->post_job(BACKGROUND_THREADS, job); } } @@ -898,19 +959,19 @@ file_relex_parallel(System_Functions *system, file_first_lex_parallel(system, general, file); return; } - + b32 inline_lex = !file->state.still_lexing; if (inline_lex){ Cpp_File cpp_file; cpp_file.data = file->state.buffer.data; cpp_file.size = file->state.buffer.size; - + Cpp_Token_Stack *stack = &file->state.token_stack; - + Cpp_Relex_State state = cpp_relex_nonalloc_start(cpp_file, stack, start_i, end_i, amount, 100); - + Temp_Memory temp = begin_temp_memory(part); i32 relex_end; Cpp_Token_Stack relex_space; @@ -923,43 +984,43 @@ file_relex_parallel(System_Functions *system, else{ i32 delete_amount = relex_end - state.start_token_i; i32 shift_amount = relex_space.count - delete_amount; - + if (shift_amount != 0){ - int new_count = stack->count + shift_amount; + i32 new_count = stack->count + shift_amount; if (new_count > stack->max_count){ - int new_max = LargeRoundUp(new_count, Kbytes(1)); + i32 new_max = LargeRoundUp(new_count, Kbytes(1)); stack->tokens = (Cpp_Token*) general_memory_reallocate(general, stack->tokens, stack->count*sizeof(Cpp_Token), new_max*sizeof(Cpp_Token), BUBBLE_TOKENS); stack->max_count = new_max; } - - int shift_size = stack->count - relex_end; + + i32 shift_size = stack->count - relex_end; if (shift_size > 0){ Cpp_Token *old_base = stack->tokens + relex_end; memmove(old_base + shift_amount, old_base, sizeof(Cpp_Token)*shift_size); } - + stack->count += shift_amount; } - + memcpy(state.stack->tokens + state.start_token_i, relex_space.tokens, sizeof(Cpp_Token)*relex_space.count); } - + end_temp_memory(temp); } - + if (!inline_lex){ Cpp_Token_Stack *stack = &file->state.token_stack; Cpp_Get_Token_Result get_token_result = cpp_get_token(stack, end_i); i32 end_token_i = get_token_result.token_index; - + if (end_token_i < 0) end_token_i = 0; else if (end_i > stack->tokens[end_token_i].start) ++end_token_i; - + cpp_shift_token_starts(stack, end_token_i, amount); --end_token_i; if (end_token_i >= 0){ @@ -968,14 +1029,13 @@ file_relex_parallel(System_Functions *system, token->size += amount; } } - + file->state.still_lexing = 1; - + Job_Data job; job.callback = job_full_lex; job.data[0] = file; job.data[1] = general; - job.memory_request = Kbytes(64); file->state.lex_job = system->post_job(BACKGROUND_THREADS, job); } } @@ -1030,22 +1090,22 @@ undo_children_push(General_Memory *general, Small_Edit_Stack *children, i32 result = children->edit_count; if (children->edit_count + edit_count > children->edit_max) child_stack_grow_edits(general, children, edit_count); - + if (children->size + string_size > children->max) child_stack_grow_string(general, children, string_size); - + memcpy(children->edits + children->edit_count, edits, edit_count*sizeof(Buffer_Edit)); memcpy(children->strings + children->size, strings, string_size); - + Buffer_Edit *edit = children->edits + children->edit_count; i32 start_pos = children->size; for (i32 i = 0; i < edit_count; ++i, ++edit){ edit->str_start += start_pos; } - + children->edit_count += edit_count; children->size += string_size; - + return result; } @@ -1061,25 +1121,25 @@ file_post_undo(General_Memory *general, Editing_File *file, file->state.undo.redo.size = 0; file->state.undo.redo.edit_count = 0; } - + Edit_Stack *undo = &file->state.undo.undo; Edit_Step *result = 0; - + if (step.child_count == 0){ if (step.edit.end - step.edit.start + undo->size > undo->max) undo_stack_grow_string(general, undo, step.edit.end - step.edit.start); - + Buffer_Edit inv; buffer_invert_edit(&file->state.buffer, step.edit, &inv, (char*)undo->strings, &undo->size, undo->max); - + Edit_Step inv_step = {}; inv_step.edit = inv; inv_step.pre_pos = step.pre_pos; inv_step.post_pos = step.post_pos; inv_step.can_merge = (b8)can_merge; inv_step.type = ED_UNDO; - + b32 did_merge = 0; if (do_merge && undo->edit_count > 0){ Edit_Step prev = undo->edits[undo->edit_count-1]; @@ -1091,7 +1151,7 @@ file_post_undo(General_Memory *general, Editing_File *file, } } } - + if (did_merge){ result = undo->edits + (undo->edit_count-1); *result = inv_step; @@ -1099,7 +1159,7 @@ file_post_undo(General_Memory *general, Editing_File *file, else{ if (undo->edit_count == undo->edit_max) undo_stack_grow_edits(general, undo); - + result = undo->edits + (undo->edit_count++); *result = inv_step; } @@ -1112,7 +1172,7 @@ file_post_undo(General_Memory *general, Editing_File *file, inv_step.special_type = step.special_type; inv_step.child_count = step.inverse_child_count; inv_step.inverse_child_count = step.child_count; - + if (undo->edit_count == undo->edit_max) undo_stack_grow_edits(general, undo); result = undo->edits + (undo->edit_count++); @@ -1134,21 +1194,21 @@ undo_stack_pop(Edit_Stack *stack){ internal void file_post_redo(General_Memory *general, Editing_File *file, Edit_Step step){ Edit_Stack *redo = &file->state.undo.redo; - + if (step.child_count == 0){ if (step.edit.end - step.edit.start + redo->size > redo->max) undo_stack_grow_string(general, redo, step.edit.end - step.edit.start); - + Buffer_Edit inv; buffer_invert_edit(&file->state.buffer, step.edit, &inv, (char*)redo->strings, &redo->size, redo->max); - + Edit_Step inv_step = {}; inv_step.edit = inv; inv_step.pre_pos = step.pre_pos; inv_step.post_pos = step.post_pos; inv_step.type = ED_REDO; - + if (redo->edit_count == redo->edit_max) undo_stack_grow_edits(general, redo); redo->edits[redo->edit_count++] = inv_step; @@ -1161,9 +1221,10 @@ file_post_redo(General_Memory *general, Editing_File *file, Edit_Step step){ inv_step.special_type = step.special_type; inv_step.child_count = step.inverse_child_count; inv_step.inverse_child_count = step.child_count; - - if (redo->edit_count == redo->edit_max) + + if (redo->edit_count == redo->edit_max){ undo_stack_grow_edits(general, redo); + } redo->edits[redo->edit_count++] = inv_step; } } @@ -1172,7 +1233,7 @@ inline void file_post_history_block(Editing_File *file, i32 pos){ Assert(file->state.undo.history_head_block < pos); Assert(pos < file->state.undo.history.edit_count); - + Edit_Step *history = file->state.undo.history.edits; Edit_Step *step = history + file->state.undo.history_head_block; step->next_block = pos; @@ -1195,7 +1256,7 @@ file_post_history(General_Memory *general, Editing_File *file, Edit_Step step, b32 do_merge, b32 can_merge){ Edit_Stack *history = &file->state.undo.history; Edit_Step *result = 0; - + persist Edit_Type reverse_types[4]; if (reverse_types[ED_UNDO] == 0){ reverse_types[ED_NORMAL] = ED_REVERSE_NORMAL; @@ -1203,22 +1264,22 @@ file_post_history(General_Memory *general, Editing_File *file, reverse_types[ED_UNDO] = ED_REDO; reverse_types[ED_REDO] = ED_UNDO; } - + if (step.child_count == 0){ if (step.edit.end - step.edit.start + history->size > history->max) undo_stack_grow_string(general, history, step.edit.end - step.edit.start); - + Buffer_Edit inv; buffer_invert_edit(&file->state.buffer, step.edit, &inv, (char*)history->strings, &history->size, history->max); - + Edit_Step inv_step = {}; inv_step.edit = inv; inv_step.pre_pos = step.pre_pos; inv_step.post_pos = step.post_pos; inv_step.can_merge = (b8)can_merge; inv_step.type = reverse_types[step.type]; - + bool32 did_merge = 0; if (do_merge && history->edit_count > 0){ Edit_Step prev = history->edits[history->edit_count-1]; @@ -1230,7 +1291,7 @@ file_post_history(General_Memory *general, Editing_File *file, } } } - + if (did_merge){ result = history->edits + (history->edit_count-1); } @@ -1239,7 +1300,7 @@ file_post_history(General_Memory *general, Editing_File *file, undo_stack_grow_edits(general, history); result = history->edits + (history->edit_count++); } - + *result = inv_step; } else{ @@ -1250,13 +1311,13 @@ file_post_history(General_Memory *general, Editing_File *file, inv_step.special_type = step.special_type; inv_step.inverse_child_count = step.child_count; inv_step.child_count = step.inverse_child_count; - + if (history->edit_count == history->edit_max) undo_stack_grow_edits(general, history); result = history->edits + (history->edit_count++); *result = inv_step; } - + return result; } @@ -1265,12 +1326,12 @@ view_compute_cursor_from_pos(View *view, i32 pos){ Editing_File *file = view->file_data.file; Models *models = view->persistent.models; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - + Full_Cursor result = {}; if (font){ f32 max_width = view_file_width(view); result = buffer_cursor_from_pos(&file->state.buffer, pos, view->file_data.line_wrap_y, - max_width, (f32)view->font_height, font->advance_data); + max_width, (f32)view->line_height, font->advance_data); } return result; } @@ -1280,14 +1341,14 @@ view_compute_cursor_from_unwrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 ro Editing_File *file = view->file_data.file; Models *models = view->persistent.models; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - + Full_Cursor result = {}; if (font){ f32 max_width = view_file_width(view); result = buffer_cursor_from_unwrapped_xy(&file->state.buffer, seek_x, seek_y, - round_down, view->file_data.line_wrap_y, max_width, (f32)view->font_height, font->advance_data); + round_down, view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data); } - + return result; } @@ -1296,15 +1357,15 @@ view_compute_cursor_from_wrapped_xy(View *view, f32 seek_x, f32 seek_y, b32 roun Editing_File *file = view->file_data.file; Models *models = view->persistent.models; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - + Full_Cursor result = {}; if (font){ f32 max_width = view_file_width(view); result = buffer_cursor_from_wrapped_xy(&file->state.buffer, seek_x, seek_y, round_down, view->file_data.line_wrap_y, - max_width, (f32)view->font_height, font->advance_data); + max_width, (f32)view->line_height, font->advance_data); } - + return (result); } @@ -1313,39 +1374,39 @@ view_compute_cursor_from_line_pos(View *view, i32 line, i32 pos){ Editing_File *file = view->file_data.file; Models *models = view->persistent.models; Render_Font *font = get_font_info(models->font_set, models->global_font.font_id)->font; - + Full_Cursor result = {}; if (font){ f32 max_width = view_file_width(view); result = buffer_cursor_from_line_character(&file->state.buffer, line, pos, - view->file_data.line_wrap_y, max_width, (f32)view->font_height, font->advance_data); + view->file_data.line_wrap_y, max_width, (f32)view->line_height, font->advance_data); } - + return (result); } inline Full_Cursor view_compute_cursor(View *view, Buffer_Seek seek){ Full_Cursor result = {}; - + switch(seek.type){ case buffer_seek_pos: result = view_compute_cursor_from_pos(view, seek.pos); break; - + case buffer_seek_wrapped_xy: result = view_compute_cursor_from_wrapped_xy(view, seek.x, seek.y); break; - + case buffer_seek_unwrapped_xy: result = view_compute_cursor_from_unwrapped_xy(view, seek.x, seek.y); break; - + case buffer_seek_line_char: result = view_compute_cursor_from_line_pos(view, seek.line, seek.character); break; } - + return (result); } @@ -1399,39 +1460,66 @@ inline f32 view_get_cursor_y(View *view){ Full_Cursor *cursor; f32 result; - + if (view->file_data.show_temp_highlight) cursor = &view->file_data.temp_highlight; else cursor = &view->recent->cursor; - + if (view->file_data.unwrapped_lines) result = cursor->unwrapped_y; else result = cursor->wrapped_y; - + return result; } -#define CursorMaxY_(m,h) ((m) - (h)*3) -#define CursorMinY_(m,h) (-(m) + (h)*2) +struct Cursor_Limits{ + f32 min, max; + f32 delta; +}; -#define CursorMaxY(m,h) (CursorMaxY_(m,h) > 0)?(CursorMaxY_(m,h)):(0) -#define CursorMinY(m,h) (CursorMinY_(m,h) > 0)?(CursorMinY_(m,h)):(0) +inline Cursor_Limits +view_cursor_limits(View *view){ + Cursor_Limits limits = {0}; + + f32 line_height = (f32)view->line_height; + f32 visible_height = view_file_height(view); + + limits.max = visible_height - line_height*3.f; + limits.min = line_height * 2; + + if (limits.max - limits.min <= line_height){ + if (visible_height >= line_height){ + limits.max = visible_height - line_height; + limits.min = -line_height; + } + else{ + limits.max = visible_height; + limits.min = -line_height; + } + } + + limits.max = (limits.max > 0)?(limits.max):(0); + limits.min = (limits.min > 0)?(limits.min):(0); + + limits.delta = clamp_top(line_height*3.f, (limits.max - limits.min)*.5f); + + return(limits); +} internal void -view_move_cursor_to_view(View *view){ - f32 min_target_y = view->recent->scroll.min_y; - i32 line_height = view->font_height; +view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll){ + i32 line_height = view->line_height; f32 old_cursor_y = view_get_cursor_y(view); f32 cursor_y = old_cursor_y; - f32 target_y = view->recent->scroll.target_y; - f32 cursor_max_y = CursorMaxY(view_file_height(view), line_height); - f32 cursor_min_y = CursorMinY(min_target_y, line_height); - - if (cursor_y > target_y + cursor_max_y){ - cursor_y = target_y + cursor_max_y; + f32 target_y = scroll.target_y; + + Cursor_Limits limits = view_cursor_limits(view); + + if (cursor_y > target_y + limits.max){ + cursor_y = target_y + limits.max; } - if (target_y != 0 && cursor_y < target_y + cursor_min_y){ - cursor_y = target_y + cursor_min_y; + if (target_y != 0 && cursor_y < target_y + limits.min){ + cursor_y = target_y + limits.min; } - + if (cursor_y != old_cursor_y){ if (cursor_y > old_cursor_y){ cursor_y += line_height; @@ -1446,10 +1534,6 @@ view_move_cursor_to_view(View *view){ internal void view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll){ - f32 line_height = (f32)view->font_height; - f32 delta_y = 3.f*line_height; - - f32 max_visible_y = view_file_height(view); f32 max_x = view_file_width(view); f32 cursor_y = view_get_cursor_y(view); @@ -1459,18 +1543,16 @@ view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll){ f32 target_y = scroll_vars.target_y; f32 target_x = scroll_vars.target_x; - f32 cursor_max_y = CursorMaxY(max_visible_y, line_height); - f32 cursor_min_y = CursorMinY(scroll_vars.min_y, line_height); + Cursor_Limits limits = view_cursor_limits(view); - if (cursor_y > target_y + cursor_max_y){ - target_y = cursor_y - cursor_max_y + delta_y; + if (cursor_y > target_y + limits.max){ + target_y = cursor_y - limits.max + limits.delta; } - if (cursor_y < target_y + cursor_min_y){ - target_y = cursor_y - delta_y - cursor_min_y; + if (cursor_y < target_y + limits.min){ + target_y = cursor_y - limits.delta - limits.min; } - if (target_y > scroll_vars.max_y) target_y = scroll_vars.max_y; - if (target_y < scroll_vars.min_y) target_y = view->recent->scroll.min_y; + target_y = clamp(0.f, target_y, scroll_vars.max_y); if (cursor_x < target_x){ target_x = (f32)Max(0, cursor_x - max_x/2); @@ -1501,7 +1583,7 @@ view_set_file(View *view, Editing_File *file, Models *models){ // TODO(allen): This belongs somewhere else. fnt_info = get_font_info(models->font_set, models->global_font.font_id); view->font_advance = fnt_info->advance; - view->font_height = fnt_info->height; + view->line_height = fnt_info->height; file_view_nullify_file(view); view->file_data.file = file; @@ -1530,7 +1612,8 @@ view_set_file(View *view, Editing_File *file, Models *models){ if (file_is_ready(file)){ view_measure_wraps(&models->mem.general, view); view->recent->cursor = view_compute_cursor_from_pos(view, view->recent->cursor.pos); - view->recent->scroll.max_y = 1000000000.f; + view->recent->scroll.max_y = view_compute_max_target_y(view); + view_move_view_to_cursor(view, &view->recent->scroll); } } @@ -1546,11 +1629,10 @@ view_set_file(View *view, Editing_File *file, Models *models){ if (file_is_ready(file)){ view_measure_wraps(&models->mem.general, view); view->recent->cursor = view_compute_cursor_from_pos(view, file->state.cursor_pos); - view->recent->scroll.max_y = 1000000000.f; + view->recent->scroll.max_y = view_compute_max_target_y(view); + view_move_view_to_cursor(view, &view->recent->scroll); - if (!found_recent_entry){ - view->reinit_scrolling = 1; - } + view->reinit_scrolling = 1; } } } @@ -1559,7 +1641,6 @@ view_set_file(View *view, Editing_File *file, Models *models){ struct Relative_Scrolling{ f32 scroll_x, scroll_y; f32 target_x, target_y; - f32 scroll_min_limit; }; internal Relative_Scrolling @@ -1569,7 +1650,6 @@ view_get_relative_scrolling(View *view){ cursor_y = view_get_cursor_y(view); result.scroll_y = cursor_y - view->recent->scroll.scroll_y; result.target_y = cursor_y - view->recent->scroll.target_y; - result.scroll_min_limit = view->recent->scroll.min_y; return(result); } @@ -1578,10 +1658,8 @@ view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){ f32 cursor_y; cursor_y = view_get_cursor_y(view); view->recent->scroll.scroll_y = cursor_y - scrolling.scroll_y; - view->recent->scroll.target_y = cursor_y - scrolling.target_y; - if (view->recent->scroll.target_y < scrolling.scroll_min_limit){ - view->recent->scroll.target_y = scrolling.scroll_min_limit; - } + view->recent->scroll.target_y = + clamp_bottom(0.f, cursor_y - scrolling.target_y); } inline void @@ -1616,21 +1694,16 @@ view_cursor_move(View *view, i32 line, i32 pos){ view_cursor_move(view, cursor); } -inline void -view_set_widget(View *view, View_Widget_Type type){ - view->widget.type = type; -} - inline i32_Rect -view_widget_rect(View *view, i32 font_height){ +view_widget_rect(View *view, i32 line_height){ Panel *panel = view->panel; i32_Rect result = panel->inner; - + if (view->file_data.file){ - result.y0 = result.y0 + font_height + 2; + result.y0 = result.y0 + line_height + 2; } - + return(result); } @@ -1645,30 +1718,30 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step History_Mode history_mode){ if (!file->state.undo.undo.edits) return; General_Memory *general = &mem->general; - + b32 can_merge = 0, do_merge = 0; switch (step.type){ case ED_NORMAL: { if (step.edit.len == 1 && str && char_is_alpha_numeric(*str)) can_merge = 1; if (step.edit.len == 1 && str && (can_merge || char_is_whitespace(*str))) do_merge = 1; - + if (history_mode != hist_forward) file_post_history(general, file, step, do_merge, can_merge); file_post_undo(general, file, step, do_merge, can_merge); }break; - + case ED_REVERSE_NORMAL: { if (history_mode != hist_forward) file_post_history(general, file, step, do_merge, can_merge); - + undo_stack_pop(&file->state.undo.undo); - + b32 restore_redos = 0; Edit_Step *redo_end = 0; - + if (history_mode == hist_backward && file->state.undo.edit_history_cursor > 0){ restore_redos = 1; redo_end = file->state.undo.history.edits + (file->state.undo.edit_history_cursor - 1); @@ -1677,7 +1750,7 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step restore_redos = 1; redo_end = file->state.undo.history.edits + (file->state.undo.history.edit_count - 1); } - + if (restore_redos){ Edit_Step *redo_start = redo_end; i32 steps_of_redo = 0; @@ -1696,25 +1769,25 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step } --redo_start; } - + if (redo_start < redo_end){ ++redo_start; ++redo_end; - + if (file->state.undo.redo.edit_count + steps_of_redo > file->state.undo.redo.edit_max) undo_stack_grow_edits(general, &file->state.undo.redo); - + if (file->state.undo.redo.size + strings_of_redo > file->state.undo.redo.max) undo_stack_grow_string(general, &file->state.undo.redo, strings_of_redo); - + u8 *str_src = file->state.undo.history.strings + redo_end->edit.str_start; u8 *str_dest_base = file->state.undo.redo.strings; i32 str_redo_pos = file->state.undo.redo.size + strings_of_redo; - + Edit_Step *edit_src = redo_end; Edit_Step *edit_dest = file->state.undo.redo.edits + file->state.undo.redo.edit_count + steps_of_redo; - + i32 undo_count = 0; for (i32 i = 0; i < steps_of_redo;){ --edit_src; @@ -1725,13 +1798,13 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step } else{ ++i; - + --edit_dest; *edit_dest = *edit_src; - + str_redo_pos -= edit_dest->edit.len; edit_dest->edit.str_start = str_redo_pos; - + memcpy(str_dest_base + str_redo_pos, str_src, edit_dest->edit.len); } } @@ -1740,13 +1813,13 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step } } Assert(undo_count == 0); - + file->state.undo.redo.size += strings_of_redo; file->state.undo.redo.edit_count += steps_of_redo; } } }break; - + case ED_UNDO: { if (history_mode != hist_forward) @@ -1754,20 +1827,20 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step file_post_redo(general, file, step); undo_stack_pop(&file->state.undo.undo); }break; - + case ED_REDO: { if (step.edit.len == 1 && str && char_is_alpha_numeric(*str)) can_merge = 1; if (step.edit.len == 1 && str && (can_merge || char_is_whitespace(*str))) do_merge = 1; - + if (history_mode != hist_forward) file_post_history(general, file, step, do_merge, can_merge); - + file_post_undo(general, file, step, do_merge, can_merge); undo_stack_pop(&file->state.undo.redo); }break; } - + if (history_mode != hist_forward){ if (step.type == ED_UNDO || step.type == ED_REDO){ if (file->state.undo.current_block_normal){ @@ -1788,7 +1861,7 @@ file_update_history_before_edit(Mem_Options *mem, Editing_File *file, Edit_Step file->state.undo.current_block_normal = !file->state.undo.current_block_normal; } } - + if (history_mode == hist_normal){ file->state.undo.edit_history_cursor = file->state.undo.history.edit_count; } @@ -1804,8 +1877,9 @@ file_pre_edit_maintenance(System_Functions *system, general_memory_free(general, file->state.swap_stack.tokens); file->state.swap_stack.tokens = 0; } + file->state.still_lexing = 0; } - file->state.last_4ed_edit_time = system->time(); + file->state.last_4ed_edit_time = system->now_time_stamp(); } struct Cursor_Fix_Descriptor{ @@ -1827,19 +1901,19 @@ file_edit_cursor_fix(System_Functions *system, Partition *part, General_Memory *general, Editing_File *file, Editing_Layout *layout, Cursor_Fix_Descriptor desc){ - + Full_Cursor temp_cursor; Temp_Memory cursor_temp = begin_temp_memory(part); i32 cursor_max = layout->panel_max_count * 2; Cursor_With_Index *cursors = push_array(part, Cursor_With_Index, cursor_max); - + f32 y_offset = 0, y_position = 0; i32 cursor_count = 0; - + View *view; Panel *panel, *used_panels; used_panels = &layout->used_sentinel; - + for (dll_items(panel, used_panels)){ view = panel->view; if (view->file_data.file == file){ @@ -1849,7 +1923,7 @@ file_edit_cursor_fix(System_Functions *system, write_cursor_with_index(cursors, &cursor_count, view->recent->scroll_i - 1); } } - + if (cursor_count > 0){ buffer_sort_cursors(cursors, cursor_count); if (desc.is_batch){ @@ -1862,20 +1936,20 @@ file_edit_cursor_fix(System_Functions *system, desc.shift_amount + (desc.end - desc.start)); } buffer_unsort_cursors(cursors, cursor_count); - + cursor_count = 0; for (dll_items(panel, used_panels)){ view = panel->view; if (view && view->file_data.file == file){ view_cursor_move(view, cursors[cursor_count++].pos); view->recent->preferred_x = view_get_cursor_x(view); - + view->recent->mark = cursors[cursor_count++].pos + 1; i32 new_scroll_i = cursors[cursor_count++].pos + 1; if (view->recent->scroll_i != new_scroll_i){ view->recent->scroll_i = new_scroll_i; temp_cursor = view_compute_cursor_from_pos(view, view->recent->scroll_i); - y_offset = MOD(view->recent->scroll.scroll_y, view->font_height); + y_offset = MOD(view->recent->scroll.scroll_y, view->line_height); if (view->file_data.unwrapped_lines){ y_position = temp_cursor.unwrapped_y + y_offset; @@ -1891,7 +1965,7 @@ file_edit_cursor_fix(System_Functions *system, } } } - + end_temp_memory(cursor_temp); } @@ -1900,26 +1974,26 @@ file_do_single_edit(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){ if (!use_high_permission && file->settings.read_only) return; - + Mem_Options *mem = &models->mem; Editing_Layout *layout = &models->layout; - + // NOTE(allen): fixing stuff beforewards???? file_update_history_before_edit(mem, file, spec.step, spec.str, history_mode); file_pre_edit_maintenance(system, &mem->general, file); - + // NOTE(allen): actual text replacement i32 shift_amount = 0; General_Memory *general = &mem->general; Partition *part = &mem->part; - + char *str = (char*)spec.str; i32 start = spec.step.edit.start; i32 end = spec.step.edit.end; i32 str_len = spec.step.edit.len; - + i32 scratch_size = partition_remaining(part); - + Assert(scratch_size > 0); i32 request_amount = 0; Assert(end <= buffer_size(&file->state.buffer)); @@ -1932,42 +2006,42 @@ file_do_single_edit(System_Functions *system, void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount); if (old_data) general_memory_free(general, old_data); } - + Buffer_Type *buffer = &file->state.buffer; i32 line_start = buffer_get_line_index(&file->state.buffer, start); i32 line_end = buffer_get_line_index(&file->state.buffer, end); i32 replaced_line_count = line_end - line_start; i32 new_line_count = buffer_count_newlines(&file->state.buffer, start, start+str_len); i32 line_shift = new_line_count - replaced_line_count; - + Render_Font *font = get_font_info(models->font_set, file->state.font_id)->font; - + file_grow_starts_widths_as_needed(general, buffer, line_shift); buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount); buffer_remeasure_widths(buffer, font->advance_data, line_start, line_end, line_shift); - + // NOTE(allen): update the views looking at this file Panel *panel, *used_panels; used_panels = &layout->used_sentinel; - + for (dll_items(panel, used_panels)){ View *view = panel->view; if (view->file_data.file == file){ view_measure_wraps(general, view); } } - + #if BUFFER_EXPERIMENT_SCALPEL <= 0 // NOTE(allen): fixing stuff afterwards if (file->settings.tokens_exist) file_relex_parallel(system, mem, file, start, end, shift_amount); #endif - + Cursor_Fix_Descriptor desc = {}; desc.start = start; desc.end = end; desc.shift_amount = shift_amount; - + file_edit_cursor_fix(system, part, general, file, layout, desc); } @@ -1975,26 +2049,26 @@ internal void file_do_white_batch_edit(System_Functions *system, Models *models, Editing_File *file, Edit_Spec spec, History_Mode history_mode, b32 use_high_permission = 0){ if (!use_high_permission && file->settings.read_only) return; - + Mem_Options *mem = &models->mem; Editing_Layout *layout = &models->layout; - + // NOTE(allen): fixing stuff "beforewards"??? Assert(spec.str == 0); file_update_history_before_edit(mem, file, spec.step, 0, history_mode); file_pre_edit_maintenance(system, &mem->general, file); - + // NOTE(allen): actual text replacement General_Memory *general = &mem->general; Partition *part = &mem->part; - + u8 *str_base = file->state.undo.children.strings; i32 batch_size = spec.step.child_count; Buffer_Edit *batch = file->state.undo.children.edits + spec.step.first_child; - + Assert(spec.step.first_child < file->state.undo.children.edit_count); Assert(batch_size >= 0); - + i32 scratch_size = partition_remaining(part); Buffer_Batch_State state = {}; i32 request_amount; @@ -2008,7 +2082,7 @@ file_do_white_batch_edit(System_Functions *system, Models *models, Editing_File void *old_data = buffer_edit_provide_memory(&file->state.buffer, new_data, request_amount); if (old_data) general_memory_free(general, old_data); } - + // NOTE(allen): meta data { Buffer_Measure_Starts state = {}; @@ -2017,17 +2091,17 @@ file_do_white_batch_edit(System_Functions *system, Models *models, Editing_File if (font) advance_data = font->advance_data; buffer_measure_starts_widths(&state, &file->state.buffer, advance_data); } - + // NOTE(allen): cursor fixing { Cursor_Fix_Descriptor desc = {}; desc.is_batch = 1; desc.batch = batch; desc.batch_size = batch_size; - + file_edit_cursor_fix(system, part, general, file, layout, desc); } - + // NOTE(allen): token fixing if (file->state.tokens_complete){ Cpp_Token_Stack tokens = file->state.token_stack; @@ -2065,7 +2139,7 @@ file_replace_range(System_Functions *system, Models *models, Editing_File *file, spec.step.type = ED_NORMAL; spec.step.edit.start = start; spec.step.edit.end = end; - + spec.step.edit.len = len; spec.step.pre_pos = file->state.cursor_pos; spec.step.post_pos = next_cursor; @@ -2087,7 +2161,7 @@ view_replace_range(System_Functions *system, Models *models, View *view, inline void view_post_paste_effect(View *view, i32 ticks, i32 start, i32 size, u32 color){ Editing_File *file = view->file_data.file; - + file->state.paste_effect.start = start; file->state.paste_effect.end = start + size; file->state.paste_effect.color = color; @@ -2110,25 +2184,25 @@ view_undo_redo(System_Functions *system, Models *models, View *view, Edit_Stack *stack, Edit_Type expected_type){ Editing_File *file = view->file_data.file; - + if (stack->edit_count > 0){ Edit_Step step = stack->edits[stack->edit_count-1]; - + Assert(step.type == expected_type); - + Edit_Spec spec = {}; spec.step = step; - + if (step.child_count == 0){ spec.step.edit.str_start = 0; spec.str = stack->strings + step.edit.str_start; - + file_do_single_edit(system, models, file, spec, hist_normal); - + if (expected_type == ED_UNDO) view_cursor_move(view, step.pre_pos); else view_cursor_move(view, step.post_pos); view->recent->mark = view->recent->cursor.pos; - + Style *style = main_style(models); view_post_paste_effect(view, 10, step.edit.start, step.edit.len, style->main.undo_color); @@ -2162,9 +2236,9 @@ write_data(u8 *ptr, void *x, i32 size){ internal void file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename){ if (!file->state.undo.undo.edits) return; - + i32 size = 0; - + size += sizeof(i32); size += file->state.undo.undo.edit_count*sizeof(Edit_Step); size += sizeof(i32); @@ -2173,7 +2247,7 @@ file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file size += file->state.undo.history.edit_count*sizeof(Edit_Step); size += sizeof(i32); size += file->state.undo.children.edit_count*sizeof(Buffer_Edit); - + size += sizeof(i32); size += file->state.undo.undo.size; size += sizeof(i32); @@ -2182,7 +2256,7 @@ file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file size += file->state.undo.history.size; size += sizeof(i32); size += file->state.undo.children.size; - + Partition *part = &mem->part; i32 remaining = partition_remaining(part); if (size < remaining){ @@ -2197,17 +2271,17 @@ file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file curs = write_data(curs, &file->state.undo.redo.size, 4); curs = write_data(curs, &file->state.undo.history.size, 4); curs = write_data(curs, &file->state.undo.children.size, 4); - + curs = write_data(curs, file->state.undo.undo.edits, sizeof(Edit_Step)*file->state.undo.undo.edit_count); curs = write_data(curs, file->state.undo.redo.edits, sizeof(Edit_Step)*file->state.undo.redo.edit_count); curs = write_data(curs, file->state.undo.history.edits, sizeof(Edit_Step)*file->state.undo.history.edit_count); curs = write_data(curs, file->state.undo.children.edits, sizeof(Buffer_Edit)*file->state.undo.children.edit_count); - + curs = write_data(curs, file->state.undo.undo.strings, file->state.undo.undo.size); curs = write_data(curs, file->state.undo.redo.strings, file->state.undo.redo.size); curs = write_data(curs, file->state.undo.history.strings, file->state.undo.history.size); curs = write_data(curs, file->state.undo.children.strings, file->state.undo.children.size); - + Assert((i32)(curs - data) == size); system->save_file(filename, data, size); } @@ -2217,9 +2291,9 @@ file_dump_history(System_Functions *system, Mem_Options *mem, Editing_File *file internal void view_history_step(System_Functions *system, Models *models, View *view, History_Mode history_mode){ Assert(history_mode != hist_normal); - + Editing_File *file = view->file_data.file; - + b32 do_history_step = 0; Edit_Step step = {}; if (history_mode == hist_backward){ @@ -2237,23 +2311,23 @@ view_history_step(System_Functions *system, Models *models, View *view, History_ do_history_step = 1; } } - + if (do_history_step){ Edit_Spec spec; spec.step = step; - + if (spec.step.child_count == 0){ spec.step.edit.str_start = 0; spec.str = file->state.undo.history.strings + step.edit.str_start; - + file_do_single_edit(system, models, file, spec, history_mode); - + switch (spec.step.type){ case ED_NORMAL: case ED_REDO: view_cursor_move(view, step.post_pos); break; - + case ED_REVERSE_NORMAL: case ED_UNDO: view_cursor_move(view, step.pre_pos); @@ -2383,21 +2457,21 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po Buffer_Edit *inverse_array, char *inv_str, i32 inv_max, i32 edit_count){ General_Memory *general = &mem->general; - + i32 inv_str_pos = 0; Buffer_Invert_Batch state = {}; if (buffer_invert_batch(&state, &file->state.buffer, edits, edit_count, inverse_array, inv_str, &inv_str_pos, inv_max)){ Assert(0); } - + i32 first_child = undo_children_push(general, &file->state.undo.children, edits, edit_count, (u8*)(str_base), str_size); i32 inverse_first_child = undo_children_push(general, &file->state.undo.children, inverse_array, edit_count, (u8*)(inv_str), inv_str_pos); - + Edit_Spec spec = {}; spec.step.type = ED_NORMAL; spec.step.first_child = first_child; @@ -2407,7 +2481,7 @@ file_compute_whitespace_edit(Mem_Options *mem, Editing_File *file, i32 cursor_po spec.step.inverse_child_count = edit_count; spec.step.pre_pos = cursor_pos; spec.step.post_pos = cursor_pos; - + return spec; } @@ -2415,26 +2489,26 @@ internal void view_clean_whitespace(System_Functions *system, Models *models, View *view){ Mem_Options *mem = &models->mem; Editing_File *file = view->file_data.file; - + Partition *part = &mem->part; i32 line_count = file->state.buffer.line_count; i32 edit_max = line_count * 2; i32 edit_count = 0; - - Assert(file && !file->state.is_dummy); - + + Assert(file && !file->is_dummy); + Temp_Memory temp = begin_temp_memory(part); Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max); - + char *str_base = (char*)part->base + part->pos; i32 str_size = 0; for (i32 line_i = 0; line_i < line_count; ++line_i){ i32 start = file->state.buffer.line_starts[line_i]; Hard_Start_Result hard_start = buffer_find_hard_start(&file->state.buffer, start, 4); - + if (hard_start.all_whitespace) hard_start.indent_pos = 0; - + if ((hard_start.all_whitespace && hard_start.char_pos > start) || !hard_start.all_space){ Buffer_Edit new_edit; new_edit.str_start = str_size; @@ -2448,22 +2522,22 @@ view_clean_whitespace(System_Functions *system, Models *models, View *view){ } Assert(edit_count <= edit_max); } - + if (edit_count > 0){ Assert(buffer_batch_debug_sort_check(edits, edit_count)); - + // NOTE(allen): computing edit spec, doing batch edit Buffer_Edit *inverse_array = push_array(part, Buffer_Edit, edit_count); Assert(inverse_array); - + char *inv_str = (char*)part->base + part->pos; Edit_Spec spec = file_compute_whitespace_edit(mem, file, view->recent->cursor.pos, edits, str_base, str_size, inverse_array, inv_str, part->max - part->pos, edit_count); - + file_do_white_batch_edit(system, models, view->file_data.file, spec, hist_normal); } - + end_temp_memory(temp); } @@ -2476,7 +2550,7 @@ struct Indent_Options{ struct Make_Batch_Result{ char *str_base; i32 str_size; - + Buffer_Edit *edits; i32 edit_max; i32 edit_count; @@ -2487,12 +2561,12 @@ get_first_token_at_line(Buffer *buffer, Cpp_Token_Stack tokens, i32 line){ Cpp_Token *result = 0; i32 start_pos = 0; Cpp_Get_Token_Result get_token = {0}; - + start_pos = buffer->line_starts[line]; get_token = cpp_get_token(&tokens, start_pos); if (get_token.in_whitespace) get_token.token_index += 1; result = tokens.tokens + get_token.token_index; - + return(result); } @@ -2533,22 +2607,24 @@ struct Indent_Parse_State{ internal i32 compute_this_indent(Buffer *buffer, Indent_Parse_State indent, Cpp_Token T, Cpp_Token prev_token, i32 line_i, i32 tab_width){ - + i32 previous_indent = indent.previous_line_indent; i32 this_indent = 0; - + i32 this_line_start = buffer->line_starts[line_i]; i32 next_line_start = 0; - + if (line_i+1 < buffer->line_count){ next_line_start = buffer->line_starts[line_i+1]; } else{ next_line_start = buffer_size(buffer); } - - if ((prev_token.type == CPP_TOKEN_COMMENT || prev_token.type == CPP_TOKEN_STRING_CONSTANT) && - prev_token.start <= this_line_start && prev_token.start + prev_token.size > this_line_start){ + + if ((prev_token.type == CPP_TOKEN_COMMENT || + prev_token.type == CPP_TOKEN_STRING_CONSTANT) && + prev_token.start <= this_line_start && + prev_token.start + prev_token.size > this_line_start){ this_indent = previous_indent; } else{ @@ -2566,7 +2642,7 @@ compute_this_indent(Buffer *buffer, Indent_Parse_State indent, default: if (indent.current_indent > 0){ if (!(prev_token.flags & CPP_TFLAG_PP_BODY || - prev_token.flags & CPP_TFLAG_PP_DIRECTIVE)){ + prev_token.flags & CPP_TFLAG_PP_DIRECTIVE)){ switch (prev_token.type){ case CPP_TOKEN_BRACKET_OPEN: case CPP_TOKEN_BRACE_OPEN: case CPP_TOKEN_BRACE_CLOSE: @@ -2581,20 +2657,22 @@ compute_this_indent(Buffer *buffer, Indent_Parse_State indent, } if (this_indent < 0) this_indent = 0; } - + if (indent.paren_nesting > 0){ - i32 level = indent.paren_nesting-1; - if (level >= ArrayCount(indent.paren_anchor_indent)){ - level = ArrayCount(indent.paren_anchor_indent)-1; + if (prev_token.type != CPP_TOKEN_PARENTHESE_OPEN){ + i32 level = indent.paren_nesting-1; + if (level >= ArrayCount(indent.paren_anchor_indent)){ + level = ArrayCount(indent.paren_anchor_indent)-1; + } + this_indent = indent.paren_anchor_indent[level]; } - this_indent = indent.paren_anchor_indent[level]; } return(this_indent); } internal i32* get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack tokens, - i32 line_start, i32 line_end, i32 tab_width){ + i32 line_start, i32 line_end, i32 tab_width){ i32 indent_mark_count = line_end - line_start; i32 *indent_marks = push_array(part, i32, indent_mark_count); @@ -2623,12 +2701,12 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke i32 line = buffer_get_line_index(buffer, token->start); i32 start = buffer->line_starts[line]; Hard_Start_Result hard_start = buffer_find_hard_start(buffer, start, tab_width); - + indent.current_indent = hard_start.indent_pos; - + Cpp_Token *start_token = get_first_token_at_line(buffer, tokens, line); Cpp_Token *brace_token = token; - + if (start_token->type == CPP_TOKEN_PARENTHESE_OPEN){ if (start_token == tokens.tokens){ found_safe_start_position = 1; @@ -2639,7 +2717,7 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke } else{ int close = 0; - + for (token = brace_token; token >= start_token; --token){ switch(token->type){ case CPP_TOKEN_PARENTHESE_CLOSE: @@ -2653,19 +2731,19 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke switch (close){ case 0: token = start_token; found_safe_start_position = 1; break; - + case CPP_TOKEN_PARENTHESE_CLOSE: token = seek_matching_token_backwards(tokens, token-1, CPP_TOKEN_PARENTHESE_OPEN, CPP_TOKEN_PARENTHESE_CLOSE); break; - + case CPP_TOKEN_BRACKET_CLOSE: token = seek_matching_token_backwards(tokens, token-1, CPP_TOKEN_BRACKET_OPEN, CPP_TOKEN_BRACKET_CLOSE); break; - + case CPP_TOKEN_BRACE_CLOSE: token = seek_matching_token_backwards(tokens, token-1, CPP_TOKEN_BRACE_OPEN, @@ -2674,7 +2752,7 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke } } } while(found_safe_start_position == 0); - + // NOTE(allen): Shift the array so that line_i can just operate in // it's natural value range. indent_marks -= line_start; @@ -2689,6 +2767,7 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke switch (token->type){ case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += tab_width; break; case CPP_TOKEN_BRACE_OPEN: indent.current_indent += tab_width; break; + case CPP_TOKEN_PARENTHESE_OPEN: indent.current_indent += tab_width; break; } indent.previous_line_indent = indent.current_indent; @@ -2705,7 +2784,7 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke T.start = buffer_size(buffer); T.flags = 0; } - + for (; T.start >= next_line_start && line_i < line_end;){ if (line_i+1 < buffer->line_count){ next_line_start = buffer->line_starts[line_i+1]; @@ -2717,7 +2796,19 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke // TODO(allen): Since this is called in one place we can probably go back // to directly passing in next_line_start and this_line_start. i32 this_indent = compute_this_indent(buffer, indent, T, prev_token, line_i, tab_width); - + + // NOTE(allen): Rebase the paren anchor if the first token + // after an open paren is on the next line. + if (indent.paren_nesting > 0){ + if (prev_token.type == CPP_TOKEN_PARENTHESE_OPEN){ + i32 level = indent.paren_nesting-1; + if (level >= ArrayCount(indent.paren_anchor_indent)){ + level = ArrayCount(indent.paren_anchor_indent)-1; + } + indent.paren_anchor_indent[level] = this_indent; + } + } + if (line_i >= line_start){ indent_marks[line_i] = this_indent; } @@ -2740,7 +2831,7 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke i32 char_pos = T.start - start; Hard_Start_Result hard_start = buffer_find_hard_start( - buffer, start, tab_width); + buffer, start, tab_width); i32 line_pos = hard_start.char_pos - start; @@ -2750,7 +2841,7 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke ++indent.paren_nesting; } break; - + case CPP_TOKEN_PARENTHESE_CLOSE: if (!(T.flags & CPP_TFLAG_PP_BODY)){ --indent.paren_nesting; @@ -2769,7 +2860,7 @@ get_line_indentation_marks(Partition *part, Buffer *buffer, Cpp_Token_Stack toke internal Make_Batch_Result make_batch_from_indent_marks(Partition *part, Buffer *buffer, i32 line_start, i32 line_end, - i32 *indent_marks, Indent_Options opts){ + i32 *indent_marks, Indent_Options opts){ Make_Batch_Result result = {0}; @@ -2789,13 +2880,13 @@ make_batch_from_indent_marks(Partition *part, Buffer *buffer, i32 line_start, i3 i32 start = buffer->line_starts[line_i]; Hard_Start_Result hard_start = buffer_find_hard_start(buffer, start, opts.tab_width); - + i32 correct_indentation = indent_marks[line_i]; if (hard_start.all_whitespace && opts.empty_blank_lines) correct_indentation = 0; if (correct_indentation == -1) correct_indentation = hard_start.indent_pos; - + if ((hard_start.all_whitespace && hard_start.char_pos > start) || - !hard_start.all_space || correct_indentation != hard_start.indent_pos){ + !hard_start.all_space || correct_indentation != hard_start.indent_pos){ Buffer_Edit new_edit; new_edit.str_start = str_size; str_size += correct_indentation; @@ -2814,7 +2905,7 @@ make_batch_from_indent_marks(Partition *part, Buffer *buffer, i32 line_start, i3 new_edit.end = hard_start.char_pos; edits[edit_count++] = new_edit; } - + Assert(edit_count <= edit_max); } @@ -2830,14 +2921,14 @@ make_batch_from_indent_marks(Partition *part, Buffer *buffer, i32 line_start, i3 internal void view_auto_tab_tokens(System_Functions *system, Models *models, - View *view, i32 start, i32 end, Indent_Options opts){ + View *view, i32 start, i32 end, Indent_Options opts){ #if BUFFER_EXPERIMENT_SCALPEL <= 0 Editing_File *file = view->file_data.file; Mem_Options *mem = &models->mem; Partition *part = &mem->part; Buffer *buffer = &file->state.buffer; - Assert(file && !file->state.is_dummy); + Assert(file && !file->is_dummy); Cpp_Token_Stack tokens = file->state.token_stack; Assert(tokens.tokens); @@ -2845,30 +2936,30 @@ view_auto_tab_tokens(System_Functions *system, Models *models, i32 line_end = buffer_get_line_index(buffer, end) + 1; Temp_Memory temp = begin_temp_memory(part); - + i32 *indent_marks = get_line_indentation_marks(part, buffer, tokens, line_start, line_end, opts.tab_width); - + Make_Batch_Result batch = make_batch_from_indent_marks(part, buffer, line_start, line_end, indent_marks, opts); - + if (batch.edit_count > 0){ Assert(buffer_batch_debug_sort_check(batch.edits, batch.edit_count)); - + // NOTE(allen): computing edit spec, doing batch edit Buffer_Edit *inverse_array = push_array(part, Buffer_Edit, batch.edit_count); Assert(inverse_array); - + char *inv_str = (char*)part->base + part->pos; Edit_Spec spec = file_compute_whitespace_edit(mem, file, view->recent->cursor.pos, - batch.edits, batch.str_base, batch.str_size, - inverse_array, inv_str, part->max - part->pos, batch.edit_count); - + batch.edits, batch.str_base, batch.str_size, + inverse_array, inv_str, part->max - part->pos, batch.edit_count); + file_do_white_batch_edit(system, models, view->file_data.file, spec, hist_normal); } end_temp_memory(temp); - + { i32 start = view->recent->cursor.pos; Hard_Start_Result hard_start = buffer_find_hard_start(buffer, start, 4); @@ -2902,27 +2993,27 @@ style_get_color(Style *style, Cpp_Token token){ case CPP_TOKEN_COMMENT: result = &style->main.comment_color; break; - + case CPP_TOKEN_STRING_CONSTANT: result = &style->main.str_constant_color; break; - + case CPP_TOKEN_CHARACTER_CONSTANT: result = &style->main.char_constant_color; break; - + case CPP_TOKEN_INTEGER_CONSTANT: result = &style->main.int_constant_color; break; - + case CPP_TOKEN_FLOATING_CONSTANT: result = &style->main.float_constant_color; break; - + case CPP_TOKEN_INCLUDE_FILE: result = &style->main.include_color; break; - + default: result = &style->main.default_color; break; @@ -2931,22 +3022,6 @@ style_get_color(Style *style, Cpp_Token token){ return result; } -inline f32 -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; - if (max_target_y < 0) max_target_y = 0; - return(max_target_y); -} - -internal f32 -view_compute_max_target_y(View *view){ - i32 lowest_line = view_compute_lowest_line(view); - i32 line_height = view->font_height; - f32 view_height = view_file_height(view); - f32 max_target_y = view_compute_max_target_y(lowest_line, line_height, view_height); - return(max_target_y); -} - internal void remeasure_file_view(System_Functions *system, View *view){ if (file_is_ready(view->file_data.file)){ @@ -2974,8 +3049,8 @@ view_show_config(View *view, Command_Map *gui_map){ inline void view_show_interactive(System_Functions *system, View *view, - Command_Map *gui_map, Interactive_Action action, - Interactive_Interaction interaction, String query){ + Command_Map *gui_map, Interactive_Action action, + Interactive_Interaction interaction, String query){ Models *models = view->persistent.models; @@ -3016,74 +3091,277 @@ view_show_file(View *view){ } internal void -interactive_view_complete(View *view, String dest, i32 user_action){ - Models *models = view->persistent.models; - Panel *panel = view->panel; - Editing_File *old_file = view->file_data.file; +view_save_file(System_Functions *system, Models *models, + Editing_File *file, View *view, String filename, b32 save_as){ + Mem_Options *mem = &models->mem; + Working_Set *working_set = &models->working_set; + + if (!file){ + if (view){ + file = view->file_data.file; + } + else{ + file = working_set_lookup_file(working_set, filename); + } + } + + if (file && buffer_get_sync(file) != SYNC_GOOD){ + if (file_save(system, mem, file, filename.str)){ + if (save_as){ + file_set_name(working_set, file, filename.str); + } + } + } +} +internal void +view_new_file(System_Functions *system, Models *models, + View *view, String string){ + Working_Set *working_set = &models->working_set; + General_Memory *general = &models->mem.general; + + Editing_File *file = working_set_alloc_always(working_set, general); + file_create_empty(system, models, file, string.str); + working_set_add(system, working_set, file, general); + + view_set_file(view, file, models); + view_show_file(view); + view->map = get_map(models, file->settings.base_map_id); + + Hook_Function *new_file_fnc = models->hooks[hook_new_file]; + if (new_file_fnc){ + models->buffer_param_indices[models->buffer_param_count++] = file->id.id; + new_file_fnc(&models->app_links); + models->buffer_param_count = 0; + file->settings.is_initialized = 1; + } + +#if BUFFER_EXPERIMENT_SCALPEL <= 0 + if (file->settings.tokens_exist){ + file_first_lex_parallel(system, general, file); + } +#endif +} + +internal void +init_normal_file(System_Functions *system, Models *models, Editing_File *file, + char *buffer, i32 size){ + + General_Memory *general = &models->mem.general; + + String val = make_string(buffer, size); + file_create_from_string(system, models, file, file->name.source_path.str, val); + + if (file->settings.tokens_exist){ + file_first_lex_parallel(system, general, file); + } + + for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ + view_measure_wraps(general, iter.view); + } +} + +internal void +view_open_file(System_Functions *system, Models *models, + View *view, String filename){ + Working_Set *working_set = &models->working_set; + General_Memory *general = &models->mem.general; + Partition *part = &models->mem.part; + + Editing_File *file = working_set_contains(system, working_set, filename); + + if (file == 0){ + File_Loading loading = system->file_load_begin(filename.str); + + if (loading.exists){ + b32 in_general_mem = 0; + Temp_Memory temp = begin_temp_memory(part); + char *buffer = push_array(part, char, loading.size); + + // TODO(allen): How will we get temporary space for large + // buffers? The main partition isn't always big enough + // but getting a general block this large and copying it + // then freeing it is *super* dumb! + if (buffer == 0){ + buffer = (char*)general_memory_allocate(general, loading.size); + if (buffer != 0){ + in_general_mem = 1; + } + } + + if (system->file_load_end(loading, buffer)){ + file = working_set_alloc_always(working_set, general); + if (file){ + file_init_strings(file); + file_set_name(working_set, file, filename.str); + working_set_add(system, working_set, file, general); + + init_normal_file(system, models, file, + buffer, loading.size); + } + } + + if (in_general_mem){ + general_memory_free(general, buffer); + } + + end_temp_memory(temp); + } + } + + if (file){ + if (view){ + view_set_file(view, file, models); + } + } +} + +internal void +kill_file(System_Functions *system, Models *models, + Editing_File *file, String string){ + Working_Set *working_set = &models->working_set; + + if (!file && string.str){ + file = working_set_lookup_file(working_set, string); + if (!file){ + file = working_set_contains(system, working_set, string); + } + } + + if (file && !file->settings.never_kill){ + working_set_remove(system, working_set, file->name.source_path); + file_close(system, &models->mem.general, file); + working_set_free_file(&models->working_set, file); + + File_Node *used = &models->working_set.used_sentinel; + File_Node *node = used->next; + for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ + if (node != used){ + iter.view->file_data.file = 0; + view_set_file(iter.view, (Editing_File*)node, models); + node = node->next; + } + else{ + iter.view->file_data.file = 0; + view_set_file(iter.view, 0, models); + } + } + } +} + +internal void +try_kill_file(System_Functions *system, Models *models, + Editing_File *file, View *view, String string){ + Working_Set *working_set = &models->working_set; + + if (!file && string.str){ + file = working_set_lookup_file(working_set, string); + if (!file){ + file = working_set_contains(system, working_set, string); + } + } + + if (file && !file->settings.never_kill){ + if (buffer_needs_save(file)){ + if (view == 0){ + view = models->layout.panels[models->layout.active_panel].view; + } + view_show_interactive(system, view, &models->map_ui, + IAct_Sure_To_Kill, IInt_Sure_To_Kill, + make_lit_string("Are you sure?")); + copy(&view->dest, file->name.live_name); + } + else{ + kill_file(system, models, file, string_zero()); + } + } +} + +internal void +interactive_view_complete(System_Functions *system, View *view, String dest, i32 user_action){ + Models *models = view->persistent.models; + Editing_File *old_file = view->file_data.file; + switch (view->action){ case IAct_Open: - delayed_open(&models->delay1, dest, panel); - delayed_touch_file(&models->delay1, old_file); + view_open_file(system, models, view, dest); + touch_file(&models->working_set, old_file); + view_show_file(view); break; - + case IAct_Save_As: - delayed_save_as(&models->delay1, dest, panel); + view_save_file(system, models, 0, view, dest, 1); + view_show_file(view); break; - + case IAct_New: - if (dest.size > 0 && - !char_is_slash(models->hot_directory.string.str[dest.size-1])){ - delayed_new(&models->delay1, dest, panel); + if (dest.size > 0 && !char_is_slash(dest.str[dest.size-1])){ + view_new_file(system, models, view, dest); + view_show_file(view); }break; - + case IAct_Switch: - delayed_switch(&models->delay1, dest, panel); - delayed_touch_file(&models->delay1, old_file); + { + touch_file(&models->working_set, old_file); + + Editing_File *file = 0; + String string = dest; + + file = working_set_lookup_file(&models->working_set, string); + if (!file){ + file = working_set_contains(system, &models->working_set, string); + } + if (file){ + view_set_file(view, file, models); + } + view_show_file(view); + } break; - + case IAct_Kill: - delayed_try_kill(&models->delay1, dest); + try_kill_file(system, models, 0, 0, dest); + view_show_file(view); break; - + case IAct_Sure_To_Close: switch (user_action){ case 0: - delayed_close(&models->delay1); + models->keep_playing = 0; break; - + case 1: + view_show_file(view); break; - + case 2: - // TODO(allen): Save all. + // TODO(allen): Save all and close. break; } break; - + case IAct_Sure_To_Kill: switch (user_action){ case 0: - delayed_kill(&models->delay1, dest); + kill_file(system, models, 0, dest); + view_show_file(view); break; - + case 1: + view_show_file(view); break; - + case 2: - // TODO(allen): This is fishy! What if the save doesn't happen this time around? - // We need to ensure delayed acts happen in order I think... or better yet destroy delayed action entirely. - delayed_save(&models->delay1, dest); - delayed_kill(&models->delay1, dest); + view_save_file(system, models, 0, 0, dest, 0); + kill_file(system, models, 0, dest); + view_show_file(view); break; } break; } - view_show_file(view); - - // TODO(allen): This is here to prevent the key press from being passed to the - // underlying file which is a giant pain. But I want a better system. - file_view_nullify_file(view); } #if 0 @@ -3209,10 +3487,7 @@ view_reinit_scrolling(View *view){ target_x = (f32)(cursor_x - w*.5f); } - target_y = (f32)FLOOR32(cursor_y - h*.5f); - if (target_y < view->recent->scroll.min_y){ - target_y = view->recent->scroll.min_y; - } + target_y = clamp_bottom(0.f, (f32)FLOOR32(cursor_y - h*.5f)); } view->recent->scroll.target_y = target_y; @@ -3268,13 +3543,9 @@ view_get_cursor_scroll_change_state(View *view){ internal void view_begin_cursor_scroll_updates(View *view){ - if (view->file_data.file == view->prev_context.file){ + if (view->file_data.file && view->file_data.file == view->prev_context.file){ Assert(view->prev_cursor_pos == view_get_cursor_pos(view)); } - - view->prev_context.file = view->file_data.file; - view->prev_context.scroll = view->gui_target.scroll_id; - view->prev_context.mode = view->showing_ui; } internal void @@ -3287,12 +3558,15 @@ view_end_cursor_scroll_updates(View *view){ case CursorScroll_Cursor: case CursorScroll_Cursor|CursorScroll_Scroll: + if (view->gui_target.did_file){ + view->recent->scroll.max_y = view_compute_max_target_y(view); + } view_move_view_to_cursor(view, view->current_scroll); gui_post_scroll_vars(&view->gui_target, view->current_scroll, view->scroll_region); break; case CursorScroll_Scroll: - view_move_cursor_to_view(view); + view_move_cursor_to_view(view, view->recent->scroll); gui_post_scroll_vars(&view->gui_target, view->current_scroll, view->scroll_region); break; } @@ -3303,16 +3577,18 @@ view_end_cursor_scroll_updates(View *view){ gui_post_scroll_vars(&view->gui_target, view->current_scroll, view->scroll_region); } - if (view->gui_target.did_file){ - view->prev_cursor_pos = view_get_cursor_pos(view); - } + view->prev_cursor_pos = view_get_cursor_pos(view); + + view->prev_context.file = view->file_data.file; + view->prev_context.scroll = view->gui_target.scroll_id; + view->prev_context.mode = view->showing_ui; } internal b32 file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active){ i32 is_animating = 0; Editing_File *file = view->file_data.file; - if (file && !file->state.is_loading){ + if (file && !file->is_loading){ f32 max_visible_y = view_file_height(view); f32 max_x = view_file_width(view); @@ -3327,15 +3603,16 @@ file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active) f32 rx = (f32)(user_input->mouse.x - region.x0); f32 ry = (f32)(user_input->mouse.y - region.y0); - if (ry >= -view->recent->scroll.min_y){ - view_set_widget(view, FWIDG_NONE); + if (ry >= 0){ if (rx >= 0 && rx < max_x && ry >= 0 && ry < max_visible_y){ - view_cursor_move(view, rx + scroll_vars.scroll_x, ry + scroll_vars.scroll_y, 1); + view_cursor_move(view, + rx + scroll_vars.scroll_x, + ry + scroll_vars.scroll_y, + 1); view->mode = view_mode_zero(); } } } - if (!is_active) view_set_widget(view, FWIDG_NONE); } return(is_animating); @@ -3346,14 +3623,20 @@ do_widget(View *view, GUI_Target *target){ Query_Slot *slot; Query_Bar *bar; - gui_begin_serial_section(target); + // NOTE(allen): A temporary measure... although in + // general we maybe want the user to be able to ask + // how large a particular section of the GUI turns + // out to be after layout? + f32 height = 0.f; for (slot = view->query_set.used_slot; slot != 0; slot = slot->next){ bar = slot->query_bar; gui_do_text_field(target, bar->prompt, bar->string); + + height += view->line_height + 2; } - gui_end_serial_section(target); + view->widget_height = height; } struct Exhaustive_File_Loop{ @@ -3588,8 +3871,15 @@ app_single_number_input_step(System_Functions *system, Key_Event_Data key, Strin return result; } -internal b32 +struct View_Step_Result{ + b32 animating; + b32 consume_keys; + b32 consume_esc; +}; + +internal View_Step_Result step_file_view(System_Functions *system, View *view, View *active_view, Input_Summary input){ + View_Step_Result result = {0}; GUI_Target *target = &view->gui_target; Models *models = view->persistent.models; Key_Summary keys = input.keys; @@ -3598,37 +3888,51 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su view->current_scroll = 0; + if (view->showing_ui != VUI_None){ + b32 did_esc = 0; + Key_Event_Data key; + i32 i; + + for (i = 0; i < keys.count; ++i){ + key = get_single_key(&keys, i); + if (key.keycode == key_esc){ + did_esc = 1; + break; + } + } + + if (did_esc){ + view_show_file(view); + result.consume_esc = 1; + } + } + gui_begin_top_level(target, input); { gui_do_top_bar(target); + do_widget(view, target); if (view->showing_ui == VUI_None){ - gui_begin_overlap(target); + + gui_begin_serial_section(target); { - do_widget(view, target); + f32 delta = 9.f * view->line_height; + GUI_id scroll_context = {0}; + scroll_context.id[1] = view->showing_ui; + scroll_context.id[0] = (u64)(view->file_data.file); - gui_begin_serial_section(target); - { - f32 delta = 9.f * view->font_height; - GUI_id scroll_context = {0}; - scroll_context.id[1] = view->showing_ui; - scroll_context.id[0] = (u64)(view->file_data.file); - - view->current_scroll = &view->recent->scroll; - gui_get_scroll_vars(target, scroll_context, - &view->recent->scroll, &view->scroll_region); - - gui_begin_scrollable(target, scroll_context, view->recent->scroll, - delta, show_scrollbar); - gui_do_file(target); - gui_end_scrollable(target); - } - gui_end_serial_section(target); + view->current_scroll = &view->recent->scroll; + gui_get_scroll_vars(target, scroll_context, + &view->recent->scroll, &view->scroll_region); + + gui_begin_scrollable(target, scroll_context, view->recent->scroll, + delta, show_scrollbar); + gui_do_file(target); + gui_end_scrollable(target); } - gui_end_overlap(target); + gui_end_serial_section(target); } else{ - do_widget(view, target); switch (view->showing_ui){ case VUI_Menu: { @@ -3638,22 +3942,22 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su String empty_string = {0}; GUI_id id = {0}; id.id[1] = VUI_Menu; - + gui_do_text_field(target, message, empty_string); - + id.id[0] = 0; message = make_lit_string("Theme"); if (gui_do_fixed_option(target, id, message, 0)){ view_show_theme(view, view->map); } - + id.id[0] = 1; message = make_lit_string("Config"); if (gui_do_fixed_option(target, id, message, 0)){ view_show_config(view, view->map); } }break; - + case VUI_Config: { view->current_scroll = &view->gui_scroll; @@ -3662,16 +3966,16 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su String empty_string = {0}; GUI_id id = {0}; id.id[1] = VUI_Config; - + gui_do_text_field(target, message, empty_string); - + id.id[0] = 0; message = make_lit_string("Left Ctrl + Left Alt = AltGr"); if (gui_do_fixed_option_checkbox(target, id, message, 0, (b8)models->settings.lctrl_lalt_is_altgr)){ models->settings.lctrl_lalt_is_altgr = !models->settings.lctrl_lalt_is_altgr; } }break; - + case VUI_Theme: { view->current_scroll = &view->gui_scroll; @@ -3679,7 +3983,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su if (view != active_view){ view->hot_file_view = active_view; } - + String message = {0}; String empty_string = {0}; @@ -3712,7 +4016,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su view->current_scroll = &view->gui_scroll; gui_get_scroll_vars(target, scroll_context, &view->gui_scroll, &view->scroll_region); gui_begin_scrollable(target, scroll_context, view->gui_scroll, - 9.f * view->font_height, show_scrollbar); + 9.f * view->line_height, show_scrollbar); { i32 count = models->styles.count; @@ -3786,7 +4090,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su view->current_scroll = &view->gui_scroll; gui_get_scroll_vars(target, scroll_context, &view->gui_scroll, &view->scroll_region); gui_begin_scrollable(target, scroll_context, view->gui_scroll, - 9.f * view->font_height, show_scrollbar); + 9.f * view->line_height, show_scrollbar); i32 next_color_editing = view->current_color_editing; @@ -3801,47 +4105,50 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su next_color_editing = i; view->color_cursor = 0; } - + if (view->current_color_editing == i){ GUI_Item_Update update = {0}; char text_space[7]; String text = make_fixed_width_string(text_space); - + color_to_hexstr(*edit_color, &text); if (gui_do_text_with_cursor(target, view->color_cursor, text, &update)){ b32 r = 0; i32 j = 0; - + for (j = 0; j < keys.count; ++j){ i16 key = keys.keys[j].keycode; switch (key){ - case key_left: --view->color_cursor; r = 1; break; - case key_right: ++view->color_cursor; r = 1; break; - + case key_left: --view->color_cursor; r = 1; result.consume_keys = 1; break; + case key_right: ++view->color_cursor; r = 1; result.consume_keys = 1; break; + case key_up: if (next_color_editing > 0){ --next_color_editing; } + result.consume_keys = 1; break; - + case key_down: if (next_color_editing <= ArrayCount(colors_to_edit)-1){ ++next_color_editing; } + result.consume_keys = 1; break; - + default: if ((key >= '0' && key <= '9') || (key >= 'a' && key <= 'f') || (key >= 'A' && key <= 'F')){ text.str[view->color_cursor] = (char)key; r = 1; + result.consume_keys = 1; } break; } - + if (view->color_cursor < 0) view->color_cursor = 0; if (view->color_cursor >= 6) view->color_cursor = 5; } - + if (r){ hexstr_to_color(text, edit_color); gui_rollback(target, &update); @@ -3850,12 +4157,12 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su } } } - + if (view->current_color_editing != next_color_editing){ view->current_color_editing = next_color_editing; view->color_cursor = 0; } - + gui_end_scrollable(target); }break; } @@ -3863,6 +4170,11 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su case VUI_Interactive: { + b32 complete = 0; + char comp_dest_space[1024]; + String comp_dest = make_fixed_width_string(comp_dest_space); + i32 comp_action = 0; + view->current_scroll = &view->gui_scroll; GUI_id id = {0}; @@ -3908,9 +4220,11 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su &hdir->string, hdir, 1, 1, 0); if (step.made_a_change){ view->list_i = 0; + result.consume_keys = 1; } if (!use_item_in_list && (key.keycode == '\n' || key.keycode == '\t')){ activate_directly = 1; + result.consume_keys = 1; } } } @@ -3923,12 +4237,13 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su snap_into_view = 1; } gui_begin_scrollable(target, scroll_context, view->gui_scroll, - 9.f * view->font_height, show_scrollbar); + 9.f * view->line_height, show_scrollbar); id.id[0] = (u64)(hdir) + 1; if (gui_begin_list(target, id, view->list_i, 0, snap_into_view, &update)){ + // TODO(allen): Allow me to handle key consumption correctly here! gui_standard_list(target, id, view->current_scroll, view->scroll_region, &keys, &view->list_i, &update); } @@ -3947,7 +4262,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su do_new_directory = 1; } else if (use_item_in_list){ - interactive_view_complete(view, loop.full_path, 0); + complete = 1; + copy(&comp_dest, loop.full_path); } } } @@ -3957,7 +4273,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su gui_end_list(target); if (activate_directly){ - interactive_view_complete(view, hdir->string, 0); + complete = 1; + copy(&comp_dest, hdir->string); } if (do_new_directory){ @@ -3972,19 +4289,19 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su b32 snap_into_view = 0; persist String message_unsaved = make_lit_string(" *"); persist String message_unsynced = make_lit_string(" !"); - + String message = {0}; switch (view->action){ case IAct_Switch: message = make_lit_string("Switch: "); break; case IAct_Kill: message = make_lit_string("Kill: "); break; } - + Absolutes absolutes; Editing_File *file; Working_Set *working_set = &models->working_set; Editing_Layout *layout = &models->layout; GUI_Item_Update update = {0}; - + { Single_Line_Input_Step step; Key_Event_Data key; @@ -3994,22 +4311,23 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su step = app_single_line_input_step(system, key, &view->dest); if (step.made_a_change){ view->list_i = 0; + result.consume_keys = 1; } } } - + get_absolutes(view->dest, &absolutes, 1, 1); - + gui_do_text_field(target, message, view->dest); - + scroll_context.id[0] = (u64)(working_set); if (gui_get_scroll_vars(target, scroll_context, &view->gui_scroll, &view->scroll_region)){ snap_into_view = 1; } gui_begin_scrollable(target, scroll_context, view->gui_scroll, - 9.f * view->font_height, show_scrollbar); - + 9.f * view->line_height, show_scrollbar); + id.id[0] = (u64)(working_set) + 1; if (gui_begin_list(target, id, view->list_i, 0, snap_into_view, &update)){ @@ -4031,7 +4349,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su used_nodes = &working_set->used_sentinel; for (dll_items(node, used_nodes)){ file = (Editing_File*)node; - Assert(!file->state.is_dummy); + Assert(!file->is_dummy); if (filename_match(view->dest, &absolutes, file->name.live_name, 1)){ iter = file_view_iter_init(layout, file, 0); @@ -4051,7 +4369,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su id.id[0] = (u64)(file); if (gui_do_file_option(target, id, file->name.live_name, 0, message)){ - interactive_view_complete(view, file->name.live_name, 0); + complete = 1; + copy(&comp_dest, file->name.live_name); } } } @@ -4069,7 +4388,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su id.id[0] = (u64)(file); if (gui_do_file_option(target, id, file->name.live_name, 0, message)){ - interactive_view_complete(view, file->name.live_name, 0); + complete = 1; + copy(&comp_dest, file->name.live_name); } } @@ -4103,7 +4423,9 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su } if (action != -1){ - interactive_view_complete(view, view->dest, action); + complete = 1; + copy(&comp_dest, view->dest); + comp_action = action; } }break; @@ -4133,18 +4455,27 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su if (gui_do_fixed_option(target, id, message, 's')){ action = 2; } - + if (action != -1){ - interactive_view_complete(view, view->dest, action); + complete = 1; + copy(&comp_dest, view->dest); + comp_action = action; } }break; } + + if (complete){ + terminate_with_null(&comp_dest); + interactive_view_complete(system, view, comp_dest, comp_action); + } }break; } } } gui_end_top_level(target); - return(target->animating); + + result.animating = target->animating; + return(result); } internal f32 @@ -4211,10 +4542,10 @@ struct Input_Process_Result{ }; internal Input_Process_Result -do_input_file_view(System_Functions *system, Exchange *exchange, - View *view, i32_Rect rect, b32 is_active, - Input_Summary *user_input, - GUI_Scroll_Vars vars, i32_Rect region){ +do_step_file_view(System_Functions *system, + View *view, i32_Rect rect, b32 is_active, + Input_Summary *user_input, + GUI_Scroll_Vars vars, i32_Rect region){ Input_Process_Result result = {0}; b32 is_file_scroll = 0; @@ -4223,13 +4554,15 @@ do_input_file_view(System_Functions *system, Exchange *exchange, GUI_Target *target = &view->gui_target; GUI_Interpret_Result interpret_result = {0}; + vars.target_y = clamp(0.f, vars.target_y, vars.max_y); + result.vars = vars; result.region = region; target->active = gui_id_zero(); if (target->push.pos > 0){ - gui_session_init(&gui_session, target, rect, view->font_height); + gui_session_init(&gui_session, target, rect, view->line_height); for (h = (GUI_Header*)target->push.base; h->type; @@ -4268,12 +4601,9 @@ do_input_file_view(System_Functions *system, Exchange *exchange, case guicom_file: { - f32 new_min_y = -(f32)(gui_session_get_eclipsed_y(&gui_session) - - gui_session.rect.y0); f32 new_max_y = view_compute_max_target_y(view); view->file_region = gui_session.rect; - result.vars.min_y = new_min_y; result.vars.max_y = new_max_y; if (view->reinit_scrolling){ @@ -4350,10 +4680,8 @@ do_input_file_view(System_Functions *system, Exchange *exchange, if (gui_id_eq(target->mouse_hot, id)){ v = unlerp(gui_session.scroll_top, (f32)my, gui_session.scroll_bottom); - if (v < 0) v = 0; - if (v > 1.f) v = 1.f; - result.vars.target_y = - lerp(result.vars.min_y, v, result.vars.max_y); + v = clamp(0.f, v, 1.f); + result.vars.target_y = lerp(0.f, v, result.vars.max_y); gui_activate_scrolling(target); result.is_animating = 1; @@ -4366,12 +4694,8 @@ do_input_file_view(System_Functions *system, Exchange *exchange, if (user_input->mouse.wheel != 0){ result.vars.target_y += user_input->mouse.wheel*target->delta; - if (result.vars.target_y < result.vars.min_y){ - result.vars.target_y = result.vars.min_y; - } - if (result.vars.target_y > result.vars.max_y){ - result.vars.target_y = result.vars.max_y; - } + result.vars.target_y = + clamp(0.f, result.vars.target_y, result.vars.max_y); gui_activate_scrolling(target); result.is_animating = 1; } @@ -4383,9 +4707,7 @@ do_input_file_view(System_Functions *system, Exchange *exchange, if (scroll_button_input(target, &gui_session, user_input, id, &result.is_animating)){ result.vars.target_y -= target->delta * 0.25f; - if (result.vars.target_y < result.vars.min_y){ - result.vars.target_y = result.vars.min_y; - } + result.vars.target_y = clamp_bottom(0.f, result.vars.target_y); } }break; @@ -4395,19 +4717,14 @@ do_input_file_view(System_Functions *system, Exchange *exchange, if (scroll_button_input(target, &gui_session, user_input, id, &result.is_animating)){ result.vars.target_y += target->delta * 0.25f; - if (result.vars.target_y > result.vars.max_y){ - result.vars.target_y = result.vars.max_y; - } + result.vars.target_y = clamp_top(result.vars.target_y, result.vars.max_y); } }break; case guicom_end_scrollable_section: { if (!is_file_scroll){ - f32 new_min_y = gui_session.suggested_min_y; f32 new_max_y = gui_session.suggested_max_y; - - result.vars.min_y = new_min_y; result.vars.max_y = new_max_y; } }break; @@ -4439,27 +4756,6 @@ do_input_file_view(System_Functions *system, Exchange *exchange, result.vars = scroll_vars; } - - // TODO(allen): GET RID OF THIS!!! - { - Key_Summary *keys = &user_input->keys; - b32 did_esc = 0; - Key_Event_Data key; - i32 i, count; - - count = keys->count; - for (i = 0; i < count; ++i){ - key = get_single_key(keys, i); - if (key.keycode == key_esc){ - did_esc = 1; - break; - } - } - - if (did_esc && view->showing_ui != VUI_None){ - view_show_file(view); - } - } } return(result); @@ -4470,47 +4766,54 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target Models *models = view->persistent.models; Editing_File *file = view->file_data.file; Style *style = main_style(models); - i32 line_height = view->font_height; - + i32 line_height = view->line_height; + i32 max_x = rect.x1 - rect.x0; i32 max_y = rect.y1 - rect.y0 + line_height; - - Assert(file && !file->state.is_dummy && buffer_good(&file->state.buffer)); - + + Assert(file && !file->is_dummy && buffer_good(&file->state.buffer)); + b32 tokens_use = 0; Cpp_Token_Stack token_stack = {}; if (file){ tokens_use = file->state.tokens_complete && (file->state.token_stack.count > 0); token_stack = file->state.token_stack; } - + Partition *part = &models->mem.part; - + Temp_Memory temp = begin_temp_memory(part); - + partition_align(part, 4); i32 max = partition_remaining(part) / sizeof(Buffer_Render_Item); Buffer_Render_Item *items = push_array(part, Buffer_Render_Item, max); - + i16 font_id = models->global_font.font_id; Render_Font *font = get_font_info(models->font_set, font_id)->font; float *advance_data = 0; if (font) advance_data = font->advance_data; - + i32 count; Full_Cursor render_cursor; Buffer_Render_Options opts = {}; - + f32 *wraps = view->file_data.line_wrap_y; f32 scroll_x = view->recent->scroll.scroll_x; f32 scroll_y = view->recent->scroll.scroll_y; - + + // NOTE(allen): For now we will temporarily adjust scroll_y to try + // to prevent the view moving around until floating sections are added + // to the gui system. + scroll_y += view->widget_height; + { render_cursor = buffer_get_start_cursor(&file->state.buffer, wraps, scroll_y, - !view->file_data.unwrapped_lines, (f32)max_x, advance_data, (f32)line_height); - + !view->file_data.unwrapped_lines, + (f32)max_x, + advance_data, (f32)line_height); + view->recent->scroll_i = render_cursor.pos; - + buffer_get_render_data(&file->state.buffer, items, max, &count, (f32)rect.x0, (f32)rect.y0, scroll_x, scroll_y, render_cursor, @@ -4519,9 +4822,9 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target advance_data, (f32)line_height, opts); } - + Assert(count > 0); - + i32 cursor_begin, cursor_end; u32 cursor_color, at_cursor_color; if (view->file_data.show_temp_highlight){ @@ -4536,7 +4839,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target cursor_color = style->main.cursor_color; at_cursor_color = style->main.at_cursor_color; } - + i32 token_i = 0; u32 main_color = style->main.default_color; u32 special_color = style->main.special_character_color; @@ -4545,19 +4848,19 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target main_color = *style_get_color(style, token_stack.tokens[result.token_index]); token_i = result.token_index + 1; } - + u32 mark_color = style->main.mark_color; Buffer_Render_Item *item = items; i32 prev_ind = -1; u32 highlight_color = 0; u32 highlight_this_color = 0; - + for (i32 i = 0; i < count; ++i, ++item){ i32 ind = item->index; highlight_this_color = 0; if (tokens_use && ind != prev_ind){ Cpp_Token current_token = token_stack.tokens[token_i-1]; - + if (token_i < token_stack.count){ if (ind >= token_stack.tokens[token_i].start){ main_color = @@ -4569,7 +4872,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target main_color = 0xFFFFFFFF; } } - + if (current_token.type == CPP_TOKEN_JUNK && i >= current_token.start && i < current_token.start + current_token.size){ highlight_color = style->main.highlight_junk_color; @@ -4578,10 +4881,10 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target highlight_color = 0; } } - + u32 char_color = main_color; if (item->flags & BRFlag_Special_Character) char_color = special_color; - + f32_Rect char_rect = f32R(item->x0, item->y0, item->x1, item->y1); if (view->file_data.show_whitespace && highlight_color == 0 && char_is_whitespace((char)item->glyphid)){ @@ -4590,7 +4893,7 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target else{ highlight_this_color = highlight_color; } - + if (cursor_begin <= ind && ind < cursor_end && (ind != prev_ind || cursor_begin < ind)){ if (is_active){ draw_rectangle(target, char_rect, cursor_color); @@ -4605,19 +4908,19 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target else if (highlight_this_color){ draw_rectangle(target, char_rect, highlight_this_color); } - + u32 fade_color = 0xFFFF00FF; f32 fade_amount = 0.f; - + if (file->state.paste_effect.tick_down > 0 && file->state.paste_effect.start <= ind && ind < file->state.paste_effect.end){ fade_color = file->state.paste_effect.color; fade_amount = (f32)(file->state.paste_effect.tick_down) / file->state.paste_effect.tick_max; } - + char_color = color_blend(char_color, fade_amount, fade_color); - + if (ind == view->recent->mark && prev_ind != ind){ draw_rectangle_outline(target, char_rect, mark_color); } @@ -4627,9 +4930,9 @@ draw_file_loaded(View *view, i32_Rect rect, b32 is_active, Render_Target *target } prev_ind = ind; } - + end_temp_memory(temp); - + return(0); } @@ -4687,7 +4990,7 @@ draw_text_with_cursor(Render_Target *target, View *view, i32_Rect rect, String s 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->font_height; + 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); @@ -4729,7 +5032,7 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re intbar_draw_string(target, &bar, file->name.live_name, base_color); intbar_draw_string(target, &bar, make_lit_string(" -"), base_color); - if (file->state.is_loading){ + if (file->is_loading){ intbar_draw_string(target, &bar, make_lit_string(" loading"), base_color); } else{ @@ -4845,7 +5148,7 @@ draw_fat_option_block(GUI_Target *gui_target, Render_Target *target, View *view, u32 text_color = style->main.default_color; u32 pop_color = style->main.special_character_color; - i32 h = view->font_height; + i32 h = view->line_height; i32 x = inner.x0 + 3; i32 y = inner.y0 + h/2 - 1; @@ -4885,7 +5188,7 @@ draw_button(GUI_Target *gui_target, Render_Target *target, View *view, i32_Rect u32 back = get_margin_color(active_level, style); u32 text_color = style->main.default_color; - i32 h = view->font_height; + i32 h = view->line_height; i32 y = inner.y0 + h/2 - 1; i32 w = (i32)font_string_width(target, font_id, text); @@ -4941,9 +5244,9 @@ draw_style_preview(GUI_Target *gui_target, Render_Target *target, View *view, i3 } internal i32 -do_render_file_view(System_Functions *system, Exchange *exchange, - View *view, View *active, i32_Rect rect, b32 is_active, - Render_Target *target, Input_Summary *user_input){ +do_render_file_view(System_Functions *system, View *view, + View *active, i32_Rect rect, b32 is_active, + Render_Target *target, Input_Summary *user_input){ Editing_File *file = view->file_data.file; i32 result = 0; @@ -4954,233 +5257,208 @@ do_render_file_view(System_Functions *system, Exchange *exchange, GUI_Interpret_Result interpret_result = {0}; f32 v; - + if (gui_target->push.pos > 0){ - gui_session_init(&gui_session, gui_target, rect, view->font_height); - - v = view_get_scroll_y(view); - - i32_Rect clip_rect = rect; - draw_push_clip(target, clip_rect); - - for (h = (GUI_Header*)gui_target->push.base; - h->type; - h = NextHeader(h)){ - interpret_result = gui_interpret(gui_target, &gui_session, h, - *view->current_scroll, - view->scroll_region); + gui_session_init(&gui_session, gui_target, rect, view->line_height); - if (interpret_result.has_info){ - if (gui_session.clip_y > clip_rect.y0){ - clip_rect.y0 = gui_session.clip_y; - draw_change_clip(target, clip_rect); - } + v = view_get_scroll_y(view); + + i32_Rect clip_rect = rect; + draw_push_clip(target, clip_rect); + + for (h = (GUI_Header*)gui_target->push.base; + h->type; + h = NextHeader(h)){ + interpret_result = gui_interpret(gui_target, &gui_session, h, + *view->current_scroll, + view->scroll_region); - switch (h->type){ - case guicom_top_bar: - { - draw_file_bar(target, view, file, gui_session.rect); - }break; - - case guicom_file: - { - if (view->reinit_scrolling){ - view_reinit_scrolling(view); - } - if (file && file_is_ready(file)){ - result = draw_file_loaded(view, gui_session.rect, is_active, target); - } - }break; + if (interpret_result.has_info){ + if (gui_session.clip_y > clip_rect.y0){ + clip_rect.y0 = gui_session.clip_y; + draw_change_clip(target, clip_rect); + } - case guicom_text_field: - { - void *ptr = (h+1); - String p = gui_read_string(&ptr); - String t = gui_read_string(&ptr); - draw_text_field(target, view, gui_session.rect, p, t); - }break; - - case guicom_text_with_cursor: - { - void *ptr = (h+1); - String s = gui_read_string(&ptr); - i32 pos = gui_read_integer(&ptr); + switch (h->type){ + case guicom_top_bar: + { + draw_file_bar(target, view, file, gui_session.rect); + }break; - draw_text_with_cursor(target, view, gui_session.rect, s, pos); - }break; - - case guicom_color_button: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - u32 fore = (u32)gui_read_integer(&ptr); - u32 back = (u32)gui_read_integer(&ptr); - String t = gui_read_string(&ptr); + case guicom_file: + { + if (view->reinit_scrolling){ + view_reinit_scrolling(view); + } + if (file && file_is_ready(file)){ + result = draw_file_loaded(view, gui_session.rect, is_active, target); + } + }break; - draw_color_button(gui_target, target, view, gui_session.rect, b->id, fore, back, t); - }break; - - case guicom_font_button: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - i16 font_id = (i16)gui_read_integer(&ptr); - String t = gui_read_string(&ptr); + case guicom_text_field: + { + void *ptr = (h+1); + String p = gui_read_string(&ptr); + String t = gui_read_string(&ptr); + draw_text_field(target, view, gui_session.rect, p, t); + }break; - draw_font_button(gui_target, target, view, gui_session.rect, b->id, font_id, t); - }break; - - case guicom_file_option: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - b32 folder = gui_read_integer(&ptr); - String f = gui_read_string(&ptr); - String m = gui_read_string(&ptr); + case guicom_text_with_cursor: + { + void *ptr = (h+1); + String s = gui_read_string(&ptr); + i32 pos = gui_read_integer(&ptr); + + draw_text_with_cursor(target, view, gui_session.rect, s, pos); + }break; - if (folder){ - append(&f, system->slash); - } + case guicom_color_button: + { + GUI_Interactive *b = (GUI_Interactive*)h; + void *ptr = (b + 1); + u32 fore = (u32)gui_read_integer(&ptr); + u32 back = (u32)gui_read_integer(&ptr); + String t = gui_read_string(&ptr); + + draw_color_button(gui_target, target, view, gui_session.rect, b->id, fore, back, t); + }break; - draw_fat_option_block(gui_target, target, view, gui_session.rect, b->id, f, m); - }break; - - case guicom_style_preview: - { - GUI_Interactive *b = (GUI_Interactive*)h; - i32 style_index = *(i32*)(b + 1); - Style *style = get_style(view->persistent.models, style_index); + case guicom_font_button: + { + GUI_Interactive *b = (GUI_Interactive*)h; + void *ptr = (b + 1); + i16 font_id = (i16)gui_read_integer(&ptr); + String t = gui_read_string(&ptr); + + draw_font_button(gui_target, target, view, gui_session.rect, b->id, font_id, t); + }break; - draw_style_preview(gui_target, target, view, gui_session.rect, b->id, style); - }break; - - case guicom_fixed_option: - case guicom_fixed_option_checkbox: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - String f = gui_read_string(&ptr); - String m = {0}; - i8 status = -1; - if (h->type == guicom_fixed_option_checkbox){ - gui_read_byte(&ptr); - status = (i8)gui_read_byte(&ptr); - } + case guicom_file_option: + { + GUI_Interactive *b = (GUI_Interactive*)h; + void *ptr = (b + 1); + b32 folder = gui_read_integer(&ptr); + String f = gui_read_string(&ptr); + String m = gui_read_string(&ptr); + + if (folder){ + append(&f, system->slash); + } + + draw_fat_option_block(gui_target, target, view, gui_session.rect, b->id, f, m); + }break; - draw_fat_option_block(gui_target, target, view, gui_session.rect, b->id, f, m, status); - }break; - - case guicom_button: - { - GUI_Interactive *b = (GUI_Interactive*)h; - void *ptr = (b + 1); - String t = gui_read_string(&ptr); + case guicom_style_preview: + { + GUI_Interactive *b = (GUI_Interactive*)h; + i32 style_index = *(i32*)(b + 1); + Style *style = get_style(view->persistent.models, style_index); + + draw_style_preview(gui_target, target, view, gui_session.rect, b->id, style); + }break; - draw_button(gui_target, target, view, gui_session.rect, b->id, t); - }break; - - case guicom_scrollable_bar: - { - Models *models = view->persistent.models; - Style *style = main_style(models); + case guicom_fixed_option: + case guicom_fixed_option_checkbox: + { + GUI_Interactive *b = (GUI_Interactive*)h; + void *ptr = (b + 1); + String f = gui_read_string(&ptr); + String m = {0}; + i8 status = -1; + if (h->type == guicom_fixed_option_checkbox){ + gui_read_byte(&ptr); + status = (i8)gui_read_byte(&ptr); + } + + draw_fat_option_block(gui_target, target, view, gui_session.rect, b->id, f, m, status); + }break; - u32 back; - u32 outline; + case guicom_button: + { + GUI_Interactive *b = (GUI_Interactive*)h; + void *ptr = (b + 1); + String t = gui_read_string(&ptr); + + draw_button(gui_target, target, view, gui_session.rect, b->id, t); + }break; - i32_Rect bar = gui_session.rect; + case guicom_scrollable_bar: + { + Models *models = view->persistent.models; + Style *style = main_style(models); + + u32 back; + u32 outline; + + i32_Rect bar = gui_session.rect; + + back = style->main.back_color; + if (is_active){ + outline = style->main.margin_active_color; + } + else{ + outline = style->main.margin_color; + } + + draw_rectangle(target, bar, back); + draw_rectangle_outline(target, bar, outline); + }break; - back = style->main.back_color; - if (is_active){ - outline = style->main.margin_active_color; - } - else{ - outline = style->main.margin_color; - } + case guicom_scrollable_top: + case guicom_scrollable_slider: + case guicom_scrollable_bottom: + { + GUI_id id; + Models *models = view->persistent.models; + Style *style = main_style(models); + i32_Rect box = gui_session.rect; + + i32 active_level; + + u32 back; + u32 outline; + + switch (h->type){ + case guicom_scrollable_top: id = gui_id_scrollbar_top(); break; + case guicom_scrollable_bottom: id = gui_id_scrollbar_bottom(); break; + default: id = gui_id_scrollbar_slider(); break; + } + + active_level = gui_active_level(gui_target, id); + + switch (active_level){ + case 0: back = style->main.back_color; break; + case 1: back = style->main.margin_hover_color; break; + default: back = style->main.margin_active_color; break; + } + + if (is_active){ + outline = style->main.margin_active_color; + } + else{ + outline = style->main.margin_color; + } + + draw_rectangle(target, box, back); + draw_margin(target, box, get_inner_rect(box, 2), outline); + }break; - draw_rectangle(target, bar, back); - draw_rectangle_outline(target, bar, outline); - }break; - - case guicom_scrollable_top: - case guicom_scrollable_slider: - case guicom_scrollable_bottom: - { - GUI_id id; - Models *models = view->persistent.models; - Style *style = main_style(models); - i32_Rect box = gui_session.rect; + case guicom_begin_scrollable_section: + clip_rect.x1 = Min(gui_session.scroll_region.x1, clip_rect.x1); + draw_push_clip(target, clip_rect); + break; - i32 active_level; - - u32 back; - u32 outline; - - switch (h->type){ - case guicom_scrollable_top: id = gui_id_scrollbar_top(); break; - case guicom_scrollable_bottom: id = gui_id_scrollbar_bottom(); break; - default: id = gui_id_scrollbar_slider(); break; - } - - active_level = gui_active_level(gui_target, id); - - switch (active_level){ - case 0: back = style->main.back_color; break; - case 1: back = style->main.margin_hover_color; break; - default: back = style->main.margin_active_color; break; - } - - if (is_active){ - outline = style->main.margin_active_color; - } - else{ - outline = style->main.margin_color; - } - - draw_rectangle(target, box, back); - draw_margin(target, box, get_inner_rect(box, 2), outline); - }break; - - case guicom_begin_scrollable_section: - clip_rect.x1 = Min(gui_session.scroll_region.x1, clip_rect.x1); - draw_push_clip(target, clip_rect); - break; - - case guicom_end_scrollable_section: - clip_rect = draw_pop_clip(target); - break; - } - } - } - - draw_pop_clip(target); -} - - return(result); -} - -internal void -kill_file(System_Functions *system, Exchange *exchange, Models *models, Editing_File *file){ - File_Node *node, *used; - - file_close(system, &models->mem.general, file); - working_set_free_file(&models->working_set, file); - - used = &models->working_set.used_sentinel; - node = used->next; - - for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ - if (node != used){ - iter.view->file_data.file = 0; - view_set_file(iter.view, (Editing_File*)node, models); - node = node->next; - } - else{ - iter.view->file_data.file = 0; - view_set_file(iter.view, 0, models); + case guicom_end_scrollable_section: + clip_rect = draw_pop_clip(target); + break; + } + } } + + draw_pop_clip(target); } + + return(result); } inline void @@ -5416,7 +5694,6 @@ live_set_alloc_view(Live_Views *live_set, Panel *panel, Models *models){ result.view->panel = panel; result.view->persistent.models = models; - result.view->scrub_max = 1; result.view->current_scroll = &result.view->recent->scroll; init_query_set(&result.view->query_set); @@ -5433,7 +5710,7 @@ live_set_alloc_view(Live_Views *live_set, Panel *panel, Models *models){ } inline void -live_set_free_view(System_Functions *system, Exchange *exchange, Live_Views *live_set, View *view){ +live_set_free_view(System_Functions *system, Live_Views *live_set, View *view){ Assert(live_set->count > 0); --live_set->count; file_view_free_buffers(view); diff --git a/4ed_font_set.cpp b/4ed_font_set.cpp index 3a3ee64c..ab107521 100644 --- a/4ed_font_set.cpp +++ b/4ed_font_set.cpp @@ -1,11 +1,11 @@ /* - * Mr. 4th Dimention - Allen Webster - * - * 18.12.2015 - * - * Font set for 4coder - * - */ +* Mr. 4th Dimention - Allen Webster +* +* 18.12.2015 +* +* Font set for 4coder +* +*/ // TOP @@ -40,9 +40,9 @@ font__remove(Font_Slot *slot){ n->prev = p; } -internal Font_Slot +inline Font_Slot font_slot_zero(){ - Font_Slot slot = {}; + Font_Slot slot = {0}; return(slot); } @@ -57,10 +57,10 @@ font_set_init(Font_Set *set, Partition *partition, i32 max, i16 live_max){ partition_align(partition, 8); set->font_block = push_block(partition, live_max*(sizeof(Render_Font) + sizeof(Font_Slot))); - + set->free_slots = font_slot_zero(); set->used_slots = font_slot_zero(); - + dll_init_sentinel(&set->free_slots); dll_init_sentinel(&set->used_slots); @@ -69,7 +69,7 @@ font_set_init(Font_Set *set, Partition *partition, i32 max, i16 live_max){ dll_insert(&set->free_slots, (Font_Slot*)ptr); ptr += sizeof(Font_Slot) + sizeof(Render_Font); } - + set->font_used_flags = push_array(partition, b8, max); set->live_max = live_max; } @@ -87,12 +87,12 @@ font_set_add_hash(Font_Set *set, String name, i16 font_id){ entry.hash = font_hash(name); entry.name = name; entry.font_id = font_id; - + u32 i, j; i = entry.hash % set->max; j = i - 1; if (i <= 1) j += set->max; - + for (; i != j; ++i){ if (i == set->max) i = 0; if (set->entries[i].font_id == 0){ @@ -100,7 +100,7 @@ font_set_add_hash(Font_Set *set, String name, i16 font_id){ break; } } - + Assert(i != j); } @@ -119,7 +119,7 @@ font_set_load(Partition *partition, Font_Set *set, i16 font_id){ font__insert(&set->used_slots, slot); Render_Font *font = (Render_Font*)(slot + 1); - set->font_load(font, info->filename.str, info->pt_size, 4); + set->font_load(font, info->filename.str, info->pt_size, 4, 1); info->font = font; slot->font_id = font_id; } @@ -145,7 +145,7 @@ internal void font_set_use(Partition *partition, Font_Set *set, i16 font_id){ b8 already_used; already_used = set->font_used_flags[font_id-1]; - + if (!already_used){ if (set->used_this_frame < set->live_max){ ++set->used_this_frame; @@ -153,7 +153,7 @@ font_set_use(Partition *partition, Font_Set *set, i16 font_id){ already_used = 1; } } - + if (already_used){ // TODO(allen): optimize if you don't mind!!!! Font_Info *info = get_font_info(set, font_id); @@ -165,7 +165,7 @@ font_set_use(Partition *partition, Font_Set *set, i16 font_id){ font_set_load(partition, set, font_id); } slot = ((Font_Slot*)info->font) - 1; - + font__remove(slot); font__insert(&set->used_slots, slot); } @@ -176,12 +176,16 @@ font_set_add(Partition *partition, Font_Set *set, String filename, String name, i32 pt_size){ b32 result = 0; if (font_set_can_add(set)){ + Render_Font dummy_font = {0}; i16 font_id = (i16)(++set->count); Font_Info *info = get_font_info(set, font_id); info->filename = filename; info->name = name; info->pt_size = pt_size; - set->font_info_load(partition, filename.str, pt_size, &info->height, &info->advance); + set->font_load(&dummy_font, info->filename.str, info->pt_size, 4, 0); + info->height = dummy_font.height; + info->advance = dummy_font.advance; + font_set_add_hash(set, name, font_id); if (font_set_can_load(set)){ @@ -201,7 +205,7 @@ font_set_find_pos(Font_Set *set, String name, u32 *position){ i = hash % set->max; j = i - 1; if (j <= 1) j += set->max; - + result = 0; Font_Table_Entry *entry; for (; i != j; ++i){ @@ -215,7 +219,7 @@ font_set_find_pos(Font_Set *set, String name, u32 *position){ } } } - + return(result); } @@ -228,7 +232,7 @@ font_set_extract(Font_Set *set, String name, i16 *font_id){ if (result){ *font_id = set->entries[position].font_id; } - + return(result); } diff --git a/4ed_gui.cpp b/4ed_gui.cpp index c43c5503..63f5995e 100644 --- a/4ed_gui.cpp +++ b/4ed_gui.cpp @@ -171,8 +171,6 @@ struct GUI_Edit{ enum GUI_Command_Type{ guicom_null, - guicom_begin_overlap, - guicom_end_overlap, guicom_begin_serial, guicom_end_serial, guicom_top_bar, @@ -371,16 +369,6 @@ gui_push_string(GUI_Target *target, GUI_Header *h, String s){ gui_push_string(target, h, s, 0); } -internal void -gui_begin_overlap(GUI_Target *target){ - gui_push_simple_command(target, guicom_begin_overlap); -} - -internal void -gui_end_overlap(GUI_Target *target){ - gui_push_simple_command(target, guicom_end_overlap); -} - internal void gui_begin_serial_section(GUI_Target *target){ gui_push_simple_command(target, guicom_begin_serial); @@ -661,17 +649,13 @@ gui_get_scroll_vars(GUI_Target *target, GUI_id scroll_context_id, GUI_Scroll_Var *vars_out = target->scroll_updated; *region_out = target->region_updated; - if (vars_out->target_y < vars_out->min_y) vars_out->target_y = vars_out->min_y; - if (vars_out->target_y > vars_out->max_y) vars_out->target_y = vars_out->max_y; - - if (vars_out->scroll_y < vars_out->min_y) vars_out->scroll_y = vars_out->min_y; - if (vars_out->scroll_y > vars_out->max_y) vars_out->scroll_y = vars_out->max_y; + vars_out->target_y = clamp(0.f, vars_out->target_y, vars_out->max_y); if (gui_id_eq(target->active, gui_id_scrollbar())){ result = 1; target->animating = 1; } - } + } return(result); } @@ -724,7 +708,6 @@ gui_activate_scrolling(GUI_Target *target){ } struct GUI_Section{ - b32 overlapped; i32 max_v, v, top_v; }; @@ -739,7 +722,6 @@ struct GUI_Session{ i32_Rect full_rect; i32_Rect rect; - f32 suggested_min_y; f32 suggested_max_y; i32 clip_y; @@ -759,17 +741,11 @@ struct GUI_Session{ #define GUIScrollbarWidth 16 +// TODO(allen): We can probably totally get rid of this now. internal i32 gui_session_get_eclipsed_y(GUI_Session *session){ - GUI_Section *section = session->sections; - i32 count = session->t + 1, i; - i32 max_v = 0; - for (i = 0; i < count; ++i, ++section){ - if (section->overlapped){ - max_v = Max(max_v, section->max_v); - } - } - max_v = Max(max_v, session->sections[count-1].top_v); + i32 count = session->t + 1; + i32 max_v = session->sections[count-1].top_v; return(max_v); } @@ -804,9 +780,7 @@ gui_session_init(GUI_Session *session, GUI_Target *target, internal void gui_section_end_item(GUI_Section *section, i32 v){ - if (!section->overlapped){ - section->v = v; - } + section->v = v; if (section->max_v < v){ section->max_v = v; } @@ -978,29 +952,10 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, switch (h->type){ case guicom_null: Assert(0); break; - case guicom_begin_overlap: - ++session->t; - Assert(session->t < ArrayCount(session->sections)); - new_section = &session->sections[session->t]; - new_section->overlapped = 1; - new_section->v = y; - new_section->max_v = y; - new_section->top_v = y; - break; - - case guicom_end_overlap: - Assert(session->t > 0); - Assert(section->overlapped); - prev_section = &session->sections[--session->t]; - end_v = section->max_v; - end_section = prev_section; - break; - case guicom_begin_serial: ++session->t; Assert(session->t < ArrayCount(session->sections)); new_section = &session->sections[session->t]; - new_section->overlapped = 0; new_section->v = y; new_section->max_v = y; new_section->top_v = y; @@ -1008,7 +963,6 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, case guicom_end_serial: Assert(session->t > 0); - Assert(!section->overlapped); prev_section = &session->sections[--session->t]; end_v = section->max_v; end_section = prev_section; @@ -1110,7 +1064,6 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, case guicom_scrollable: Assert(session->is_scrollable == 0); - Assert(!section->overlapped); session->is_scrollable = 1; always_give_to_user = 1; @@ -1128,7 +1081,6 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, case guicom_scrollable_bar: Assert(session->is_scrollable); - Assert(!section->overlapped); give_to_user = 1; rect.x1 = session->full_rect.x1; rect.x0 = rect.x1 - GUIScrollbarWidth; @@ -1151,7 +1103,6 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, case guicom_scrollable_top: Assert(session->is_scrollable); - Assert(!section->overlapped); give_to_user = 1; gui_scrollbar_top(session->scroll_rect, &rect); scroll_v = 0; @@ -1159,29 +1110,26 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, case guicom_scrollable_slider: Assert(session->is_scrollable); - Assert(!section->overlapped); give_to_user = 1; lerp_space_scroll_v = - unlerp((f32)target->scroll_original.min_y, + unlerp(0, (f32)target->scroll_original.target_y, (f32)target->scroll_original.max_y); gui_scrollbar_slider(session->scroll_rect, &rect, lerp_space_scroll_v, &session->scroll_top, &session->scroll_bottom, - target->scroll_original.min_y, target->scroll_original.max_y); + 0, target->scroll_original.max_y); scroll_v = 0; break; case guicom_scrollable_invisible: Assert(session->is_scrollable); - Assert(!section->overlapped); always_give_to_user = 1; break; case guicom_scrollable_bottom: Assert(session->is_scrollable); - Assert(!section->overlapped); give_to_user = 1; gui_scrollbar_bottom(session->scroll_rect, &rect); scroll_v = 0; @@ -1196,9 +1144,6 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, case guicom_end_scrollable_section: always_give_to_user = 1; - session->suggested_min_y = - -(f32)(gui_session_get_eclipsed_y(session) - - gui_session_get_current_top(session)); session->suggested_max_y = (f32)(session->scrollable_items_bottom - session->full_rect.y1 * .5f); @@ -1268,7 +1213,7 @@ internal GUI_View_Jump gui_compute_view_jump(i32_Rect scroll_region, i32_Rect position){ GUI_View_Jump jump = {0}; i32 region_h = scroll_region.y1 - scroll_region.y0; - jump.view_min = (f32)position.y1 - region_h - scroll_region.y0; + jump.view_min = (f32)position.y1 - scroll_region.y0 - region_h; jump.view_max = (f32)position.y0 - scroll_region.y0; return(jump); } @@ -1295,8 +1240,8 @@ gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect if (update->has_index_position){ GUI_View_Jump jump = gui_compute_view_jump(scroll_region, update->index_position); - jump.view_min += 45.f; - jump.view_max -= 45.f; + jump.view_min = jump.view_min + 45.f; + jump.view_max = jump.view_max - 45.f; *vars = gui_do_jump(target, jump, *vars); } diff --git a/4ed_math.cpp b/4ed_math.cpp index cb49e7c0..de324c35 100644 --- a/4ed_math.cpp +++ b/4ed_math.cpp @@ -464,9 +464,23 @@ unlerp(f32 a, f32 x, f32 b){ return(r); } +inline f32 +clamp_bottom(f32 a, f32 n){ + if (n < a) n = a; + return (n); +} + +inline f32 +clamp_top(f32 n, f32 z){ + if (n > z) n = z; + return (n); +} + inline f32 clamp(f32 a, f32 n, f32 z){ - return (nz)?(z):n); + if (n < a) n = a; + else if (n > z) n = z; + return (n); } /* diff --git a/4ed_mem.cpp b/4ed_mem.cpp index e0009911..6be08ccb 100644 --- a/4ed_mem.cpp +++ b/4ed_mem.cpp @@ -143,7 +143,9 @@ general_memory_attempt_merge(Bubble *left, Bubble *right){ internal void general_memory_free(General_Memory *general, void *memory){ Bubble *bubble = ((Bubble*)memory) - 1; - Assert((!FRED_INTERNAL) || (bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_DEBUG); +#if FRED_INTERNAL + Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_DEBUG); +#endif bubble->flags &= ~MEM_BUBBLE_USED; bubble->type = 0; Bubble *prev, *next; @@ -158,7 +160,9 @@ general_memory_reallocate(General_Memory *general, void *old, i32 old_size, i32 void *result = old; Bubble *bubble = ((Bubble*)old) - 1; bubble->type = type; - Assert((!FRED_INTERNAL) || (bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_DEBUG); +#if FRED_INTERNAL + Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_DEBUG); +#endif i32 additional_space = size - bubble->size; if (additional_space > 0){ Bubble *next = bubble->next; diff --git a/4ed_metagen.cpp b/4ed_metagen.cpp index 8ed6c967..d052ce25 100644 --- a/4ed_metagen.cpp +++ b/4ed_metagen.cpp @@ -143,184 +143,6 @@ char* generate_keycode_enum(){ return(filename); } -////////////////////////////////////////////////////////////////////////////////////////////////// -char daction_enum_name[] = "Action_Type"; -char *daction_enum[] = { - "OPEN", - "OPEN_BACKGROUND", - "SET_LINE", - "SAVE_AS", - "SAVE", - "NEW", - "SWITCH", - "TRY_KILL", - "KILL", - "TOUCH_FILE", - "CLOSE", -}; - -char str_alloc_copy[] = -"internal String\n" -"str_alloc_copy(General_Memory *general, String str){\n" -" String result;\n" -" result.memory_size = str.memory_size + 1;\n" -" result.size = str.size;\n" -" result.str = (char*)general_memory_allocate(general, result.memory_size, 0);\n" -" memcpy(result.str, str.str, str.size);\n" -" result.str[result.size] = 0;\n" -" return(result);\n" -"}\n\n"; - -char delayed_action_zero[] = -"inline Delayed_Action\n" -"delayed_action_zero(){\n" -" Delayed_Action result = {(Action_Type)0};\n" -" return(result);\n" -"}\n\n" -; - -char daction_name[] = "Delayed_Action"; -Struct_Field daction_fields[] = { - {"Action_Type", "type"}, -}; -Struct_Field daction_fields_primary[] = { - {"String", "string"}, - {"Panel*", "panel"}, - {"Editing_File*", "file"}, - {"i32", "integer"}, -}; -enum Daction_Field_Handle{ - dfph_null, - dfph_string, - dfph_panel, - dfph_file, - dfph_integer, -}; -Daction_Field_Handle dact_param_sets[] = { - dfph_string, dfph_null, - dfph_panel, dfph_null, - dfph_file, dfph_null, - dfph_file, dfph_panel, dfph_null, - dfph_string, dfph_panel, dfph_null, - dfph_string, dfph_file, dfph_null, - dfph_panel, dfph_integer, dfph_null, -}; - -char delay_name[] = "Delay"; -Struct_Field delay_fields[] = { - {"General_Memory*", "general"}, - {"Delayed_Action*", "acts"}, - {"i32", "count"}, - {"i32", "max"}, -}; - -char delayed_action_function_top[] = -"inline Delayed_Action*\n" -"delayed_action_(Delay *delay, Action_Type type"; - -char delayed_action_function_bottom[] = -"){\n" -" Delayed_Action *result;\n" -" if (delay->count == delay->max){\n" -" delay->max *= 2;\n" -" delay->acts = (Delayed_Action*)general_memory_reallocate(" -"delay->general, delay->acts, delay->count*sizeof(Delayed_Action), delay->max*sizeof(Delayed_Action), 0);\n" -" }\n" -" result = delay->acts + delay->count++;\n" -" *result = delayed_action_zero();\n" -" result->type = type;\n" -" return(result);\n" -"}\n\n"; - -char delayed_action_special_param[] = ", %s %s"; - -char delayed_action_specialized_middle[] = -"){\n" -" Delayed_Action *result;\n" -" result = delayed_action_(delay, type);\n"; - -char delayed_action_special_line[] = -" result->%s = %s;\n"; - -char delayed_action_special_string_line[] = -" result->%s = str_alloc_copy(delay->general, %s);\n"; - -char delayed_action_specialized_bottom[] = -" return(result);\n" -"}\n\n"; - -char delayed_action_macro[] = -"#define delayed_%s(delay, ...) delayed_action_(delay, DACT_%s, ##__VA_ARGS__)\n"; - -char delayed_action_repush_function[] = -"inline Delayed_Action*\n" -"delayed_action_repush(Delay *delay, Delayed_Action *act){\n" -" Delayed_Action *new_act = delayed_action_(delay, (Action_Type)0);\n" -" *new_act = *act;\n" -" if (act->string.str){\n" -" new_act->string = str_alloc_copy(delay->general, act->string);\n" -" }\n" -" return(new_act);\n" -"}\n\n"; - -char* generate_delayed_action(){ - FILE *file; - char *filename = "4ed_delay.cpp"; - char scratch[256]; - int i,j; - - file = fopen(filename, "wb"); - - fprintf(file, "enum %s{\n", daction_enum_name); - for (i = 0; i < ArrayCount(daction_enum); ++i){ - fprintf(file, " DACT_%s,\n", daction_enum[i]); - } - fprintf(file, "};\n\n"); - - struct_begin(file, daction_name); - struct_fields(file, daction_fields, ArrayCount(daction_fields)); - struct_fields(file, daction_fields_primary, ArrayCount(daction_fields_primary)); - struct_end(file); - - struct_begin(file, delay_name); - struct_fields(file, delay_fields, ArrayCount(delay_fields)); - struct_end(file); - - fprintf(file, "%s", str_alloc_copy); - fprintf(file, "%s", delayed_action_zero); - fprintf(file, "%s%s", delayed_action_function_top, delayed_action_function_bottom); - - for (i = 0; i < ArrayCount(dact_param_sets); ++i){ - j = i; - fprintf(file, "%s", delayed_action_function_top); - for (; dact_param_sets[i] != dfph_null; ++i){ - Struct_Field field = daction_fields_primary[dact_param_sets[i] - 1]; - fprintf(file, delayed_action_special_param, field.type, field.name); - } - fprintf(file, "%s", delayed_action_specialized_middle); - for (; dact_param_sets[j] != dfph_null; ++j){ - int handle = (int)(dact_param_sets[j]); - Struct_Field field = daction_fields_primary[handle - 1]; - if (handle == dfph_string){ - fprintf(file, delayed_action_special_string_line, field.name, field.name); - } - else{ - fprintf(file, delayed_action_special_line, field.name, field.name); - } - } - fprintf(file, "%s", delayed_action_specialized_bottom); - } - - fprintf(file, "%s", delayed_action_repush_function); - - for (i = 0; i < ArrayCount(daction_enum); ++i){ - to_lower(daction_enum[i], scratch); - fprintf(file, delayed_action_macro, scratch, daction_enum[i]); - } - - return(filename); -} - ////////////////////////////////////////////////////////////////////////////////////////////////// char* bar_style_fields[] = { "bar", @@ -456,6 +278,7 @@ char* generate_style(){ return(filename); } +////////////////////////////////////////////////////////////////////////////////////////////////// struct Function_Signature{ String name; String ret; @@ -653,6 +476,24 @@ generate_custom_headers(){ ); fprintf(file, "};\n"); + // TODO(allen): Generate app->function(app, ...) to function(app, ...) wrappers. + // Need to parse parameter names to do this. +#if 0 + for (int i = 0; i < sig_count; ++i){ + Function_Signature *sig = sigs + i; + + copy_fast_unsafe(name_buffer, sig->name); + name_buffer[sig->name.size] = 0; + to_lower(name_buffer, name_buffer); + + fprintf(file, + "inline %.*s\n" + "%s%.*s{ app->%s(", + sig->name.size, sig->name.str, + name_buffer); + } +#endif + fclose(file); return(filename); @@ -664,9 +505,6 @@ int main(){ filename = generate_keycode_enum(); printf("gen success: %s\n", filename); - filename = generate_delayed_action(); - printf("gen success: %s\n", filename); - filename = generate_style(); printf("gen success: %s\n", filename); diff --git a/4ed_rendering.cpp b/4ed_rendering.cpp index 8a13f632..45705544 100644 --- a/4ed_rendering.cpp +++ b/4ed_rendering.cpp @@ -34,28 +34,36 @@ draw_set_color(Render_Target *target, u32 color){ } } -#define PutStruct(s,x) *(s*)(target->push_buffer + target->size) = x; target->size += sizeof(s) +inline void +draw_safe_push(Render_Target *target, i32 size, void *x){ + if (size + target->size <= target->max){ + memcpy(target->push_buffer + target->size, x, size); + target->size += size; + } +} + +#define PutStruct(s,x) draw_safe_push(target, sizeof(s), &x) internal void draw_push_piece(Render_Target *target, Render_Piece_Combined piece){ PutStruct(Render_Piece_Header, piece.header); switch (piece.header.type){ - case piece_type_rectangle: - case piece_type_outline: + case piece_type_rectangle: + case piece_type_outline: PutStruct(Render_Piece_Rectangle, piece.rectangle); break; - case piece_type_gradient: + case piece_type_gradient: PutStruct(Render_Piece_Gradient, piece.gradient); break; - case piece_type_glyph: - case piece_type_mono_glyph: + case piece_type_glyph: + case piece_type_mono_glyph: PutStruct(Render_Piece_Glyph, piece.glyph); break; - case piece_type_mono_glyph_advance: + case piece_type_mono_glyph_advance: PutStruct(Render_Piece_Glyph_Advance, piece.glyph_advance); break; } @@ -297,101 +305,17 @@ launch_rendering(Render_Target *target){ #undef ExtractStruct -internal i32 -draw_font_info_load(Partition *partition, - char *filename_untranslated, - i32 pt_size, i32 *height, i32 *advance){ - - char space_[1024]; - String filename = make_fixed_width_string(space_); - b32 translate_success = sysshared_to_binary_path(&filename, filename_untranslated); - if (!translate_success) return 0; - - i32 result = 1; - File_Data file; - file = sysshared_load_file(filename.str); - - Temp_Memory temp = begin_temp_memory(partition); - stbtt_packedchar *chardata = push_array(partition, stbtt_packedchar, 256); - - i32 oversample = 2; - - i32 tex_width, tex_height; - tex_width = pt_size*128*oversample; - tex_height = pt_size*2*oversample; - void *block = push_block(partition, tex_width * tex_height); - - if (!file.data.data){ - result = 0; - } - else{ - stbtt_fontinfo font; - if (!stbtt_InitFont(&font, (u8*)file.data.data, 0)){ - result = 0; - } - else{ - i32 ascent, descent, line_gap; - f32 scale; - - stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap); - scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size); - - f32 scaled_ascent, scaled_descent, scaled_line_gap; - - scaled_ascent = scale*ascent; - scaled_descent = scale*descent; - scaled_line_gap = scale*line_gap; - - i32 font_height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap); - - stbtt_pack_context spc; - if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height, tex_width, 1, partition)){ - stbtt_PackSetOversampling(&spc, oversample, oversample); - if (stbtt_PackFontRange(&spc, (u8*)file.data.data, 0, - STBTT_POINT_SIZE((f32)pt_size), 0, 128, chardata)){ - // do nothing - } - else{ - result = 0; - } - - stbtt_PackEnd(&spc); - } - else{ - result = 0; - } - - if (result){ - i32 max_advance = 0; - for (u8 code_point = 0; code_point < 128; ++code_point){ - if (stbtt_FindGlyphIndex(&font, code_point) != 0){ - i32 adv = CEIL32(chardata[code_point].xadvance); - if (max_advance < adv){ - max_advance = adv; - } - } - } - - *height = font_height; - *advance = max_advance - 1; - } - } - - system_free_memory(file.data.data); - } - - end_temp_memory(temp); - - return(result); -} - +// TODO(allen): Put the burden of translation outside +// of this function (and other functions implementing +// the same interface). internal i32 draw_font_load(Partition *part, Render_Font *font_out, char *filename_untranslated, i32 pt_size, i32 tab_width, - i32 oversample){ + i32 oversample, + b32 store_texture){ char space_[1024]; String filename = make_fixed_width_string(space_); @@ -402,12 +326,6 @@ draw_font_load(Partition *part, stbtt_packedchar *chardata = font_out->chardata; - Temp_Memory temp = begin_temp_memory(part); - - i32 tex_width = pt_size*16*oversample; - i32 tex_height = pt_size*16*oversample; - void *block = sysshared_push_block(part, tex_width * tex_height); - File_Data file = sysshared_load_file(filename.str); if (!file.data.data){ @@ -420,85 +338,89 @@ draw_font_load(Partition *part, result = 0; } else{ + memset(font_out, 0, sizeof(*font_out)); + i32 ascent, descent, line_gap; - f32 scale; - stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap); - scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size); - f32 scaled_ascent, scaled_descent, scaled_line_gap; + f32 scale = stbtt_ScaleForPixelHeight(&font, (f32)pt_size); - scaled_ascent = scale*ascent; - scaled_descent = scale*descent; - scaled_line_gap = scale*line_gap; + f32 scaled_ascent = scale*ascent; + f32 scaled_descent = scale*descent; + f32 scaled_line_gap = scale*line_gap; font_out->height = (i32)(scaled_ascent - scaled_descent + scaled_line_gap); font_out->ascent = (i32)(scaled_ascent); font_out->descent = (i32)(scaled_descent); font_out->line_skip = (i32)(scaled_line_gap); - font_out->tex_width = tex_width; - font_out->tex_height = tex_height; - - stbtt_pack_context spc; - - // TODO(allen): If this fails we can just expand the partition here now - // rather than forcing the user to do it. - if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height, - tex_width, 1, part)){ - stbtt_PackSetOversampling(&spc, oversample, oversample); - if (!stbtt_PackFontRange(&spc, (u8*)file.data.data, 0, - STBTT_POINT_SIZE((f32)pt_size), - 0, 128, chardata)){ + if (store_texture){ + Temp_Memory temp = begin_temp_memory(part); + + i32 tex_width = pt_size*16*oversample; + i32 tex_height = pt_size*16*oversample; + void *block = sysshared_push_block(part, tex_width * tex_height); + + font_out->tex_width = tex_width; + font_out->tex_height = tex_height; + + stbtt_pack_context spc; + + if (stbtt_PackBegin(&spc, (u8*)block, tex_width, tex_height, + tex_width, 1, part)){ + stbtt_PackSetOversampling(&spc, oversample, oversample); + if (!stbtt_PackFontRange(&spc, (u8*)file.data.data, 0, + STBTT_POINT_SIZE((f32)pt_size), + 0, 128, chardata)){ + result = 0; + } + + stbtt_PackEnd(&spc); + } + else{ result = 0; } - stbtt_PackEnd(&spc); - } - else{ - result = 0; - } - - if (result){ - GLuint font_tex; - glGenTextures(1, &font_tex); - glBindTexture(GL_TEXTURE_2D, font_tex); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, block); - - font_out->tex = font_tex; - glBindTexture(GL_TEXTURE_2D, 0); - - font_out->chardata['\r'] = font_out->chardata[' ']; - font_out->chardata['\n'] = font_out->chardata[' ']; - font_out->chardata['\t'] = font_out->chardata[' ']; - font_out->chardata['\t'].xadvance *= tab_width; - - i32 max_advance = 0; - 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(font_out->chardata[code_point].xadvance); - if (max_advance < advance) max_advance = advance; - font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance; - } - else if (code_point == '\r' || code_point == '\n' || code_point == '\t'){ - font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance; + if (result){ + GLuint font_tex; + glGenTextures(1, &font_tex); + glBindTexture(GL_TEXTURE_2D, font_tex); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tex_width, tex_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, block); + + font_out->tex = font_tex; + glBindTexture(GL_TEXTURE_2D, 0); + + font_out->chardata['\r'] = font_out->chardata[' ']; + font_out->chardata['\n'] = font_out->chardata[' ']; + font_out->chardata['\t'] = font_out->chardata[' ']; + font_out->chardata['\t'].xadvance *= tab_width; + + i32 max_advance = 0; + 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(font_out->chardata[code_point].xadvance); + if (max_advance < advance) max_advance = advance; + font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance; + } + else if (code_point == '\r' || code_point == '\n' || code_point == '\t'){ + font_out->advance_data[code_point] = font_out->chardata[code_point].xadvance; + } } + font_out->advance = max_advance - 1; } - font_out->advance = max_advance - 1; + + end_temp_memory(temp); } - } system_free_memory(file.data.data); } - end_temp_memory(temp); - return(result); } diff --git a/4ed_rendering.h b/4ed_rendering.h index 961c50cb..0c2e8d4b 100644 --- a/4ed_rendering.h +++ b/4ed_rendering.h @@ -115,16 +115,11 @@ typedef Draw_Push_Piece_Sig(Draw_Push_Piece); Render_Font *font_out, \ char *filename, \ i32 pt_size, \ - i32 tab_width) + i32 tab_width, \ + b32 store_texture) typedef Font_Load_Sig(Font_Load); -#define Font_Info_Load_Sig(name) i32 name( \ - Partition *partition, \ - char *filename, \ - i32 pt_size, \ - i32 *height, \ - i32 *advance) -typedef Font_Info_Load_Sig(Font_Info_Load); + #define Release_Font_Sig(name) void name(Render_Font *font) typedef Release_Font_Sig(Release_Font); @@ -158,7 +153,7 @@ struct Font_Set{ Font_Slot free_slots; Font_Slot used_slots; - Font_Info_Load *font_info_load; + //Font_Info_Load *font_info_load; Font_Load *font_load; Release_Font *release_font; diff --git a/4ed_system.h b/4ed_system.h index 65e2dee7..82f12bdd 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -35,9 +35,16 @@ uhash_equal(Unique_Hash a, Unique_Hash b){ return(result); } +// NOTE(allen): These two time functions should return values +// in the same time space. There is no requirement about +// resolution but the higher the better. These functions +// should not be used for profiling purposes. #define Sys_File_Time_Stamp_Sig(name) u64 name(char *filename) typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp); +#define Sys_Now_Time_Stamp_Sig(name) u64 name() +typedef Sys_Now_Time_Stamp_Sig(System_Now_Time_Stamp); + // TODO(allen): make directory a char* to signal that it must be null terminated #define Sys_Set_File_List_Sig(name) void name(File_List *file_list, String directory) typedef Sys_Set_File_List_Sig(System_Set_File_List); @@ -66,13 +73,9 @@ typedef Sys_File_Load_End_Sig(System_File_Load_End); #define Sys_File_Save_Sig(name) b32 name(char *filename, char *buffer, i32 size) typedef Sys_File_Save_Sig(System_File_Save); - #define Sys_Post_Clipboard_Sig(name) void name(String str) typedef Sys_Post_Clipboard_Sig(System_Post_Clipboard); -#define Sys_Time_Sig(name) u64 name() -typedef Sys_Time_Sig(System_Time); - // cli struct CLI_Handles{ Plat_Handle proc; @@ -154,15 +157,17 @@ thread_memory_zero(){ struct Thread_Exchange; struct System_Functions; -#define Job_Callback_Sig(name) void name( \ - System_Functions *system, Thread_Context *thread, Thread_Memory *memory, \ - Thread_Exchange *exchange, void *data[2]) +#define Job_Callback_Sig(name) void name( \ + System_Functions *system, \ + Thread_Context *thread, \ + Thread_Memory *memory, \ + void *data[2]) typedef Job_Callback_Sig(Job_Callback); struct Job_Data{ Job_Callback *callback; void *data[2]; - i32 memory_request; + //i32 memory_request; }; struct Full_Job_Data{ @@ -186,17 +191,15 @@ struct Work_Queue{ #define JOB_ID_WRAP (ArrayCount(queue->jobs) * 4) #define QUEUE_WRAP (ArrayCount(queue->jobs)) -struct Thread_Exchange{ - Work_Queue queues[THREAD_GROUP_COUNT]; - volatile u32 force_redraw; -}; - #define Sys_Post_Job_Sig(name) u32 name(Thread_Group_ID group_id, Job_Data job) typedef Sys_Post_Job_Sig(System_Post_Job); #define Sys_Cancel_Job_Sig(name) void name(Thread_Group_ID group_id, u32 job_id) typedef Sys_Cancel_Job_Sig(System_Cancel_Job); +#define Sys_Check_Cancel_Sig(name) b32 name(Thread_Context *thread) +typedef Sys_Check_Cancel_Sig(System_Check_Cancel); + #define Sys_Grow_Thread_Memory_Sig(name) void name(Thread_Memory *memory) typedef Sys_Grow_Thread_Memory_Sig(System_Grow_Thread_Memory); @@ -217,8 +220,9 @@ typedef INTERNAL_Sys_Get_Thread_States_Sig(INTERNAL_System_Get_Thread_States); typedef INTERNAL_Sys_Debug_Message_Sig(INTERNAL_System_Debug_Message); struct System_Functions{ - // files: 6 + // files: 7 System_File_Time_Stamp *file_time_stamp; + System_Now_Time_Stamp *now_time_stamp; System_Set_File_List *set_file_list; System_File_Unique_Hash *file_unique_hash; System_File_Track *file_track; @@ -226,17 +230,14 @@ struct System_Functions{ System_File_Load_Begin *file_load_begin; System_File_Load_End *file_load_end; System_File_Save *file_save; - + // file system navigation (4coder_custom.h): 3 File_Exists_Function *file_exists; Directory_CD_Function *directory_cd; Get_4ed_Path_Function *get_4ed_path; - + // clipboard: 1 System_Post_Clipboard *post_clipboard; - - // time: 1 - System_Time *time; // coroutine: 4 System_Create_Coroutine *create_coroutine; @@ -249,14 +250,15 @@ struct System_Functions{ System_CLI_Begin_Update *cli_begin_update; System_CLI_Update_Step *cli_update_step; System_CLI_End_Update *cli_end_update; - - // threads: 5 + + // threads: 7 System_Post_Job *post_job; System_Cancel_Job *cancel_job; + System_Check_Cancel *check_cancel; System_Grow_Thread_Memory *grow_thread_memory; System_Acquire_Lock *acquire_lock; System_Release_Lock *release_lock; - + // debug: 3 INTERNAL_System_Sentinel *internal_sentinel; INTERNAL_System_Get_Thread_States *internal_get_thread_states; @@ -266,9 +268,5 @@ struct System_Functions{ char slash; }; -struct Exchange{ - Thread_Exchange thread; -}; - // BOTTOM diff --git a/4ed_template.cpp b/4ed_template.cpp index 22be5e61..fc1abfcf 100644 --- a/4ed_template.cpp +++ b/4ed_template.cpp @@ -12,7 +12,7 @@ // NOTE(allen): This is an experiment, BUT remember a lot of people shit on templates. // So if you start getting a wiff of stupidity from this back out immediately! // -// experience 1: no badness, haven't seen any anoying template errors +// experience 1: no badness, haven't seen any annoying template errors // ... template diff --git a/4tech_table.cpp b/4tech_table.cpp index 7c4144e5..fc4257c4 100644 --- a/4tech_table.cpp +++ b/4tech_table.cpp @@ -57,12 +57,13 @@ table_at_capacity(Table *table){ internal b32 table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ u32 hash, *inspect; - i32 i; + i32 i, start; Assert(table->count * 8 < table->max * 7); - + hash = (hash_func(item, arg) | TableHashMin); i = hash % table->max; + start = i; inspect = table->hash_array + i; while (*inspect >= TableHashMin){ @@ -77,6 +78,7 @@ table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare i = 0; inspect = table->hash_array; } + Assert(i != start); } *inspect = hash; memcpy(table->data_array + i*table->item_size, item, table->item_size); @@ -88,12 +90,13 @@ table_add(Table *table, void *item, void *arg, Hash_Function *hash_func, Compare internal b32 table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index, Hash_Function *hash_func, Compare_Function *comp_func){ u32 hash, *inspect; - i32 i; + i32 i, start; Assert((table->count - 1) * 8 < table->max * 7); hash = (hash_func(search_key, arg) | TableHashMin); i = hash % table->max; + start = i; inspect = table->hash_array + i; while (*inspect != TableHashEmpty){ @@ -110,6 +113,7 @@ table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index, i = 0; inspect = table->hash_array; } + if (i == start) break; } return(0); diff --git a/README.txt b/README.txt index 9d9b308d..fb715b69 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -Distribution Date: 24.5.2016 (dd.mm.yyyy) +Distribution Date: 31.5.2016 (dd.mm.yyyy) Thank you for contributing to the 4coder project! diff --git a/SUPERREADME.txt b/SUPERREADME.txt index e25362cb..d7220460 100644 --- a/SUPERREADME.txt +++ b/SUPERREADME.txt @@ -1,4 +1,4 @@ -Distribution Date: 24.5.2016 (dd.mm.yyyy) +Distribution Date: 31.5.2016 (dd.mm.yyyy) Thank you for contributing to the 4coder project! diff --git a/TODO.txt b/TODO.txt index 8a8d85a7..ed15ee12 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,7 +1,3 @@ - -; before shipping: -; [] make sure 4coder_handmade_hero.cpp works - ; Started this list on: (18.01.2016)(dd.mm.yyyy) ; This list is an informal todo list, it may very well miss items ; checked or unchecked, that I inted to do some day. It is included @@ -67,11 +63,15 @@ ; [X] chronal's map setting issue ; [X] linux save jankieness ; [X] bouncing when scrolling down +; [X] sometimes the main cursor is not the same width as the mark cursor in the same spot +; [X] tab character wrong width +; [X] miblo's off screen cursor thing +; [X] new file is messed up for code files, it never finishes parsing! +; [X] key presses that should be consumed in the GUI are now passed to the file! +; [X] paste snaps the cursor back into view! +; ; [] indication on failure to save ; [] clean whitespace doesn't appear to be cleaning trailing whitespace anymore??? -; [] sometimes the main cursor is not the same width as the mark cursor in the same spot -; [] tab character wrong width -; [] miblo's off screen cursor thing ; ; @@ -99,6 +99,9 @@ ; [X] feedback messages ; [X] feedback message API ; [X] kill rect +; [X] add high DPI support +; +; [] OS font rendering ; ; [] file status in custom API ; [] user file bar string @@ -117,14 +120,13 @@ ; [X] rewrite GUI ; [X] arrow navigation of GUIs ; [] GUI API -; [] text links -> arbitrary commands / callbacks? ; ; search related tech ; [X] replace word (incremental and/or in range) +; [X] caps insensitivety ; [] optimize search ; [] allow search wrap around beginning/end ; [] improved custom API for text "streams" -; [] caps insensitivety ; ; theme related business ; [] fix the versioning system for themes @@ -173,12 +175,11 @@ ; INTERNAL TODOS ; [X] switch building non-extensible version by statically linking to custom.cpp +; [X] pack fonts more squarely ; [] general parameter handling ; [] hashed string pool for clipboard/filenames/etc -; [] ask for clipboards to update by request, not on loop -; [] pack fonts more squarely -; [] setup tests through special tool ; [] new profiling/debugging system +; [] change job canceling to a polling based thing ; ; EASY TODOS @@ -192,7 +193,6 @@ ; HARD BUGS ; [X] reduce cpu consumption -; [?] minimize and reopen problem (reported by two users now, still not reproduced here) ; [X] repainting too slow for resize looks really dumb ; [] fyoucon's segfaults with malloc on win10 ; [] handling cursor in non-client part of window so it doesn't spaz @@ -200,6 +200,17 @@ ; [] how to get fast repaint (do I really need double buffering?) ; [] history breaks when heavily used (disk swaping?) ; +; [] minimize and reopen problem (reported by two users now, still not reproduced here) +; + +; FANCY PANTS IDEAS +; [] pass messages to 'jobs' to try to avoid cancelling them +; if the job still thinks it should be cancelled it will say so +; but otherwise the job can try to incorporate the new info +; without throwing away the progress it has made so far. +; +; + ; PORTING TODOS ; [X] command line parameters diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index 32ab27f9..5a52c209 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -128,98 +128,6 @@ buffer_reverse_seek_delimiter(Buffer_Type *buffer, int pos, char delim){ return(pos); } -internal_4tech int -buffer_seek_whitespace_down(Buffer_Type *buffer, int pos){ - Buffer_Stringify_Type loop; - char *data; - int end; - int size; - int no_hard; - int prev_endline; - - size = buffer_size(buffer); - loop = buffer_stringify_loop(buffer, pos, size); - - for (;buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - end = loop.size + loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (;pos < end; ++pos){ - if (!is_whitespace(data[pos])) goto buffer_seek_whitespace_down_mid; - } - } - -buffer_seek_whitespace_down_mid: - no_hard = 0; - prev_endline = -1; - for (;buffer_stringify_good(&loop); - buffer_stringify_next(&loop)){ - end = loop.size + loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; pos < end; ++pos){ - if (data[pos] == '\n'){ - if (no_hard) goto buffer_seek_whitespace_down_end; - else{ - no_hard = 1; - prev_endline = pos; - } - } - else if (!is_whitespace(data[pos])){ - no_hard = 0; - } - } - } - -buffer_seek_whitespace_down_end: - if (prev_endline == -1 || prev_endline+1 >= size) pos = size; - else pos = prev_endline+1; - - return pos; -} - -internal_4tech int -buffer_seek_whitespace_up(Buffer_Type *buffer, int pos){ - Buffer_Backify_Type loop; - char *data; - int end; - int size; - int no_hard; - - size = buffer_size(buffer); - loop = buffer_backify_loop(buffer, pos-1, 1); - - for (;buffer_backify_good(&loop); - buffer_backify_next(&loop)){ - end = loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (;pos >= end; --pos){ - if (!is_whitespace(data[pos])) goto buffer_seek_whitespace_up_mid; - } - } - -buffer_seek_whitespace_up_mid: - no_hard = 0; - for (;buffer_backify_good(&loop); - buffer_backify_next(&loop)){ - end = loop.absolute_pos; - data = loop.data - loop.absolute_pos; - for (; pos >= end; --pos){ - if (data[pos] == '\n'){ - if (no_hard) goto buffer_seek_whitespace_up_end; - else no_hard = 1; - } - else if (!is_whitespace(data[pos])){ - no_hard = 0; - } - } - } - -buffer_seek_whitespace_up_end: - if (pos != 0) ++pos; - - return pos; -} - internal_4tech int buffer_seek_whitespace_right(Buffer_Type *buffer, int pos){ Buffer_Stringify_Type loop; @@ -945,6 +853,8 @@ buffer_get_line_index_range(Buffer_Type *buffer, int pos, int l_bound, int u_bou lines = buffer->line_starts; + assert_4tech(lines != 0); + start = l_bound; end = u_bound; for (;;){ @@ -964,8 +874,7 @@ buffer_get_line_index_range(Buffer_Type *buffer, int pos, int l_bound, int u_bou inline_4tech int buffer_get_line_index(Buffer_Type *buffer, int pos){ - int result; - result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count); + int result = buffer_get_line_index_range(buffer, pos, 0, buffer->line_count); return(result); } @@ -1313,6 +1222,42 @@ buffer_get_start_cursor(Buffer_Type *buffer, float *wraps, float scroll_y, return(result); } +#define BRFlag_Special_Character (1 << 0) + +typedef struct Buffer_Render_Item{ + int index; + unsigned short glyphid; + unsigned short flags; + float x0, y0; + float x1, y1; +} Buffer_Render_Item; + +inline_4tech void +write_render_item(Buffer_Render_Item *item, + int index, + unsigned short glyphid, + float x, float y, + float w, float h){ + item->index = index; + item->glyphid = glyphid; + item->x0 = x; + item->y0 = y; + item->x1 = x + w; + item->y1 = y + h; +} + +inline_4tech float +write_render_item_inline(Buffer_Render_Item *item, + int index, + unsigned short glyphid, + float x, float y, + float *advance_data, float h){ + float ch_width; + ch_width = measure_character(advance_data, (char)glyphid); + write_render_item(item, index, glyphid, x, y, ch_width, h); + return(ch_width); +} + internal_4tech void buffer_get_render_data(Buffer_Type *buffer, Buffer_Render_Item *items, int max, int *count, float port_x, float port_y, @@ -1324,6 +1269,7 @@ buffer_get_render_data(Buffer_Type *buffer, Buffer_Render_Item *items, int max, Buffer_Stringify_Type loop; Buffer_Render_Item *item; + Buffer_Render_Item *item_end; char *data; int size, end; float shift_x, shift_y; @@ -1343,116 +1289,141 @@ buffer_get_render_data(Buffer_Type *buffer, Buffer_Render_Item *items, int max, y = shift_y; item_i = 0; item = items + item_i; + item_end = items + max; + // TODO(allen): What's the plan for when there is not enough space to store + // more render items? It seems like we should be able to use the view_x + // to skip items that are not in view right? That way I think it would + // just always fit in the buffer. if (advance_data){ for (loop = buffer_stringify_loop(buffer, start_cursor.pos, size); - buffer_stringify_good(&loop); + buffer_stringify_good(&loop) && item < item_end; buffer_stringify_next(&loop)){ - + end = loop.size + loop.absolute_pos; data = loop.data - loop.absolute_pos; - + for (i = loop.absolute_pos; i < end; ++i){ ch = data[i]; ch_width = measure_character(advance_data, ch); - + if (ch_width + x > width + shift_x && wrapped && ch != '\n'){ x = shift_x; y += font_height; } if (y > height + shift_y) goto buffer_get_render_data_end; - - switch (ch){ - case '\n': - write_render_item_inline(item, i, ' ', x, y, advance_data, font_height); - item->flags = 0; - ++item_i; - ++item; - x = shift_x; - y += font_height; - break; - - case 0: - ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height); - item->flags = BRFlag_Special_Character; - ++item_i; - ++item; - x += ch_width; - - ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, font_height); - item->flags = BRFlag_Special_Character; - ++item_i; - ++item; - x += ch_width; - break; - - case '\r': - ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height); - item->flags = BRFlag_Special_Character; - ++item_i; - ++item; - x += ch_width; - - ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, font_height); - item->flags = BRFlag_Special_Character; - ++item_i; - ++item; - x += ch_width; - break; - - case '\t': - if (opts.show_slash_t){ - ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height); - item->flags = BRFlag_Special_Character; - ++item_i; - ++item; - - write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, font_height); - item->flags = BRFlag_Special_Character; - ++item_i; - ++item; - } - else{ + switch (ch){ + case '\n': + if (item < item_end){ write_render_item_inline(item, i, ' ', x, y, advance_data, font_height); item->flags = 0; ++item_i; ++item; + + x = shift_x; + y += font_height; + } + break; + + case 0: + if (item < item_end){ + ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height); + item->flags = BRFlag_Special_Character; + ++item_i; + ++item; + x += ch_width; + + if (item < item_end){ + ch_width = write_render_item_inline(item, i, '0', x, y, advance_data, font_height); + item->flags = BRFlag_Special_Character; + ++item_i; + ++item; + x += ch_width; + } + } + break; + + case '\r': + if (item < item_end){ + ch_width = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height); + item->flags = BRFlag_Special_Character; + ++item_i; + ++item; + x += ch_width; + + if (item < item_end){ + ch_width = write_render_item_inline(item, i, 'r', x, y, advance_data, font_height); + item->flags = BRFlag_Special_Character; + ++item_i; + ++item; + x += ch_width; + } + } + break; + + case '\t': + if (opts.show_slash_t){ + if (item < item_end){ + ch_width_sub = write_render_item_inline(item, i, '\\', x, y, advance_data, font_height); + item->flags = BRFlag_Special_Character; + ++item_i; + ++item; + if (item < item_end){ + write_render_item_inline(item, i, 't', x + ch_width_sub, y, advance_data, font_height); + item->flags = BRFlag_Special_Character; + ++item_i; + ++item; + } + } + } + else{ + if (item < item_end){ + write_render_item_inline(item, i, ' ', x, y, advance_data, font_height); + item->flags = 0; + ++item_i; + ++item; + } } x += ch_width; break; - - default: - write_render_item(item, i, ch, x, y, ch_width, font_height); - item->flags = 0; - ++item_i; - ++item; - x += ch_width; - + + default: + if (item < item_end){ + write_render_item(item, i, ch, x, y, ch_width, font_height); + item->flags = 0; + ++item_i; + ++item; + x += ch_width; + } break; } if (y > height + shift_y) goto buffer_get_render_data_end; } } - -buffer_get_render_data_end: + + buffer_get_render_data_end: if (y <= height + shift_y || item == items){ + if (item < item_end){ + ch = 0; + ch_width = measure_character(advance_data, ' '); + write_render_item(item, size, ch, x, y, ch_width, font_height); + ++item_i; + ++item; + x += ch_width; + } + } + } + else{ + if (item < item_end){ ch = 0; - ch_width = measure_character(advance_data, ' '); + ch_width = 0; write_render_item(item, size, ch, x, y, ch_width, font_height); ++item_i; ++item; x += ch_width; } } - else{ - ch = 0; - ch_width = 0; - write_render_item(item, size, ch, x, y, ch_width, font_height); - ++item_i; - ++item; - x += ch_width; - } // TODO(allen): handle this with a control state assert_4tech(item_i <= max); diff --git a/buffer/4coder_shared.cpp b/buffer/4coder_shared.cpp index afb630be..8a70e3e1 100644 --- a/buffer/4coder_shared.cpp +++ b/buffer/4coder_shared.cpp @@ -88,36 +88,6 @@ typedef struct Buffer_Batch_State{ int shift_total; } Buffer_Batch_State; -#define BRFlag_Special_Character (1 << 0) - -typedef struct Buffer_Render_Item{ - int index; - unsigned short glyphid; - unsigned short flags; - float x0, y0; - float x1, y1; -} Buffer_Render_Item; - -inline_4tech void -write_render_item(Buffer_Render_Item *item, int index, unsigned short glyphid, - float x, float y, float w, float h){ - item->index = index; - item->glyphid = glyphid; - item->x0 = x; - item->y0 = y; - item->x1 = x + w; - item->y1 = y + h; -} - -inline_4tech float -write_render_item_inline(Buffer_Render_Item *item, int index, unsigned short glyphid, - float x, float y, float *advance_data, float h){ - float ch_width; - ch_width = measure_character(advance_data, (char)glyphid); - write_render_item(item, index, glyphid, x, y, ch_width, h); - return(ch_width); -} - inline_4tech Full_Cursor make_cursor_hint(int line_index, int *starts, float *wrap_ys, float font_height){ Full_Cursor hint; diff --git a/build_all.bat b/build_all.bat index bf8abcb0..a5873ee7 100644 --- a/build_all.bat +++ b/build_all.bat @@ -21,8 +21,8 @@ if %ERRORLEVEL% neq 0 (set FirstError=1) popd pushd ..\build -call "..\code\buildsuper.bat" ..\code\4coder_default_bindings.cpp -REM call "..\code\buildsuper.bat" ..\code\power\4coder_experiments.cpp +REM call "..\code\buildsuper.bat" ..\code\4coder_default_bindings.cpp +call "..\code\buildsuper.bat" ..\code\power\4coder_experiments.cpp REM call "..\code\buildsuper.bat" ..\code\power\4coder_casey.cpp if %ERRORLEVEL% neq 0 (set FirstError=1) diff --git a/buildsuper.bat b/buildsuper.bat index 83f0802e..105a74b3 100644 --- a/buildsuper.bat +++ b/buildsuper.bat @@ -11,7 +11,7 @@ SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd SET OPTS=%OPTS% /GR- /nologo SET DEBUG=/Zi set BUILD_DLL=/LD /link /INCREMENTAL:NO /OPT:REF -SET EXPORTS=/EXPORT:view_routine /EXPORT:get_bindings /EXPORT:get_alpha_4coder_version +SET EXPORTS=/EXPORT:get_bindings /EXPORT:get_alpha_4coder_version REM SET LINKS=user32.lib gdi32.lib SET LINKS= diff --git a/custom_api_spec.txt b/custom_api_spec.txt index 853b2bab..fd11836f 100644 --- a/custom_api_spec.txt +++ b/custom_api_spec.txt @@ -18,14 +18,12 @@ Buffer_Summary Get_Buffer_First(Application_Links *app) void Get_Buffer_Next(Application_Links *app, Buffer_Summary *buffer) Buffer_Summary Get_Buffer(Application_Links *app, int index) -Buffer_Summary Get_Active_Buffer(Application_Links *app) Buffer_Summary Get_Parameter_Buffer(Application_Links *app, int param_index) Buffer_Summary Get_Buffer_By_Name(Application_Links *app, char *filename, int len) -// TODO(allen): Need more flexible seek system somehow. Regex? Just expose the text stream to the user? -int Buffer_Seek_Delimiter(Application_Links *app, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out) -int Buffer_Seek_String(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out) -int Buffer_Seek_String_Insensitive(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out) +//int Buffer_Seek_Delimiter(Application_Links *app, Buffer_Summary *buffer, int start, char delim, int seek_forward, int *out) +//int Buffer_Seek_String(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out) +//int Buffer_Seek_String_Insensitive(Application_Links *app, Buffer_Summary *buffer, int start, char *str, int len, int seek_forward, int *out) int Refresh_Buffer(Application_Links *app, Buffer_Summary *buffer) int Buffer_Read_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out) diff --git a/linux_4ed.cpp b/linux_4ed.cpp index 1b3a5655..e45f3c2e 100644 --- a/linux_4ed.cpp +++ b/linux_4ed.cpp @@ -72,116 +72,6 @@ #include "system_shared.h" -// -// Linux structs / enums -// - -#if FRED_INTERNAL - -struct Sys_Bubble : public Bubble{ - i32 line_number; - char *file_name; -}; - -#endif - -enum { - LINUX_4ED_EVENT_X11, - LINUX_4ED_EVENT_FILE, - LINUX_4ED_EVENT_STEP, - LINUX_4ED_EVENT_STEP_TIMER, - LINUX_4ED_EVENT_CLI, -}; - -struct Linux_Coroutine { - Coroutine coroutine; - Linux_Coroutine *next; - ucontext_t ctx, yield_ctx; - stack_t stack; - b32 done; -}; - -struct Thread_Context{ - u32 job_id; - b32 running; - - Work_Queue *queue; - u32 id; - pthread_t handle; -}; - -struct Thread_Group{ - Thread_Context *threads; - i32 count; -}; - -struct Linux_Vars{ - Display *XDisplay; - Window XWindow; - Render_Target target; - - XIM input_method; - XIMStyle input_style; - XIC input_context; - - Key_Input_Data key_data; - Mouse_State mouse_data; - - String clipboard_contents; - String clipboard_outgoing; - b32 new_clipboard; - - Atom atom_CLIPBOARD; - Atom atom_UTF8_STRING; - Atom atom_NET_WM_STATE; - Atom atom_NET_WM_STATE_MAXIMIZED_HORZ; - Atom atom_NET_WM_STATE_MAXIMIZED_VERT; - Atom atom_NET_WM_PING; - Atom atom_WM_DELETE_WINDOW; - - b32 has_xfixes; - int xfixes_selection_event; - - int epoll; - - int step_timer_fd; - int step_event_fd; - int x11_fd; - int inotify_fd; - - u64 last_step; - - b32 keep_running; - - Application_Mouse_Cursor cursor; - - void *app_code; - void *custom; - - Thread_Memory *thread_memory; - Thread_Group groups[THREAD_GROUP_COUNT]; - sem_t thread_semaphores[THREAD_GROUP_COUNT]; - pthread_mutex_t locks[LOCK_COUNT]; - - Partition font_part; - - Plat_Settings settings; - System_Functions *system; - App_Functions app; - Custom_API custom_api; - b32 first; - b32 redraw; - b32 vsync; - -#if FRED_INTERNAL - Sys_Bubble internal_bubble; - pthread_mutex_t DEBUG_sysmem_lock; -#endif - - Linux_Coroutine coroutine_data[18]; - Linux_Coroutine *coroutine_free; -}; - // // Linux macros // @@ -210,13 +100,137 @@ struct Linux_Vars{ #define OLD_STAT_NANO_TIME 1 #endif +#define SUPPORT_DPI 1 + +// +// Linux structs / enums +// + +#if FRED_INTERNAL + +struct Sys_Bubble : public Bubble{ + i32 line_number; + char *file_name; +}; + +#endif + +enum { + LINUX_4ED_EVENT_X11 = (UINT64_C(1) << 32), + LINUX_4ED_EVENT_X11_INTERNAL = (UINT64_C(1) << 33), + LINUX_4ED_EVENT_FILE = (UINT64_C(1) << 34), + LINUX_4ED_EVENT_STEP = (UINT64_C(1) << 35), + LINUX_4ED_EVENT_STEP_TIMER = (UINT64_C(1) << 36), + LINUX_4ED_EVENT_CLI = (UINT64_C(1) << 37), +}; + +struct Linux_Coroutine { + Coroutine coroutine; + Linux_Coroutine *next; + ucontext_t ctx, yield_ctx; + stack_t stack; + b32 done; +}; + +struct Thread_Context{ + u32 job_id; + b32 running; + b32 cancel; + + Work_Queue *queue; + u32 id; + u32 group_id; + pthread_t handle; +}; + +struct Thread_Group{ + Thread_Context *threads; + i32 count; + + i32 cancel_lock0; + i32 cancel_cv0; +}; + +struct Linux_Vars{ + Display *XDisplay; + Window XWindow; + Render_Target target; + + XIM input_method; + XIMStyle input_style; + XIC input_context; + + Application_Step_Input input; + + String clipboard_contents; + String clipboard_outgoing; + b32 new_clipboard; + + Atom atom_TARGETS; + Atom atom_CLIPBOARD; + Atom atom_UTF8_STRING; + Atom atom__NET_WM_STATE; + Atom atom__NET_WM_STATE_MAXIMIZED_HORZ; + Atom atom__NET_WM_STATE_MAXIMIZED_VERT; + Atom atom__NET_WM_PING; + Atom atom__NET_WM_WINDOW_TYPE; + Atom atom__NET_WM_WINDOW_TYPE_NORMAL; + Atom atom__NET_WM_PID; + Atom atom_WM_DELETE_WINDOW; + + b32 has_xfixes; + int xfixes_selection_event; + + int epoll; + + int step_timer_fd; + int step_event_fd; + int x11_fd; + int inotify_fd; + + u64 last_step; + + b32 keep_running; + + Application_Mouse_Cursor cursor; + + void *app_code; + void *custom; + + Thread_Memory *thread_memory; + Thread_Group groups[THREAD_GROUP_COUNT]; + Work_Queue queues[THREAD_GROUP_COUNT]; + pthread_mutex_t locks[LOCK_COUNT]; + pthread_cond_t conds[8]; + sem_t thread_semaphore; + + Partition font_part; + +#if SUPPORT_DPI + i32 dpi_x, dpi_y; +#endif + + Plat_Settings settings; + System_Functions system; + App_Functions app; + Custom_API custom_api; + b32 vsync; + +#if FRED_INTERNAL + Sys_Bubble internal_bubble; + pthread_mutex_t DEBUG_sysmem_lock; +#endif + + Linux_Coroutine coroutine_data[18]; + Linux_Coroutine *coroutine_free; +}; + // // Linux globals // globalvar Linux_Vars linuxvars; globalvar Application_Memory memory_vars; -globalvar Exchange exchange_vars; // // Linux forward declarations @@ -278,8 +292,6 @@ LinuxGetMemory_(i32 size, i32 line_number, char *file_name){ pthread_mutex_unlock(&linuxvars.DEBUG_sysmem_lock); result = bubble + 1; - - fprintf(stderr, "new bubble: %p\n", result); #else size_t real_size = size + sizeof(size_t); result = mmap(0, real_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -299,8 +311,6 @@ internal void LinuxFreeMemory(void *block){ if (block){ #if FRED_INTERNAL - fprintf(stderr, "del bubble: %p\n", block); - Sys_Bubble *bubble = ((Sys_Bubble*)block) - 1; Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_SYS_DEBUG); @@ -385,6 +395,20 @@ Sys_File_Time_Stamp_Sig(system_file_time_stamp){ return(microsecond_timestamp); } +internal +Sys_Now_Time_Stamp_Sig(system_now_time_stamp){ + struct timespec spec; + u64 result; + + clock_gettime(CLOCK_REALTIME, &spec); + result = (spec.tv_sec * UINT64_C(1000000)) + (spec.tv_nsec / UINT64_C(1000)); + + //LINUX_FN_DEBUG("ts: %" PRIu64, result); + + return(result); +} + + internal Sys_Set_File_List_Sig(system_set_file_list){ DIR *d; @@ -556,8 +580,6 @@ Sys_File_Load_End_Sig(system_file_load_end){ char* ptr = buffer; size_t size = loading.size; - LINUX_FN_DEBUG("%d %p %zu", fd, ptr, size); - if(!loading.exists || fd == -1) return 0; do { @@ -575,6 +597,8 @@ Sys_File_Load_End_Sig(system_file_load_end){ close(fd); + LINUX_FN_DEBUG("success == %d", (size == 0)); + return (size == 0); } @@ -685,23 +709,6 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){ XSetSelectionOwner(linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, linuxvars.XWindow, CurrentTime); } -// -// Time -// - -internal -Sys_Time_Sig(system_time){ - struct timespec spec; - u64 result; - - clock_gettime(CLOCK_REALTIME, &spec); - result = (spec.tv_sec * UINT64_C(1000000)) + (spec.tv_nsec / UINT64_C(1000)); - - //LINUX_FN_DEBUG("ts: %" PRIu64, result); - - return(result); -} - // // Coroutine // @@ -912,8 +919,22 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ internal void* ThreadProc(void* arg){ Thread_Context *thread = (Thread_Context*)arg; - Work_Queue *queue = thread->queue; - + Work_Queue *queue = linuxvars.queues + thread->group_id; + Thread_Group *group = linuxvars.groups + thread->group_id; + + i32 thread_index = thread->id - 1; + + i32 cancel_lock = group->cancel_lock0 + thread_index; + i32 cancel_cv = group->cancel_cv0 + thread_index; + + Thread_Memory *thread_memory = linuxvars.thread_memory + thread_index; + + if (thread_memory->size == 0){ + i32 new_size = Kbytes(64); + thread_memory->data = LinuxGetMemory(new_size); + thread_memory->size = new_size; + } + for (;;){ u32 read_index = queue->read_position; u32 write_index = queue->write_position; @@ -937,25 +958,18 @@ ThreadProc(void* arg){ if (safe_running_thread == THREAD_NOT_ASSIGNED){ thread->job_id = full_job->id; thread->running = 1; - Thread_Memory *thread_memory = 0; - // TODO(allen): remove memory_request - if (full_job->job.memory_request != 0){ - thread_memory = linuxvars.thread_memory + thread->id - 1; - if (thread_memory->size < full_job->job.memory_request){ - if (thread_memory->data){ - LinuxFreeMemory(thread_memory->data); - } - i32 new_size = LargeRoundUp(full_job->job.memory_request, Kbytes(4)); - thread_memory->data = LinuxGetMemory(new_size); - thread_memory->size = new_size; - } - } - full_job->job.callback(linuxvars.system, thread, thread_memory, - &exchange_vars.thread, full_job->job.data); + full_job->job.callback(&linuxvars.system, thread, thread_memory, full_job->job.data); full_job->running_thread = 0; thread->running = 0; + system_acquire_lock(cancel_lock); + if(thread->cancel){ + thread->cancel = 0; + pthread_cond_signal(linuxvars.conds + cancel_cv); + } + system_release_lock(cancel_lock); + LinuxScheduleStep(); } } @@ -968,7 +982,7 @@ ThreadProc(void* arg){ internal Sys_Post_Job_Sig(system_post_job){ - Work_Queue *queue = exchange_vars.thread.queues + group_id; + Work_Queue *queue = linuxvars.queues + group_id; Assert((queue->write_position + 1) % QUEUE_WRAP != queue->read_position % QUEUE_WRAP); @@ -997,13 +1011,12 @@ Sys_Post_Job_Sig(system_post_job){ internal Sys_Cancel_Job_Sig(system_cancel_job){ - Work_Queue *queue = exchange_vars.thread.queues + group_id; + Work_Queue *queue = linuxvars.queues + group_id; Thread_Group *group = linuxvars.groups + group_id; u32 job_index; u32 thread_id; Full_Job_Data *full_job; - Thread_Context *thread; job_index = job_id % QUEUE_WRAP; full_job = queue->jobs + job_index; @@ -1013,19 +1026,46 @@ Sys_Cancel_Job_Sig(system_cancel_job){ __sync_val_compare_and_swap(&full_job->running_thread, THREAD_NOT_ASSIGNED, 0); - if (thread_id != THREAD_NOT_ASSIGNED){ - system_acquire_lock(CANCEL_LOCK0 + thread_id - 1); - thread = group->threads + thread_id - 1; - pthread_kill(thread->handle, SIGINT); //NOTE(inso) SIGKILL if you really want it to die. - pthread_create(&thread->handle, NULL, &ThreadProc, thread); - system_release_lock(CANCEL_LOCK0 + thread_id - 1); - thread->running = 0; + if (thread_id != THREAD_NOT_ASSIGNED && thread_id != 0){ + i32 thread_index = thread_id - 1; + + i32 cancel_lock = group->cancel_lock0 + thread_index; + i32 cancel_cv = group->cancel_cv0 + thread_index; + Thread_Context *thread = group->threads + thread_index; + + system_acquire_lock(cancel_lock); + thread->cancel = 1; + + system_release_lock(FRAME_LOCK); + do { + pthread_cond_wait(linuxvars.conds + cancel_cv, linuxvars.locks + cancel_lock); + } while(thread->cancel == 1); + system_acquire_lock(FRAME_LOCK); + + system_release_lock(cancel_lock); LinuxScheduleStep(); } } +internal +Sys_Check_Cancel_Sig(system_check_cancel){ + b32 result = 0; + + Thread_Group* group = linuxvars.groups + thread->group_id; + i32 thread_index = thread->id - 1; + i32 cancel_lock = group->cancel_lock0 + thread_index; + + system_acquire_lock(cancel_lock); + if (thread->cancel){ + result = 1; + } + system_release_lock(cancel_lock); + + return (result); +} + internal Sys_Grow_Thread_Memory_Sig(system_grow_thread_memory){ void *old_data; @@ -1067,7 +1107,7 @@ INTERNAL_Sys_Sentinel_Sig(internal_sentinel){ internal INTERNAL_Sys_Get_Thread_States_Sig(internal_get_thread_states){ - Work_Queue *queue = exchange_vars.thread.queues + id; + Work_Queue *queue = linuxvars.queues + id; u32 write = queue->write_position; u32 read = queue->read_position; if (write < read) write += JOB_ID_WRAP; @@ -1093,12 +1133,21 @@ INTERNAL_Sys_Debug_Message_Sig(internal_debug_message){ #include "system_shared.cpp" #include "4ed_rendering.cpp" +internal f32 +size_change(i32 dpi_x, i32 dpi_y){ + // TODO(allen): We're just hoping dpi_x == dpi_y for now I guess. + f32 size_x = linuxvars.dpi_x / 96.f; + f32 size_y = linuxvars.dpi_y / 96.f; + f32 size_max = Max(size_x, size_y); + return(size_max); +} + internal Font_Load_Sig(system_draw_font_load){ b32 success = 0; i32 attempts = 0; - LINUX_FN_DEBUG("%p %s %d %d", font_out, filename, pt_size, tab_width); + 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)); @@ -1106,6 +1155,10 @@ Font_Load_Sig(system_draw_font_load){ i32 oversample = 2; +#if SUPPORT_DPI + pt_size = ROUND32(pt_size * size_change(linuxvars.dpi_x, linuxvars.dpi_y)); +#endif + for(; attempts < 3; ++attempts){ success = draw_font_load( &linuxvars.font_part, @@ -1163,45 +1216,46 @@ LinuxLoadAppCode(String* base_dir){ internal void LinuxLoadSystemCode(){ - linuxvars.system->file_time_stamp = system_file_time_stamp; - linuxvars.system->file_unique_hash = system_file_unique_hash; - linuxvars.system->set_file_list = system_set_file_list; - linuxvars.system->file_track = system_file_track; - linuxvars.system->file_untrack = system_file_untrack; - linuxvars.system->file_load_begin = system_file_load_begin; - linuxvars.system->file_load_end = system_file_load_end; - linuxvars.system->file_save = system_file_save; + linuxvars.system.file_time_stamp = system_file_time_stamp; + linuxvars.system.file_unique_hash = system_file_unique_hash; + linuxvars.system.set_file_list = system_set_file_list; + linuxvars.system.file_track = system_file_track; + linuxvars.system.file_untrack = system_file_untrack; + linuxvars.system.file_load_begin = system_file_load_begin; + linuxvars.system.file_load_end = system_file_load_end; + linuxvars.system.file_save = system_file_save; - linuxvars.system->file_exists = system_file_exists; - linuxvars.system->directory_cd = system_directory_cd; - linuxvars.system->get_4ed_path = system_get_4ed_path; + linuxvars.system.file_exists = system_file_exists; + linuxvars.system.directory_cd = system_directory_cd; + linuxvars.system.get_4ed_path = system_get_4ed_path; - linuxvars.system->post_clipboard = system_post_clipboard; - linuxvars.system->time = system_time; + linuxvars.system.post_clipboard = system_post_clipboard; + linuxvars.system.now_time_stamp = system_now_time_stamp; - linuxvars.system->create_coroutine = system_create_coroutine; - linuxvars.system->launch_coroutine = system_launch_coroutine; - linuxvars.system->resume_coroutine = system_resume_coroutine; - linuxvars.system->yield_coroutine = system_yield_coroutine; + linuxvars.system.create_coroutine = system_create_coroutine; + linuxvars.system.launch_coroutine = system_launch_coroutine; + linuxvars.system.resume_coroutine = system_resume_coroutine; + linuxvars.system.yield_coroutine = system_yield_coroutine; - linuxvars.system->cli_call = system_cli_call; - linuxvars.system->cli_begin_update = system_cli_begin_update; - linuxvars.system->cli_update_step = system_cli_update_step; - linuxvars.system->cli_end_update = system_cli_end_update; + linuxvars.system.cli_call = system_cli_call; + linuxvars.system.cli_begin_update = system_cli_begin_update; + linuxvars.system.cli_update_step = system_cli_update_step; + linuxvars.system.cli_end_update = system_cli_end_update; - linuxvars.system->post_job = system_post_job; - linuxvars.system->cancel_job = system_cancel_job; - linuxvars.system->grow_thread_memory = system_grow_thread_memory; - linuxvars.system->acquire_lock = system_acquire_lock; - linuxvars.system->release_lock = system_release_lock; + linuxvars.system.post_job = system_post_job; + linuxvars.system.cancel_job = system_cancel_job; + linuxvars.system.check_cancel = system_check_cancel; + linuxvars.system.grow_thread_memory = system_grow_thread_memory; + linuxvars.system.acquire_lock = system_acquire_lock; + linuxvars.system.release_lock = system_release_lock; #if FRED_INTERNAL - linuxvars.system->internal_sentinel = internal_sentinel; - linuxvars.system->internal_get_thread_states = internal_get_thread_states; - linuxvars.system->internal_debug_message = internal_debug_message; + linuxvars.system.internal_sentinel = internal_sentinel; + linuxvars.system.internal_get_thread_states = internal_get_thread_states; + linuxvars.system.internal_debug_message = internal_debug_message; #endif - linuxvars.system->slash = '/'; + linuxvars.system.slash = '/'; } internal void @@ -1236,7 +1290,6 @@ LinuxResizeTarget(i32 width, i32 height){ linuxvars.target.width = width; linuxvars.target.height = height; - linuxvars.redraw = 1; } } @@ -1546,9 +1599,8 @@ init_input_result_zero(){ return(result); } -// NOTE(inso): doesn't actually use XInput anymore, i should change the name... internal Init_Input_Result -InitializeXInput(Display *dpy, Window XWindow) +LinuxInputInit(Display *dpy, Window XWindow) { Init_Input_Result result = {}; XIMStyles *styles = 0; @@ -1715,11 +1767,11 @@ LinuxPushKey(u8 code, u8 chr, u8 chr_nocaps, b8 (*mods)[MDFR_INDEX_COUNT], b32 i Key_Event_Data *data; if(is_hold){ - count = &linuxvars.key_data.hold_count; - data = linuxvars.key_data.hold; + count = &linuxvars.input.keys.hold_count; + data = linuxvars.input.keys.hold; } else { - count = &linuxvars.key_data.press_count; - data = linuxvars.key_data.press; + count = &linuxvars.input.keys.press_count; + data = linuxvars.input.keys.press; } if(*count < KEY_INPUT_BUFFER_SIZE){ @@ -1775,7 +1827,7 @@ LinuxStringDup(String* str, void* data, size_t size){ internal void LinuxScheduleStep(void) { - u64 now = system_time(); + u64 now = system_now_time_stamp(); u64 diff = (now - linuxvars.last_step); if(diff > (u64)frame_useconds){ @@ -1806,12 +1858,12 @@ LinuxMaximizeWindow(Display* d, Window w, b32 maximize) XEvent e = {}; e.xany.type = ClientMessage; - e.xclient.message_type = linuxvars.atom_NET_WM_STATE; + e.xclient.message_type = linuxvars.atom__NET_WM_STATE; e.xclient.format = 32; e.xclient.window = w; e.xclient.data.l[0] = maximize ? STATE_ADD : STATE_REMOVE; - e.xclient.data.l[1] = linuxvars.atom_NET_WM_STATE_MAXIMIZED_VERT; - e.xclient.data.l[2] = linuxvars.atom_NET_WM_STATE_MAXIMIZED_HORZ; + e.xclient.data.l[1] = linuxvars.atom__NET_WM_STATE_MAXIMIZED_VERT; + e.xclient.data.l[2] = linuxvars.atom__NET_WM_STATE_MAXIMIZED_HORZ; e.xclient.data.l[3] = 0L; XSendEvent( @@ -1841,11 +1893,191 @@ LinuxSetIcon(Display* d, Window w) ); } +internal void +LinuxX11ConnectionWatch(Display* dpy, XPointer cdata, int fd, Bool opening, XPointer* wdata){ + struct epoll_event e = {}; + e.events = EPOLLIN | EPOLLET; + e.data.u64 = LINUX_4ED_EVENT_X11_INTERNAL | fd; + + int op = opening ? EPOLL_CTL_ADD : EPOLL_CTL_DEL; + epoll_ctl(linuxvars.epoll, op, fd, &e); +} + +// +// X11 window init +// + +internal b32 +LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight) +{ + // NOTE(allen): Here begins the linux screen setup stuff. + // Behold the true nature of this wonderful OS: + // (thanks again to Casey for providing this stuff) + +#define BASE_W 800 +#define BASE_H 600 + + if (linuxvars.settings.set_window_size){ + *WinWidth = linuxvars.settings.window_w; + *WinHeight = linuxvars.settings.window_h; + } else { + *WinWidth = BASE_W; + *WinHeight = BASE_H; + } + + if (!GLXCanUseFBConfig(linuxvars.XDisplay)){ + fprintf(stderr, "Your GLX version is too old.\n"); + return false; + } + + glx_config_result Config = ChooseGLXConfig(linuxvars.XDisplay, DefaultScreen(linuxvars.XDisplay)); + if (!Config.Found){ + fprintf(stderr, "Could not create GLX FBConfig.\n"); + } + + XSetWindowAttributes swa = {}; + swa.backing_store = WhenMapped; + swa.event_mask = StructureNotifyMask; + swa.bit_gravity = NorthWestGravity; + swa.colormap = XCreateColormap(linuxvars.XDisplay, + RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), + Config.BestInfo.visual, AllocNone); + + linuxvars.XWindow = + XCreateWindow(linuxvars.XDisplay, + RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), + 0, 0, *WinWidth, *WinHeight, + 0, Config.BestInfo.depth, InputOutput, + Config.BestInfo.visual, + CWBackingStore|CWBitGravity|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &swa); + + if (!linuxvars.XWindow){ + fprintf(stderr, "Error creating window.\n"); + return false; + } + + //NOTE(inso): Set the window's type to normal + XChangeProperty( + linuxvars.XDisplay, + linuxvars.XWindow, + linuxvars.atom__NET_WM_WINDOW_TYPE, + XA_ATOM, + 32, + PropModeReplace, + (unsigned char*)&linuxvars.atom__NET_WM_WINDOW_TYPE_NORMAL, + 1 + ); + + //NOTE(inso): window managers want the PID as a window property for some reason. + pid_t pid = getpid(); + XChangeProperty( + linuxvars.XDisplay, + linuxvars.XWindow, + linuxvars.atom__NET_WM_PID, + XA_CARDINAL, + 32, + PropModeReplace, + (unsigned char*)&pid, + 1 + ); + +#define WINDOW_NAME "4coder 4linux: " VERSION + + //NOTE(inso): set wm properties + XStoreName(linuxvars.XDisplay, linuxvars.XWindow, WINDOW_NAME); + + XSizeHints *sz_hints = XAllocSizeHints(); + XWMHints *wm_hints = XAllocWMHints(); + XClassHint *cl_hints = XAllocClassHint(); + + sz_hints->flags = PMinSize | PMaxSize | PWinGravity; + + sz_hints->min_width = 50; + sz_hints->min_height = 50; + + sz_hints->max_width = sz_hints->max_height = (1UL << 16UL); + +/* NOTE(inso): fluxbox thinks this is minimum, so don't set it + sz_hints->base_width = BASE_W; + sz_hints->base_height = BASE_H; +*/ + sz_hints->win_gravity = NorthWestGravity; + + if (linuxvars.settings.set_window_pos){ + sz_hints->flags |= USPosition; + sz_hints->x = linuxvars.settings.window_x; + sz_hints->y = linuxvars.settings.window_y; + } + + wm_hints->flags |= InputHint | StateHint; + wm_hints->input = True; + wm_hints->initial_state = NormalState; + + cl_hints->res_name = "4coder"; + cl_hints->res_class = "4coder"; + + char* win_name_list[] = { WINDOW_NAME }; + XTextProperty win_name; + XStringListToTextProperty(win_name_list, 1, &win_name); + + XSetWMProperties( + linuxvars.XDisplay, + linuxvars.XWindow, + &win_name, NULL, + argv, argc, + sz_hints, wm_hints, cl_hints + ); + + XFree(win_name.value); + + XFree(sz_hints); + XFree(wm_hints); + XFree(cl_hints); + + LinuxSetIcon(linuxvars.XDisplay, linuxvars.XWindow); + + //NOTE(inso): make the window visible + XMapWindow(linuxvars.XDisplay, linuxvars.XWindow); + + b32 IsLegacy = false; + GLXContext GLContext = + InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy); + + XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow); + + if (linuxvars.settings.set_window_pos){ + XMoveWindow( + linuxvars.XDisplay, + linuxvars.XWindow, + linuxvars.settings.window_x, + linuxvars.settings.window_y + ); + } + + if (linuxvars.settings.maximize_window){ + LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1); + } + XSync(linuxvars.XDisplay, False); + + XWindowAttributes WinAttribs; + if (XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs)) + { + *WinWidth = WinAttribs.width; + *WinHeight = WinAttribs.height; + } + + Atom wm_protos[] = { + linuxvars.atom_WM_DELETE_WINDOW, + linuxvars.atom__NET_WM_PING + }; + + XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, wm_protos, 2); +} internal void LinuxHandleX11Events(void) { - XEvent PrevEvent = {}; + static XEvent PrevEvent = {}; b32 should_step = 0; while(XPending(linuxvars.XDisplay)) @@ -1937,30 +2169,30 @@ LinuxHandleX11Events(void) case MotionNotify: { should_step = 1; - linuxvars.mouse_data.x = Event.xmotion.x; - linuxvars.mouse_data.y = Event.xmotion.y; + linuxvars.input.mouse.x = Event.xmotion.x; + linuxvars.input.mouse.y = Event.xmotion.y; }break; case ButtonPress: { should_step = 1; switch(Event.xbutton.button){ case Button1: { - linuxvars.mouse_data.press_l = 1; - linuxvars.mouse_data.l = 1; + linuxvars.input.mouse.press_l = 1; + linuxvars.input.mouse.l = 1; } break; case Button3: { - linuxvars.mouse_data.press_r = 1; - linuxvars.mouse_data.r = 1; + linuxvars.input.mouse.press_r = 1; + linuxvars.input.mouse.r = 1; } break; //NOTE(inso): scroll up case Button4: { - linuxvars.mouse_data.wheel = 1; + linuxvars.input.mouse.wheel = 1; }break; //NOTE(inso): scroll down case Button5: { - linuxvars.mouse_data.wheel = -1; + linuxvars.input.mouse.wheel = -1; }break; } }break; @@ -1969,31 +2201,31 @@ LinuxHandleX11Events(void) should_step = 1; switch(Event.xbutton.button){ case Button1: { - linuxvars.mouse_data.release_l = 1; - linuxvars.mouse_data.l = 0; + linuxvars.input.mouse.release_l = 1; + linuxvars.input.mouse.l = 0; } break; case Button3: { - linuxvars.mouse_data.release_r = 1; - linuxvars.mouse_data.r = 0; + linuxvars.input.mouse.release_r = 1; + linuxvars.input.mouse.r = 0; } break; } }break; case EnterNotify: { should_step = 1; - linuxvars.mouse_data.out_of_window = 0; + linuxvars.input.mouse.out_of_window = 0; }break; case LeaveNotify: { should_step = 1; - linuxvars.mouse_data.out_of_window = 1; + linuxvars.input.mouse.out_of_window = 1; }break; case FocusIn: case FocusOut: { should_step = 1; - linuxvars.mouse_data.l = 0; - linuxvars.mouse_data.r = 0; + linuxvars.input.mouse.l = 0; + linuxvars.input.mouse.r = 0; }break; case ConfigureNotify: { @@ -2017,7 +2249,7 @@ LinuxHandleX11Events(void) should_step = 1; linuxvars.keep_running = 0; } - else if ((Atom)Event.xclient.data.l[0] == linuxvars.atom_NET_WM_PING) { + else if ((Atom)Event.xclient.data.l[0] == linuxvars.atom__NET_WM_PING) { Event.xclient.window = DefaultRootWindow(linuxvars.XDisplay); XSendEvent( linuxvars.XDisplay, @@ -2041,27 +2273,57 @@ LinuxHandleX11Events(void) response.time = request.time; response.property = None; - //TODO(inso): handle TARGETS negotiation instead of requiring UTF8_STRING if ( linuxvars.clipboard_outgoing.size && - request.target == linuxvars.atom_UTF8_STRING && request.selection == linuxvars.atom_CLIPBOARD && request.property != None && request.display && request.requestor ){ - XChangeProperty( - request.display, - request.requestor, - request.property, - request.target, - 8, - PropModeReplace, - (unsigned char*)linuxvars.clipboard_outgoing.str, - linuxvars.clipboard_outgoing.size - ); + Atom atoms[] = { + XA_STRING, + linuxvars.atom_UTF8_STRING + }; - response.property = request.property; + if(request.target == linuxvars.atom_TARGETS){ + + XChangeProperty( + request.display, + request.requestor, + request.property, + XA_ATOM, + 32, + PropModeReplace, + (u8*)atoms, + ArrayCount(atoms) + ); + + response.property = request.property; + + } else { + b32 found = false; + for(int i = 0; i < ArrayCount(atoms); ++i){ + if(request.target == atoms[i]){ + found = true; + break; + } + } + + if(found){ + XChangeProperty( + request.display, + request.requestor, + request.property, + request.target, + 8, + PropModeReplace, + (u8*)linuxvars.clipboard_outgoing.str, + linuxvars.clipboard_outgoing.size + ); + + response.property = request.property; + } + } } XSendEvent(request.display, request.requestor, True, 0, (XEvent*)&response); @@ -2108,6 +2370,7 @@ LinuxHandleX11Events(void) should_step = 1; linuxvars.new_clipboard = 1; XFree(data); + XDeleteProperty(linuxvars.XDisplay, linuxvars.XWindow, linuxvars.atom_CLIPBOARD); } } }break; @@ -2115,7 +2378,6 @@ LinuxHandleX11Events(void) case Expose: case VisibilityNotify: { should_step = 1; - linuxvars.redraw = 1; }break; default: { @@ -2164,6 +2426,9 @@ LinuxHandleFileEvents() int main(int argc, char **argv) { + // + // System & Memory init + // #if FRED_INTERNAL linuxvars.internal_bubble.next = &linuxvars.internal_bubble; @@ -2173,68 +2438,38 @@ main(int argc, char **argv) pthread_mutex_init(&linuxvars.DEBUG_sysmem_lock, 0); #endif - linuxvars.first = 1; - char base_dir_mem[PATH_MAX]; String base_dir = make_fixed_width_string(base_dir_mem); if (!LinuxLoadAppCode(&base_dir)){ - // TODO(allen): Failed to load app code, serious problem. + fprintf(stderr, "Could not load 4ed_app.so! It should be in the same dir as 4ed.\n"); return 99; } - System_Functions system_; - System_Functions *system = &system_; - linuxvars.system = system; LinuxLoadSystemCode(); + LinuxLoadRenderCode(); - linuxvars.coroutine_free = linuxvars.coroutine_data; - for (i32 i = 0; i+1 < ArrayCount(linuxvars.coroutine_data); ++i){ - linuxvars.coroutine_data[i].next = linuxvars.coroutine_data + i + 1; - } - - const size_t stack_size = Mbytes(16); - 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); - } - - memory_vars.vars_memory_size = Mbytes(2); - memory_vars.vars_memory = system_get_memory(memory_vars.vars_memory_size); + memory_vars.vars_memory_size = Mbytes(2); + memory_vars.vars_memory = system_get_memory(memory_vars.vars_memory_size); memory_vars.target_memory_size = Mbytes(512); - memory_vars.target_memory = system_get_memory(memory_vars.target_memory_size); - memory_vars.user_memory_size = Mbytes(2); - memory_vars.user_memory = system_get_memory(memory_vars.user_memory_size); + memory_vars.target_memory = system_get_memory(memory_vars.target_memory_size); + memory_vars.user_memory_size = Mbytes(2); + memory_vars.user_memory = system_get_memory(memory_vars.user_memory_size); -#if 0 - memory_vars.vars_memory_size = Mbytes(2); - memory_vars.vars_memory = mmap(0, memory_vars.vars_memory_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - memory_vars.target_memory_size = Mbytes(512); - memory_vars.target_memory = mmap(0, memory_vars.target_memory_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - memory_vars.user_memory_size = Mbytes(2); - memory_vars.user_memory = mmap(0, memory_vars.user_memory_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -#endif - - String current_directory; - i32 curdir_req, curdir_size; - char *curdir_mem; + linuxvars.target.max = Mbytes(1); + linuxvars.target.push_buffer = (byte*)system_get_memory(linuxvars.target.max); - curdir_req = (1 << 9); - curdir_mem = (char*)system_get_memory(curdir_req); - for (; getcwd(curdir_mem, curdir_req) == 0 && curdir_req < (1 << 13);){ - system_free_memory(curdir_mem); - curdir_req *= 4; - curdir_mem = (char*)system_get_memory(curdir_req); + // + // Read command line + // + + char* cwd = get_current_dir_name(); + if(!cwd){ + perror("get_current_dir_name"); + return 1; } - if (curdir_req >= (1 << 13)){ - // TODO(allen): bullshit string APIs makin' me pissed - return 57; - } - - for (curdir_size = 0; curdir_mem[curdir_size]; ++curdir_size); - - current_directory = make_string(curdir_mem, curdir_size, curdir_req); + String current_directory = make_string_slowly(cwd); Command_Line_Parameters clparams; clparams.argv = argv; @@ -2245,12 +2480,12 @@ main(int argc, char **argv) i32 output_size; output_size = - linuxvars.app.read_command_line(system, - &memory_vars, - current_directory, - &linuxvars.settings, - &files, &file_count, - clparams); + linuxvars.app.read_command_line(&linuxvars.system, + &memory_vars, + current_directory, + &linuxvars.settings, + &files, &file_count, + clparams); if (output_size > 0){ // TODO(allen): crt free version @@ -2260,16 +2495,12 @@ main(int argc, char **argv) sysshared_filter_real_files(files, file_count); - linuxvars.XDisplay = XOpenDisplay(0); - - if(!linuxvars.XDisplay){ - fprintf(stderr, "Can't open display!\n"); - return 1; - } - - LinuxKeycodeInit(linuxvars.XDisplay); + // + // Custom layer linkage + // #ifdef FRED_SUPER + char *custom_file_default = "4coder_custom.so"; sysshared_to_binary_path(&base_dir, custom_file_default); custom_file_default = base_dir.str; @@ -2309,34 +2540,60 @@ main(int argc, char **argv) fprintf(stderr, "Successfully loaded 4coder_custom.so\n"); } } + } else { + const char* error = dlerror(); + fprintf(stderr, "*** Failed to load 4coder_custom.so: %s\n", error ? error : "dlopen failed."); } + #endif if (linuxvars.custom_api.get_bindings == 0){ linuxvars.custom_api.get_bindings = get_bindings; } +#if 0 + if (linuxvars.custom_api.view_routine == 0){ + linuxvars.custom_api.view_routine = view_routine; + } +#endif + + // + // Coroutine / Thread / Semaphore / Mutex init + // + + linuxvars.coroutine_free = linuxvars.coroutine_data; + for (i32 i = 0; i+1 < ArrayCount(linuxvars.coroutine_data); ++i){ + linuxvars.coroutine_data[i].next = linuxvars.coroutine_data + i + 1; + } + + const size_t stack_size = Mbytes(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); + } + Thread_Context background[4] = {}; linuxvars.groups[BACKGROUND_THREADS].threads = background; linuxvars.groups[BACKGROUND_THREADS].count = ArrayCount(background); + linuxvars.groups[BACKGROUND_THREADS].cancel_lock0 = CANCEL_LOCK0; + linuxvars.groups[BACKGROUND_THREADS].cancel_cv0 = 0; Thread_Memory thread_memory[ArrayCount(background)]; linuxvars.thread_memory = thread_memory; - sem_init(&linuxvars.thread_semaphores[BACKGROUND_THREADS], 0, 0); - - exchange_vars.thread.queues[BACKGROUND_THREADS].semaphore = - LinuxSemToHandle(&linuxvars.thread_semaphores[BACKGROUND_THREADS]); + sem_init(&linuxvars.thread_semaphore, 0, 0); + linuxvars.queues[BACKGROUND_THREADS].semaphore = LinuxSemToHandle(&linuxvars.thread_semaphore); for(i32 i = 0; i < linuxvars.groups[BACKGROUND_THREADS].count; ++i){ Thread_Context *thread = linuxvars.groups[BACKGROUND_THREADS].threads + i; thread->id = i + 1; + thread->group_id = BACKGROUND_THREADS; Thread_Memory *memory = linuxvars.thread_memory + i; *memory = thread_memory_zero(); memory->id = thread->id; - thread->queue = &exchange_vars.thread.queues[BACKGROUND_THREADS]; + thread->queue = &linuxvars.queues[BACKGROUND_THREADS]; pthread_create(&thread->handle, NULL, &ThreadProc, thread); } @@ -2344,210 +2601,42 @@ main(int argc, char **argv) pthread_mutex_init(linuxvars.locks + i, NULL); } - LinuxLoadRenderCode(); - linuxvars.target.max = Mbytes(1); - linuxvars.target.push_buffer = (byte*)system_get_memory(linuxvars.target.max); + for(i32 i = 0; i < ArrayCount(linuxvars.conds); ++i){ + pthread_cond_init(linuxvars.conds + i, NULL); + } - // NOTE(allen): Here begins the linux screen setup stuff. - // Behold the true nature of this wonderful OS: - // (thanks again to Casey for providing this stuff) + // + // X11 init + // + + linuxvars.XDisplay = XOpenDisplay(0); + if(!linuxvars.XDisplay){ + fprintf(stderr, "Can't open display!\n"); + return 1; + } + +#define LOAD_ATOM(x) linuxvars.atom_##x = XInternAtom(linuxvars.XDisplay, #x, False); + + LOAD_ATOM(TARGETS); + LOAD_ATOM(CLIPBOARD); + LOAD_ATOM(UTF8_STRING); + LOAD_ATOM(_NET_WM_STATE); + LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ); + LOAD_ATOM(_NET_WM_STATE_MAXIMIZED_VERT); + LOAD_ATOM(_NET_WM_PING); + LOAD_ATOM(_NET_WM_WINDOW_TYPE); + LOAD_ATOM(_NET_WM_WINDOW_TYPE_NORMAL); + LOAD_ATOM(_NET_WM_PID); + LOAD_ATOM(WM_DELETE_WINDOW); + +#undef LOAD_ATOM - Colormap cmap; - XSetWindowAttributes swa; int WinWidth, WinHeight; - b32 window_setup_success = 0; - - if (linuxvars.settings.set_window_size){ - WinWidth = linuxvars.settings.window_w; - WinHeight = linuxvars.settings.window_h; - } else { - WinWidth = 800; - WinHeight = 600; - } - - int XScreenCount = ScreenCount(linuxvars.XDisplay); - glx_config_result Config = {}; - - if(!GLXCanUseFBConfig(linuxvars.XDisplay)){ - fprintf(stderr, "Your GLX version is too old.\n"); - exit(1); - } - - // TODO(inso): maybe should try the default screen first? or only the default without iterating. - - for(int XScreenIndex = 0; - XScreenIndex < XScreenCount; - ++XScreenIndex) - { - Screen *XScreen = ScreenOfDisplay(linuxvars.XDisplay, XScreenIndex); - - i32 ScrnWidth, ScrnHeight; - ScrnWidth = WidthOfScreen(XScreen); - ScrnHeight = HeightOfScreen(XScreen); - - if (ScrnWidth + 50 < WinWidth) WinWidth = ScrnWidth + 50; - if (ScrnHeight + 50 < WinHeight) WinHeight = ScrnHeight + 50; - - Config = ChooseGLXConfig(linuxvars.XDisplay, XScreenIndex); - if(Config.Found) - { - swa.colormap = cmap = XCreateColormap(linuxvars.XDisplay, - RootWindow(linuxvars.XDisplay, Config.BestInfo.screen ), - Config.BestInfo.visual, AllocNone); - swa.background_pixmap = None; - swa.border_pixel = 0; - swa.event_mask = StructureNotifyMask; - - linuxvars.XWindow = - XCreateWindow(linuxvars.XDisplay, - RootWindow(linuxvars.XDisplay, Config.BestInfo.screen), - 0, 0, WinWidth, WinHeight, - 0, Config.BestInfo.depth, InputOutput, - Config.BestInfo.visual, - CWBorderPixel|CWColormap|CWEventMask, &swa); - - if(linuxvars.XWindow) - { - window_setup_success = 1; - break; - } - } - } - - if (!window_setup_success){ - fprintf(stderr, "Error creating window.\n"); - exit(1); - } - - //NOTE(inso): Set the window's type to normal - Atom _NET_WM_WINDOW_TYPE = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE", False); - Atom _NET_WIN_TYPE_NORMAL = XInternAtom(linuxvars.XDisplay, "_NET_WM_WINDOW_TYPE_NORMAL", False); - XChangeProperty( - linuxvars.XDisplay, - linuxvars.XWindow, - _NET_WM_WINDOW_TYPE, - XA_ATOM, - 32, - PropModeReplace, - (unsigned char*)&_NET_WIN_TYPE_NORMAL, - 1 - ); - - //NOTE(inso): window managers want the PID as a window property for some reason. - Atom _NET_WM_PID = XInternAtom(linuxvars.XDisplay, "_NET_WM_PID", False); - pid_t pid = getpid(); - XChangeProperty( - linuxvars.XDisplay, - linuxvars.XWindow, - _NET_WM_PID, - XA_CARDINAL, - 32, - PropModeReplace, - (unsigned char*)&pid, - 1 - ); - -#define WINDOW_NAME "4coder 4linux: " VERSION - - //NOTE(inso): set wm properties - XStoreName(linuxvars.XDisplay, linuxvars.XWindow, WINDOW_NAME); - - char* win_name_list[] = { WINDOW_NAME }; - XTextProperty win_name; - - XStringListToTextProperty(win_name_list, 1, &win_name); - - XSizeHints *sz_hints = XAllocSizeHints(); - XWMHints *wm_hints = XAllocWMHints(); - XClassHint *cl_hints = XAllocClassHint(); - - if(linuxvars.settings.set_window_pos){ - sz_hints->flags |= USPosition; - sz_hints->x = linuxvars.settings.window_x; - sz_hints->y = linuxvars.settings.window_y; - } - - wm_hints->flags |= InputHint; - wm_hints->input = True; - - cl_hints->res_name = "4coder"; - cl_hints->res_class = "4coder"; - - XSetWMProperties( - linuxvars.XDisplay, - linuxvars.XWindow, - &win_name, - NULL, - argv, - argc, - sz_hints, - wm_hints, - cl_hints - ); - - XFree(sz_hints); - XFree(wm_hints); - XFree(cl_hints); - - XFree(win_name.value); - - LinuxSetIcon(linuxvars.XDisplay, linuxvars.XWindow); - - //NOTE(inso): make the window visible - XMapWindow(linuxvars.XDisplay, linuxvars.XWindow); - - Init_Input_Result input_result = - InitializeXInput(linuxvars.XDisplay, linuxvars.XWindow); - - linuxvars.input_method = input_result.input_method; - linuxvars.input_style = input_result.best_style; - linuxvars.input_context = input_result.xic; - - b32 IsLegacy = false; - GLXContext GLContext = - InitializeOpenGLContext(linuxvars.XDisplay, linuxvars.XWindow, Config.BestConfig, IsLegacy); - - XWindowAttributes WinAttribs; - if(XGetWindowAttributes(linuxvars.XDisplay, linuxvars.XWindow, &WinAttribs)) - { - WinWidth = WinAttribs.width; - WinHeight = WinAttribs.height; - } - - XRaiseWindow(linuxvars.XDisplay, linuxvars.XWindow); - XSync(linuxvars.XDisplay, False); - - if (linuxvars.settings.set_window_pos){ - XMoveWindow( - linuxvars.XDisplay, - linuxvars.XWindow, - linuxvars.settings.window_x, - linuxvars.settings.window_y - ); - } - - Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = { - None, - XCreateFontCursor(linuxvars.XDisplay, XC_arrow), - XCreateFontCursor(linuxvars.XDisplay, XC_xterm), - XCreateFontCursor(linuxvars.XDisplay, XC_sb_h_double_arrow), - XCreateFontCursor(linuxvars.XDisplay, XC_sb_v_double_arrow) - }; - - XSetICFocus(linuxvars.input_context); - - linuxvars.atom_CLIPBOARD = XInternAtom(linuxvars.XDisplay, "CLIPBOARD", False); - linuxvars.atom_UTF8_STRING = XInternAtom(linuxvars.XDisplay, "UTF8_STRING", False); - linuxvars.atom_NET_WM_STATE = XInternAtom(linuxvars.XDisplay, "_NET_WM_STATE", False); - linuxvars.atom_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(linuxvars.XDisplay, "_NET_WM_STATE_MAXIMIZED_HORZ", False); - linuxvars.atom_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(linuxvars.XDisplay, "_NET_WM_STATE_MAXIMIZED_VERT", False); - - if (linuxvars.settings.maximize_window){ - LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1); + if(!LinuxX11WindowInit(argc, argv, &WinWidth, &WinHeight)){ + return 1; } int xfixes_version_unused, xfixes_err_unused; - linuxvars.has_xfixes = XQueryExtension( linuxvars.XDisplay, "XFIXES", @@ -2563,22 +2652,51 @@ main(int argc, char **argv) linuxvars.atom_CLIPBOARD, XFixesSetSelectionOwnerNotifyMask ); + } else { + fputs("Your X server doesn't support XFIXES, mention this fact if you report any clipboard-related issues.\n", stderr); } - linuxvars.atom_WM_DELETE_WINDOW = XInternAtom(linuxvars.XDisplay, "WM_DELETE_WINDOW", False); - linuxvars.atom_NET_WM_PING = XInternAtom(linuxvars.XDisplay, "_NET_WM_PING", False); + Init_Input_Result input_result = + LinuxInputInit(linuxvars.XDisplay, linuxvars.XWindow); - Atom wm_protos[] = { - linuxvars.atom_WM_DELETE_WINDOW, - linuxvars.atom_NET_WM_PING + linuxvars.input_method = input_result.input_method; + linuxvars.input_style = input_result.best_style; + linuxvars.input_context = input_result.xic; + + LinuxKeycodeInit(linuxvars.XDisplay); + + Cursor xcursors[APP_MOUSE_CURSOR_COUNT] = { + None, + XCreateFontCursor(linuxvars.XDisplay, XC_arrow), + XCreateFontCursor(linuxvars.XDisplay, XC_xterm), + XCreateFontCursor(linuxvars.XDisplay, XC_sb_h_double_arrow), + XCreateFontCursor(linuxvars.XDisplay, XC_sb_v_double_arrow) }; - XSetWMProtocols(linuxvars.XDisplay, linuxvars.XWindow, wm_protos, 2); - linuxvars.app.init(linuxvars.system, &linuxvars.target, &memory_vars, &exchange_vars, - linuxvars.clipboard_contents, current_directory, - linuxvars.custom_api); + // + // DPI + // - LinuxResizeTarget(WinWidth, WinHeight); +#if SUPPORT_DPI + { + int scr = DefaultScreen(linuxvars.XDisplay); + + int dw = DisplayWidth(linuxvars.XDisplay, scr); + int dh = DisplayHeight(linuxvars.XDisplay, scr); + + int dw_mm = DisplayWidthMM(linuxvars.XDisplay, scr); + int dh_mm = DisplayHeightMM(linuxvars.XDisplay, scr); + + linuxvars.dpi_x = dw_mm ? dw / (dw_mm / 25.4) : 96; + linuxvars.dpi_y = dh_mm ? dh / (dh_mm / 25.4) : 96; + + fprintf(stderr, "%dx%d - %dmmx%dmm DPI: %dx%d\n", dw, dh, dw_mm, dh_mm, linuxvars.dpi_x, linuxvars.dpi_y); + } +#endif + + // + // Epoll init + // linuxvars.x11_fd = ConnectionNumber(linuxvars.XDisplay); linuxvars.inotify_fd = inotify_init1(IN_NONBLOCK); @@ -2604,14 +2722,46 @@ main(int argc, char **argv) epoll_ctl(linuxvars.epoll, EPOLL_CTL_ADD, linuxvars.step_timer_fd, &e); } + // + // App init + // + + XAddConnectionWatch(linuxvars.XDisplay, &LinuxX11ConnectionWatch, NULL); + + linuxvars.app.init(&linuxvars.system, + &linuxvars.target, + &memory_vars, + linuxvars.clipboard_contents, + current_directory, + linuxvars.custom_api); + + LinuxResizeTarget(WinWidth, WinHeight); + + // + // Main loop + // + + system_acquire_lock(FRAME_LOCK); + LinuxScheduleStep(); + linuxvars.keep_running = 1; + linuxvars.input.first_step = 1; + linuxvars.input.dt = (frame_useconds / 1000000.f); while(1){ + if(XEventsQueued(linuxvars.XDisplay, QueuedAlready)){ + LinuxHandleX11Events(); + } + + system_release_lock(FRAME_LOCK); + struct epoll_event events[16]; int num_events = epoll_wait(linuxvars.epoll, events, ArrayCount(events), -1); + system_acquire_lock(FRAME_LOCK); + if(num_events == -1){ if(errno != EINTR){ perror("epoll_wait"); @@ -2619,16 +2769,22 @@ main(int argc, char **argv) continue; } - system_acquire_lock(FRAME_LOCK); - b32 do_step = 0; for(int i = 0; i < num_events; ++i){ - switch(events[i].data.u64){ + + int fd = events[i].data.u64 & UINT32_MAX; + u64 type = events[i].data.u64 & ~fd; + + switch(type){ case LINUX_4ED_EVENT_X11: { LinuxHandleX11Events(); } break; + case LINUX_4ED_EVENT_X11_INTERNAL: { + XProcessInternalConnection(linuxvars.XDisplay, fd); + } break; + case LINUX_4ED_EVENT_FILE: { LinuxHandleFileEvents(); } break; @@ -2662,12 +2818,9 @@ main(int argc, char **argv) } if(do_step){ - linuxvars.last_step = system_time(); + linuxvars.last_step = system_now_time_stamp(); - // TODO(inso): not all events should require a redraw? - linuxvars.redraw = 1; - - if(linuxvars.first || !linuxvars.has_xfixes){ + if(linuxvars.input.first_step || !linuxvars.has_xfixes){ XConvertSelection( linuxvars.XDisplay, linuxvars.atom_CLIPBOARD, @@ -2682,24 +2835,18 @@ main(int argc, char **argv) result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; result.trying_to_kill = !linuxvars.keep_running; - String clipboard = {}; if(linuxvars.new_clipboard){ - clipboard = linuxvars.clipboard_contents; + linuxvars.input.clipboard = linuxvars.clipboard_contents; linuxvars.new_clipboard = 0; + } else { + linuxvars.input.clipboard = string_zero(); } - f32 dt = frame_useconds / 1000000.f; - linuxvars.app.step( - linuxvars.system, - &linuxvars.key_data, - &linuxvars.mouse_data, + &linuxvars.system, &linuxvars.target, &memory_vars, - &exchange_vars, - clipboard, - dt, - linuxvars.first, + &linuxvars.input, &result ); @@ -2710,32 +2857,25 @@ main(int argc, char **argv) } if(result.animating){ - linuxvars.redraw = 1; LinuxScheduleStep(); } - if(linuxvars.redraw){ - LinuxRedrawTarget(); - linuxvars.redraw = 0; - } + LinuxRedrawTarget(); - if(result.mouse_cursor_type != linuxvars.cursor){ + if(result.mouse_cursor_type != linuxvars.cursor && !linuxvars.input.mouse.l){ Cursor c = xcursors[result.mouse_cursor_type]; XDefineCursor(linuxvars.XDisplay, linuxvars.XWindow, c); linuxvars.cursor = result.mouse_cursor_type; } - linuxvars.first = 0; - linuxvars.redraw = 0; - linuxvars.key_data = key_input_data_zero(); - linuxvars.mouse_data.press_l = 0; - linuxvars.mouse_data.release_l = 0; - linuxvars.mouse_data.press_r = 0; - linuxvars.mouse_data.release_r = 0; - linuxvars.mouse_data.wheel = 0; + linuxvars.input.first_step = 0; + linuxvars.input.keys = key_input_data_zero(); + linuxvars.input.mouse.press_l = 0; + linuxvars.input.mouse.release_l = 0; + linuxvars.input.mouse.press_r = 0; + linuxvars.input.mouse.release_r = 0; + linuxvars.input.mouse.wheel = 0; } - - system_release_lock(FRAME_LOCK); } return 0; diff --git a/not_shipping_4coder_default_view.cpp b/not_shipping_4coder_default_view.cpp new file mode 100644 index 00000000..122a2da3 --- /dev/null +++ b/not_shipping_4coder_default_view.cpp @@ -0,0 +1,89 @@ + +struct Custom_Vars{ + int initialized; + Partition part; +}; + +enum View_Mode{ + ViewMode_File, +}; + +struct View_Vars{ + int id; + View_Mode mode; + + GUI_Scroll_Vars scroll; + i32_Rect scroll_region; + + int buffer_id; +}; +inline View_Vars +view_vars_zero(){ + View_Vars vars = {0}; + return(vars); +} + +extern "C" void +view_routine(Application_Links *app, int view_id){ + Custom_Vars *vars = (Custom_Vars*)app->memory; + View_Vars view = {0}; + view.id = view_id; + + int 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_casey.cpp b/power/4coder_casey.cpp index df8fbc20..bd2cb789 100644 --- a/power/4coder_casey.cpp +++ b/power/4coder_casey.cpp @@ -104,13 +104,11 @@ #include #include +#include +#include #include "../4coder_default_include.cpp" -enum maps{ - my_code_map -}; - #ifndef Assert #define internal static #define Assert assert diff --git a/power/4coder_experiments.cpp b/power/4coder_experiments.cpp index 81bb017e..06b77398 100644 --- a/power/4coder_experiments.cpp +++ b/power/4coder_experiments.cpp @@ -4,6 +4,8 @@ #define NO_BINDING #include "../4coder_default_bindings.cpp" +#include + CUSTOM_COMMAND_SIG(kill_rect){ View_Summary view = app->get_active_view(app); Buffer_Summary buffer = app->get_buffer(app, view.buffer_id); @@ -25,102 +27,6 @@ CUSTOM_COMMAND_SIG(kill_rect){ } } -// NOTE(allen): This stream stuff will be moved to helper if it looks -// like it will be helpful. So if you want to use it to build your own -// commands I suggest you move it there first. -struct Stream_Chunk{ - Application_Links *app; - Buffer_Summary *buffer; - - char *base_data; - int start, end; - int data_size; - - char *data; -}; - -int -round_down(int x, int b){ - int r = 0; - if (x >= 0){ - r = x - (x % b); - } - return(r); -} - -int -round_up(int x, int b){ - int r = 0; - if (x >= 0){ - r = x - (x % b) + b; - } - return(r); -} - -int -init_stream_chunk(Stream_Chunk *chunk, - Application_Links *app, Buffer_Summary *buffer, - int pos, char *data, int size){ - int result = 0; - - app->refresh_buffer(app, buffer); - if (pos >= 0 && pos < buffer->size && size > 0){ - result = 1; - 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->end > buffer->size){ - chunk->end = buffer->size; - } - app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); - chunk->data = chunk->base_data - chunk->start; - } - return(result); -} - -int -forward_stream_chunk(Stream_Chunk *chunk){ - Application_Links *app = chunk->app; - Buffer_Summary *buffer = chunk->buffer; - int result = 0; - - app->refresh_buffer(app, buffer); - if (chunk->end < buffer->size){ - result = 1; - chunk->start = chunk->end; - chunk->end += chunk->data_size; - if (chunk->end > buffer->size){ - chunk->end = buffer->size; - } - app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); - chunk->data = chunk->base_data - chunk->start; - } - return(result); -} - -int -backward_stream_chunk(Stream_Chunk *chunk){ - Application_Links *app = chunk->app; - Buffer_Summary *buffer = chunk->buffer; - int result = 0; - - app->refresh_buffer(app, buffer); - if (chunk->start > 0){ - result = 1; - chunk->end = chunk->start; - chunk->start -= chunk->data_size; - if (chunk->start < 0){ - chunk->start = 0; - } - app->buffer_read_range(app, buffer, chunk->start, chunk->end, chunk->base_data); - chunk->data = chunk->base_data - chunk->start; - } - return(result); -} - // TODO(allen): Both of these brace related commands would work better // if the API exposed access to the tokens in a code file. CUSTOM_COMMAND_SIG(mark_matching_brace){ @@ -144,7 +50,8 @@ CUSTOM_COMMAND_SIG(mark_matching_brace){ int nesting_counter = 0; char at_cursor = 0; - if (init_stream_chunk(&chunk, app, &buffer, i, chunk_space, sizeof(chunk_space))){ + if (init_stream_chunk(&chunk, app, &buffer, i, + chunk_space, sizeof(chunk_space))){ // NOTE(allen): This is important! The data array is a pointer that is adjusted // so that indexing it with "i" will put it with the chunk that is actually loaded. @@ -377,10 +284,5 @@ get_bindings(void *data, int size){ return(result); } -extern "C" void -view_routine(Application_Links *app, int view_id){ - app->get_user_input(app, 0, 0); -} - // BOTTOM diff --git a/test/4cpp_lexer_tables.c b/test/4cpp_lexer_tables.c index a801c884..5b231e08 100644 --- a/test/4cpp_lexer_tables.c +++ b/test/4cpp_lexer_tables.c @@ -35,34 +35,34 @@ const int num_main_fsm_eq_classes = 29; unsigned char main_fsm_table[] = { 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, - 0, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -37, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 7, 1,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -42, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -34, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -29, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 4, 1,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -33, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -31, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -27, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -21, 1,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -16, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +37,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 7,40,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +42,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +34,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +29,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 4,40,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +33,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +31,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +27,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +21,40,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +16,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 11, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 10, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -32, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -23, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -36, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -25, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -35, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -30, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +32,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +23,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +36,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +25,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +35,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +30,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, }; unsigned short pp_include_fsm_eq_classes[] = { @@ -88,34 +88,34 @@ const int num_pp_macro_fsm_eq_classes = 29; unsigned char pp_macro_fsm_table[] = { 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, - 0, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -37, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 7, 1,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 2, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -34, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -29, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 4, 1,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -33, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -31, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -27, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -21, 1,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -16, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +37,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 7,40,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 2,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +34,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +29,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 4,40,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +33,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +31,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +27,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +21,40,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +16,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 11, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 10, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -32, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -23, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -36, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -25, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -35, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -30, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +32,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +23,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +36,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +25,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +35,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +30,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, }; unsigned short pp_identifier_fsm_eq_classes[] = { @@ -126,34 +126,34 @@ const int num_pp_identifier_fsm_eq_classes = 29; unsigned char pp_identifier_fsm_table[] = { 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, - 0, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -37, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 7, 1,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 2, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -34, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -29, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 4, 1,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -33, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -31, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -27, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -21, 1,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -16, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +37,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 7,40,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 2,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +34,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +29,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 4,40,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +33,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +31,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +27,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +21,40,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +16,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 11, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 10, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -32, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -23, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -36, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -25, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -35, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -30, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +32,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +23,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +36,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +25,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +35,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +30,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, }; unsigned short pp_body_if_fsm_eq_classes[] = { @@ -164,34 +164,34 @@ const int num_pp_body_if_fsm_eq_classes = 29; unsigned char pp_body_if_fsm_table[] = { 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, - 0, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -37, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 7, 1,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 2, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -34, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -29, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 4, 1,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -33, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -31, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -27, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -21, 1,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -16, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +37,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 7,40,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 2,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +34,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +29,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 4,40,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +33,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +31,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +27,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +21,40,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +16,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 11, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 10, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -32, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -23, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -36, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -25, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -35, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -30, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +32,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +23,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +36,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +25,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +35,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +30,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, }; unsigned short pp_body_fsm_eq_classes[] = { @@ -202,34 +202,34 @@ const int num_pp_body_fsm_eq_classes = 29; unsigned char pp_body_fsm_table[] = { 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, - 0, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -37, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 7, 1,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 2, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -34, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -29, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 4, 1,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -33, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -31, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -27, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -21, 1,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -16, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +37,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 7,40,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 2,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +34,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +29,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 4,40,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +33,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +31,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +27,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +21,40,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +16,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 11, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 10, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -32, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -23, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -36, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -25, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -35, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -30, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +32,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +23,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +36,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +25,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +35,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +30,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, }; unsigned short pp_number_fsm_eq_classes[] = { @@ -240,34 +240,34 @@ const int num_pp_number_fsm_eq_classes = 29; unsigned char pp_number_fsm_table[] = { 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, - 0, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -37, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 7, 1,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 2, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -34, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -29, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 4, 1,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -33, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -31, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -27, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -21, 1,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -16, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +37,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 7,40,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 2,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +34,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +29,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 4,40,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +33,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +31,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +27,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +21,40,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +16,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 11, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 10, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -32, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -23, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -36, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -25, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -35, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -30, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +32,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +23,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +36,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +25,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +35,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +30,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, }; unsigned short pp_error_fsm_eq_classes[] = { @@ -290,34 +290,34 @@ const int num_pp_junk_fsm_eq_classes = 29; unsigned char pp_junk_fsm_table[] = { 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77, - 0, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 0, 1,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -37, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 7, 1,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 2, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -34, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -29, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, - 4, 1,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -33, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -31, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -27, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -21, 1,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -16, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 5, 7, 8, 8,49,50,51,52,53,54,55,56,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 0,40,41, 3, 4, 5, 6, 7, 8, 9,49,50,51,52,53,54,55,17,18,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +37,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 7,40,41, 3, 4, 5, 4,46,47, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 2,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +34,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +29,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 4,40,41, 3,43,44, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +33,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,19,17,17,20,20,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +31,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +27,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,14,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +21,40,41, 3, 4, 5, 4, 7, 8, 7,12,12,51,52,53,54,55,17,17,19,19,22,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +16,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,17,17,17,19,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 11, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, 10, 1,41, 3, 4, 5, 4, 7, 8, 7,10,10,12,14,14,15,55,17,17,19,19,12,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -32, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -23, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -36, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -25, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -39, 1,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -35, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -40, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, -30, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +32,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +23,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,24,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +36,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +25,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,26,65,28,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +39,40,41, 3, 6, 6, 4, 9, 9, 7,49,50,51,52,53,54,55,18,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +35,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,50,13,52,53,15,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, + 1, 1,41, 3, 4, 5, 4, 7, 8, 7,49,15,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, +30,40,41, 3, 4, 5, 4, 7, 8, 7,49,50,51,52,53,54,55,17,17,19,19,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,38, }; unsigned short * get_eq_classes[] = { @@ -393,1068 +393,3 @@ unsigned char LSDIR_count = 119; unsigned char pp_directive_terminal_base = 200; -unsigned short keyword_part_0_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20,40,60,80,100,120,140,160,180, 0, 0,200, 0,220,240,260, 0,280,300,320,340,360,380,400,420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_0_table_eq_classes = 22; - -unsigned char keyword_part_0_table_table[] = { -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, - 3,75,31,75,75,75,75,75,52,75,57,75,75,75,75,75,75,75,75,75, - 4,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -10,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, - 7,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -15,30,75,75,75,75,75,47,50,75,75,75,75,75,75,75,75,70,75,75, - 2,75,75,75,75,75,75,75,75,75,75,75,62,75,75,75,75,75,75,75, -16,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,28,75,75,75,75,44,75,75,75,56,75,75,75,75,75,75,75,71,75, -12,75,75,75,38,75,43,75,75,75,75,60,75,75,75,75,75,75,75,75, -13,75,32,36,75,75,75,75,75,75,58,75,75,75,75,66,75,75,75,75, - 8,75,75,35,75,75,75,75,75,75,75,75,61,75,64,67,75,75,75,75, - 5,75,33,75,39,75,75,48,51,54,55,59,75,63,75,75,69,75,75,75, -19,75,75,75,75,42,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -17,27,34,75,40,41,75,75,75,75,75,75,75,75,75,75,75,75,75,72, - 6,75,75,37,75,75,75,75,75,75,75,75,75,75,65,75,75,75,75,75, - 1,75,75,75,75,75,46,75,75,75,75,75,75,75,75,75,75,75,75,75, -14,75,75,75,75,75,75,75,53,75,75,75,75,75,75,75,75,75,75,73, -11,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -18,75,75,75,75,75,45,75,75,75,75,75,75,75,75,75,75,75,75,75, - 9,75,75,75,75,75,75,75,75,75,75,75,75,75,75,68,75,75,75,75, -75,29,75,75,75,75,75,49,75,75,75,75,75,75,75,75,75,75,75,75, -}; - -/* -true -try -*/ -unsigned short keyword_part_1_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,12, 4, 4, 4,16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_1_table_eq_classes = 5; - -unsigned char keyword_part_1_table_table[] = { -75,75,98,76, -75,75,75,75, -75, 3,75,75, - 1,75,75,75, - 2,75,75,75, -}; - -/* -throw -this -thread_local -*/ -unsigned short keyword_part_2_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,15,15,15,15,15,15,15,15,15,15, 0, 0, 0, 0, 0, 0, 0,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 0, 0, 0, 0,30, 0,45,15,60,75,90,15,15,15,105,15,15,120,15,15,135,15,15,150,165,15,15,15,180,15,15,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_2_table_eq_classes = 13; - -unsigned char keyword_part_2_table_table[] = { -75,75,75,75,75,86,75,75,75,75,75,75,75,103,103, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75, 8,75,75,75,75,75,75,75, -75,75,75,75, 6,75,75,75,75,75,75,12,75,75,75, -75,75,75,75,75,75,75,75,75,75,11,75,75,75,75, -75,75,75,75,75,75, 7,75,75,75,75,75,75,75,75, -75, 4,75,75,75,75,75,75,75,75,75,75,75,75,75, - 2,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75, 9,75,75,75,13,75,75, -75, 3,75,75,75,75,75,75,75,10,75,75,75,75,75, - 1,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,14,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75, 5,75,75,75,75,75,75,75,75,75,75,75, -}; - -/* -typeid -typedef -typename -*/ -unsigned short keyword_part_3_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,12,12,12,12,12,12, 0, 0, 0, 0, 0, 0, 0,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, 0, 0, 0, 0,12, 0,24,12,12,36,48,60,12,12,72,12,12,12,84,96,12,108,12,12,12,12,12,12,12,12,12,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_3_table_eq_classes = 10; - -unsigned char keyword_part_3_table_table[] = { -75,75,75,75,75,75,93,75,100,75,75,100, -75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75, 9,75,75,75,75,75,75, -75,75, 4, 6,75,75,75,75,75,75,75,75, -75, 2,75,75, 7,75,75,75,75,75,11,75, -75,75,75,75,75,75,75, 8,75,75,75,75, -75,75, 3,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,10,75,75, -75,75, 5,75,75,75,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75,75,75,75,75, -}; - -/* -template -*/ -unsigned short keyword_part_4_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 0,14, 7, 7, 7,21, 7, 7, 7, 7, 7, 7,28,35, 7, 7,42, 7, 7, 7,49, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_4_table_eq_classes = 8; - -unsigned char keyword_part_4_table_table[] = { -75,75,75,75,75,75,100, -75,75,75,75,75,75,75, -75,75,75, 4,75,75,75, -75,75,75,75,75, 6,75, -75,75, 3,75,75,75,75, - 1,75,75,75,75,75,75, -75, 2,75,75,75,75,75, -75,75,75,75, 5,75,75, -}; - -/* -false -*/ -unsigned short keyword_part_5_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4,12, 4, 4, 4, 4, 4, 4,16, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_5_table_eq_classes = 5; - -unsigned char keyword_part_5_table_table[] = { -75,75,75,76, -75,75,75,75, -75,75, 3,75, - 1,75,75,75, -75, 2,75,75, -}; - -/* -float -*/ -unsigned short keyword_part_6_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,12, 4, 4, 4, 4,16, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_6_table_eq_classes = 5; - -unsigned char keyword_part_6_table_table[] = { -75,75,75,95, -75,75,75,75, -75, 2,75,75, - 1,75,75,75, -75,75, 3,75, -}; - -/* -for -*/ -unsigned short keyword_part_7_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_7_table_eq_classes = 3; - -unsigned char keyword_part_7_table_table[] = { -75,98, -75,75, - 1,75, -}; - -/* -friend -*/ -unsigned short keyword_part_8_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 5, 5, 5,10,15, 5, 5, 5,20, 5, 5, 5, 5,25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_8_table_eq_classes = 6; - -unsigned char keyword_part_8_table_table[] = { -75,75,75,75,101, -75,75,75,75,75, -75,75,75, 4,75, -75, 2,75,75,75, - 1,75,75,75,75, -75,75, 3,75,75, -}; - -/* -and -and_eq -*/ -unsigned short keyword_part_9_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,10, 0, 5, 5, 5,15,20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_9_table_eq_classes = 6; - -unsigned char keyword_part_9_table_table[] = { -75,77,75,75,78, -75,75,75,75,75, -75, 2,75,75,75, - 1,75,75,75,75, -75,75, 3,75,75, -75,75,75, 4,75, -}; - -/* -alignof -alignas -*/ -unsigned short keyword_part_10_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 8, 0,16, 8, 8, 8, 8,24,32, 8,40, 8, 8, 8, 8,48,56, 8, 8, 8,64, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_10_table_eq_classes = 9; - -unsigned char keyword_part_10_table_table[] = { -75,75,75,75,75,75,84,103, -75,75,75,75,75,75,75,75, -75,75,75, 5,75,75,75,75, -75,75,75,75, 6,75,75,75, -75, 2,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75, -75,75, 3,75,75,75,75,75, -75,75,75, 4,75,75,75,75, -75,75,75,75,75, 7,75,75, -}; - -/* -asm -*/ -unsigned short keyword_part_11_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_11_table_eq_classes = 3; - -unsigned char keyword_part_11_table_table[] = { -75,98, -75,75, - 1,75, -}; - -/* -bitand -bitor -*/ -unsigned short keyword_part_12_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 0,14, 7, 7,21, 7, 7, 7, 7, 7, 7, 7, 7, 7,28,35, 7, 7,42, 7,49, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_12_table_eq_classes = 8; - -unsigned char keyword_part_12_table_table[] = { -75,75,75,75,75,79,80, -75,75,75,75,75,75,75, -75, 2,75,75,75,75,75, -75,75,75,75, 5,75,75, -75,75, 4,75,75,75,75, -75, 3,75,75,75,75,75, -75,75,75, 6,75,75,75, - 1,75,75,75,75,75,75, -}; - -/* -bool -*/ -unsigned short keyword_part_13_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_13_table_eq_classes = 4; - -unsigned char keyword_part_13_table_table[] = { -75,75,95, -75,75,75, -75, 2,75, - 1,75,75, -}; - -/* -break -*/ -unsigned short keyword_part_14_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 8, 4, 4, 4,12, 4, 4, 4, 4, 4,16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_14_table_eq_classes = 5; - -unsigned char keyword_part_14_table_table[] = { -75,75,75,98, -75,75,75,75, -75, 2,75,75, - 1,75,75,75, -75,75, 3,75, -}; - -/* -or -or_eq -*/ -unsigned short keyword_part_15_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 8, 0, 4, 4, 4, 4,12, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_15_table_eq_classes = 5; - -unsigned char keyword_part_15_table_table[] = { -81,75,75,82, -75,75,75,75, - 1,75,75,75, -75, 2,75,75, -75,75, 3,75, -}; - -/* -operator -*/ -unsigned short keyword_part_16_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 7, 0,14, 7, 7, 7,21, 7, 7, 7, 7, 7, 7, 7, 7, 7,28, 7, 7,35, 7,42, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_16_table_eq_classes = 7; - -unsigned char keyword_part_16_table_table[] = { -75,75,75,75,75,75,103, -75,75,75,75,75,75,75, -75,75, 3,75,75,75,75, - 1,75,75,75,75,75,75, -75,75,75,75, 5,75,75, -75, 2,75,75,75, 6,75, -75,75,75, 4,75,75,75, -}; - -/* -sizeof -*/ -unsigned short keyword_part_17_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 5, 5, 5, 5,10,15, 5, 5, 5, 5, 5, 5, 5, 5,20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_17_table_eq_classes = 6; - -unsigned char keyword_part_17_table_table[] = { -75,75,75,75,83, -75,75,75,75,75, -75, 2,75,75,75, -75,75,75, 4,75, -75,75, 3,75,75, - 1,75,75,75,75, -}; - -/* -short -*/ -unsigned short keyword_part_18_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4,12, 4,16, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_18_table_eq_classes = 5; - -unsigned char keyword_part_18_table_table[] = { -75,75,75,96, -75,75,75,75, - 1,75,75,75, -75, 2,75,75, -75,75, 3,75, -}; - -/* -switch -*/ -unsigned short keyword_part_19_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 5, 5,10, 5, 5, 5, 5,15,20, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,25, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_19_table_eq_classes = 6; - -unsigned char keyword_part_19_table_table[] = { -75,75,75,75,98, -75,75,75,75,75, -75,75, 3,75,75, -75,75,75, 4,75, - 1,75,75,75,75, -75, 2,75,75,75, -}; - -/* -static_assert -static_cast -struct -static -*/ -unsigned short keyword_part_20_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20,20,20,20,20,20,20,20,20,20, 0, 0, 0, 0, 0, 0, 0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, 0, 0, 0, 0,40, 0,60,20,80,20,100,20,20,20,120,20,20,20,20,20,20,20,20,140,160,180,200,20,20,20,20,20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_20_table_eq_classes = 11; - -unsigned char keyword_part_20_table_table[] = { -75,75,75,75,75,102,75,75,75,75,75,75,75,98,75,75,99,75,75,100, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75, 6,75,75,75,75,75,75,75,75,75,75,75,75,75,75, - 1,75,75,75,75,75, 7,75,14,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75, 5,75, 8,75,75,75,75,75,75,75,75,75,75,18,75,75, -75,75,75,75,75,75,75,75,75,75,11,75,75,75,75,75,75,75,75,75, -75,75,75, 4,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, - 2,75,75,75,75,75,75,75,75,75,75,12,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75, 9,75,10,75,75,75,75,15,75,75,75,75,75, -75, 3,75,75,75,75,75,75,75,75,75,75,13,75,75,16,75,75,19,75, -75,75,17,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -}; - -/* -decltype -delete -default -*/ -unsigned short keyword_part_21_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 0, 0, 0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0,16, 0,32,16,48,16,64,80,16,16,16,16,16,96,16,16,16,112,16,16,16,128,144,16,16,16,160,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_21_table_eq_classes = 11; - -unsigned char keyword_part_21_table_table[] = { -75,75,75,75,75,75,75,75,85,75,75,88,75,75,75,98, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,12,75,75,75,75,75,75,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75, 9,75,75,75,75, 8,75,75,11,75,75,75,75,75, - 3,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, - 2, 4,75,75,75,75,75,75,75,75,75,75,75,14,75,75, -75,75,75,75,75,75, 7,75,75,75,75,75,75,75,75,75, -75,75,75,75, 5,75,75,75,75,10,75,75,75,75,15,75, -75,75,75,75,75,75,75,75,75,75,75,75,13,75,75,75, -75,75,75,75,75, 6,75,75,75,75,75,75,75,75,75,75, -}; - -/* -double -do -*/ -unsigned short keyword_part_22_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 5,10, 5, 5,15, 5, 5, 5, 5, 5, 5,20, 5, 5, 5, 5, 5, 5, 5, 5,25, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_22_table_eq_classes = 6; - -unsigned char keyword_part_22_table_table[] = { -98,75,75,75,95, -75,75,75,75,75, -75, 2,75,75,75, -75,75,75, 4,75, -75,75, 3,75,75, - 1,75,75,75,75, -}; - -/* -dynamic_cast -*/ -unsigned short keyword_part_23_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11,11,11,11,11,11,11,11,11, 0, 0, 0, 0, 0, 0, 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 0, 0, 0, 0,22, 0,33,11,44,11,11,11,11,11,55,11,11,11,66,77,11,11,11,11,88,99,11,11,11,11,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_23_table_eq_classes = 10; - -unsigned char keyword_part_23_table_table[] = { -75,75,75,75,75,75,75,75,75,75,99, -75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75, 6,75,75,75,75,75, -75, 2,75,75,75,75,75, 8,75,75,75, -75,75,75,75, 5,75, 7,75,75,75,75, -75,75,75, 4,75,75,75,75,75,75,75, -75,75, 3,75,75,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75, 9,75,75, -75,75,75,75,75,75,75,75,75,10,75, -}; - -/* -new -*/ -unsigned short keyword_part_24_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_24_table_eq_classes = 3; - -unsigned char keyword_part_24_table_table[] = { -75,87, -75,75, - 1,75, -}; - -/* -not -not_eq -noexcept -*/ -unsigned short keyword_part_25_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,11,11,11,11,11,11,11,11,11,11, 0, 0, 0, 0, 0, 0, 0,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 0, 0, 0, 0,22, 0,11,11,33,11,44,11,11,11,11,11,11,11,11,11,11,55,66,11,11,77,11,11,11,88,11,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_25_table_eq_classes = 9; - -unsigned char keyword_part_25_table_table[] = { -75,91,75,75,75,92,75,75,75,75,103, -75,75,75,75,75,75,75,75,75,75,75, -75, 3,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75, 7,75,75,75,75, - 2,75,75, 4,75,75,75, 8,75,75,75, -75,75,75,75,75,75,75,75, 9,75,75, -75,75,75,75, 5,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75,75,10,75, -75,75, 6,75,75,75,75,75,75,75,75, -}; - -/* -namespace -*/ -unsigned short keyword_part_26_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 8, 0,16, 8,24, 8,32, 8, 8, 8, 8, 8, 8, 8,40, 8, 8,48, 8, 8,56, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_26_table_eq_classes = 8; - -unsigned char keyword_part_26_table_table[] = { -75,75,75,75,75,75,75,101, -75,75,75,75,75,75,75,75, -75,75,75,75, 5,75,75,75, -75,75,75,75,75, 6,75,75, -75, 2,75,75,75,75, 7,75, - 1,75,75,75,75,75,75,75, -75,75,75, 4,75,75,75,75, -75,75, 3,75,75,75,75,75, -}; - -/* -nullptr -*/ -unsigned short keyword_part_27_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 6, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,12, 6, 6, 6,18, 6,24, 6,30, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_27_table_eq_classes = 6; - -unsigned char keyword_part_27_table_table[] = { -75,75,75,75,75,103, -75,75,75,75,75,75, - 1, 2,75,75,75,75, -75,75, 3,75,75,75, -75,75,75,75, 5,75, -75,75,75, 4,75,75, -}; - -/* -xor -xor_eq -*/ -unsigned short keyword_part_28_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,10, 0, 5, 5, 5, 5,15, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,20,25, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_28_table_eq_classes = 6; - -unsigned char keyword_part_28_table_table[] = { -75,89,75,75,90, -75,75,75,75,75, -75, 2,75,75,75, -75,75, 3,75,75, -75,75,75, 4,75, - 1,75,75,75,75, -}; - -/* -compl -const -continue -const_cast -*/ -unsigned short keyword_part_29_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,17,17,17,17,17,17,17,17,17,17, 0, 0, 0, 0, 0, 0, 0,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 0, 0, 0, 0,34, 0,51,17,68,17,85,17,17,17,102,17,17,119,136,153,17,170,17,17,187,204,221,17,17,17,17,17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_29_table_eq_classes = 14; - -unsigned char keyword_part_29_table_table[] = { -75,75,75,75,94,75,75,97,75,75,75,75,99,75,75,75,98, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75, 8,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,10,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75, 9,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,16,75, -75,75,75,75,75,75,13,75,75,75,75,75,75,75,75,75,75, -75,75,75, 4,75,75,75,75,75,75,75,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, - 2,75,75,75,75,75,75,75,75,75,75,75,75,14,75,75,75, -75, 3,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75, 5,75,75,75,75,75,75,75,11,75,75,75,75,75,75, -75,75, 6,75,75, 7,75,75,75,75,75,12,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,15,75,75, -}; - -/* -char -*/ -unsigned short keyword_part_30_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_30_table_eq_classes = 4; - -unsigned char keyword_part_30_table_table[] = { -75,75,95, -75,75,75, - 1,75,75, -75, 2,75, -}; - -/* -case -catch -*/ -unsigned short keyword_part_31_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 6, 0, 6, 6,12, 6,18, 6, 6,24, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,30,36, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_31_table_eq_classes = 7; - -unsigned char keyword_part_31_table_table[] = { -75,75,75,98,75,98, -75,75,75,75,75,75, -75,75, 4,75,75,75, -75, 3,75,75,75,75, -75,75,75,75, 5,75, - 1,75,75,75,75,75, - 2,75,75,75,75,75, -}; - -/* -class -*/ -unsigned short keyword_part_32_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,12, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_32_table_eq_classes = 4; - -unsigned char keyword_part_32_table_table[] = { -75,75,75,100, -75,75,75,75, - 1,75,75,75, -75, 2, 3,75, -}; - -/* -void -volatile -*/ -unsigned short keyword_part_33_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0,18, 9, 9,27,36, 9, 9, 9,45, 9, 9,54, 9, 9, 9, 9, 9, 9, 9,63, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_33_table_eq_classes = 8; - -unsigned char keyword_part_33_table_table[] = { -75,75,75,95,75,75,75,75,97, -75,75,75,75,75,75,75,75,75, -75,75, 4,75,75,75,75,75,75, -75, 3,75,75,75,75,75,75,75, -75,75,75,75,75,75,75, 8,75, - 1,75,75,75,75, 6,75,75,75, - 2,75,75,75,75,75, 7,75,75, -75,75,75,75, 5,75,75,75,75, -}; - -/* -virtual -*/ -unsigned short keyword_part_34_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 6, 0,12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,18, 6, 6, 6, 6, 6,24, 6,30,36, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_34_table_eq_classes = 7; - -unsigned char keyword_part_34_table_table[] = { -75,75,75,75,75,102, -75,75,75,75,75,75, -75,75,75, 4,75,75, -75,75,75,75, 5,75, - 1,75,75,75,75,75, -75, 2,75,75,75,75, -75,75, 3,75,75,75, -}; - -/* -int -inline -*/ -unsigned short keyword_part_35_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 6, 0, 6, 6, 6, 6,12, 6, 6, 6,18, 6, 6,24, 6,30, 6, 6, 6, 6, 6,36, 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_35_table_eq_classes = 7; - -unsigned char keyword_part_35_table_table[] = { -75,95,75,75,75,102, -75,75,75,75,75,75, -75,75,75,75, 5,75, -75,75, 3,75,75,75, - 2,75,75,75,75,75, -75,75,75, 4,75,75, - 1,75,75,75,75,75, -}; - -/* -if -*/ -unsigned short keyword_part_36_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_36_table_eq_classes = 2; - -unsigned char keyword_part_36_table_table[] = { -98, -75, -}; - -/* -long -*/ -unsigned short keyword_part_37_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 9, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_37_table_eq_classes = 4; - -unsigned char keyword_part_37_table_table[] = { -75,75,96, -75,75,75, -75, 2,75, - 1,75,75, -}; - -/* -unsigned -union -*/ -unsigned short keyword_part_38_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10,10,10,10,10,10,10,10,10,10, 0, 0, 0, 0, 0, 0, 0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, 0, 0, 0, 0,10, 0,10,10,10,20,30,10,40,10,50,10,10,10,10,60,70,10,10,10,80,10,10,10,10,10,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_38_table_eq_classes = 9; - -unsigned char keyword_part_38_table_table[] = { -75,75,75,75,75,75,75,96,75,100, -75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75, 7,75,75,75, -75,75,75,75,75, 6,75,75,75,75, -75,75,75, 4,75,75,75,75,75,75, - 2, 3,75,75,75,75,75,75,75,75, -75,75,75,75, 5,75,75,75, 9,75, -75,75, 8,75,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75,75,75, -}; - -/* -using -*/ -unsigned short keyword_part_39_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 4, 4, 8, 4,12, 4, 4, 4, 4,16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_39_table_eq_classes = 5; - -unsigned char keyword_part_39_table_table[] = { -75,75,75,101, -75,75,75,75, -75,75, 3,75, - 1,75,75,75, -75, 2,75,75, -}; - -/* -else -*/ -unsigned short keyword_part_40_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_40_table_eq_classes = 4; - -unsigned char keyword_part_40_table_table[] = { -75,75,98, -75,75,75, -75, 2,75, - 1,75,75, -}; - -/* -enum -*/ -unsigned short keyword_part_41_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 3, 9, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_41_table_eq_classes = 4; - -unsigned char keyword_part_41_table_table[] = { -75,75,100, -75,75,75, -75, 2,75, - 1,75,75, -}; - -/* -extern -export -explicit -*/ -unsigned short keyword_part_42_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,14,14,14,14,14,14,14,14,14,14, 0, 0, 0, 0, 0, 0, 0,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 0, 0, 0, 0,14, 0,14,14,28,14,42,14,14,14,56,14,14,70,14,84,98,112,14,126,14,140,14,14,14,14,14,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_42_table_eq_classes = 11; - -unsigned char keyword_part_42_table_table[] = { -75,75,75,75,75,102,75,75,75,102,75,75,75,103, -75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,11,75,75,75, -75, 3,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,10,75,75,75,12,75,75, -75,75, 7,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75, 5,75,75,75,75,75,75,75,75,75, -75,75, 6,75,75,75,75,75,75,75,75,75,75,75, - 2,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75, 4,75,75, 8,75,75,75,75,75,75,75, - 1,75,75,75,75,75,75,75, 9,75,75,75,13,75, -}; - -/* -goto -*/ -unsigned short keyword_part_43_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 9, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_43_table_eq_classes = 4; - -unsigned char keyword_part_43_table_table[] = { -75,75,98, -75,75,75, -75, 2,75, - 1,75,75, -}; - -/* -return -reinterpret_cast -register -*/ -unsigned short keyword_part_44_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,22,22,22,22,22,22,22,22,22,22, 0, 0, 0, 0, 0, 0, 0,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22, 0, 0, 0, 0,44, 0,66,22,88,22,110,22,132,22,154,22,22,22,22,176,22,198,22,220,242,264,286,22,22,22,22,22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_44_table_eq_classes = 14; - -unsigned char keyword_part_44_table_table[] = { -75,75,75,75,75,75,98,75,75,75,75,75,75,75,75,75,75,75,75,75,75,103, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,15,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,74,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,16,75,75,75,75,75,75, -75,75,75,75,75,75,75,75, 9,75,75,75,13,75,75,75,75,75,75,20,75,75, - 3,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, - 2,75,75,17,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75, 7,75,75, 6,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,11,75,75,75,75,75,75,75,75,75,75,75, -75,75,75,75, 5,75,75,75,75,10,75,12,75,75,75,75,75,75,75,75,21,75, -75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,18,75,75,75,75, - 1,75,75,75,75,75,75, 8,75,75,75,75,75,14,75,75,75,75,19,75,75,75, -75, 4,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75, -}; - -/* -while -*/ -unsigned short keyword_part_45_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 0, 4, 4, 4, 4, 8, 4, 4, 4,12, 4, 4,16, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_45_table_eq_classes = 5; - -unsigned char keyword_part_45_table_table[] = { -75,75,75,98, -75,75,75,75, -75,75, 3,75, - 1,75,75,75, -75, 2,75,75, -}; - -/* -private -protected -*/ -unsigned short keyword_part_46_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,13,13,13,13,13,13,13,13,13, 0, 0, 0, 0, 0, 0, 0,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 0, 0, 0, 0,13, 0,26,13,39,52,65,13,13,13,78,13,13,13,13,13,91,13,13,13,13,104,13,117,13,13,13,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_46_table_eq_classes = 10; - -unsigned char keyword_part_46_table_table[] = { -75,75,75,75,75,75,101,75,75,75,75,75,101, -75,75,75,75,75,75,75,75,75,75,75,75,75, -75,75,75, 4,75,75,75,75,75,75,75,75,75, -75,75,75,75,75,75,75,75, 9,75,75,75,75, -75,75,75,75,75,75,75,75,75,75,75,12,75, -75,75,75,75,75, 6,75, 8,75,75,11,75,75, - 1,75,75,75,75,75,75,75,75,75,75,75,75, - 2,75,75,75,75,75,75,75,75,75,75,75,75, -75,75, 7,75, 5,75,75,75,75,10,75,75,75, -75, 3,75,75,75,75,75,75,75,75,75,75,75, -}; - -/* -public -*/ -unsigned short keyword_part_47_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 5,10,15, 5, 5, 5, 5, 5,20, 5, 5,25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_47_table_eq_classes = 6; - -unsigned char keyword_part_47_table_table[] = { -75,75,75,75,101, -75,75,75,75,75, - 1,75,75,75,75, -75,75,75, 4,75, -75,75, 3,75,75, -75, 2,75,75,75, -}; - -/* -reinterpret_cast -*/ -unsigned short keyword_part_48_table_eq_classes[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 6, 9, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -const int num_keyword_part_48_table_eq_classes = 4; - -unsigned char keyword_part_48_table_table[] = { -75,75,99, -75,75,75, - 1,75,75, -75, 2,75, -}; - -unsigned short * key_eq_class_tables[] = { -keyword_part_0_table_eq_classes, -keyword_part_1_table_eq_classes, -keyword_part_2_table_eq_classes, -keyword_part_3_table_eq_classes, -keyword_part_4_table_eq_classes, -keyword_part_5_table_eq_classes, -keyword_part_6_table_eq_classes, -keyword_part_7_table_eq_classes, -keyword_part_8_table_eq_classes, -keyword_part_9_table_eq_classes, -keyword_part_10_table_eq_classes, -keyword_part_11_table_eq_classes, -keyword_part_12_table_eq_classes, -keyword_part_13_table_eq_classes, -keyword_part_14_table_eq_classes, -keyword_part_15_table_eq_classes, -keyword_part_16_table_eq_classes, -keyword_part_17_table_eq_classes, -keyword_part_18_table_eq_classes, -keyword_part_19_table_eq_classes, -keyword_part_20_table_eq_classes, -keyword_part_21_table_eq_classes, -keyword_part_22_table_eq_classes, -keyword_part_23_table_eq_classes, -keyword_part_24_table_eq_classes, -keyword_part_25_table_eq_classes, -keyword_part_26_table_eq_classes, -keyword_part_27_table_eq_classes, -keyword_part_28_table_eq_classes, -keyword_part_29_table_eq_classes, -keyword_part_30_table_eq_classes, -keyword_part_31_table_eq_classes, -keyword_part_32_table_eq_classes, -keyword_part_33_table_eq_classes, -keyword_part_34_table_eq_classes, -keyword_part_35_table_eq_classes, -keyword_part_36_table_eq_classes, -keyword_part_37_table_eq_classes, -keyword_part_38_table_eq_classes, -keyword_part_39_table_eq_classes, -keyword_part_40_table_eq_classes, -keyword_part_41_table_eq_classes, -keyword_part_42_table_eq_classes, -keyword_part_43_table_eq_classes, -keyword_part_44_table_eq_classes, -keyword_part_45_table_eq_classes, -keyword_part_46_table_eq_classes, -keyword_part_47_table_eq_classes, -keyword_part_48_table_eq_classes, -}; - -unsigned char * key_tables[] = { -keyword_part_0_table_table, -keyword_part_1_table_table, -keyword_part_2_table_table, -keyword_part_3_table_table, -keyword_part_4_table_table, -keyword_part_5_table_table, -keyword_part_6_table_table, -keyword_part_7_table_table, -keyword_part_8_table_table, -keyword_part_9_table_table, -keyword_part_10_table_table, -keyword_part_11_table_table, -keyword_part_12_table_table, -keyword_part_13_table_table, -keyword_part_14_table_table, -keyword_part_15_table_table, -keyword_part_16_table_table, -keyword_part_17_table_table, -keyword_part_18_table_table, -keyword_part_19_table_table, -keyword_part_20_table_table, -keyword_part_21_table_table, -keyword_part_22_table_table, -keyword_part_23_table_table, -keyword_part_24_table_table, -keyword_part_25_table_table, -keyword_part_26_table_table, -keyword_part_27_table_table, -keyword_part_28_table_table, -keyword_part_29_table_table, -keyword_part_30_table_table, -keyword_part_31_table_table, -keyword_part_32_table_table, -keyword_part_33_table_table, -keyword_part_34_table_table, -keyword_part_35_table_table, -keyword_part_36_table_table, -keyword_part_37_table_table, -keyword_part_38_table_table, -keyword_part_39_table_table, -keyword_part_40_table_table, -keyword_part_41_table_table, -keyword_part_42_table_table, -keyword_part_43_table_table, -keyword_part_44_table_table, -keyword_part_45_table_table, -keyword_part_46_table_table, -keyword_part_47_table_table, -keyword_part_48_table_table, -}; - -#define LSKEY_table_transition 26 -#define LSKEY_totally_finished 75 diff --git a/test/4cpp_new_lexer.h b/test/4cpp_new_lexer.h index 0240294d..67861d54 100644 --- a/test/4cpp_new_lexer.h +++ b/test/4cpp_new_lexer.h @@ -4,6 +4,7 @@ #ifndef FCPP_NEW_LEXER_INC #define FCPP_NEW_LEXER_INC +#include "..\4cpp_lexer_types.h" #include "4cpp_lexer_fsms.h" #include "4cpp_lexer_tables.c" @@ -286,22 +287,35 @@ cpp_attempt_token_merge(Cpp_Token prev_token, Cpp_Token next_token){ return result; } -lexer_link void -cpp_push_token_nonalloc(Cpp_Token *out_tokens, int *token_i, Cpp_Token token){ +lexer_link int +cpp_place_token_nonalloc(Cpp_Token *out_tokens, int token_i, Cpp_Token token){ Cpp_Token_Merge merge = {(Cpp_Token_Type)0}; Cpp_Token prev_token = {(Cpp_Token_Type)0}; - if (*token_i > 0){ - prev_token = out_tokens[*token_i - 1]; + if (token_i > 0){ + prev_token = out_tokens[token_i - 1]; merge = new_lex::cpp_attempt_token_merge(prev_token, token); if (merge.did_merge){ - out_tokens[*token_i - 1] = merge.new_token; + out_tokens[token_i - 1] = merge.new_token; } } if (!merge.did_merge){ - out_tokens[(*token_i)++] = token; + out_tokens[token_i++] = token; } + + return(token_i); +} + +lexer_link bool +cpp_push_token_nonalloc(Cpp_Token_Stack *out_tokens, Cpp_Token token){ + bool result = 0; + if (out_tokens->count == out_tokens->max_count){ + out_tokens->count = + cpp_place_token_nonalloc(out_tokens->tokens, out_tokens->count, token); + result = 1; + } + return(result); } struct Lex_Data{ @@ -311,15 +325,13 @@ struct Lex_Data{ int pos; int pos_overide; + int chunk_pos; Lex_FSM fsm; Whitespace_FSM wfsm; unsigned char pp_state; unsigned char completed; - unsigned short *key_eq_classes; - unsigned char *key_table; - Cpp_Token token; int __pc__; @@ -335,20 +347,27 @@ struct Lex_Data{ token_stack_out->count = token_i;\ *S_ptr = S; S_ptr->__pc__ = -1; return(n); } +enum Lex_Result{ + LexFinished, + LexNeedChunk, + LexNeedTokenMemory, + LexHitTokenLimit +}; + lexer_link int cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_stack_out){ Lex_Data S = *S_ptr; - + Cpp_Token *out_tokens = token_stack_out->tokens; int token_i = token_stack_out->count; int max_token_i = token_stack_out->max_count; - + Pos_Update_Rule pos_update_rule = PUR_none; - + char c = 0; - - int end_pos = size + S.pos; - chunk -= S.pos; + + int end_pos = size + S.chunk_pos; + chunk -= S.chunk_pos; switch (S.__pc__){ DrCase(1); @@ -357,7 +376,6 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ DrCase(4); DrCase(5); DrCase(6); - DrCase(7); } for (;;){ @@ -372,7 +390,8 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.wfsm.white_done = (S.wfsm.pp_state >= LSPP_count); if (S.wfsm.white_done == 0){ - DrYield(4, 1); + S.chunk_pos += size; + DrYield(4, LexNeedChunk); } else break; } @@ -380,7 +399,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.pp_state = S.wfsm.pp_state; if (S.pp_state >= LSPP_count){ S.pp_state -= LSPP_count; - } + } S.token_start = S.pos; S.tb_pos = 0; @@ -388,19 +407,20 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ for(;;){ unsigned short *eq_classes = get_eq_classes[S.pp_state]; unsigned char *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++] = c; - + int i = S.fsm.state + eq_classes[c]; S.fsm.state = fsm_table[i]; S.fsm.multi_line |= multiline_state_table[S.fsm.state]; } S.fsm.emit_token = (S.fsm.state >= LS_count); - + if (S.fsm.emit_token == 0){ - DrYield(3, 1); + S.chunk_pos += size; + DrYield(3, LexNeedChunk); } else break; } @@ -413,13 +433,13 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ if (S.pp_state == LSPP_include){ switch (S.fsm.state){ case LSINC_default:break; - + case LSINC_quotes: case LSINC_pointy: S.token.type = CPP_TOKEN_INCLUDE_FILE; S.token.flags = 0; break; - + case LSINC_junk: S.token.type = CPP_TOKEN_JUNK; S.token.flags = 0; @@ -433,22 +453,22 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ #define OperCase(op,t) case op: S.token.type = t; break; OperCase('{', CPP_TOKEN_BRACE_OPEN); OperCase('}', CPP_TOKEN_BRACE_CLOSE); - + OperCase('[', CPP_TOKEN_BRACKET_OPEN); OperCase(']', CPP_TOKEN_BRACKET_CLOSE); - + OperCase('(', CPP_TOKEN_PARENTHESE_OPEN); OperCase(')', CPP_TOKEN_PARENTHESE_CLOSE); - + OperCase('~', CPP_TOKEN_TILDE); OperCase(',', CPP_TOKEN_COMMA); OperCase(';', CPP_TOKEN_SEMICOLON); OperCase('?', CPP_TOKEN_TERNARY_QMARK); - + OperCase('@', CPP_TOKEN_JUNK); OperCase('$', CPP_TOKEN_JUNK); #undef OperCase - + case '\\': if (S.pp_state == LSPP_default){ S.token.type = CPP_TOKEN_JUNK; @@ -461,13 +481,14 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ c = chunk[S.pos++]; if (!(c == ' ' || c == '\t' || c == '\r' || c == '\v' || c == '\f')) S.wfsm.white_done = 1; } - + if (S.wfsm.white_done == 0){ - DrYield(1, 1); + S.chunk_pos += size; + DrYield(1, LexNeedChunk); } else break; } - + if (c == '\n'){ S.fsm.emit_token = 0; S.pos_overide = 0; @@ -485,46 +506,10 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ case LS_identifier: { - S.fsm.state = 0; - S.fsm.emit_token = 0; - S.fsm.sub_machine = 0; - --S.pos; - for (;;){ - // TODO(allen): Need to drop down to the instructions to optimize - // this correctly I think. This looks like it will have more branches - // than it needs unless I am very careful. - for (; S.fsm.state < LSKEY_totally_finished && S.pos < end_pos;){ - // TODO(allen): Rebase these super tables so that we don't have - // to do a subtract on the state. - S.key_table = key_tables[S.fsm.sub_machine]; - S.key_eq_classes = key_eq_class_tables[S.fsm.sub_machine]; - for (; S.fsm.state < LSKEY_table_transition && S.pos < end_pos;){ - c = chunk[S.pos++]; - S.fsm.state = S.key_table[S.fsm.state + S.key_eq_classes[c]]; - } - if (S.fsm.state >= LSKEY_table_transition && S.fsm.state < LSKEY_totally_finished){ - S.fsm.sub_machine = S.fsm.state - LSKEY_table_transition; - S.fsm.state = 0; - } - } - S.fsm.emit_token = (S.fsm.int_state >= LSKEY_totally_finished); - - if (S.fsm.emit_token == 0){ - DrYield(7, 1); - } - else break; - } --S.pos; - // TODO(allen): do stuff regarding the actual type of the token - S.token.type = CPP_TOKEN_INTEGER_CONSTANT; - S.token.flags = 0; - -#if 0 - --S.pos; - int word_size = S.pos - S.token_start; - + if (S.pp_state == LSPP_body_if){ if (match(make_string(S.tb, word_size), make_lit_string("defined"))){ S.token.type = CPP_TOKEN_DEFINED; @@ -532,17 +517,17 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } } - + Sub_Match_List_Result sub_match; sub_match = sub_match_list(S.tb, S.tb_pos, 0, bool_lits, word_size); - + if (sub_match.index != -1){ S.token.type = CPP_TOKEN_BOOLEAN_CONSTANT; S.token.flags = CPP_TFLAG_IS_KEYWORD; } else{ sub_match = sub_match_list(S.tb, S.tb_pos, 0, keywords, word_size); - + if (sub_match.index != -1){ String_And_Flag data = keywords.data[sub_match.index]; S.token.type = (Cpp_Token_Type)data.flags; @@ -553,10 +538,8 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.token.flags = 0; } } -#endif - }break; - + case LS_pound: S.token.flags = 0; switch (c){ @@ -567,7 +550,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_pp: { S.fsm.directive_state = LSDIR_default; @@ -578,9 +561,10 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.fsm.directive_state = pp_directive_table[S.fsm.directive_state + pp_directive_eq_classes[c]]; } S.fsm.emit_token = (S.fsm.int_state >= LSDIR_count); - + if (S.fsm.emit_token == 0){ - DrYield(6, 1); + S.chunk_pos += size; + DrYield(6, LexNeedChunk); } else break; } @@ -590,13 +574,13 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.token.type = type; if (type == CPP_TOKEN_JUNK){ S.token.flags = 0; - } + } else{ S.token.flags = CPP_TFLAG_PP_DIRECTIVE; S.pp_state = (unsigned char)cpp_pp_directive_to_state(S.token.type); - } + } }break; - + case LS_number: case LS_number0: case LS_hex: @@ -609,18 +593,19 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.fsm.int_state = int_fsm_table[S.fsm.int_state + int_fsm_eq_classes[c]]; } S.fsm.emit_token = (S.fsm.int_state >= LSINT_count); - + if (S.fsm.emit_token == 0){ - DrYield(5, 1); + S.chunk_pos += size; + DrYield(5, LexNeedChunk); } else break; } --S.pos; - + S.token.type = CPP_TOKEN_INTEGER_CONSTANT; S.token.flags = 0; break; - + case LS_float: case LS_crazy_float0: case LS_crazy_float1: @@ -634,27 +619,27 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_char: S.token.type = CPP_TOKEN_CHARACTER_CONSTANT; S.token.flags = 0; break; - + case LS_char_multiline: S.token.type = CPP_TOKEN_CHARACTER_CONSTANT; S.token.flags = CPP_TFLAG_MULTILINE; break; - + case LS_string: S.token.type = CPP_TOKEN_STRING_CONSTANT; S.token.flags = 0; break; - + case LS_string_multiline: S.token.type = CPP_TOKEN_STRING_CONSTANT; S.token.flags = CPP_TFLAG_MULTILINE; break; - + case LS_comment_pre: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -665,19 +650,19 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_comment: case LS_comment_block_ending: S.token.type = CPP_TOKEN_COMMENT; S.token.flags = 0; pos_update_rule = PUR_unget_whitespace; break; - + case LS_error_message: S.token.type = CPP_TOKEN_ERROR_MESSAGE; S.token.flags = 0; pos_update_rule = PUR_unget_whitespace; break; - + case LS_dot: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -688,21 +673,21 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_ellipsis: switch (c){ case '.': S.token.flags = CPP_TFLAG_IS_OPERATOR; S.token.type = CPP_TOKEN_ELLIPSIS; break; - + default: S.token.type = CPP_TOKEN_JUNK; pos_update_rule = PUR_back_one; break; } break; - + case LS_less: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -713,7 +698,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_less_less: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -724,7 +709,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_more: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -735,7 +720,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_more_more: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -746,7 +731,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_minus: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -758,7 +743,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_arrow: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -769,7 +754,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_and: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -781,7 +766,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_or: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -793,7 +778,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_plus: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -805,7 +790,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_colon: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -816,7 +801,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_star: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -827,7 +812,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_modulo: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -838,7 +823,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_caret: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -849,7 +834,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_eq: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -860,7 +845,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ break; } break; - + case LS_bang: S.token.flags = CPP_TFLAG_IS_OPERATOR; switch (c){ @@ -872,12 +857,12 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ } break; } - + switch (pos_update_rule){ case PUR_back_one: --S.pos; break; - + case PUR_unget_whitespace: c = chunk[--S.pos]; while (c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\v' || c == '\f'){ @@ -886,7 +871,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ ++S.pos; break; } - + if ((S.token.flags & CPP_TFLAG_PP_DIRECTIVE) == 0){ switch (S.pp_state){ case LSPP_include: @@ -895,7 +880,7 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ } S.pp_state = LSPP_junk; break; - + case LSPP_macro_identifier: if (S.fsm.state != LS_identifier){ S.token.type = CPP_TOKEN_JUNK; @@ -905,14 +890,14 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.pp_state = LSPP_body; } break; - + case LSPP_identifier: if (S.fsm.state != LS_identifier){ S.token.type = CPP_TOKEN_JUNK; } S.pp_state = LSPP_junk; break; - + case LSPP_number: if (S.token.type != CPP_TOKEN_INTEGER_CONSTANT){ S.token.type = CPP_TOKEN_JUNK; @@ -922,14 +907,14 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ S.pp_state = LSPP_include; } break; - + case LSPP_junk: S.token.type = CPP_TOKEN_JUNK; break; } } } - + if (S.fsm.emit_token){ S.token.start = S.token_start; if (S.pos_overide){ @@ -944,9 +929,9 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ } S.token.state_flags = S.pp_state; - cpp_push_token_nonalloc(out_tokens, &token_i, S.token); + token_i = cpp_place_token_nonalloc(out_tokens, token_i, S.token); if (token_i == max_token_i){ - DrYield(2, 2); + DrYield(2, LexNeedTokenMemory); } } } @@ -957,13 +942,199 @@ cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, Cpp_Token_Stack *token_ } } - DrReturn(0); + DrReturn(LexFinished); } #undef DrYield #undef DrReturn #undef DrCase +lexer_link int +cpp_lex_nonalloc(Lex_Data *S_ptr, char *chunk, int size, + Cpp_Token_Stack *token_stack_out, int max_tokens){ + Cpp_Token_Stack temp_stack = *token_stack_out; + if (temp_stack.max_count > temp_stack.count + max_tokens){ + temp_stack.max_count = temp_stack.count + max_tokens; + } + + int result = cpp_lex_nonalloc(S_ptr, chunk, size, &temp_stack); + + token_stack_out->count = temp_stack.count; + + if (result == LexNeedTokenMemory){ + if (token_stack_out->count < token_stack_out->max_count){ + result = LexHitTokenLimit; + } + } + + return(result); +} + +lexer_link int +cpp_lex_size_nonalloc(Lex_Data *S_ptr, char *chunk, int size, int full_size, + Cpp_Token_Stack *token_stack_out){ + int result = 0; + if (S_ptr->pos >= full_size){ + char end_null = 0; + result = cpp_lex_nonalloc(S_ptr, &end_null, 1, token_stack_out); + } + else{ + result = cpp_lex_nonalloc(S_ptr, chunk, size, token_stack_out); + if (result == LexNeedChunk){ + if (S_ptr->pos >= full_size){ + char end_null = 0; + result = cpp_lex_nonalloc(S_ptr, &end_null, 1, token_stack_out); + } + } + } + return(result); +} + +lexer_link int +cpp_lex_size_nonalloc(Lex_Data *S_ptr, char *chunk, int size, int full_size, + Cpp_Token_Stack *token_stack_out, int max_tokens){ + Cpp_Token_Stack temp_stack = *token_stack_out; + if (temp_stack.max_count > temp_stack.count + max_tokens){ + temp_stack.max_count = temp_stack.count + max_tokens; + } + + int result = cpp_lex_size_nonalloc(S_ptr, chunk, size, full_size, + &temp_stack); + + token_stack_out->count = temp_stack.count; + + if (result == LexNeedTokenMemory){ + if (token_stack_out->count < token_stack_out->max_count){ + result = LexHitTokenLimit; + } + } + + return(result); +} + +#if 0 +lexer_link Cpp_Relex_State +cpp_relex_nonalloc_start(Cpp_File file, Cpp_Token_Stack *stack, + int start, int end, int amount, int tolerance){ + Cpp_Relex_State state; + state.file = file; + state.stack = stack; + state.start = start; + state.end = end; + state.amount = amount; + state.tolerance = tolerance; + + Cpp_Get_Token_Result result = new_lex::cpp_get_token(stack, start); + if (result.token_index <= 0){ + state.start_token_i = 0; + } + else{ + state.start_token_i = result.token_index-1; + } + + result = new_lex::cpp_get_token(stack, end); + if (result.token_index < 0) result.token_index = 0; + else if (end > stack->tokens[result.token_index].start) ++result.token_index; + state.end_token_i = result.token_index; + + state.relex_start = stack->tokens[state.start_token_i].start; + if (start < state.relex_start) state.relex_start = start; + + state.space_request = state.end_token_i - state.start_token_i + tolerance + 1; + + return(state); +} + +// TODO(allen): Eliminate this once we actually store the EOF token +// in the token stack. +inline Cpp_Token +cpp__get_token(Cpp_Token_Stack *stack, Cpp_Token *tokens, int size, int index){ + Cpp_Token result; + if (index < stack->count){ + result = tokens[index]; + } + else{ + result.start = size; + result.size = 0; + result.type = CPP_TOKEN_EOF; + result.flags = 0; + result.state_flags = 0; + } + return result; +} + +FCPP_LINK bool +cpp_relex_nonalloc_main(Cpp_Relex_State *state, Cpp_Token_Stack *relex_stack, int *relex_end){ + Cpp_Token_Stack *stack = state->stack; + Cpp_Token *tokens = stack->tokens; + + new_lex::cpp_shift_token_starts(stack, state->end_token_i, state->amount); + + Lex_Data lex = {}; + lex.pp_state = cpp_token_get_pp_state(tokens[state->start_token_i].state_flags); + lex.pos = state->relex_start; + + int relex_end_i = state->end_token_i; + Cpp_Token match_token = cpp__get_token(stack, tokens, state->file.size, relex_end_i); + Cpp_Token end_token = match_token; + bool went_too_far = 0; + + for (;;){ + Cpp_Read_Result read = cpp_lex_step(state->file, &lex); + if (read.has_result){ + if (read.token.start == end_token.start && + read.token.size == end_token.size && + read.token.flags == end_token.flags && + read.token.state_flags == end_token.state_flags){ + break; + } + cpp_push_token_nonalloc(relex_stack, read.token); + + while (lex.pos > end_token.start && relex_end_i < stack->count){ + ++relex_end_i; + end_token = cpp__get_token(stack, tokens, state->file.size, relex_end_i); + } + if (relex_stack->count == relex_stack->max_count){ + went_too_far = 1; + break; + } + } + if (lex.pos >= state->file.size) break; + } + + if (!went_too_far){ + if (relex_stack->count > 0){ + if (state->start_token_i > 0){ + Cpp_Token_Merge merge = + cpp_attempt_token_merge(tokens[state->start_token_i - 1], + relex_stack->tokens[0]); + if (merge.did_merge){ + --state->start_token_i; + relex_stack->tokens[0] = merge.new_token; + } + } + + if (relex_end_i < state->stack->count){ + Cpp_Token_Merge merge = + cpp_attempt_token_merge(relex_stack->tokens[relex_stack->count-1], + tokens[relex_end_i]); + if (merge.did_merge){ + ++relex_end_i; + relex_stack->tokens[relex_stack->count-1] = merge.new_token; + } + } + } + + *relex_end = relex_end_i; + } + else{ + cpp_shift_token_starts(stack, state->end_token_i, -state->amount); + } + + return went_too_far; +} +#endif + #endif // BOTTOM diff --git a/test/experiment.cpp b/test/experiment.cpp index e7cd8ed9..9f9e260a 100644 --- a/test/experiment.cpp +++ b/test/experiment.cpp @@ -7,6 +7,9 @@ * */ +// TODO(allen): In what corner cases, such as invalid files +// does the new lexer suffer??? + // TOP #include "../4ed_meta.h" @@ -204,104 +207,166 @@ end_t(Times *t){ } static void -run_experiment(Experiment *exp, char *filename, int verbose, int chunks){ +run_experiment(Experiment *exp, char *filename, int verbose, + int chunks, int max_tokens){ String extension = {}; Data file_data; Cpp_File file_cpp; new_lex::Lex_Data ld = {0}; int pass; int k, chunk_size, is_last; - + extension = file_extension(make_string_slowly(filename)); - + if (match(extension, "cpp") || match(extension, "h")){ file_data = dump_file(filename); if (file_data.size < (100 << 10)){ pass = 1; if (verbose >= 0) printf("testing on file: %s\n", filename); exp->test_total++; - + exp->correct_stack.count = 0; exp->testing_stack.count = 0; - - memset(exp->correct_stack.tokens, TOKEN_ARRAY_SIZE, 0); - memset(exp->testing_stack.tokens, TOKEN_ARRAY_SIZE, 0); - + + memset(exp->correct_stack.tokens, 0, TOKEN_ARRAY_SIZE); + memset(exp->testing_stack.tokens, 0, TOKEN_ARRAY_SIZE); + file_cpp.data = (char*)file_data.data; file_cpp.size = file_data.size; - + ld.tb = (char*)malloc(file_data.size + 1); - + { i64 start; - + start = __rdtsc(); cpp_lex_file_nonalloc(file_cpp, &exp->correct_stack, lex_data); time.handcoded += (__rdtsc() - start); - - start = __rdtsc(); - if (chunks){ - int relevant_size = file_data.size + 1; - is_last = 0; - for (k = 0; k < relevant_size; k += chunks){ - chunk_size = chunks; - if (chunk_size + k >= relevant_size){ - chunk_size = relevant_size - k; - is_last = 1; + + if (max_tokens == 0){ + if (chunks){ + start = __rdtsc(); + int relevant_size = file_data.size + 1; + is_last = 0; + for (k = 0; k < relevant_size; k += chunks){ + chunk_size = chunks; + if (chunk_size + k >= relevant_size){ + chunk_size = relevant_size - k; + is_last = 1; + } + + int result = + new_lex::cpp_lex_nonalloc(&ld, + (char*)file_data.data + k, chunk_size, + &exp->testing_stack); + + if (result == new_lex::LexFinished || + result == new_lex::LexNeedTokenMemory) break; } - - int result = new_lex::cpp_lex_nonalloc(&ld, (char*)file_data.data + k, chunk_size, &exp->testing_stack); - if (result == 0 || result == 2) break; + time.fsm += (__rdtsc() - start); + } + else{ + start = __rdtsc(); + new_lex::cpp_lex_nonalloc(&ld, + (char*)file_data.data, file_data.size, + &exp->testing_stack); + time.fsm += (__rdtsc() - start); } } else{ - new_lex::cpp_lex_nonalloc(&ld, (char*)file_data.data, file_data.size, &exp->testing_stack); + if (chunks){ + start = __rdtsc(); + int relevant_size = file_data.size + 1; + is_last = 0; + for (k = 0; k < relevant_size; k += chunks){ + chunk_size = chunks; + if (chunk_size + k >= relevant_size){ + chunk_size = relevant_size - k; + is_last = 1; + } + + int result = 0; + int still_lexing = 1; + do{ + result = + new_lex::cpp_lex_size_nonalloc(&ld, + (char*)file_data.data + k, chunk_size, file_data.size, + &exp->testing_stack, + max_tokens); + if (result == new_lex::LexFinished || + result == new_lex::LexNeedTokenMemory || + result == new_lex::LexNeedChunk){ + still_lexing = 0; + } + } while(still_lexing); + + + if (result == new_lex::LexFinished || + result == new_lex::LexNeedTokenMemory) break; + } + time.fsm += (__rdtsc() - start); + } + else{ + start = __rdtsc(); + int still_lexing = 1; + do{ + int result = + new_lex::cpp_lex_size_nonalloc(&ld, + (char*)file_data.data, file_data.size, file_data.size, + &exp->testing_stack, + max_tokens); + if (result == new_lex::LexFinished || + result == new_lex::LexNeedTokenMemory){ + still_lexing = 0; + } + } while(still_lexing); + time.fsm += (__rdtsc() - start); + } } - time.fsm += (__rdtsc() - start); } - + free(ld.tb); - + if (exp->correct_stack.count != exp->testing_stack.count){ pass = 0; if (verbose >= 0){ printf("error: stack size mismatch %d original and %d testing\n", - exp->correct_stack.count, exp->testing_stack.count); + exp->correct_stack.count, exp->testing_stack.count); } } - + int min_count = exp->correct_stack.count; if (min_count > exp->testing_stack.count) min_count = exp->testing_stack.count; - + for (int j = 0; j < min_count; ++j){ Cpp_Token *correct, *testing; correct = exp->correct_stack.tokens + j; testing = exp->testing_stack.tokens + j; - + if (correct->type != testing->type){ pass = 0; if (verbose >= 1) printf("type mismatch at token %d\n", j); } - + if (correct->start != testing->start || correct->size != testing->size){ pass = 0; if (verbose >= 1){ printf("token range mismatch at token %d\n" - " %d:%d original %d:%d testing\n" - " %.*s original %.*s testing\n", - j, - correct->start, correct->size, testing->start, testing->size, - correct->size, file_cpp.data + correct->start, - testing->size, file_cpp.data + testing->start); + " %d:%d original %d:%d testing\n" + " %.*s original %.*s testing\n", + j, + correct->start, correct->size, testing->start, testing->size, + correct->size, file_cpp.data + correct->start, + testing->size, file_cpp.data + testing->start); } } - + if (correct->flags != testing->flags){ pass = 0; if (verbose >= 1) printf("token flag mismatch at token %d\n", j); } } - + if (pass){ exp->passed_total++; if (verbose >= 0) printf("test passed!\n\n"); @@ -310,7 +375,7 @@ run_experiment(Experiment *exp, char *filename, int verbose, int chunks){ if (verbose >= 0) printf("test failed, you failed, fix it now!\n\n"); } } - + free(file_data.data); } } @@ -338,12 +403,13 @@ show_time(Times t, int repeats, char *type){ int main(){ int repeats = 1; - int verbose_level = 1; - int chunk_start = 0; - int chunk_end = 0; + int verbose_level = 0; + int chunk_start = 32; + int chunk_end = 64; #define TEST_FILE "parser_test1.cpp" -#define SINGLE_ITEM 1 - +#define SINGLE_ITEM 0 + int token_limit = 2; + int chunks = (chunk_start > 0 && chunk_start <= chunk_end); int c = 0; @@ -371,14 +437,14 @@ int main(){ begin_t(&chunk_exp_t); printf("With chunks of %d\n", chunks); for (c = chunk_start; c <= chunk_end; ++c){ - run_experiment(&chunk_exp, BASE_DIR TEST_FILE, 1, c); + run_experiment(&chunk_exp, BASE_DIR TEST_FILE, 1, c, token_limit); } end_t(&chunk_exp_t); } begin_t(&exp_t); printf("Unchunked\n"); - run_experiment(&exp, BASE_DIR TEST_FILE, 1, 0); + run_experiment(&exp, BASE_DIR TEST_FILE, 1, 0, token_limit); end_t(&exp_t); #else @@ -391,19 +457,19 @@ int main(){ if (chunks){ begin_t(&chunk_exp_t); for (c = chunk_start; c <= chunk_end; ++c){ - run_experiment(&chunk_exp, all_files.infos[i].filename.str, verbose_level, c); + run_experiment(&chunk_exp, all_files.infos[i].filename.str, verbose_level, c, token_limit); } end_t(&chunk_exp_t); } - + begin_t(&exp_t); if (verbose_level == -1 && chunks){ for (c = chunk_start; c <= chunk_end; ++c){ - run_experiment(&exp, all_files.infos[i].filename.str, verbose_level, 0); + run_experiment(&exp, all_files.infos[i].filename.str, verbose_level, 0, token_limit); } } else{ - run_experiment(&exp, all_files.infos[i].filename.str, verbose_level, 0); + run_experiment(&exp, all_files.infos[i].filename.str, verbose_level, 0, token_limit); } end_t(&exp_t); } diff --git a/test/fsm_table_generator.cpp b/test/fsm_table_generator.cpp index ba8f5e8b..7fb97479 100644 --- a/test/fsm_table_generator.cpp +++ b/test/fsm_table_generator.cpp @@ -576,97 +576,6 @@ process_match_node(String_And_Flag *input, Match_Node *node, Match_Tree *tree, F } } -FSM_Stack -generate_keyword_fsms(){ - Terminal_Lookup_Table terminal_table; - Cpp_Token_Type type; - - Future_FSM_Stack unfinished_futures; - Match_Tree_Stack tree_stack; - FSM_Stack fsm_stack; - Match_Tree *tree; - FSM *fsm; - Future_FSM *future; - Match_Node *root_node; - FSM_State *root_state; - int i, j; - - memset(terminal_table.type_to_state, 0, sizeof(terminal_table.type_to_state)); - memset(terminal_table.state_to_type, 0, sizeof(terminal_table.state_to_type)); - - for (i = 0; i < ArrayCount(keyword_strings); ++i){ - type = (Cpp_Token_Type)keyword_strings[i].flags; - if (terminal_table.type_to_state[type] == 0){ - terminal_table.type_to_state[type] = terminal_table.state_count; - terminal_table.state_to_type[terminal_table.state_count] = type; - ++terminal_table.state_count; - } - } - - fsm_stack.max = 255; - fsm_stack.count = 0; - fsm_stack.fsms = (FSM*)malloc(sizeof(FSM)*fsm_stack.max); - fsm_stack.table_transition_state = 26; - - tree_stack.max = 255; - tree_stack.count = 0; - tree_stack.trees = (Match_Tree*)malloc(sizeof(Match_Tree)*tree_stack.max); - - unfinished_futures.max = 255; - unfinished_futures.count = 0; - unfinished_futures.futures = (Future_FSM*)malloc(sizeof(Future_FSM)*unfinished_futures.max); - - fsm = get_fsm(&fsm_stack); - tree = get_tree(&tree_stack); - - *fsm = fsm_init(200, fsm_stack.table_transition_state); - *tree = tree_init(200); - - root_state = fsm_get_state(fsm, RealTerminateBase); - root_node = match_get_node(tree); - match_init_node(root_node, ArrayCount(keyword_strings)); - for (i = 0; i < ArrayCount(keyword_strings); ++i){ - root_node->words[i] = i; - } - - root_node->count = ArrayCount(keyword_strings); - root_node->state = root_state; - root_node->index = -1; - - push_future_fsm(&unfinished_futures, root_node); - process_match_node(keyword_strings, root_node, tree, fsm, &terminal_table, 2, &unfinished_futures); - - for (i = 1; i < unfinished_futures.count; ++i){ - future = unfinished_futures.futures + i; - - fsm = get_fsm(&fsm_stack); - tree = get_tree(&tree_stack); - - assert((int)(fsm - fsm_stack.fsms) == i); - - *fsm = fsm_init(200, fsm_stack.table_transition_state); - *tree = tree_init(200); - - root_state = fsm_get_state(fsm, RealTerminateBase); - root_node = match_get_node(tree); - match_copy_init_node(root_node, future->source); - root_node->state = root_state; - - for (j = 0; j < root_node->count; ++j){ - char space[1024]; - sprintf(space, "%s\n", keyword_strings[root_node->words[j]].str); - fsm_add_comment(fsm, space); - } - - process_match_node(keyword_strings, root_node, tree, fsm, &terminal_table, 12, &unfinished_futures); - } - - assert(fsm_stack.count < 255); - fsm_stack.final_state = fsm_stack.table_transition_state + (unsigned char)fsm_stack.count; - - return(fsm_stack); -} - Whitespace_FSM whitespace_skip_fsm(Whitespace_FSM wfsm, char c){ if (wfsm.pp_state != LSPP_default){ @@ -781,7 +690,6 @@ main_fsm(Lex_FSM fsm, unsigned char pp_state, unsigned char c){ case LS_default: if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'){ fsm.state = LS_identifier; - fsm.emit_token = 1; } else if (c >= '1' && c <= '9'){ fsm.state = LS_number; @@ -849,13 +757,11 @@ main_fsm(Lex_FSM fsm, unsigned char pp_state, unsigned char c){ } break; -#if 0 case LS_identifier: if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')){ fsm.emit_token = 1; } break; -#endif case LS_pound: switch (c){ @@ -1405,39 +1311,6 @@ main(){ render_variable(file, "unsigned char", "LSDIR_count", pp_directive_fsm.count); render_variable(file, "unsigned char", "pp_directive_terminal_base", pp_directive_fsm.terminal_base); - FSM_Stack keyword_fsms = generate_keyword_fsms(); - - char name[1024]; - for (int i = 0; i < keyword_fsms.count; ++i){ - FSM_Tables partial_keywords_table = - generate_table_from_abstract_fsm(keyword_fsms.fsms[i], keyword_fsms.final_state); - if (keyword_fsms.fsms[i].comment){ - render_comment(file, keyword_fsms.fsms[i].comment); - } - - sprintf(name, "keyword_part_%d_table", i); - render_fsm_table(file, partial_keywords_table, name); - } - - begin_ptr_table(file, "short", "key_eq_class_tables"); - for (int i = 0; i < keyword_fsms.count; ++i){ - sprintf(name, "keyword_part_%d_table_eq_classes", i); - do_table_item_direct(file, name, ""); - end_row(file); - } - end_table(file); - - begin_ptr_table(file, "char", "key_tables"); - for (int i = 0; i < keyword_fsms.count; ++i){ - sprintf(name, "keyword_part_%d_table_table", i); - do_table_item_direct(file, name, ""); - end_row(file); - } - end_table(file); - - fprintf(file, "#define LSKEY_table_transition %d\n", (int)(keyword_fsms.table_transition_state)); - fprintf(file, "#define LSKEY_totally_finished %d\n", (int)(keyword_fsms.final_state)); - fclose(file); return(0); } diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 0710504c..4a96ceb2 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -28,6 +28,9 @@ #include "system_shared.h" +#define SUPPORT_DPI 1 +#define USE_WIN32_FONTS 1 + #define FPS 60 #define frame_useconds (1000000 / FPS) @@ -40,9 +43,11 @@ struct Thread_Context{ u32 job_id; b32 running; + b32 cancel; Work_Queue *queue; u32 id; + u32 group_id; u32 windows_id; HANDLE handle; }; @@ -50,6 +55,9 @@ struct Thread_Context{ struct Thread_Group{ Thread_Context *threads; i32 count; + + i32 cancel_lock0; + i32 cancel_cv0; }; #define UseWinDll 1 @@ -89,8 +97,6 @@ struct Win32_Input_Chunk_Persistent{ i32 mouse_x, mouse_y; b8 mouse_l, mouse_r; - b8 keep_playing; - Control_Keys controls; b8 control_keys[MDFR_INDEX_COUNT]; }; @@ -113,33 +119,22 @@ struct Sys_Bubble : public Bubble{ }; #endif +enum CV_ID{ + CANCEL_CV0, + CANCEL_CV1, + CANCEL_CV2, + CANCEL_CV3, + CANCEL_CV4, + CANCEL_CV5, + CANCEL_CV6, + CANCEL_CV7, + CV_COUNT +}; + struct Win32_Vars{ - HWND window_handle; - HDC window_hdc; - Render_Target target; - - Win32_Input_Chunk input_chunk; - b32 lctrl_lalt_is_altgr; - b32 got_useful_event; - - HCURSOR cursor_ibeam; - HCURSOR cursor_arrow; - HCURSOR cursor_leftright; - HCURSOR cursor_updown; - String clipboard_contents; - b32 next_clipboard_is_self; - DWORD clipboard_sequence; - - Thread_Group groups[THREAD_GROUP_COUNT]; - HANDLE locks[LOCK_COUNT]; - HANDLE DEBUG_sysmem_lock; - - Thread_Memory *thread_memory; - - u64 performance_frequency; - u64 start_pcount; - u64 start_time; - + System_Functions system; + App_Functions app; + Custom_API custom_api; #if UseWinDll HMODULE app_code; HMODULE custom; @@ -147,28 +142,57 @@ struct Win32_Vars{ DLL_Loaded app_dll; DLL_Loaded custom_dll; #endif - - Partition font_part; - Plat_Settings settings; - System_Functions *system; - App_Functions app; - Custom_API custom_api; - b32 first; -#if FRED_INTERNAL - Sys_Bubble internal_bubble; -#endif + Work_Queue queues[THREAD_GROUP_COUNT]; + Thread_Group groups[THREAD_GROUP_COUNT]; + CRITICAL_SECTION locks[LOCK_COUNT]; + CONDITION_VARIABLE condition_vars[CV_COUNT]; + Thread_Memory *thread_memory; Win32_Coroutine coroutine_data[18]; Win32_Coroutine *coroutine_free; + + Win32_Input_Chunk input_chunk; + b32 lctrl_lalt_is_altgr; + b32 got_useful_event; + + + HCURSOR cursor_ibeam; + HCURSOR cursor_arrow; + HCURSOR cursor_leftright; + HCURSOR cursor_updown; + String clipboard_contents; + b32 next_clipboard_is_self; + DWORD clipboard_sequence; + + + HWND window_handle; + Render_Target target; + Partition font_part; +#if SUPPORT_DPI + i32 dpi_x, dpi_y; +#endif + + u64 count_per_usecond; + b32 first; i32 running_cli; + + +#if FRED_INTERNAL + CRITICAL_SECTION DEBUG_sysmem_lock; + Sys_Bubble internal_bubble; +#endif }; globalvar Win32_Vars win32vars; globalvar Application_Memory memory_vars; -globalvar Exchange exchange_vars; + + +// +// Helpers +// internal HANDLE Win32Handle(Plat_Handle h){ @@ -199,60 +223,49 @@ Win32Ptr(void *h){ return(result); } -// -// System Layer Memory -// -#if FRED_INTERNAL +// +// Memory (not exposed to application, but needed in system_shared.cpp) +// internal Sys_Get_Memory_Sig(system_get_memory_){ void *ptr = 0; if (size > 0){ + +#if FRED_INTERNAL ptr = VirtualAlloc(0, size + sizeof(Sys_Bubble), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); Sys_Bubble *bubble = (Sys_Bubble*)ptr; bubble->flags = MEM_BUBBLE_SYS_DEBUG; bubble->line_number = line_number; bubble->file_name = file_name; bubble->size = size; - WaitForSingleObject(win32vars.DEBUG_sysmem_lock, INFINITE); + EnterCriticalSection(&win32vars.DEBUG_sysmem_lock); insert_bubble(&win32vars.internal_bubble, bubble); - ReleaseSemaphore(win32vars.DEBUG_sysmem_lock, 1, 0); + LeaveCriticalSection(&win32vars.DEBUG_sysmem_lock); ptr = bubble + 1; +#else + ptr = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +#endif } return(ptr); } internal Sys_Free_Memory_Sig(system_free_memory){ if (block){ +#if FRED_INTERNAL Sys_Bubble *bubble = ((Sys_Bubble*)block) - 1; Assert((bubble->flags & MEM_BUBBLE_DEBUG_MASK) == MEM_BUBBLE_SYS_DEBUG); - WaitForSingleObject(win32vars.DEBUG_sysmem_lock, INFINITE); + EnterCriticalSection(&win32vars.DEBUG_sysmem_lock); remove_bubble(bubble); - ReleaseSemaphore(win32vars.DEBUG_sysmem_lock, 1, 0); + LeaveCriticalSection(&win32vars.DEBUG_sysmem_lock); VirtualFree(bubble, 0, MEM_RELEASE); - } -} - #else - -internal -Sys_Get_Memory_Sig(system_get_memory_){ - void *ptr = 0; - if (size > 0){ - ptr = VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); - } - return(ptr); -} -internal -Sys_Free_Memory_Sig(system_free_memory){ - if (block){ VirtualFree(block, 0, MEM_RELEASE); +#endif } } -#endif - #define Win32GetMemory(size) system_get_memory_(size, __LINE__, __FILE__) #define Win32FreeMemory(ptr) system_free_memory(ptr) @@ -272,22 +285,341 @@ INTERNAL_system_debug_message(char *message){ } #endif + // -// Platform Layer File Services +// Multithreading +// + +internal +Sys_Acquire_Lock_Sig(system_acquire_lock){ + EnterCriticalSection(&win32vars.locks[id]); +} + +internal +Sys_Release_Lock_Sig(system_release_lock){ + LeaveCriticalSection(&win32vars.locks[id]); +} + +internal void +system_wait_cv(i32 crit_id, i32 cv_id){ + SleepConditionVariableCS(win32vars.condition_vars + cv_id, + win32vars.locks + crit_id, + INFINITE); +} + +internal void +system_signal_cv(i32 crit_id, i32 cv_id){ + AllowLocal(crit_id); + WakeConditionVariable(win32vars.condition_vars + cv_id); +} + +internal DWORD +JobThreadProc(LPVOID lpParameter){ + Thread_Context *thread = (Thread_Context*)lpParameter; + Work_Queue *queue = win32vars.queues + thread->group_id; + Thread_Group *group = win32vars.groups + thread->group_id; + + i32 thread_index = thread->id - 1; + + i32 cancel_lock = group->cancel_lock0 + thread_index; + i32 cancel_cv = group->cancel_cv0 + thread_index; + + Thread_Memory *thread_memory = win32vars.thread_memory + thread_index; + + if (thread_memory->size == 0){ + i32 new_size = Kbytes(64); + thread_memory->data = Win32GetMemory(new_size); + thread_memory->size = new_size; + } + + for (;;){ + u32 read_index = queue->read_position; + u32 write_index = queue->write_position; + + if (read_index != write_index){ + u32 next_read_index = (read_index + 1) % JOB_ID_WRAP; + u32 safe_read_index = + InterlockedCompareExchange(&queue->read_position, + next_read_index, read_index); + + if (safe_read_index == read_index){ + Full_Job_Data *full_job = queue->jobs + (safe_read_index % QUEUE_WRAP); + // NOTE(allen): This is interlocked so that it plays nice + // with the cancel job routine, which may try to cancel this job + // at the same time that we try to run it + + i32 safe_running_thread = + InterlockedCompareExchange(&full_job->running_thread, + thread->id, THREAD_NOT_ASSIGNED); + + if (safe_running_thread == THREAD_NOT_ASSIGNED){ + thread->job_id = full_job->id; + thread->running = 1; + + full_job->job.callback(&win32vars.system, + thread, thread_memory, full_job->job.data); + PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0); + full_job->running_thread = 0; + thread->running = 0; + + system_acquire_lock(cancel_lock); + if (thread->cancel){ + thread->cancel = 0; + system_signal_cv(cancel_lock, cancel_cv); + } + system_release_lock(cancel_lock); + } + } + } + else{ + WaitForSingleObject(Win32Handle(queue->semaphore), INFINITE); + } + } +} + +internal +Sys_Post_Job_Sig(system_post_job){ + Work_Queue *queue = win32vars.queues + group_id; + + Assert((queue->write_position + 1) % QUEUE_WRAP != queue->read_position % QUEUE_WRAP); + + b32 success = 0; + u32 result = 0; + while (!success){ + u32 write_index = queue->write_position; + u32 next_write_index = (write_index + 1) % JOB_ID_WRAP; + u32 safe_write_index = + InterlockedCompareExchange(&queue->write_position, + next_write_index, write_index); + if (safe_write_index == write_index){ + result = write_index; + write_index = write_index % QUEUE_WRAP; + queue->jobs[write_index].job = job; + queue->jobs[write_index].running_thread = THREAD_NOT_ASSIGNED; + queue->jobs[write_index].id = result; + success = 1; + } + } + + ReleaseSemaphore(Win32Handle(queue->semaphore), 1, 0); + + return result; +} + +// NOTE(allen): New job cancelling system: +// +// Jobs are expected to periodically check their cancelation +// state, especially if they are taking a while. +// +// When the main thread asks to cancel a job it sets the cancel +// state and does not resume until the thread running the job +// signals that it is okay. +// +// Don't hold the frame lock while sleeping, as this can dead-lock +// the job thread and the main thread, and since main is sleeping +// they won't collide anyway. +internal +Sys_Cancel_Job_Sig(system_cancel_job){ + Work_Queue *queue = win32vars.queues + group_id; + Thread_Group *group = win32vars.groups + group_id; + + u32 job_index; + u32 thread_id; + Full_Job_Data *full_job; + + job_index = job_id % QUEUE_WRAP; + full_job = queue->jobs + job_index; + + Assert(full_job->id == job_id); + thread_id = + InterlockedCompareExchange(&full_job->running_thread, + 0, THREAD_NOT_ASSIGNED); + + if (thread_id != THREAD_NOT_ASSIGNED && thread_id != 0){ + i32 thread_index = thread_id - 1; + + i32 cancel_lock = group->cancel_lock0 + thread_index; + i32 cancel_cv = group->cancel_cv0 + thread_index; + Thread_Context *thread = group->threads + thread_index; + + + system_acquire_lock(cancel_lock); + + thread->cancel = 1; + + system_release_lock(FRAME_LOCK); + do{ + system_wait_cv(cancel_lock, cancel_cv); + }while (thread->cancel == 1); + system_acquire_lock(FRAME_LOCK); + + system_release_lock(cancel_lock); + } +} + +internal +Sys_Check_Cancel_Sig(system_check_cancel){ + b32 result = 0; + + Thread_Group *group = win32vars.groups + thread->group_id; + i32 thread_index = thread->id - 1; + i32 cancel_lock = group->cancel_lock0 + thread_index; + + system_acquire_lock(cancel_lock); + if (thread->cancel){ + result = 1; + } + system_release_lock(cancel_lock); + + return(result); +} + +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 = LargeRoundUp(memory->size*2, Kbytes(4)); + memory->data = system_get_memory(new_size); + memory->size = new_size; + if (old_data){ + memcpy(memory->data, old_data, old_size); + system_free_memory(old_data); + } + system_release_lock(CANCEL_LOCK0 + memory->id - 1); +} + +#if FRED_INTERNAL +internal void +INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){ + Work_Queue *queue = win32vars.queues + id; + u32 write = queue->write_position; + u32 read = queue->read_position; + if (write < read) write += JOB_ID_WRAP; + *pending = (i32)(write - read); + + Thread_Group *group = win32vars.groups + id; + for (i32 i = 0; i < group->count; ++i){ + running[i] = (group->threads[i].running != 0); + } +} +#endif + + +// +// Coroutines +// + +internal Win32_Coroutine* +Win32AllocCoroutine(){ + Win32_Coroutine *result = win32vars.coroutine_free; + Assert(result != 0); + win32vars.coroutine_free = result->next; + return(result); +} + +internal void +Win32FreeCoroutine(Win32_Coroutine *data){ + data->next = win32vars.coroutine_free; + win32vars.coroutine_free = data; +} + +internal void +Win32CoroutineMain(void *arg_){ + Win32_Coroutine *c = (Win32_Coroutine*)arg_; + c->coroutine.func(&c->coroutine); + c->done = 1; + Win32FreeCoroutine(c); + SwitchToFiber(c->coroutine.yield_handle); +} + +internal +Sys_Create_Coroutine_Sig(system_create_coroutine){ + Win32_Coroutine *c; + Coroutine *coroutine; + void *fiber; + + c = Win32AllocCoroutine(); + c->done = 0; + + coroutine = &c->coroutine; + + fiber = CreateFiber(0, Win32CoroutineMain, coroutine); + + coroutine->plat_handle = Win32Handle(fiber); + coroutine->func = func; + + return(coroutine); +} + +internal +Sys_Launch_Coroutine_Sig(system_launch_coroutine){ + Win32_Coroutine *c = (Win32_Coroutine*)coroutine; + void *fiber; + + fiber = Win32Handle(coroutine->plat_handle); + coroutine->yield_handle = GetCurrentFiber(); + coroutine->in = in; + coroutine->out = out; + + SwitchToFiber(fiber); + + if (c->done){ + DeleteFiber(fiber); + Win32FreeCoroutine(c); + coroutine = 0; + } + + return(coroutine); +} + +Sys_Resume_Coroutine_Sig(system_resume_coroutine){ + Win32_Coroutine *c = (Win32_Coroutine*)coroutine; + void *fiber; + + Assert(c->done == 0); + + coroutine->yield_handle = GetCurrentFiber(); + coroutine->in = in; + coroutine->out = out; + + fiber = Win32Ptr(coroutine->plat_handle); + + SwitchToFiber(fiber); + + if (c->done){ + DeleteFiber(fiber); + Win32FreeCoroutine(c); + coroutine = 0; + } + + return(coroutine); +} + +Sys_Yield_Coroutine_Sig(system_yield_coroutine){ + SwitchToFiber(coroutine->yield_handle); +} + + +// +// Files // internal Sys_File_Can_Be_Made_Sig(system_file_can_be_made){ - HANDLE file; - file = CreateFile((char*)filename, FILE_APPEND_DATA, 0, 0, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); - - if (!file || file == INVALID_HANDLE_VALUE){ - return 0; - } - - CloseHandle(file); - + HANDLE file; + file = CreateFile((char*)filename, FILE_APPEND_DATA, 0, 0, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); + + if (!file || file == INVALID_HANDLE_VALUE){ + return 0; + } + + CloseHandle(file); + return(1); } @@ -379,17 +711,9 @@ Sys_File_Save_Sig(system_file_save){ return(success); } -// TODO(allen): THIS system does not really work. -// I want to eliminate them both entirely and find a better -// way to track the dirty state of files. It shouldn't be too -// hard to get the * part right. The trick is how we will know -// when a file is updated... hmm... maybe we can keep the -// file_time_stamp part. - internal Sys_File_Time_Stamp_Sig(system_file_time_stamp){ - u64 result; - result = 0; + u64 result = 0; FILETIME last_write; WIN32_FILE_ATTRIBUTE_DATA data; @@ -397,21 +721,18 @@ Sys_File_Time_Stamp_Sig(system_file_time_stamp){ last_write = data.ftLastWriteTime; result = ((u64)last_write.dwHighDateTime << 32) | (last_write.dwLowDateTime); - result /= 10; } return(result); } internal -Sys_Time_Sig(system_time){ +Sys_Now_Time_Stamp_Sig(system_now_time_stamp){ u64 result = 0; - LARGE_INTEGER time; - if (QueryPerformanceCounter(&time)){ - result = (u64)(time.QuadPart - win32vars.start_pcount) * 1000000 / win32vars.performance_frequency; - result += win32vars.start_time; - } - return result; + FILETIME filetime; + GetSystemTimeAsFileTime(&filetime); + result = ((u64)filetime.dwHighDateTime << 32) | (filetime.dwLowDateTime); + return(result); } internal @@ -539,6 +860,7 @@ Sys_File_Unique_Hash_Sig(system_file_unique_hash){ return(hash); } +// NOTE(allen): Exposed to the custom layer. internal FILE_EXISTS_SIG(system_file_exists){ char full_filename_space[1024]; @@ -571,6 +893,7 @@ b32 Win32DirectoryExists(char *path){ (attrib & FILE_ATTRIBUTE_DIRECTORY)); } +// NOTE(allen): Exposed to the custom layer. internal DIRECTORY_CD_SIG(system_directory_cd){ String directory = make_string(dir, *len, capacity); @@ -618,11 +941,17 @@ Sys_Get_Binary_Path_Sig(system_get_binary_path){ return(result); } +// NOTE(allen): Exposed to the custom layer. GET_4ED_PATH_SIG(system_get_4ed_path){ String str = make_string(out, 0, capacity); return(system_get_binary_path(&str)); } + +// +// Clipboard +// + internal Sys_Post_Clipboard_Sig(system_post_clipboard){ if (OpenClipboard(win32vars.window_handle)){ @@ -640,284 +969,33 @@ Sys_Post_Clipboard_Sig(system_post_clipboard){ } } -internal -Sys_Acquire_Lock_Sig(system_acquire_lock){ - WaitForSingleObject(win32vars.locks[id], INFINITE); -} - -internal -Sys_Release_Lock_Sig(system_release_lock){ - ReleaseSemaphore(win32vars.locks[id], 1, 0); -} - -internal void -Win32SetCursorFromUpdate(Application_Mouse_Cursor cursor){ - switch (cursor){ - case APP_MOUSE_CURSOR_ARROW: - SetCursor(win32vars.cursor_arrow); break; - - case APP_MOUSE_CURSOR_IBEAM: - SetCursor(win32vars.cursor_ibeam); break; - - case APP_MOUSE_CURSOR_LEFTRIGHT: - SetCursor(win32vars.cursor_leftright); break; - - case APP_MOUSE_CURSOR_UPDOWN: - SetCursor(win32vars.cursor_updown); break; - } -} - -internal void -Win32Resize(i32 width, i32 height){ - if (width > 0 && height > 0){ - glViewport(0, 0, width, height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, width, height, 0, -1, 1); - glScissor(0, 0, width, height); - - win32vars.target.width = width; - win32vars.target.height = height; - } -} - -internal DWORD WINAPI -JobThreadProc(LPVOID lpParameter){ - Thread_Context *thread = (Thread_Context*)lpParameter; - Work_Queue *queue = thread->queue; - - for (;;){ - u32 read_index = queue->read_position; - u32 write_index = queue->write_position; - - if (read_index != write_index){ - u32 next_read_index = (read_index + 1) % JOB_ID_WRAP; - u32 safe_read_index = - InterlockedCompareExchange(&queue->read_position, - next_read_index, read_index); - - if (safe_read_index == read_index){ - Full_Job_Data *full_job = queue->jobs + (safe_read_index % QUEUE_WRAP); - // NOTE(allen): This is interlocked so that it plays nice - // with the cancel job routine, which may try to cancel this job - // at the same time that we try to run it - - i32 safe_running_thread = - InterlockedCompareExchange(&full_job->running_thread, - thread->id, THREAD_NOT_ASSIGNED); - - if (safe_running_thread == THREAD_NOT_ASSIGNED){ - thread->job_id = full_job->id; - thread->running = 1; - Thread_Memory *thread_memory = 0; - - // TODO(allen): remove memory_request - if (full_job->job.memory_request != 0){ - thread_memory = win32vars.thread_memory + thread->id - 1; - if (thread_memory->size < full_job->job.memory_request){ - if (thread_memory->data){ - Win32FreeMemory(thread_memory->data); - } - i32 new_size = LargeRoundUp(full_job->job.memory_request, Kbytes(4)); - thread_memory->data = Win32GetMemory(new_size); - thread_memory->size = new_size; - } - } - full_job->job.callback(win32vars.system, thread, thread_memory, - &exchange_vars.thread, full_job->job.data); - PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0); - full_job->running_thread = 0; - thread->running = 0; +internal b32 +Win32ReadClipboardContents(){ + b32 result = 0; + + if (IsClipboardFormatAvailable(CF_TEXT)){ + result = 1; + if (OpenClipboard(win32vars.window_handle)){ + HANDLE clip_data; + clip_data = GetClipboardData(CF_TEXT); + if (clip_data){ + win32vars.clipboard_contents.str = (char*)GlobalLock(clip_data); + if (win32vars.clipboard_contents.str){ + win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str); + GlobalUnlock(clip_data); } } - } - else{ - WaitForSingleObject(Win32Handle(queue->semaphore), INFINITE); - } - } -} - -internal -Sys_Post_Job_Sig(system_post_job){ - Work_Queue *queue = exchange_vars.thread.queues + group_id; - - Assert((queue->write_position + 1) % QUEUE_WRAP != queue->read_position % QUEUE_WRAP); - - b32 success = 0; - u32 result = 0; - while (!success){ - u32 write_index = queue->write_position; - u32 next_write_index = (write_index + 1) % JOB_ID_WRAP; - u32 safe_write_index = - InterlockedCompareExchange(&queue->write_position, - next_write_index, write_index); - if (safe_write_index == write_index){ - result = write_index; - write_index = write_index % QUEUE_WRAP; - queue->jobs[write_index].job = job; - queue->jobs[write_index].running_thread = THREAD_NOT_ASSIGNED; - queue->jobs[write_index].id = result; - success = 1; + CloseClipboard(); } } - ReleaseSemaphore(Win32Handle(queue->semaphore), 1, 0); - - return result; -} - -internal -Sys_Cancel_Job_Sig(system_cancel_job){ - Work_Queue *queue = exchange_vars.thread.queues + group_id; - Thread_Group *group = win32vars.groups + group_id; - - u32 job_index; - u32 thread_id; - Full_Job_Data *full_job; - Thread_Context *thread; - - job_index = job_id % QUEUE_WRAP; - full_job = queue->jobs + job_index; - - Assert(full_job->id == job_id); - thread_id = - InterlockedCompareExchange(&full_job->running_thread, - 0, THREAD_NOT_ASSIGNED); - - if (thread_id != THREAD_NOT_ASSIGNED){ - system_acquire_lock(CANCEL_LOCK0 + thread_id - 1); - thread = group->threads + thread_id - 1; - TerminateThread(thread->handle, 0); - u32 creation_flag = 0; - thread->handle = CreateThread(0, 0, JobThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); - system_release_lock(CANCEL_LOCK0 + thread_id - 1); - thread->running = 0; - } -} - -internal void -system_grow_thread_memory(Thread_Memory *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 = LargeRoundUp(memory->size*2, Kbytes(4)); - memory->data = system_get_memory(new_size); - memory->size = new_size; - if (old_data){ - memcpy(memory->data, old_data, old_size); - system_free_memory(old_data); - } - system_release_lock(CANCEL_LOCK0 + memory->id - 1); -} - -#if FRED_INTERNAL -internal void -INTERNAL_get_thread_states(Thread_Group_ID id, bool8 *running, i32 *pending){ - Work_Queue *queue = exchange_vars.thread.queues + id; - u32 write = queue->write_position; - u32 read = queue->read_position; - if (write < read) write += JOB_ID_WRAP; - *pending = (i32)(write - read); - - Thread_Group *group = win32vars.groups + id; - for (i32 i = 0; i < group->count; ++i){ - running[i] = (group->threads[i].running != 0); - } -} -#endif - -internal Win32_Coroutine* -Win32AllocCoroutine(){ - Win32_Coroutine *result = win32vars.coroutine_free; - Assert(result != 0); - win32vars.coroutine_free = result->next; return(result); } -internal void -Win32FreeCoroutine(Win32_Coroutine *data){ - data->next = win32vars.coroutine_free; - win32vars.coroutine_free = data; -} -internal void -Win32CoroutineMain(void *arg_){ - Win32_Coroutine *c = (Win32_Coroutine*)arg_; - c->coroutine.func(&c->coroutine); - c->done = 1; - Win32FreeCoroutine(c); - SwitchToFiber(c->coroutine.yield_handle); -} - -internal -Sys_Create_Coroutine_Sig(system_create_coroutine){ - Win32_Coroutine *c; - Coroutine *coroutine; - void *fiber; - - c = Win32AllocCoroutine(); - c->done = 0; - - coroutine = &c->coroutine; - - fiber = CreateFiber(0, Win32CoroutineMain, coroutine); - - coroutine->plat_handle = Win32Handle(fiber); - coroutine->func = func; - - return(coroutine); -} - -internal -Sys_Launch_Coroutine_Sig(system_launch_coroutine){ - Win32_Coroutine *c = (Win32_Coroutine*)coroutine; - void *fiber; - - fiber = Win32Handle(coroutine->plat_handle); - coroutine->yield_handle = GetCurrentFiber(); - coroutine->in = in; - coroutine->out = out; - - SwitchToFiber(fiber); - - if (c->done){ - DeleteFiber(fiber); - Win32FreeCoroutine(c); - coroutine = 0; - } - - return(coroutine); -} - -Sys_Resume_Coroutine_Sig(system_resume_coroutine){ - Win32_Coroutine *c = (Win32_Coroutine*)coroutine; - void *fiber; - - Assert(c->done == 0); - - coroutine->yield_handle = GetCurrentFiber(); - coroutine->in = in; - coroutine->out = out; - - fiber = Win32Ptr(coroutine->plat_handle); - - SwitchToFiber(fiber); - - if (c->done){ - DeleteFiber(fiber); - Win32FreeCoroutine(c); - coroutine = 0; - } - - return(coroutine); -} - -Sys_Yield_Coroutine_Sig(system_yield_coroutine){ - SwitchToFiber(coroutine->yield_handle); -} +// +// Command Line Exectuion +// internal Sys_CLI_Call_Sig(system_cli_call){ @@ -1060,19 +1138,86 @@ Sys_CLI_End_Update_Sig(system_cli_end_update){ return close_me; } +#include "system_shared.cpp" +#include "4ed_rendering.cpp" +#if USE_WIN32_FONTS +#include "win32_font.cpp" +#endif + +internal f32 +size_change(i32 dpi_x, i32 dpi_y){ + // TODO(allen): We're just hoping dpi_x == dpi_y for now I guess. + f32 size_x = win32vars.dpi_x / 96.f; + f32 size_y = win32vars.dpi_y / 96.f; + f32 size_max = Max(size_x, size_y); + return(size_max); +} + +internal +Font_Load_Sig(system_draw_font_load){ + if (win32vars.font_part.base == 0){ + win32vars.font_part = Win32ScratchPartition(Mbytes(8)); + } + + i32 oversample = 2; + +#if SUPPORT_DPI + pt_size = ROUND32(pt_size * size_change(win32vars.dpi_x, win32vars.dpi_y)); +#endif + + for (b32 success = 0; success == 0;){ +#if USE_WIN32_FONTS + + success = win32_draw_font_load(&win32vars.font_part, + font_out, + filename, + pt_size, + tab_width, + oversample, + store_texture); + +#else + + success = draw_font_load(&win32vars.font_part, + font_out, + filename, + pt_size, + tab_width, + oversample, + store_texture); + +#endif + + // TODO(allen): Make the growable partition something + // that can just be passed directly to font load and + // let it be grown there. + if (!success){ + Win32ScratchPartitionDouble(&win32vars.font_part); + } + } + + return(1); +} + +// +// Linkage to Custom and Application +// + internal b32 Win32LoadAppCode(){ b32 result = 0; App_Get_Functions *get_funcs = 0; #if UseWinDll + win32vars.app_code = LoadLibraryA("4ed_app.dll"); if (win32vars.app_code){ get_funcs = (App_Get_Functions*) GetProcAddress(win32vars.app_code, "app_get_functions"); } - + #else + File_Data file = system_load_file("4ed_app.dll"); if (file.got_file){ @@ -1119,74 +1264,46 @@ Win32LoadAppCode(){ internal void Win32LoadSystemCode(){ - win32vars.system->file_time_stamp = system_file_time_stamp; - win32vars.system->file_unique_hash = system_file_unique_hash; - win32vars.system->set_file_list = system_set_file_list; - win32vars.system->file_track = system_file_track; - win32vars.system->file_untrack = system_file_untrack; - win32vars.system->file_load_begin = system_file_load_begin; - win32vars.system->file_load_end = system_file_load_end; - win32vars.system->file_save = system_file_save; + win32vars.system.file_time_stamp = system_file_time_stamp; + win32vars.system.now_time_stamp = system_now_time_stamp; + win32vars.system.file_unique_hash = system_file_unique_hash; + win32vars.system.set_file_list = system_set_file_list; + win32vars.system.file_track = system_file_track; + win32vars.system.file_untrack = system_file_untrack; + win32vars.system.file_load_begin = system_file_load_begin; + win32vars.system.file_load_end = system_file_load_end; + win32vars.system.file_save = system_file_save; - 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.file_exists = system_file_exists; + win32vars.system.directory_cd = system_directory_cd; + win32vars.system.get_4ed_path = system_get_4ed_path; - win32vars.system->post_clipboard = system_post_clipboard; - win32vars.system->time = system_time; + win32vars.system.post_clipboard = system_post_clipboard; - win32vars.system->create_coroutine = system_create_coroutine; - win32vars.system->launch_coroutine = system_launch_coroutine; - win32vars.system->resume_coroutine = system_resume_coroutine; - win32vars.system->yield_coroutine = system_yield_coroutine; + win32vars.system.create_coroutine = system_create_coroutine; + win32vars.system.launch_coroutine = system_launch_coroutine; + win32vars.system.resume_coroutine = system_resume_coroutine; + win32vars.system.yield_coroutine = system_yield_coroutine; - win32vars.system->cli_call = system_cli_call; - win32vars.system->cli_begin_update = system_cli_begin_update; - win32vars.system->cli_update_step = system_cli_update_step; - win32vars.system->cli_end_update = system_cli_end_update; + win32vars.system.cli_call = system_cli_call; + win32vars.system.cli_begin_update = system_cli_begin_update; + win32vars.system.cli_update_step = system_cli_update_step; + win32vars.system.cli_end_update = system_cli_end_update; - win32vars.system->post_job = system_post_job; - win32vars.system->cancel_job = system_cancel_job; - win32vars.system->grow_thread_memory = system_grow_thread_memory; - win32vars.system->acquire_lock = system_acquire_lock; - win32vars.system->release_lock = system_release_lock; + win32vars.system.post_job = system_post_job; + win32vars.system.cancel_job = system_cancel_job; + win32vars.system.check_cancel = system_check_cancel; + win32vars.system.grow_thread_memory = system_grow_thread_memory; + win32vars.system.acquire_lock = system_acquire_lock; + win32vars.system.release_lock = system_release_lock; -#ifdef FRED_INTERNAL - win32vars.system->internal_sentinel = INTERNAL_system_sentinel; - win32vars.system->internal_get_thread_states = INTERNAL_get_thread_states; - win32vars.system->internal_debug_message = INTERNAL_system_debug_message; +#if FRED_INTERNAL + win32vars.system.internal_sentinel = INTERNAL_system_sentinel; + win32vars.system.internal_get_thread_states = INTERNAL_get_thread_states; + win32vars.system.internal_debug_message = INTERNAL_system_debug_message; #endif - win32vars.system->slash = '/'; -} - -#include "system_shared.cpp" -#include "4ed_rendering.cpp" - -internal -Font_Load_Sig(system_draw_font_load){ - if (win32vars.font_part.base == 0){ - win32vars.font_part = Win32ScratchPartition(Mbytes(8)); - } - - i32 oversample = 2; - - for (b32 success = 0; success == 0;){ - success = draw_font_load(&win32vars.font_part, - font_out, - filename, - pt_size, - tab_width, - oversample); - - // TODO(allen): Make the growable partition something that can - // just be passed directly to font load and let it be grown there. - if (!success){ - Win32ScratchPartitionDouble(&win32vars.font_part); - } - } - - return(1); + win32vars.system.slash = '/'; } internal void @@ -1195,31 +1312,19 @@ Win32LoadRenderCode(){ win32vars.target.pop_clip = draw_pop_clip; win32vars.target.push_piece = draw_push_piece; - win32vars.target.font_set.font_info_load = draw_font_info_load; + //win32vars.target.font_set.font_info_load = draw_font_info_load; win32vars.target.font_set.font_load = system_draw_font_load; win32vars.target.font_set.release_font = draw_release_font; } -internal void -Win32RedrawScreen(HDC hdc){ - launch_rendering(&win32vars.target); - glFlush(); - SwapBuffers(hdc); -} - -internal void -Win32RedrawFromUpdate(){ - PAINTSTRUCT ps; - HWND hwnd = win32vars.window_handle; - HDC hdc = BeginPaint(hwnd, &ps); - Win32RedrawScreen(hdc); - EndPaint(hwnd, &ps); -} +// +// Helpers +// globalvar u8 keycode_lookup_table[255]; internal void -keycode_init(){ +Win32KeycodeInit(){ keycode_lookup_table[VK_BACK] = key_back; keycode_lookup_table[VK_DELETE] = key_del; keycode_lookup_table[VK_UP] = key_up; @@ -1252,9 +1357,58 @@ keycode_init(){ keycode_lookup_table[VK_F16] = key_f16; } +internal void +Win32RedrawScreen(HDC hdc){ + launch_rendering(&win32vars.target); + glFlush(); + SwapBuffers(hdc); +} + +internal void +Win32Resize(i32 width, i32 height){ + if (width > 0 && height > 0){ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, height, 0, -1, 1); + glScissor(0, 0, width, height); + + win32vars.target.width = width; + win32vars.target.height = height; + } +} + +internal void +Win32SetCursorFromUpdate(Application_Mouse_Cursor cursor){ + switch (cursor){ + case APP_MOUSE_CURSOR_ARROW: + SetCursor(win32vars.cursor_arrow); break; + + case APP_MOUSE_CURSOR_IBEAM: + SetCursor(win32vars.cursor_ibeam); break; + + case APP_MOUSE_CURSOR_LEFTRIGHT: + SetCursor(win32vars.cursor_leftright); break; + + case APP_MOUSE_CURSOR_UPDOWN: + SetCursor(win32vars.cursor_updown); break; + } +} + +internal u64 +Win32HighResolutionTime(){ + u64 result = 0; + LARGE_INTEGER t; + if (QueryPerformanceCounter(&t)){ + result = (u64)t.QuadPart / win32vars.count_per_usecond; + } + return(result); +} + + + internal LRESULT -Win32Callback(HWND hwnd, UINT uMsg, - WPARAM wParam, LPARAM lParam){ +Win32Callback(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){ LRESULT result = {}; switch (uMsg){ case WM_MENUCHAR: @@ -1562,7 +1716,6 @@ OpenGLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsi OutputDebugStringA("\n"); } -#if 1 int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, @@ -1572,105 +1725,155 @@ WinMain(HINSTANCE hInstance, int argc = __argc; char **argv = __argv; -#else -int main(int argc, char **argv){ - - HINSTANCE hInstance = GetModuleHandle(0); -#endif - - HANDLE original_out = GetStdHandle(STD_OUTPUT_HANDLE); - memset(&win32vars, 0, sizeof(win32vars)); - memset(&exchange_vars, 0, sizeof(exchange_vars)); - + + + // + // Threads and Coroutines + // + + // NOTE(allen): These should come before threads are started! + // Threads now get memory right away and so they use + // the internal_bubble and DEBUG_sysmem_lock + #if FRED_INTERNAL win32vars.internal_bubble.next = &win32vars.internal_bubble; win32vars.internal_bubble.prev = &win32vars.internal_bubble; win32vars.internal_bubble.flags = MEM_BUBBLE_SYS_DEBUG; + + InitializeCriticalSection(&win32vars.DEBUG_sysmem_lock); #endif - - if (!Win32LoadAppCode()){ - // TODO(allen): Failed to load app code, serious problem. - return 99; + + for (i32 i = 0; i < LOCK_COUNT; ++i){ + InitializeCriticalSection(&win32vars.locks[i]); } - - System_Functions system_; - System_Functions *system = &system_; - win32vars.system = system; - Win32LoadSystemCode(); - + + for (i32 i = 0; i < CV_COUNT; ++i){ + InitializeConditionVariable(&win32vars.condition_vars[i]); + } + + + Thread_Context background[4]; + memset(background, 0, sizeof(background)); + win32vars.groups[BACKGROUND_THREADS].threads = background; + win32vars.groups[BACKGROUND_THREADS].count = ArrayCount(background); + win32vars.groups[BACKGROUND_THREADS].cancel_lock0 = CANCEL_LOCK0; + win32vars.groups[BACKGROUND_THREADS].cancel_cv0 = CANCEL_CV0; + + Thread_Memory thread_memory[ArrayCount(background)]; + win32vars.thread_memory = thread_memory; + + win32vars.queues[BACKGROUND_THREADS].semaphore = + Win32Handle(CreateSemaphore(0, 0, + win32vars.groups[BACKGROUND_THREADS].count, + 0)); + + u32 creation_flag = 0; + for (i32 i = 0; i < win32vars.groups[BACKGROUND_THREADS].count; ++i){ + Thread_Context *thread = win32vars.groups[BACKGROUND_THREADS].threads + i; + thread->id = i + 1; + thread->group_id = BACKGROUND_THREADS; + + Thread_Memory *memory = win32vars.thread_memory + i; + *memory = thread_memory_zero(); + memory->id = thread->id; + + thread->queue = &win32vars.queues[BACKGROUND_THREADS]; + thread->handle = CreateThread(0, 0, JobThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); + } + ConvertThreadToFiber(0); win32vars.coroutine_free = win32vars.coroutine_data; for (i32 i = 0; i+1 < ArrayCount(win32vars.coroutine_data); ++i){ win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1; } - + + + // + // Memory Initialization + // + LPVOID base; #if FRED_INTERNAL base = (LPVOID)Tbytes(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); - + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); + #if FRED_INTERNAL base = (LPVOID)Tbytes(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 = + 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 = + VirtualAlloc(base, memory_vars.target_memory_size, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (!memory_vars.vars_memory){ - return 4; + exit(1); } - - DWORD required = GetCurrentDirectory(0, 0); - required += 1; - required *= 4; + + win32vars.target.max = Mbytes(1); + win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max); + + + // + // System and Application Layer Linkage + // + + if (!Win32LoadAppCode()){ + exit(1); + } + + Win32LoadSystemCode(); + + Win32LoadRenderCode(); + + + // + // Read Command Line + // + + DWORD required = (GetCurrentDirectory(0, 0)*4) + 1; char *current_directory_mem = (char*)system_get_memory(required); DWORD written = GetCurrentDirectory(required, current_directory_mem); - + String current_directory = make_string(current_directory_mem, written, required); terminate_with_null(¤t_directory); replace_char(current_directory, '\\', '/'); - + Command_Line_Parameters clparams; clparams.argv = argv; clparams.argc = argc; - - char **files; - i32 *file_count; - - files = 0; - file_count = 0; - - i32 output_size = - win32vars.app.read_command_line(system, - &memory_vars, - current_directory, - &win32vars.settings, - &files, &file_count, - clparams); - if (output_size > 0){ - DWORD written; - WriteFile(original_out, memory_vars.target_memory, output_size, &written, 0); - } - if (output_size != 0) return 0; + char **files = 0; + i32 *file_count = 0; + + win32vars.app.read_command_line(&win32vars.system, + &memory_vars, + current_directory, + &win32vars.settings, + &files, &file_count, + clparams); + + sysshared_filter_real_files(files, file_count); + + + // + // Custom Layer Linkage + // #ifdef FRED_SUPER char *custom_file_default = "4coder_custom.dll"; @@ -1691,90 +1894,52 @@ int main(int argc, char **argv){ if (win32vars.custom_api.get_alpha_4coder_version == 0 || win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){ - OutputDebugStringA("Error: application and custom version numbers don't match"); - return 22; + OutputDebugStringA("Error: application and custom version numbers don't match\n"); + exit(1); } 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 + } #endif - FreeConsole(); - - sysshared_filter_real_files(files, file_count); - - LARGE_INTEGER lpf; - QueryPerformanceFrequency(&lpf); - win32vars.performance_frequency = lpf.QuadPart; - QueryPerformanceCounter(&lpf); - win32vars.start_pcount = lpf.QuadPart; - - FILETIME filetime; - GetSystemTimeAsFileTime(&filetime); - win32vars.start_time = ((u64)filetime.dwHighDateTime << 32) | (filetime.dwLowDateTime); - win32vars.start_time /= 10; - - keycode_init(); - if (win32vars.custom_api.get_bindings == 0){ win32vars.custom_api.get_bindings = (Get_Binding_Data_Function*)get_bindings; } - Thread_Context background[4]; - memset(background, 0, sizeof(background)); - win32vars.groups[BACKGROUND_THREADS].threads = background; - win32vars.groups[BACKGROUND_THREADS].count = ArrayCount(background); + win32vars.custom_api.view_routine = (View_Routine_Function*)0; - Thread_Memory thread_memory[ArrayCount(background)]; - win32vars.thread_memory = thread_memory; - - exchange_vars.thread.queues[BACKGROUND_THREADS].semaphore = - Win32Handle(CreateSemaphore(0, 0, - win32vars.groups[BACKGROUND_THREADS].count, 0)); - - u32 creation_flag = 0; - for (i32 i = 0; i < win32vars.groups[BACKGROUND_THREADS].count; ++i){ - Thread_Context *thread = win32vars.groups[BACKGROUND_THREADS].threads + i; - thread->id = i + 1; - - Thread_Memory *memory = win32vars.thread_memory + i; - *memory = thread_memory_zero(); - memory->id = thread->id; - - thread->queue = &exchange_vars.thread.queues[BACKGROUND_THREADS]; - thread->handle = CreateThread(0, 0, JobThreadProc, thread, creation_flag, (LPDWORD)&thread->windows_id); +#if 0 + if (win32vars.custom_api.view_routine == 0){ + win32vars.custom_api.view_routine = (View_Routine_Function*)view_routine; } +#endif + - Assert(win32vars.locks); - for (i32 i = 0; i < LOCK_COUNT; ++i){ - win32vars.locks[i] = CreateSemaphore(0, 1, 1, 0); - } - win32vars.DEBUG_sysmem_lock = CreateSemaphore(0, 1, 1, 0); - - Win32LoadRenderCode(); - win32vars.target.max = Mbytes(1); - win32vars.target.push_buffer = (byte*)system_get_memory(win32vars.target.max); - - win32vars.cursor_ibeam = LoadCursor(NULL, IDC_IBEAM); - win32vars.cursor_arrow = LoadCursor(NULL, IDC_ARROW); - win32vars.cursor_leftright = LoadCursor(NULL, IDC_SIZEWE); - win32vars.cursor_updown = LoadCursor(NULL, IDC_SIZENS); + // + // Window and GL Initialization + // WNDCLASS window_class = {}; - window_class.style = CS_HREDRAW|CS_VREDRAW|CS_OWNDC; + window_class.style = CS_HREDRAW|CS_VREDRAW; window_class.lpfnWndProc = Win32Callback; window_class.hInstance = hInstance; window_class.lpszClassName = "4coder-win32-wndclass"; window_class.hIcon = LoadIcon(hInstance, "main"); if (!RegisterClass(&window_class)){ - return 1; + exit(1); } RECT window_rect = {}; - + if (win32vars.settings.set_window_size){ window_rect.right = win32vars.settings.window_w; window_rect.bottom = win32vars.settings.window_h; @@ -1783,17 +1948,17 @@ int main(int argc, char **argv){ window_rect.right = 800; window_rect.bottom = 600; } - + if (!AdjustWindowRect(&window_rect, WS_OVERLAPPEDWINDOW, false)){ // TODO(allen): non-fatal diagnostics } - + #define WINDOW_NAME "4coder-window: " VERSION - + i32 window_x; i32 window_y; i32 window_style; - + if (win32vars.settings.set_window_pos){ window_x = win32vars.settings.window_x; window_y = win32vars.settings.window_y; @@ -1802,35 +1967,39 @@ int main(int argc, char **argv){ window_x = CW_USEDEFAULT; window_y = CW_USEDEFAULT; } - + window_style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; if (win32vars.settings.maximize_window){ window_style |= WS_MAXIMIZE; } - - // TODO(allen): not Windows XP compatible, do we care? - // SetProcessDPIAware(); - - HWND window_handle = {}; - window_handle = CreateWindowA( - window_class.lpszClassName, - WINDOW_NAME, window_style, - window_x, window_y, - window_rect.right - window_rect.left, - window_rect.bottom - window_rect.top, - 0, 0, hInstance, 0); - - if (window_handle == 0){ - return 2; + + win32vars.window_handle = + CreateWindowA(window_class.lpszClassName, + WINDOW_NAME, window_style, + window_x, window_y, + window_rect.right - window_rect.left, + window_rect.bottom - window_rect.top, + 0, 0, hInstance, 0); + + if (win32vars.window_handle == 0){ + exit(1); } - - // TODO(allen): errors? - win32vars.window_handle = window_handle; - HDC hdc = GetDC(window_handle); - win32vars.window_hdc = hdc; - - GetClientRect(window_handle, &window_rect); - + + HDC hdc = GetDC(win32vars.window_handle); + +#if SUPPORT_DPI + // TODO(allen): not Windows XP compatible, how do I handle that? + SetProcessDPIAware(); + + win32vars.dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); + win32vars.dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); +#else + win32vars.dpi_x = 1; + win32vars.dpi_y = 1; +#endif + + GetClientRect(win32vars.window_handle, &window_rect); + static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, @@ -1848,232 +2017,248 @@ int main(int argc, char **argv){ PFD_MAIN_PLANE, 0, 0, 0, 0 }; - - i32 pixel_format; - pixel_format = ChoosePixelFormat(hdc, &pfd); - SetPixelFormat(hdc, pixel_format, &pfd); - - win32vars.target.handle = hdc; - win32vars.target.context = wglCreateContext(hdc); - wglMakeCurrent(hdc, (HGLRC)win32vars.target.context); + + { + i32 pixel_format; + pixel_format = ChoosePixelFormat(hdc, &pfd); + SetPixelFormat(hdc, pixel_format, &pfd); + + win32vars.target.handle = hdc; + win32vars.target.context = wglCreateContext(hdc); + wglMakeCurrent(hdc, (HGLRC)win32vars.target.context); + } + ReleaseDC(win32vars.window_handle, hdc); #if FRED_INTERNAL - // NOTE(casey): This slows down GL but puts error messages to the debug console immediately whenever you do something wrong - glDebugMessageCallback_type *glDebugMessageCallback = (glDebugMessageCallback_type *)wglGetProcAddress("glDebugMessageCallback"); - glDebugMessageControl_type *glDebugMessageControl = (glDebugMessageControl_type *)wglGetProcAddress("glDebugMessageControl"); - if(glDebugMessageCallback && glDebugMessageControl) - { - glDebugMessageCallback(OpenGLDebugCallback, 0); - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); - glEnable(GL_DEBUG_OUTPUT); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - } + // NOTE(casey): This slows down GL but puts error messages to the debug console immediately whenever you do something wrong + glDebugMessageCallback_type *glDebugMessageCallback = (glDebugMessageCallback_type *)wglGetProcAddress("glDebugMessageCallback"); + glDebugMessageControl_type *glDebugMessageControl = (glDebugMessageControl_type *)wglGetProcAddress("glDebugMessageControl"); + if(glDebugMessageCallback && glDebugMessageControl) + { + glDebugMessageCallback(OpenGLDebugCallback, 0); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); + glEnable(GL_DEBUG_OUTPUT); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + } #endif - + glEnable(GL_TEXTURE_2D); glEnable(GL_SCISSOR_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - + Win32Resize(window_rect.right - window_rect.left, window_rect.bottom - window_rect.top); - + + + // + // Misc System Initializations + // + win32vars.clipboard_sequence = GetClipboardSequenceNumber(); - if (win32vars.clipboard_sequence == 0){ system_post_clipboard(make_lit_string("")); - + win32vars.clipboard_sequence = GetClipboardSequenceNumber(); win32vars.next_clipboard_is_self = 0; - + if (win32vars.clipboard_sequence == 0){ - // TODO(allen): diagnostics + OutputDebugStringA("Failure while initializing clipboard\n"); } } - else{ - if (IsClipboardFormatAvailable(CF_TEXT)){ - if (OpenClipboard(win32vars.window_handle)){ - HANDLE clip_data; - clip_data = GetClipboardData(CF_TEXT); - if (clip_data){ - win32vars.clipboard_contents.str = (char*)GlobalLock(clip_data); - if (win32vars.clipboard_contents.str){ - win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str); - GlobalUnlock(clip_data); - } - } - CloseClipboard(); - } - } + Win32ReadClipboardContents(); } - - win32vars.app.init(win32vars.system, &win32vars.target, - &memory_vars, &exchange_vars, - win32vars.clipboard_contents, current_directory, - win32vars.custom_api); - + + Win32KeycodeInit(); + + win32vars.cursor_ibeam = LoadCursor(NULL, IDC_IBEAM); + win32vars.cursor_arrow = LoadCursor(NULL, IDC_ARROW); + win32vars.cursor_leftright = LoadCursor(NULL, IDC_SIZEWE); + win32vars.cursor_updown = LoadCursor(NULL, IDC_SIZENS); + + LARGE_INTEGER f; + if (QueryPerformanceFrequency(&f)){ + win32vars.count_per_usecond = (u64)f.QuadPart / 1000000; + } + else{ + // NOTE(allen): Just guess. + win32vars.count_per_usecond = 1; + } + + + // + // Main Loop + // + + win32vars.app.init(&win32vars.system, + &win32vars.target, + &memory_vars, + win32vars.clipboard_contents, + current_directory, + win32vars.custom_api); + system_free_memory(current_directory.str); - - win32vars.input_chunk.pers.keep_playing = 1; + + b32 keep_playing = 1; win32vars.first = 1; timeBeginPeriod(1); - + + + SetForegroundWindow(win32vars.window_handle); + SetActiveWindow(win32vars.window_handle); + + u64 timer_start = Win32HighResolutionTime(); system_acquire_lock(FRAME_LOCK); - - SetForegroundWindow(window_handle); - SetActiveWindow(window_handle); - MSG msg; - for (;win32vars.input_chunk.pers.keep_playing;){ + for (;keep_playing;){ // TODO(allen): Find a good way to wait on a pipe // without interfering with the reading process // Looks like we can ReadFile with a size of zero // in an IOCP for this effect. + system_release_lock(FRAME_LOCK); + if (win32vars.running_cli == 0){ win32vars.got_useful_event = 0; for (;win32vars.got_useful_event == 0;){ - system_release_lock(FRAME_LOCK); if (GetMessage(&msg, 0, 0, 0)){ - system_acquire_lock(FRAME_LOCK); if (msg.message == WM_QUIT){ - win32vars.input_chunk.pers.keep_playing = 0; + keep_playing = 0; }else{ TranslateMessage(&msg); DispatchMessage(&msg); } } - else{ - system_acquire_lock(FRAME_LOCK); - } } } while (PeekMessage(&msg, 0, 0, 0, 1)){ if (msg.message == WM_QUIT){ - win32vars.input_chunk.pers.keep_playing = 0; + keep_playing = 0; }else{ TranslateMessage(&msg); DispatchMessage(&msg); } } - { - i64 timer_start = system_time(); + system_acquire_lock(FRAME_LOCK); + + POINT mouse_point; + if (GetCursorPos(&mouse_point) && + ScreenToClient(win32vars.window_handle, &mouse_point)){ - POINT mouse_point; - if (GetCursorPos(&mouse_point) && ScreenToClient(win32vars.window_handle, &mouse_point)){ - if (!hit_check(mouse_point.x, mouse_point.y, - 0, 0, win32vars.target.width, win32vars.target.height)){ - win32vars.input_chunk.trans.out_of_window = 1; - } - win32vars.input_chunk.pers.mouse_x = mouse_point.x; - win32vars.input_chunk.pers.mouse_y = mouse_point.y; - } - else{ + i32_Rect screen = + i32R(0, 0, win32vars.target.width, win32vars.target.height); + + if (!hit_check(mouse_point.x, mouse_point.y, screen)){ win32vars.input_chunk.trans.out_of_window = 1; } - Win32_Input_Chunk input_chunk = win32vars.input_chunk; - win32vars.input_chunk.trans = win32_input_chunk_transient_zero(); - - input_chunk.pers.control_keys[MDFR_CAPS_INDEX] = GetKeyState(VK_CAPITAL) & 0x1; - - win32vars.clipboard_contents = string_zero(); - if (win32vars.clipboard_sequence != 0){ - DWORD new_number = GetClipboardSequenceNumber(); - if (new_number != win32vars.clipboard_sequence){ - win32vars.clipboard_sequence = new_number; - if (win32vars.next_clipboard_is_self){ - win32vars.next_clipboard_is_self = 0; - } - else if (IsClipboardFormatAvailable(CF_TEXT)){ - if (OpenClipboard(win32vars.window_handle)){ - HANDLE clip_data; - clip_data = GetClipboardData(CF_TEXT); - if (clip_data){ - win32vars.clipboard_contents.str = (char*)GlobalLock(clip_data); - if (win32vars.clipboard_contents.str){ - win32vars.clipboard_contents.size = str_size((char*)win32vars.clipboard_contents.str); - GlobalUnlock(clip_data); - } - } - CloseClipboard(); - } - } + win32vars.input_chunk.pers.mouse_x = mouse_point.x; + win32vars.input_chunk.pers.mouse_y = mouse_point.y; + } + else{ + win32vars.input_chunk.trans.out_of_window = 1; + } + + Win32_Input_Chunk input_chunk = win32vars.input_chunk; + win32vars.input_chunk.trans = win32_input_chunk_transient_zero(); + + input_chunk.pers.control_keys[MDFR_CAPS_INDEX] = GetKeyState(VK_CAPITAL) & 0x1; + + win32vars.clipboard_contents = string_zero(); + if (win32vars.clipboard_sequence != 0){ + DWORD new_number = GetClipboardSequenceNumber(); + if (new_number != win32vars.clipboard_sequence){ + win32vars.clipboard_sequence = new_number; + if (win32vars.next_clipboard_is_self){ + win32vars.next_clipboard_is_self = 0; + } + else{ + Win32ReadClipboardContents(); } } - - Key_Input_Data input_data; - Mouse_State mouse; - Application_Step_Result result; - - input_data = input_chunk.trans.key_data; - mouse.out_of_window = input_chunk.trans.out_of_window; - - mouse.l = input_chunk.pers.mouse_l; - mouse.press_l = input_chunk.trans.mouse_l_press; - mouse.release_l = input_chunk.trans.mouse_l_release; - - mouse.r = input_chunk.pers.mouse_r; - mouse.press_r = input_chunk.trans.mouse_r_press; - mouse.release_r = input_chunk.trans.mouse_r_release; - - mouse.wheel = input_chunk.trans.mouse_wheel; - - mouse.x = input_chunk.pers.mouse_x; - mouse.y = input_chunk.pers.mouse_y; - - result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; - result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr; - result.trying_to_kill = input_chunk.trans.trying_to_kill; - result.perform_kill = 0; - - // NOTE(allen): The expected dt given the frame limit in seconds. - f32 dt = frame_useconds / 1000000.f; - - win32vars.app.step(win32vars.system, - &input_data, - &mouse, - &win32vars.target, - &memory_vars, - &exchange_vars, - win32vars.clipboard_contents, - dt, win32vars.first, - &result); - - if (result.perform_kill){ - win32vars.input_chunk.pers.keep_playing = 0; - } - - Win32SetCursorFromUpdate(result.mouse_cursor_type); - win32vars.lctrl_lalt_is_altgr = result.lctrl_lalt_is_altgr; - - Win32RedrawFromUpdate(); - - win32vars.first = 0; - - i64 timer_end = system_time(); - i64 end_target = (timer_start + frame_useconds); - - system_release_lock(FRAME_LOCK); - while (timer_end < end_target){ - DWORD samount = (DWORD)((end_target - timer_end) / 1000); - if (samount > 0) Sleep(samount); - timer_end = system_time(); - } - system_acquire_lock(FRAME_LOCK); - timer_start = system_time(); - - if (result.animating){ - PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0); - } } + + Application_Step_Input input = {0}; + + input.first_step = win32vars.first; + + // NOTE(allen): The expected dt given the frame limit in seconds. + input.dt = frame_useconds / 1000000.f; + + input.keys = input_chunk.trans.key_data; + + input.mouse.out_of_window = input_chunk.trans.out_of_window; + + input.mouse.l = input_chunk.pers.mouse_l; + input.mouse.press_l = input_chunk.trans.mouse_l_press; + input.mouse.release_l = input_chunk.trans.mouse_l_release; + + input.mouse.r = input_chunk.pers.mouse_r; + input.mouse.press_r = input_chunk.trans.mouse_r_press; + input.mouse.release_r = input_chunk.trans.mouse_r_release; + + input.mouse.wheel = input_chunk.trans.mouse_wheel; + input.mouse.x = input_chunk.pers.mouse_x; + input.mouse.y = input_chunk.pers.mouse_y; + + input.clipboard = win32vars.clipboard_contents; + + + Application_Step_Result result = {(Application_Mouse_Cursor)0}; + result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; + result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr; + result.trying_to_kill = input_chunk.trans.trying_to_kill; + result.perform_kill = 0; + + win32vars.app.step(&win32vars.system, + &win32vars.target, + &memory_vars, + &input, + &result); + + if (result.perform_kill){ + keep_playing = 0; + } + + Win32SetCursorFromUpdate(result.mouse_cursor_type); + win32vars.lctrl_lalt_is_altgr = result.lctrl_lalt_is_altgr; + + HDC hdc = GetDC(win32vars.window_handle); + Win32RedrawScreen(hdc); + ReleaseDC(win32vars.window_handle, hdc); + + win32vars.first = 0; + + if (result.animating){ + PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0); + } + + u64 timer_end = Win32HighResolutionTime(); + u64 end_target = timer_start + frame_useconds; + + system_release_lock(FRAME_LOCK); + while (timer_end < end_target){ + DWORD samount = (DWORD)((end_target - timer_end) / 1000); + if (samount > 0) Sleep(samount); + timer_end = Win32HighResolutionTime(); + } + system_acquire_lock(FRAME_LOCK); + timer_start = Win32HighResolutionTime(); } - return 0; + return(0); } +#if 0 +// NOTE(allen): In case I want to switch back to a console +// application at some point. +int main(int argc, char **argv){ + HINSTANCE hInstance = GetModuleHandle(0); +} +#endif + // BOTTOM diff --git a/win32_font.cpp b/win32_font.cpp new file mode 100644 index 00000000..97ef97b6 --- /dev/null +++ b/win32_font.cpp @@ -0,0 +1,72 @@ +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.12.2014 + * + * Win32 font rendering for nicer fonts + * + */ + +// TOP + +internal i32 +win32_draw_font_load(Partition *part, + Render_Font *font_out, + char *filename_untranslated, + i32 pt_size, + i32 tab_width, + i32 oversample, + b32 store_texture){ + + char space_[1024]; + String filename = make_fixed_width_string(space_); + b32 translate_success = sysshared_to_binary_path(&filename, filename_untranslated); + if (!translate_success) return 0; + + i32 result = 0; + + AddFontResourceEx(filename.str, FR_PRIVATE, 0); + + HFONT font_handle = + CreateFontA(pt_size, 0, 0, 0, + FW_NORMAL, // WEIGHT + FALSE, // ITALICS + FALSE, // UNDERLINE + FALSE, // STRIKE-OUT + ANSI_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + ANTIALIASED_QUALITY, + DEFAULT_PITCH|FF_DONTCARE, + filename.str); + + if (font_handle){ + HDC dc = CreateCompatibleDC(0); + + if (dc){ + // TODO(allen): Have to get metrics + + result = 1; + + if (store_texture){ + i32 tex_width = pt_size*16*oversample; + i32 tex_height = pt_size*16*oversample; + + HBITAMP bitmap = CreateCompatibleBitmap(dc, tex_width, tex_height); + + // TODO(allen): pack each glyph into a texture + // and generate the equivalent data output by stb + // in the stbtt_packedchar array. + + } + } + + DeleteObject(font_handle); + } + + return(result); +} + +// BOTTOM + +