New file listing API

This commit is contained in:
Allen Webster 2019-08-03 17:49:40 -07:00
parent 2b28efa3bf
commit d4db77b3fb
19 changed files with 232 additions and 411 deletions

View File

@ -448,34 +448,15 @@ STRUCT File_Attributes{
File_Attribute_Flag flags;
};
/*
DOC(File_Info describes the name and type of a file.)
DOC_SEE(File_List)
*/
STRUCT File_Info{
// TODO(allen): Can we replace file_name this with the updated string type?
// This will be API breaking in a way I can't easily wrap, but it's probably the
// right long term thing to do... Think more later.
/* DOC(This field is a null terminated string specifying the name of the file.) */
char *filename;
/* DOC(This field specifies the length of the filename string not counting the null terminator.) */
i32 filename_len;
/* DOC(This field indicates that the description is for a folder not a file.) */
b32 folder;
// TODO(allen): Can we just stick File_Attributes in here? Or at least File_Attribute_Flag?
File_Info *next;
String_Const_u8 file_name;
File_Attributes attributes;
};
/* DOC(File_List is a list of File_Info structs.)
DOC_SEE(File_Info) */
STRUCT File_List{
/* DOC(This field is for inernal use.) */
void *block;
/* DOC(This field is an array of File_Info structs.) */
File_Info *infos;
/* DOC(This field specifies the number of struts in the info array.) */
File_Info **infos;
u32 count;
/* DOC(This field is for internal use.) */
u32 block_size;
};
/* DOC(Buffer_Identifier acts as a loosely typed description of a buffer that can either be a name or an id.) */

View File

@ -569,13 +569,6 @@ directory_set_hot(Application_Links *app, char *str, i32 len){
return(set_hot_directory(app, SCu8(str, len)));
}
static File_List
get_file_list(Application_Links *app, char *dir, i32 len){
File_List list = {};
get_file_list(app, SCu8(dir, len), &list);
return(list);
}
static b32
file_exists(Application_Links *app, char *file_name, i32 len){
File_Attributes attributes = get_file_attributes(app, SCu8(file_name, len));

View File

@ -3119,6 +3119,7 @@ SCany(String_Const_u32 str){
#define string_litinit(s) {(s), sizeof(s) - 1}
#define string_u8_litexpr(s) SCu8((u8*)(s), sizeof(s) - 1)
#define string_u8_litinit(s) {(u8*)(s), sizeof(s) - 1}
#define string_u16_litexpr(s) SCu16((u16*)(s), sizeof(s)/2 - 1)
#define string_expand(s) (i32)(s).size, (char*)(s).str

View File

@ -136,8 +136,7 @@ struct Application_Links;
#define FINALIZE_COLOR_SIG(n) argb_color n(Application_Links *app, int_color color)
#define PUSH_HOT_DIRECTORY_SIG(n) String_Const_u8 n(Application_Links *app, Arena *arena)
#define SET_HOT_DIRECTORY_SIG(n) b32 n(Application_Links *app, String_Const_u8 string)
#define GET_FILE_LIST_SIG(n) b32 n(Application_Links *app, String_Const_u8 directory, File_List *list_out)
#define FREE_FILE_LIST_SIG(n) void n(Application_Links *app, File_List list)
#define GET_FILE_LIST_SIG(n) File_List n(Application_Links *app, Arena *arena, String_Const_u8 directory)
#define SET_GUI_UP_DOWN_KEYS_SIG(n) void n(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier)
#define MEMORY_ALLOCATE_SIG(n) void* n(Application_Links *app, i32 size)
#define MEMORY_SET_PROTECTION_SIG(n) b32 n(Application_Links *app, void *ptr, i32 size, Memory_Protect_Flags flags)
@ -311,7 +310,6 @@ typedef FINALIZE_COLOR_SIG(Finalize_Color_Function);
typedef PUSH_HOT_DIRECTORY_SIG(Push_Hot_Directory_Function);
typedef SET_HOT_DIRECTORY_SIG(Set_Hot_Directory_Function);
typedef GET_FILE_LIST_SIG(Get_File_List_Function);
typedef FREE_FILE_LIST_SIG(Free_File_List_Function);
typedef SET_GUI_UP_DOWN_KEYS_SIG(Set_GUI_Up_Down_Keys_Function);
typedef MEMORY_ALLOCATE_SIG(Memory_Allocate_Function);
typedef MEMORY_SET_PROTECTION_SIG(Memory_Set_Protection_Function);
@ -487,7 +485,6 @@ Finalize_Color_Function *finalize_color;
Push_Hot_Directory_Function *push_hot_directory;
Set_Hot_Directory_Function *set_hot_directory;
Get_File_List_Function *get_file_list;
Free_File_List_Function *free_file_list;
Set_GUI_Up_Down_Keys_Function *set_gui_up_down_keys;
Memory_Allocate_Function *memory_allocate;
Memory_Set_Protection_Function *memory_set_protection;
@ -662,7 +659,6 @@ Finalize_Color_Function *finalize_color_;
Push_Hot_Directory_Function *push_hot_directory_;
Set_Hot_Directory_Function *set_hot_directory_;
Get_File_List_Function *get_file_list_;
Free_File_List_Function *free_file_list_;
Set_GUI_Up_Down_Keys_Function *set_gui_up_down_keys_;
Memory_Allocate_Function *memory_allocate_;
Memory_Set_Protection_Function *memory_set_protection_;
@ -845,7 +841,6 @@ app_links->finalize_color_ = Finalize_Color;\
app_links->push_hot_directory_ = Push_Hot_Directory;\
app_links->set_hot_directory_ = Set_Hot_Directory;\
app_links->get_file_list_ = Get_File_List;\
app_links->free_file_list_ = Free_File_List;\
app_links->set_gui_up_down_keys_ = Set_GUI_Up_Down_Keys;\
app_links->memory_allocate_ = Memory_Allocate;\
app_links->memory_set_protection_ = Memory_Set_Protection;\
@ -1019,8 +1014,7 @@ static void get_theme_colors(Application_Links *app, Theme_Color *colors, i32 co
static argb_color finalize_color(Application_Links *app, int_color color){return(app->finalize_color(app, color));}
static String_Const_u8 push_hot_directory(Application_Links *app, Arena *arena){return(app->push_hot_directory(app, arena));}
static b32 set_hot_directory(Application_Links *app, String_Const_u8 string){return(app->set_hot_directory(app, string));}
static b32 get_file_list(Application_Links *app, String_Const_u8 directory, File_List *list_out){return(app->get_file_list(app, directory, list_out));}
static void free_file_list(Application_Links *app, File_List list){(app->free_file_list(app, list));}
static File_List get_file_list(Application_Links *app, Arena *arena, String_Const_u8 directory){return(app->get_file_list(app, arena, directory));}
static void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys(app, up_key, up_key_modifier, down_key, down_key_modifier));}
static void* memory_allocate(Application_Links *app, i32 size){return(app->memory_allocate(app, size));}
static b32 memory_set_protection(Application_Links *app, void *ptr, i32 size, Memory_Protect_Flags flags){return(app->memory_set_protection(app, ptr, size, flags));}
@ -1194,8 +1188,7 @@ static void get_theme_colors(Application_Links *app, Theme_Color *colors, i32 co
static argb_color finalize_color(Application_Links *app, int_color color){return(app->finalize_color_(app, color));}
static String_Const_u8 push_hot_directory(Application_Links *app, Arena *arena){return(app->push_hot_directory_(app, arena));}
static b32 set_hot_directory(Application_Links *app, String_Const_u8 string){return(app->set_hot_directory_(app, string));}
static b32 get_file_list(Application_Links *app, String_Const_u8 directory, File_List *list_out){return(app->get_file_list_(app, directory, list_out));}
static void free_file_list(Application_Links *app, File_List list){(app->free_file_list_(app, list));}
static File_List get_file_list(Application_Links *app, Arena *arena, String_Const_u8 directory){return(app->get_file_list_(app, arena, directory));}
static void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys_(app, up_key, up_key_modifier, down_key, down_key_modifier));}
static void* memory_allocate(Application_Links *app, i32 size){return(app->memory_allocate_(app, size));}
static b32 memory_set_protection(Application_Links *app, void *ptr, i32 size, Memory_Protect_Flags flags){return(app->memory_set_protection_(app, ptr, size, flags));}

View File

@ -395,12 +395,12 @@ static Command_Metadata fcoder_metacmd_table[237] = {
{ PROC_LINKS(lister__write_character__file_path, 0), "lister__write_character__file_path", 34, "A lister mode command that inserts a character into the text field of a file system list.", 89, "w:\\4ed\\code\\4coder_lists.cpp", 28, 183 },
{ PROC_LINKS(lister__backspace_text_field__file_path, 0), "lister__backspace_text_field__file_path", 39, "A lister mode command that backspaces one character from the text field of a file system list.", 94, "w:\\4ed\\code\\4coder_lists.cpp", 28, 208 },
{ PROC_LINKS(lister__write_character__fixed_list, 0), "lister__write_character__fixed_list", 35, "A lister mode command that handles input for the fixed sure to kill list.", 73, "w:\\4ed\\code\\4coder_lists.cpp", 28, 249 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 725 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 744 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\4coder_lists.cpp", 28, 817 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 856 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 889 },
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 971 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "w:\\4ed\\code\\4coder_lists.cpp", 28, 723 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\4coder_lists.cpp", 28, 742 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "w:\\4ed\\code\\4coder_lists.cpp", 28, 815 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\4coder_lists.cpp", 28, 854 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\4coder_lists.cpp", 28, 887 },
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\4coder_lists.cpp", 28, 969 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 546 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 555 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\4coder_auto_indent.cpp", 34, 565 },
@ -425,16 +425,16 @@ static Command_Metadata fcoder_metacmd_table[237] = {
{ PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 88 },
{ PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 103 },
{ PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_direct.cpp", 34, 120 },
{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 354 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 381 },
{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 480 },
{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 497 },
{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 510 },
{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 527 },
{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 541 },
{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 558 },
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 580 },
{ PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 597 },
{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 352 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 379 },
{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 478 },
{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 495 },
{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 508 },
{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 525 },
{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 539 },
{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 556 },
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 578 },
{ PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "w:\\4ed\\code\\4coder_jump_sticky.cpp", 34, 595 },
{ PROC_LINKS(view_jump_list_with_lister, 0), "view_jump_list_with_lister", 26, "When executed on a buffer with jumps, creates a persistent lister for all the jumps", 83, "w:\\4ed\\code\\4coder_jump_lister.cpp", 34, 104 },
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 19 },
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "w:\\4ed\\code\\4coder_clipboard.cpp", 32, 28 },
@ -448,17 +448,17 @@ static Command_Metadata fcoder_metacmd_table[237] = {
{ PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 163 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 178 },
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "w:\\4ed\\code\\4coder_build_commands.cpp", 37, 184 },
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 928 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 934 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 940 },
{ PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 948 },
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 955 },
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 978 },
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1313 },
{ PROC_LINKS(setup_build_bat, 0), "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1320 },
{ PROC_LINKS(setup_build_sh, 0), "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1326 },
{ PROC_LINKS(setup_build_bat_and_sh, 0), "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1332 },
{ PROC_LINKS(project_command_lister, 0), "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1347 },
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 921 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 927 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 933 },
{ PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 941 },
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 948 },
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 971 },
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1306 },
{ PROC_LINKS(setup_build_bat, 0), "setup_build_bat", 15, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1313 },
{ PROC_LINKS(setup_build_sh, 0), "setup_build_sh", 14, "Queries the user for several configuration options and initializes a new build shell script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1319 },
{ PROC_LINKS(setup_build_bat_and_sh, 0), "setup_build_bat_and_sh", 22, "Queries the user for several configuration options and initializes a new build batch script.", 92, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1325 },
{ PROC_LINKS(project_command_lister, 0), "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "w:\\4ed\\code\\4coder_project_commands.cpp", 39, 1340 },
{ PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 266 },
{ PROC_LINKS(list_all_functions_current_buffer_lister, 0), "list_all_functions_current_buffer_lister", 40, "Creates a lister of locations that look like function definitions and declarations in the buffer.", 97, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 276 },
{ PROC_LINKS(list_all_functions_all_buffers, 0), "list_all_functions_all_buffers", 30, "Creates a jump list of lines from all buffers that appear to define or declare functions.", 89, "w:\\4ed\\code\\4coder_function_list.cpp", 36, 288 },

View File

@ -106,8 +106,6 @@ init_marker_list(Application_Links *app, Heap *heap, Buffer_ID buffer, Marker_Li
Arena *scratch = context_get_arena(app);
Temp_Memory temp = begin_temp(scratch);
String_Const_u8 buffer_name = push_buffer_base_name(app, scratch, buffer);
Sticky_Jump_Array jumps = parse_buffer_to_jump_array(app, scratch, buffer);
Range_Array buffer_ranges = get_ranges_of_duplicate_keys(scratch, &jumps.jumps->jump_buffer_id, sizeof(*jumps.jumps), jumps.count);
Sort_Pair_i32 *range_index_buffer_id_pairs = push_array(scratch, Sort_Pair_i32, buffer_ranges.count);

View File

@ -526,6 +526,8 @@ generate_all_buffers_list(Application_Links *app, Lister *lister){
static void
generate_hot_directory_file_list(Application_Links *app, Lister *lister){
Scratch_Block scratch(app);
Temp_Memory temp = begin_temp(&lister->arena);
String_Const_u8 hot = push_hot_directory(app, &lister->arena);
if (!character_is_slash(string_get_character(hot, hot.size - 1))){
@ -534,11 +536,10 @@ generate_hot_directory_file_list(Application_Links *app, Lister *lister){
lister_set_text_field(lister, hot);
lister_set_key(lister, string_front_of_path(hot));
File_List file_list = {};
get_file_list(app, hot, &file_list);
File_List file_list = get_file_list(app, scratch, hot);
end_temp(temp);
File_Info *one_past_last = file_list.infos + file_list.count;
File_Info **one_past_last = file_list.infos + file_list.count;
lister_begin_new_item_set(app, lister);
@ -547,31 +548,30 @@ generate_hot_directory_file_list(Application_Links *app, Lister *lister){
if (hot.str != 0){
String_Const_u8 empty_string = string_u8_litexpr("");
Lister_Prealloced_String empty_string_prealloced = lister_prealloced(empty_string);
for (File_Info *info = file_list.infos;
for (File_Info **info = file_list.infos;
info < one_past_last;
info += 1){
if (!info->folder) continue;
String_Const_u8 file_name = push_u8_stringf(&lister->arena, "%.*s/", info->filename_len, info->filename);
if (!HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)) continue;
String_Const_u8 file_name = push_u8_stringf(&lister->arena, "%.*s/",
string_expand((**info).file_name));
lister_add_item(lister, lister_prealloced(file_name), empty_string_prealloced, file_name.str, 0);
}
for (File_Info *info = file_list.infos;
for (File_Info **info = file_list.infos;
info < one_past_last;
info += 1){
if (info->folder) continue;
String_Const_u8 file_name = push_string_copy(&lister->arena, SCu8(info->filename, info->filename_len));
if (HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)) continue;
String_Const_u8 file_name = push_string_copy(&lister->arena, (**info).file_name);
char *is_loaded = "";
char *status_flag = "";
Buffer_ID buffer = {};
{
Temp_Memory path_temp = begin_temp(&lister->arena);
List_String_Const_u8 list = {};
string_list_push(&lister->arena, &list, hot);
string_list_push_overlap(&lister->arena, &list, '/',
SCu8(info->filename, info->filename_len));
string_list_push_overlap(&lister->arena, &list, '/', (**info).file_name);
String_Const_u8 full_file_path = string_list_flatten(&lister->arena, list);
buffer = get_buffer_by_file_name(app, full_file_path, AccessAll);
end_temp(path_temp);
@ -590,8 +590,6 @@ generate_hot_directory_file_list(Application_Links *app, Lister *lister){
lister_add_item(lister, lister_prealloced(file_name), lister_prealloced(status), file_name.str, 0);
}
}
free_file_list(app, file_list);
}
static void

View File

@ -91,20 +91,15 @@ open_all_files_in_directory_pattern_match__recursive(Application_Links *app,
Project_File_Pattern_Array blacklist,
u32 flags){
Scratch_Block scratch(app);
File_List list = {};
get_file_list(app, path, &list);
File_List list = get_file_list(app, scratch, path);
File_Info *info = list.infos;
File_Info **info = list.infos;
for (u32 i = 0; i < list.count; ++i, ++info){
String_Const_u8 file_name = SCu8(info->filename, info->filename_len);
String_Const_u8 file_name = (**info).file_name;
if (info->folder){
if ((flags & OpenAllFilesFlag_Recursive) == 0){
continue;
}
if (match_in_pattern_array(file_name, blacklist)){
continue;
}
if (HasFlag((**info).attributes.flags, FileAttribute_IsDirectory)){
if ((flags & OpenAllFilesFlag_Recursive) == 0) continue;
if (match_in_pattern_array(file_name, blacklist)) continue;
String_Const_u8 new_path = push_u8_stringf(scratch, "%.*s%.*s/",
string_expand(path),
@ -126,8 +121,6 @@ open_all_files_in_directory_pattern_match__recursive(Application_Links *app,
create_buffer(app, full_path, 0);
}
}
free_file_list(app, list);
}
static Project_File_Pattern_Array

View File

@ -981,7 +981,7 @@ App_Init_Sig(app_init){
}
// NOTE(allen): miscellaneous init
hot_directory_init(&models->hot_directory, current_directory);
hot_directory_init(system, arena, &models->hot_directory, current_directory);
child_process_container_init(&models->child_processes, models);
models->user_up_key = key_up;
models->user_down_key = key_down;
@ -1028,7 +1028,7 @@ App_Step_Sig(app_step){
for (;system->get_file_change(buffer, buffer_size, &mem_too_small, &size);){
Assert(!mem_too_small);
Editing_File_Name canon = {};
if (get_canon_name(system, SCu8(buffer, size), &canon)){
if (get_canon_name(system, scratch, SCu8(buffer, size), &canon)){
Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon));
if (file != 0){
if (file->state.ignore_behind_os == 0){

View File

@ -304,7 +304,8 @@ DOC_SEE(Access_Flag)
System_Functions *system = models->system;
Editing_File_Name canon = {};
Buffer_ID result = false;
if (get_canon_name(system, file_name, &canon)){
Scratch_Block scratch(app);
if (get_canon_name(system, scratch, file_name, &canon)){
Working_Set *working_set = &models->working_set;
Editing_File *file = working_set_contains_canon(working_set, string_from_file_name(&canon));
if (api_check_buffer(file, access)){
@ -3147,8 +3148,7 @@ DOC_SEE(directory_set_hot)
Models *models = (Models*)app->cmd_context;
Hot_Directory *hot = &models->hot_directory;
hot_directory_clean_end(hot);
String_Const_u8 result = push_string_copy(arena, SCu8(hot->string_space, hot->string_size));
return(result);
return(push_string_copy(arena, hot->string));
}
// TODO(allen): redocument
@ -3163,56 +3163,16 @@ DOC_SEE(directory_get_hot)
*/{
Models *models = (Models*)app->cmd_context;
Hot_Directory *hot = &models->hot_directory;
b32 success = false;
if (string.size < sizeof(hot->string_space)){
hot_directory_set(models->system, hot, string);
success = true;
}
return(success);
return(true);
}
// TODO(allen): redocument
API_EXPORT b32
Get_File_List(Application_Links *app, String_Const_u8 directory, File_List *list_out)
/*
DOC_PARAM(dir, This parameter specifies the directory whose files will be enumerated in the returned list; it need not be null terminated.)
DOC_PARAM(len, This parameter the length of the dir string.)
DOC_RETURN(This call returns a File_List struct containing pointers to the names of the files in the specified directory. The File_List returned should be passed to free_file_list when it is no longer in use.)
DOC_SEE(File_List)
*/{
API_EXPORT File_List
Get_File_List(Application_Links *app, Arena *arena, String_Const_u8 directory){
Models *models = (Models*)app->cmd_context;
System_Functions *system = models->system;
block_zero_struct(list_out);
Editing_File_Name canon = {};
b32 result = false;
if (get_canon_name(system, directory, &canon)){
Arena *scratch = &models->mem.arena;
Temp_Memory temp = begin_temp(scratch);
char *str = 0;
if (canon.name_size < sizeof(canon.name_space)){
canon.name_space[canon.name_size] = 0;
str = (char*)canon.name_space;
}
else{
String_Const_u8 s = push_string_copy(scratch, string_from_file_name(&canon));
str = (char*)s.str;
}
system->set_file_list(list_out, str, 0, 0, 0);
end_temp(temp);
result = true;
}
return(result);
}
API_EXPORT void
Free_File_List(Application_Links *app, File_List list)
/*
DOC_PARAM(list, This parameter provides the file list to be freed.)
DOC(After this call the file list passed in should not be read or written to.)
DOC_SEE(File_List)
*/{
Models *models = (Models*)app->cmd_context;
models->system->set_file_list(&list, 0, 0, 0, 0);
String_Const_u8 canonical_directory = system->get_canonical(arena, directory);
return(system->get_file_list(arena, canonical_directory));
}
API_EXPORT void

View File

@ -531,7 +531,7 @@ create_file(Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags)
// NOTE(allen): Try to get the file by canon name.
if (HasFlag(flags, BufferCreate_NeverAttachToFile) == 0){
if (get_canon_name(system, file_name, &canon)){
if (get_canon_name(system, scratch, file_name, &canon)){
has_canon_name = true;
file = working_set_contains_canon(working_set, string_from_file_name(&canon));
}

View File

@ -138,6 +138,7 @@ file_name_terminate(Editing_File_Name *name){
////////////////////////////////
// TODO(allen): file_name should be String_Const_u8
internal b32
save_file_to_name(System_Functions *system, Models *models, Editing_File *file, u8 *file_name){
b32 result = false;
@ -188,10 +189,9 @@ save_file_to_name(System_Functions *system, Models *models, Editing_File *file,
}
if (!using_actual_file_name){
char space[512];
umem length = cstring_length(file_name);
system->get_canonical((char*)file_name, (u32)length, space, sizeof(space));
if (string_match(SCu8(space), string_from_file_name(&file->canon))){
String_Const_u8 s_file_name = SCu8(file_name);
String_Const_u8 canonical_file_name = system->get_canonical(scratch, s_file_name);
if (string_match(canonical_file_name, string_from_file_name(&file->canon))){
using_actual_file_name = true;
}
}

View File

@ -11,34 +11,34 @@
internal void
hot_directory_clean_end(Hot_Directory *hot_directory){
String_Const_u8 str = SCu8(hot_directory->string_space, hot_directory->string_size);
String_Const_u8 str = hot_directory->string;
if (!character_is_slash(string_get_character(str, str.size - 1))){
str = string_remove_last_folder(str);
str.str[str.size] = 0;
hot_directory->string = string_remove_last_folder(str);
}
}
internal i32
hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){
File_Info *p = infos + pivot;
File_Info *a = infos + start;
hot_directory_quick_partition(File_Info **infos, i32 start, i32 pivot){
File_Info **p = infos + pivot;
File_Info **a = infos + start;
for (i32 i = start; i < pivot; ++i, ++a){
i32 comp = p->folder - a->folder;
b32 p_folder = (HasFlag((**p).attributes.flags, FileAttribute_IsDirectory));
b32 a_folder = (HasFlag((**a).attributes.flags, FileAttribute_IsDirectory));
i32 comp = p_folder - a_folder;
if (comp == 0){
comp = string_compare(SCu8(a->filename, a->filename_len),
SCu8(p->filename, p->filename_len));
comp = string_compare((**a).file_name, (**p).file_name);
}
if (comp < 0){
Swap(File_Info, *a, infos[start]);
Swap(File_Info*, *a, infos[start]);
++start;
}
}
Swap(File_Info, *p, infos[start]);
return start;
Swap(File_Info*, *p, infos[start]);
return(start);
}
internal void
hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){
hot_directory_quick_sort(File_Info **infos, i32 start, i32 pivot){
i32 mid = hot_directory_quick_partition(infos, start, pivot);
if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1);
if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot);
@ -54,55 +54,30 @@ hot_directory_fixup(Hot_Directory *hot_directory){
internal void
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String_Const_u8 str){
b32 success = (str.size < sizeof(hot_directory->string_space));
if (success){
block_copy(hot_directory->string_space, str.str, str.size);
hot_directory->string_space[str.size] = 0;
hot_directory->string_size = str.size;
if (str.size > 0){
u32 canon_max = sizeof(hot_directory->canon_dir_space);
u8 *canon_str = hot_directory->canon_dir_space;
u32 canon_length = 0;
system->set_file_list(&hot_directory->file_list, (char*)hot_directory->string_space, (char*)canon_str, &canon_length, canon_max);
if (canon_length > 0){
hot_directory->canon_dir_size = canon_length;
if (!character_is_slash(hot_directory->canon_dir_space[canon_length - 1])){
hot_directory->canon_dir_space[hot_directory->canon_dir_size] = '/';
hot_directory->canon_dir_size += 1;
hot_directory->canon_dir_space[hot_directory->canon_dir_size] = 0;
}
}
else{
hot_directory->canon_dir_size = 0;
}
}
else{
system->set_file_list(&hot_directory->file_list, 0, 0, 0, 0);
hot_directory->canon_dir_size = 0;
}
}
hot_directory_fixup(hot_directory);
linalloc_clear(&hot_directory->arena);
hot_directory->string = push_string_copy(&hot_directory->arena, str);
hot_directory->canonical = system->get_canonical(&hot_directory->arena, str);
hot_directory->file_list = system->get_file_list(&hot_directory->arena, hot_directory->canonical);
}
internal void
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){
String_Const_u8 string = SCu8(hot_directory->string_space, hot_directory->string_size);
hot_directory_reload(System_Functions *system, Arena *scratch, Hot_Directory *hot_directory){
Temp_Memory temp = begin_temp(scratch);
String_Const_u8 string = push_string_copy(scratch, hot_directory->string);
hot_directory_set(system, hot_directory, string);
end_temp(temp);
}
internal void
hot_directory_init(Hot_Directory *hot_directory, String_Const_u8 dir){
hot_directory->string_size = 0;
umem size = clamp_top(dir.size, sizeof(hot_directory->string_space));
block_copy(hot_directory->string_space, dir.str, size);
if (dir.size < sizeof(hot_directory->string_space)){
if (hot_directory->string_space[size - 1] != '/'){
hot_directory->string_space[size] = '/';
size = clamp_top(size + 1, sizeof(hot_directory->string_space));
hot_directory->string_space[size] = 0;
hot_directory->string_size = size;
}
hot_directory_init(System_Functions *system, Arena *scratch, Hot_Directory *hot_directory, String_Const_u8 directory){
hot_directory->arena = make_arena_system(system);
Temp_Memory temp = begin_temp(scratch);
String_Const_u8 dir = directory;
if (!character_is_slash(string_get_character(directory, directory.size - 1))){
dir = push_u8_stringf(scratch, "%.*s/", string_expand(directory));
}
hot_directory_set(system, hot_directory, dir);
end_temp(temp);
}
// BOTTOM

View File

@ -13,10 +13,9 @@
#define FRED_HOT_DIRECTORY_H
struct Hot_Directory{
u8 string_space[256];
umem string_size;
u8 canon_dir_space[256];
umem canon_dir_size;
Arena arena;
String_Const_u8 string;
String_Const_u8 canonical;
File_List file_list;
};

View File

@ -19,19 +19,13 @@ struct Plat_Handle{
u32 d[4];
};
internal b32
handle_equal(Plat_Handle a, Plat_Handle b){
b32 result = (memcmp(&a, &b, sizeof(a)) == 0);
return(result);
}
// files
#define Sys_Set_File_List_Sig(name) void name(File_List *file_list, char *directory, char *canon_directory_out, u32 *canon_directory_size_out, u32 canon_directory_max)
typedef Sys_Set_File_List_Sig(System_Set_File_List);
#define Sys_Get_Canonical_Sig(name) u32 name(char *filename, u32 len, char *buffer, u32 max)
#define Sys_Get_Canonical_Sig(n) String_Const_u8 n(Arena *arena, String_Const_u8 name)
typedef Sys_Get_Canonical_Sig(System_Get_Canonical);
#define Sys_Get_File_List_Sig(name) File_List name(Arena *arena, String_Const_u8 directory)
typedef Sys_Get_File_List_Sig(System_Get_File_List);
// file load/save
#define Sys_Quick_File_Attributes_Sig(name) File_Attributes name(String_Const_u8 file_name)
typedef Sys_Quick_File_Attributes_Sig(System_Quick_File_Attributes);
@ -230,8 +224,8 @@ struct System_Functions{
Graphics_Fill_Texture_Function *fill_texture;
// files (tracked api): 11
System_Set_File_List *set_file_list;
System_Get_Canonical *get_canonical;
System_Get_File_List *get_file_list;
System_Add_Listener *add_listener;
System_Remove_Listener *remove_listener;
System_Get_File_Change *get_file_change;

View File

@ -285,10 +285,15 @@ working_set_clipboard_roll_down(Working_Set *working){
////////////////////////////////
// TODO(allen): get rid of this???
internal b32
get_canon_name(System_Functions *system, String_Const_u8 file_name, Editing_File_Name *canon_name){
canon_name->name_size = system->get_canonical((char*)file_name.str, (u32)file_name.size,
(char*)canon_name->name_space, sizeof(canon_name->name_space));
get_canon_name(System_Functions *system, Arena *scratch, String_Const_u8 file_name, Editing_File_Name *canon_name){
Temp_Memory temp = begin_temp(scratch);
String_Const_u8 canonical = system->get_canonical(scratch, file_name);
umem size = Min(sizeof(canon_name->name_space), canonical.size);
block_copy(canon_name->name_space, canonical.str, size);
canon_name->name_size = size;
end_temp(temp);
file_name_terminate(canon_name);
return(canon_name->name_size > 0);
}

View File

@ -15,8 +15,8 @@
internal void
link_system_code(){
SYSLINK(set_file_list);
SYSLINK(get_canonical);
SYSLINK(get_file_list);
SYSLINK(add_listener);
SYSLINK(remove_listener);
SYSLINK(get_file_change);

View File

@ -118,205 +118,63 @@ win32_remove_unc_prefix_characters(String_Const_u8 path){
return(path);
}
internal
Sys_Set_File_List_Sig(system_set_file_list){
b32 clear_list = true;
if (directory != 0){
u8 dir_space[MAX_PATH + 32];
umem directory_original_length = cstring_length(directory);
block_copy(dir_space, directory, directory_original_length);
dir_space[directory_original_length] = 0;
String_Const_u8 dir = SCu8(dir_space, directory_original_length);
HANDLE dir_handle = CreateFile_utf8(&shared_vars.scratch, dir.str, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
if (dir_handle != INVALID_HANDLE_VALUE){
DWORD final_length = GetFinalPathNameByHandle_utf8(&shared_vars.scratch, dir_handle, dir_space, sizeof(dir_space), 0);
CloseHandle(dir_handle);
if (final_length + 3 < sizeof(dir_space)){
u8 *c_str_dir = dir_space;
if (c_str_dir[final_length - 1] == 0){
--final_length;
}
String_Const_u8 str_dir = SCu8(c_str_dir, final_length);
String_Const_u8 adjusted_str_dir = win32_remove_unc_prefix_characters(str_dir);
c_str_dir = adjusted_str_dir.str;
final_length = (DWORD)(adjusted_str_dir.size);
c_str_dir[final_length] = '\\';
c_str_dir[final_length + 1] = '*';
c_str_dir[final_length + 2] = 0;
if (canon_directory_out != 0){
if (final_length + 1 < canon_directory_max){
memcpy(canon_directory_out, c_str_dir, final_length);
if (canon_directory_out[final_length-1] != '\\'){
canon_directory_out[final_length++] = '\\';
}
canon_directory_out[final_length] = 0;
*canon_directory_size_out = final_length;
}
else{
block_copy(canon_directory_out, directory, directory_original_length);
canon_directory_out[directory_original_length] = 0;
*canon_directory_size_out = (i32)directory_original_length;
}
}
WIN32_FIND_DATA find_data;
HANDLE search = FindFirstFile_utf8(&shared_vars.scratch, c_str_dir, &find_data);
if (search != INVALID_HANDLE_VALUE){
u32 character_count = 0;
u32 file_count = 0;
BOOL more_files = true;
do{
b32 nav_dir =
(find_data.cFileName[0] == '.' && find_data.cFileName[1] == 0) ||(find_data.cFileName[0] == '.' && find_data.cFileName[1] == '.' && find_data.cFileName[2] == 0);
if (!nav_dir){
++file_count;
u32 size = 0;
for(;find_data.cFileName[size];++size);
character_count += size + 1;
}
more_files = FindNextFile(search, &find_data);
}while(more_files);
FindClose(search);
u32 remaining_size = character_count*2;
u32 required_size = remaining_size + file_count*sizeof(File_Info);
if (file_list->block_size < required_size){
system_memory_free(file_list->block, 0);
file_list->block = system_memory_allocate(required_size);
file_list->block_size = required_size;
}
file_list->infos = (File_Info*)file_list->block;
u8 *name = (u8*)(file_list->infos + file_count);
u32 corrected_file_count = 0;
if (file_list->block != 0){
search = FindFirstFile_utf8(&shared_vars.scratch, c_str_dir, &find_data);
if (search != INVALID_HANDLE_VALUE){
File_Info *info = file_list->infos;
more_files = true;
do{
b32 nav_dir =
(find_data.cFileName[0] == '.' && find_data.cFileName[1] == 0) ||(find_data.cFileName[0] == '.' && find_data.cFileName[1] == '.' && find_data.cFileName[2] == 0);
if (!nav_dir){
u32 attribs = find_data.dwFileAttributes;
info->folder = (attribs & FILE_ATTRIBUTE_DIRECTORY) != 0;
info->filename = (char*)name;
u16 *src = (u16*)find_data.cFileName;
u32 src_len = 0;
for (;src[src_len];++src_len);
u8 *dst = name;
u32 max = remaining_size-1;
b32 error = false;
u32 length = (u32)utf16_to_utf8_minimal_checking(dst, max, src, src_len, &error);
if (length <= max && !error){
name += length;
info->filename_len = length;
*name++ = 0;
String_Const_u8 fname = SCu8(info->filename, length);
fname = string_mod_replace_character(fname, '\\', '/');
++info;
++corrected_file_count;
}
}
more_files = FindNextFile(search, &find_data);
}while(more_files);
FindClose(search);
file_list->count = corrected_file_count;
clear_list = false;
}
}
}
}
}
}
if (clear_list){
system_memory_free(file_list->block, 0);
file_list->block = 0;
file_list->block_size = 0;
file_list->infos = 0;
file_list->count = 0;
}
}
internal
Sys_Get_Canonical_Sig(system_get_canonical){
u32 result = 0;
String_Const_u8 result = {};
Arena *scratch = &shared_vars.scratch;
Temp_Memory temp = begin_temp(scratch);
if ((character_is_alpha(string_get_character(name, 0)) &&
string_get_character(name, 1) == ':') ||
string_match(string_prefix(name, 2), string_u8_litexpr("\\\\"))){
String_Const_char file_name = SCchar(filename, len);
char src_space[MAX_PATH + 32];
if (len < sizeof(src_space) &&
((character_is_alpha(string_get_character(file_name, 0)) && string_get_character(file_name, 1) == ':') ||
string_match(string_prefix(file_name, 2), string_litexpr("\\\\")))){
memcpy(src_space, filename, len);
src_space[len] = 0;
HANDLE file = CreateFile_utf8(&shared_vars.scratch, (u8*)src_space, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
u8 *c_name = push_array(scratch, u8, name.size + 1);
block_copy(c_name, name.str, name.size);
c_name[name.size] = 0;
HANDLE file = CreateFile_utf8(scratch, c_name, GENERIC_READ, 0, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (file != INVALID_HANDLE_VALUE){
DWORD final_length = GetFinalPathNameByHandle_utf8(&shared_vars.scratch, file, (u8*)buffer, max, 0);
if (final_length + 3 < max){
if (buffer[final_length - 1] == 0){
--final_length;
DWORD capacity = GetFinalPathNameByHandle_utf8(scratch, file, 0, 0, 0);
u8 *buffer = push_array(arena, u8, capacity);
DWORD length = GetFinalPathNameByHandle_utf8(scratch, file, buffer, capacity, 0);
if (length > 0 && buffer[length - 1] == 0){
length -= 1;
}
String_Const_u8 str_dir = SCu8(buffer, final_length);
String_Const_u8 adjusted_str_dir = win32_remove_unc_prefix_characters(str_dir);
buffer = (char*)adjusted_str_dir.str;
final_length = (i32)adjusted_str_dir.size;
buffer[final_length] = 0;
result = final_length;
}
result = SCu8(buffer, length);
result = win32_remove_unc_prefix_characters(result);
CloseHandle(file);
}
else{
String_Const_u8 src_str = SCu8(filename, len);
String_Const_u8 path_str = string_remove_front_of_path(src_str);
String_Const_u8 front_str = string_front_of_path(src_str);
String_Const_u8 path = string_remove_front_of_path(name);
String_Const_u8 front = string_front_of_path(name);
memcpy(src_space, path_str.str, path_str.size);
src_space[path_str.size] = 0;
u8 *c_path = push_array(scratch, u8, path.size + 1);
block_copy(c_path, path.str, path.size);
c_path[path.size] = 0;
HANDLE dir = CreateFile_utf8(&shared_vars.scratch, (u8*)src_space, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
HANDLE dir = CreateFile_utf8(scratch, c_path, FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, 0);
if (dir != INVALID_HANDLE_VALUE){
DWORD final_length = GetFinalPathNameByHandle_utf8(&shared_vars.scratch, dir, (u8*)buffer, max, 0);
if (final_length + 3 < max){
if (buffer[final_length-1] == 0){
--final_length;
DWORD capacity = GetFinalPathNameByHandle_utf8(scratch, dir, 0, 0, 0);
u8 *buffer = push_array(arena, u8, capacity + front.size + 1);
DWORD length = GetFinalPathNameByHandle_utf8(scratch, dir, buffer, capacity, 0);
if (length > 0 && buffer[length - 1] == 0){
length -= 1;
}
String_Const_u8 str_dir = SCu8(buffer, final_length);
String_Const_u8 adjusted_str_dir = win32_remove_unc_prefix_characters(str_dir);
buffer = (char*)adjusted_str_dir.str;
final_length = (i32)adjusted_str_dir.size;
buffer[final_length++] = '\\';
memcpy(buffer + final_length, front_str.str, front_str.size);
final_length += (i32)(front_str.size);
buffer[final_length] = 0;
result = final_length;
}
buffer[length] = '\\';
length += 1;
block_copy(buffer + length, front.str, front.size);
length += (DWORD)front.size;
result = SCu8(buffer, length);
result = win32_remove_unc_prefix_characters(result);
CloseHandle(dir);
}
}
}
end_temp(temp);
return(result);
}
@ -327,17 +185,85 @@ win32_convert_file_attribute_flags(DWORD dwFileAttributes){
return(result);
}
internal u64
win32_u64_from_u32_u32(u32 hi, u32 lo){
return( (((u64)hi) << 32) | ((u64)lo) );
}
internal u64
win32_u64_from_filetime(FILETIME time){
return(win32_u64_from_u32_u32(time.dwHighDateTime, time.dwLowDateTime));
}
internal File_Attributes
win32_file_attributes_from_HANDLE(HANDLE file){
BY_HANDLE_FILE_INFORMATION info = {};
GetFileInformationByHandle(file, &info);
File_Attributes result = {};
result.size = ((u64)info.nFileSizeHigh << 32LL) | ((u64)info.nFileSizeLow);
result.last_write_time = ((u64)info.ftLastWriteTime.dwHighDateTime << 32LL) | ((u64)info.ftLastWriteTime.dwLowDateTime);
result.size = win32_u64_from_u32_u32(info.nFileSizeHigh, info.nFileSizeLow);
result.last_write_time = win32_u64_from_filetime(info.ftLastWriteTime);
result.flags = win32_convert_file_attribute_flags(info.dwFileAttributes);
return(result);
}
internal
Sys_Get_File_List_Sig(system_get_file_list){
File_List result = {};
Arena *scratch = &shared_vars.scratch;
Temp_Memory temp = begin_temp(scratch);
String_Const_u8 search_pattern = {};
if (character_is_slash(string_get_character(directory, directory.size - 1))){
search_pattern = push_u8_stringf(scratch, "%.*s*", string_expand(directory));
}
else{
search_pattern = push_u8_stringf(scratch, "%.*s\\*", string_expand(directory));
}
WIN32_FIND_DATA find_data = {};
HANDLE search = FindFirstFile_utf8(&shared_vars.scratch, search_pattern.str, &find_data);
if (search != INVALID_HANDLE_VALUE){
File_Info *first = 0;
File_Info *last = 0;
i32 count = 0;
for (;;){
String_Const_u16 file_name_utf16 = SCu16(find_data.cFileName);
if (!(string_match(file_name_utf16, string_u16_litexpr(L".")) ||
string_match(file_name_utf16, string_u16_litexpr(L"..")))){
String_Const_u8 file_name = string_u8_from_string_u16(arena, file_name_utf16,
StringFill_NullTerminate).string;
File_Info *info = push_array(arena, File_Info, 1);
sll_queue_push(first, last, info);
count += 1;
info->file_name = file_name;
info->attributes.size = win32_u64_from_u32_u32(find_data.nFileSizeHigh,
find_data.nFileSizeLow);
info->attributes.last_write_time = win32_u64_from_filetime(find_data.ftLastWriteTime);
info->attributes.flags = win32_convert_file_attribute_flags(find_data.dwFileAttributes);
}
if (!FindNextFile(search, &find_data)){
break;
}
}
result.infos = push_array(arena, File_Info*, count);
result.count = count;
i32 counter = 0;
for (File_Info *node = first;
node != 0;
node = node->next){
result.infos[counter] = node;
counter += 1;
}
}
end_temp(temp);
return(result);
}
internal
Sys_Quick_File_Attributes_Sig(system_quick_file_attributes){
WIN32_FILE_ATTRIBUTE_DATA info = {};

View File

@ -48,3 +48,8 @@ set_global_face_by_name -> set_buffer_face_by_font_load_location (with id = 0)
mark_enclosures -> draw_enclosures
all *marker_visuals* -> immediate mode rendering
get_file_list
free_file_list
File_Info
File_List