diff --git a/4ed.cpp b/4ed.cpp index 0f72ea73..6c4d47d5 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -338,46 +338,50 @@ COMMAND_DECL(reopen){ if (match(file->name.source_path, file->name.live_name)) return; - Unique_Hash index = file->file_index; - - if (!uhash_equal(index, uhash_zero())){ - i32 size = system->file_size(index); - - Partition *part = &models->mem.part; - Temp_Memory temp = begin_temp_memory(part); - char *buffer = push_array(part, char, size); - - if (buffer){ - if (system->load_file(index, buffer, size)){ - General_Memory *general = &models->mem.general; - - File_Edit_Positions edit_poss[16]; - View *vptrs[16]; - i32 vptr_count = 0; - for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); - file_view_iter_good(iter); - iter = file_view_iter_next(iter)){ - vptrs[vptr_count] = iter.view; - edit_poss[vptr_count] = *iter.view->edit_pos; - iter.view->edit_pos = 0; - ++vptr_count; - } - - file_close(system, general, file); - init_normal_file(system, models, file, buffer, size); - - for (i32 i = 0; - i < vptr_count; - ++i){ - view_set_file(vptrs[i], file, models); - *vptrs[i]->edit_pos = edit_poss[i]; - view_set_cursor(vptrs[i], edit_poss[i].cursor, - true, view->file_data.unwrapped_lines); + if (file->canon.name.size != 0){ + Plat_Handle handle; + if (system->load_handle(file->canon.name.str, &handle)){ + + i32 size = system->load_size(handle); + + Partition *part = &models->mem.part; + Temp_Memory temp = begin_temp_memory(part); + char *buffer = push_array(part, char, size); + + if (buffer){ + if (system->load_file(handle, buffer, size)){ + General_Memory *general = &models->mem.general; + + File_Edit_Positions edit_poss[16]; + View *vptrs[16]; + i32 vptr_count = 0; + for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ + vptrs[vptr_count] = iter.view; + edit_poss[vptr_count] = *iter.view->edit_pos; + iter.view->edit_pos = 0; + ++vptr_count; + } + + file_close(system, general, file); + init_normal_file(system, models, file, buffer, size); + + for (i32 i = 0; + i < vptr_count; + ++i){ + view_set_file(vptrs[i], file, models); + *vptrs[i]->edit_pos = edit_poss[i]; + view_set_cursor(vptrs[i], edit_poss[i].cursor, + true, view->file_data.unwrapped_lines); + } } } + + end_temp_memory(temp); + + system->load_close(handle); } - - end_temp_memory(temp); } } @@ -1939,7 +1943,7 @@ App_Step_Sig(app_step){ { Editing_File *file = working_set_alloc_always(&models->working_set, general); - buffer_bind_name(general, &models->working_set, file, "*messages*"); + buffer_bind_name(general, &models->working_set, file, make_lit_string("*messages*")); init_read_only_file(system, models, file); file->settings.never_kill = 1; file->settings.unimportant = 1; @@ -1950,7 +1954,7 @@ App_Step_Sig(app_step){ { Editing_File *file = working_set_alloc_always(&models->working_set, general); - buffer_bind_name(general, &models->working_set, file, "*scratch*"); + buffer_bind_name(general, &models->working_set, file, make_lit_string("*scratch*")); init_normal_file(system, models, file, 0, 0); file->settings.never_kill = 1; file->settings.unimportant = 1; diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 599e83f5..8e1a8435 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -247,7 +247,7 @@ DOC_SEE(Command_Line_Input_Flag) } String name = make_string_terminated(part, buffer.name, buffer.name_len); - buffer_bind_name(general, working_set, file, name.str); + buffer_bind_name(general, working_set, file, name); init_read_only_file(system, models, file); } @@ -982,67 +982,71 @@ DOC_SEE(Buffer_Create_Flag) Buffer_Summary result = {0}; + String fname = make_string(filename, filename_len); + Temp_Memory temp = begin_temp_memory(part); if (filename != 0){ - String filename_string = make_string_terminated(part, filename, filename_len); - Editing_File *file = working_set_uhash_contains(system, working_set, filename_string.str); + Editing_File_Canon_Name canon; - if (file == 0){ - b32 do_new_file = false; + if (get_canon_name(system, &canon, fname)){ + Editing_File *file = working_set_canon_contains(working_set, canon.name); - Unique_Hash index = {0}; - - if (flags & BufferCreate_AlwaysNew){ - do_new_file = true; - } - else{ - index = system->track_file(filename_string.str, TrackFileFlag_ExistingOrFail); - if (uhash_equal(index, uhash_zero())){ + if (file == 0){ + b32 do_new_file = false; + + Plat_Handle handle = {0}; + + if (flags & BufferCreate_AlwaysNew){ do_new_file = true; } - } - - if (!do_new_file){ - Assert(!uhash_equal(index, uhash_zero())); - - i32 size = system->file_size(index); - b32 in_general_mem = false; - char *buffer = push_array(part, char, size); - - if (buffer == 0){ - buffer = (char*)general_memory_allocate(general, size); - if (buffer != 0){ - in_general_mem = true; + else{ + if (!system->load_handle(canon.name.str, &handle)){ + do_new_file = true; } } - if (system->load_file(index, buffer, size)){ + if (!do_new_file){ + Assert(!handle_equal(handle, handle_zero())); + + i32 size = system->load_size(handle); + b32 in_general_mem = false; + char *buffer = push_array(part, char, size); + + if (buffer == 0){ + buffer = (char*)general_memory_allocate(general, size); + Assert(buffer != 0); + in_general_mem = true; + } + + if (system->load_file(handle, buffer, size)){ + file = working_set_alloc_always(working_set, general); + if (file){ + buffer_bind_file(general, working_set, file, canon.name); + buffer_bind_name(general, working_set, file, fname); + init_normal_file(system, models, file, buffer, size); + fill_buffer_summary(&result, file, cmd); + } + } + + if (in_general_mem){ + general_memory_free(general, buffer); + } + + system->load_close(handle); + } + else{ file = working_set_alloc_always(working_set, general); if (file){ - buffer_bind_file(system, general, working_set, file, index); - buffer_bind_name(general, working_set, file, filename_string.str); - init_normal_file(system, models, file, buffer, size); + buffer_bind_name(general, working_set, file, fname); + init_normal_file(system, models, file, 0, 0); fill_buffer_summary(&result, file, cmd); } } - - if (in_general_mem){ - general_memory_free(general, buffer); - } - } else{ - file = working_set_alloc_always(working_set, general); - if (file){ - buffer_bind_name(general, working_set, file, filename_string.str); - init_normal_file(system, models, file, 0, 0); - fill_buffer_summary(&result, file, cmd); - } + fill_buffer_summary(&result, file, cmd); } } - else{ - fill_buffer_summary(&result, file, cmd); - } } end_temp_memory(temp); diff --git a/4ed_file.cpp b/4ed_file.cpp index b18db0f3..a1886eaa 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -144,7 +144,6 @@ struct Editing_File_State{ Text_Effect paste_effect; File_Sync_State sync; - u64 last_sync; File_Edit_Positions edit_pos_space[16]; File_Edit_Positions *edit_poss[16]; @@ -160,6 +159,11 @@ struct Editing_File_Name{ String extension; }; +struct Editing_File_Canon_Name{ + char name_[256]; + String name; +}; + struct File_Node{ File_Node *next, *prev; }; @@ -186,9 +190,9 @@ struct Editing_File{ Editing_File_State state; }; Editing_File_Name name; + Editing_File_Canon_Name canon; Buffer_Slot_ID id; u64 unique_buffer_id; - Unique_Hash file_index; }; struct Non_File_Table_Entry{ @@ -209,7 +213,7 @@ struct Working_Set{ File_Node free_sentinel; File_Node used_sentinel; - Table uhash_table; + Table canon_table; Table name_table; String clipboards[64]; @@ -348,35 +352,11 @@ edit_pos_get_new(Editing_File *file, i32 index){ // Working_Set stuff // -struct File_Uhash_Entry{ - Unique_Hash hash; - Buffer_Slot_ID id; -}; - struct File_Name_Entry{ String name; Buffer_Slot_ID id; }; -internal u32 -tbl_uhash_hash(void *item, void *arg){ - Unique_Hash *hash = (Unique_Hash*)item; - return(hash->d[0] ^ (hash->d[1] << 24)); -} - -internal i32 -tbl_uhash_compare(void *a, void *b, void *arg){ - Unique_Hash *fa = (Unique_Hash*)a; - File_Uhash_Entry *fb = (File_Uhash_Entry*)b; - - i32 result = 1; - if (uhash_equal(fb->hash, *fa)){ - result = 0; - } - - return(result); -} - internal i32 tbl_name_compare(void *a, void *b, void *arg){ String *fa = (String*)a; @@ -537,14 +517,14 @@ working_set_init(Working_Set *working_set, Partition *partition, General_Memory ++working_set->file_count; } - // NOTE(allen): init uhash table + // NOTE(allen): init canon table { - i32 item_size = sizeof(File_Uhash_Entry); + i32 item_size = sizeof(File_Name_Entry); i32 table_size = working_set->file_max; i32 mem_size = table_required_mem_size(table_size, item_size); void *mem = general_memory_allocate(general, mem_size); memset(mem, 0, mem_size); - table_init_memory(&working_set->uhash_table, mem, table_size, item_size); + table_init_memory(&working_set->canon_table, mem, table_size, item_size); } // NOTE(allen): init name table @@ -574,53 +554,11 @@ working_set__grow_if_needed(Table *table, General_Memory *general, void *arg, Ha } internal Editing_File* -working_set_uhash_contains(Working_Set *working_set, Unique_Hash index){ - Editing_File *result = 0; - - File_Uhash_Entry *entry = (File_Uhash_Entry*) - table_find_item(&working_set->uhash_table, &index, 0, tbl_uhash_hash, tbl_uhash_compare); - if (entry){ - result = working_set_index(working_set, entry->id); - } - - return(result); -} - -internal Editing_File* -working_set_uhash_contains(System_Functions *system, Working_Set *working_set, char *name){ - Editing_File *file = 0; - Unique_Hash index = {0}; - if (system->get_file_index(name, &index)){ - if (!uhash_equal(index, uhash_zero())){ - file = working_set_uhash_contains(working_set, index); - } - } - return(file); -} - -internal void -working_set_uhash_add(General_Memory *general, Working_Set *working_set, - Editing_File *file, Unique_Hash hash){ - working_set__grow_if_needed(&working_set->uhash_table, general, - 0, tbl_uhash_hash, tbl_uhash_compare); - - File_Uhash_Entry entry; - entry.hash = hash; - entry.id = file->id; - table_add(&working_set->uhash_table, &entry, 0, tbl_uhash_hash, tbl_uhash_compare); -} - -internal void -working_set_uhash_remove(Working_Set *working_set, Unique_Hash hash){ - table_remove_match(&working_set->uhash_table, &hash, 0, tbl_uhash_hash, tbl_uhash_compare); -} - -internal Editing_File* -working_set_name_contains(Working_Set *working_set, String name){ +working_set_contains_basic(Working_Set *working_set, Table *table, String name){ Editing_File *result = 0; File_Name_Entry *entry = (File_Name_Entry*) - table_find_item(&working_set->name_table, &name, 0, tbl_string_hash, tbl_string_compare); + table_find_item(table, &name, 0, tbl_string_hash, tbl_string_compare); if (entry){ result = working_set_index(working_set, entry->id); } @@ -628,71 +566,63 @@ working_set_name_contains(Working_Set *working_set, String name){ return(result); } -internal void -working_set_name_add(General_Memory *general, Working_Set *working_set, - Editing_File *file, String name){ - working_set__grow_if_needed(&working_set->name_table, general, +internal b32 +working_set_add_basic(General_Memory *general, Working_Set *working_set, Table *table, + Editing_File *file, String name){ + working_set__grow_if_needed(table, general, 0, tbl_string_hash, tbl_string_compare); File_Name_Entry entry; entry.name = name; entry.id = file->id; - table_add(&working_set->name_table, &entry, 0, tbl_string_hash, tbl_string_compare); + b32 result = (table_add(table, &entry, 0, tbl_string_hash, tbl_string_compare) == 0); + return(result); +} + +internal void +working_set_remove_basic(Working_Set *working_set, Table *table, String name){ + table_remove_match(table, &name, 0, tbl_string_hash, tbl_string_compare); +} + +internal Editing_File* +working_set_canon_contains(Working_Set *working_set, String name){ + Editing_File *result = + working_set_contains_basic(working_set, &working_set->canon_table, name); + return(result); +} + +internal b32 +working_set_canon_add(General_Memory *general, Working_Set *working_set, + Editing_File *file, String name){ + b32 result = working_set_add_basic(general, working_set, &working_set->canon_table, file, name); + return(result); +} + +internal void +working_set_canon_remove(Working_Set *working_set, String name){ + working_set_remove_basic(working_set, &working_set->canon_table, name); +} + +internal Editing_File* +working_set_name_contains(Working_Set *working_set, String name){ + Editing_File *result = + working_set_contains_basic(working_set, &working_set->name_table, name); + return(result); +} + +internal b32 +working_set_name_add(General_Memory *general, Working_Set *working_set, + Editing_File *file, String name){ + b32 result = working_set_add_basic(general, working_set, &working_set->name_table, file, name); + return(result); } internal void working_set_name_remove(Working_Set *working_set, String name){ - table_remove_match(&working_set->name_table, &name, 0, tbl_string_hash, tbl_string_compare); + working_set_remove_basic(working_set, &working_set->name_table, name); } -#if 0 -inline void -working_set__entry_comp(System_Functions *system, String filename, File_Entry_Comparison *out){ - out->entry.long_name = filename; - out->entry.short_name = front_of_directory(filename); - out->hash = system->file_unique_hash(filename, &out->use_hash); -} - -inline Editing_File* -working_set_contains(System_Functions *system, Working_Set *working_set, String filename){ - File_Entry_Comparison entry_comp = {0}; - File_Entry *entry = 0; - Editing_File *result = 0; - working_set__entry_comp(system, filename, &entry_comp); - - entry = (File_Entry*)table_find_item(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare); - if (entry){ - result = working_set_index(working_set, entry->id); - } - - return(result); -} - -inline void -working_set_add(System_Functions *system, Working_Set *working_set, Editing_File *file, General_Memory *general){ - File_Entry_Comparison entry_comp; - working_set__grow_if_needed(&working_set->table, general, system, tbl_string_hash, tbl_file_compare); - working_set__entry_comp(system, file->name.source_path, &entry_comp); - entry_comp.entry.id = file->id; - if (table_add(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare)){ - if (!uhash_equal(entry_comp.hash, uhash_zero())){ - system->file_track(file->name.source_path); - } - } -} - -inline void -working_set_remove(System_Functions *system, Working_Set *working_set, String filename){ - File_Entry_Comparison entry_comp; - working_set__entry_comp(system, filename, &entry_comp); - table_remove_match(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare); - if (!uhash_equal(entry_comp.hash, uhash_zero())){ - system->file_untrack(filename); - } -} -#endif - // TODO(allen): Pick better first options. internal Editing_File* working_set_lookup_file(Working_Set *working_set, String string){ @@ -898,6 +828,19 @@ editing_file_name_init(Editing_File_Name *name){ name->extension = make_fixed_width_string(name->extension_); } +internal b32 +get_canon_name(System_Functions *system, Editing_File_Canon_Name *canon_name, String filename){ + canon_name->name = make_fixed_width_string(canon_name->name_); + + canon_name->name.size = + system->get_canonical(filename.str, filename.size, + canon_name->name.str, canon_name->name.memory_size); + terminate_with_null(&canon_name->name); + + b32 result = (canon_name->name.size != 0); + return(result); +} + internal void buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, String filename){ Assert(name->live_name.str != 0); @@ -949,48 +892,33 @@ buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, char *fil } internal void -buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set, - Editing_File *file, Unique_Hash index){ +buffer_bind_file(General_Memory *general, Working_Set *working_set, + Editing_File *file, String canon_filename){ Assert(file->name.live_name.size == 0 && file->name.source_path.size == 0 && file->name.extension.size == 0); - Assert(uhash_equal(file->file_index, uhash_zero())); - Assert(!uhash_equal(index, uhash_zero())); + Assert(file->canon.name.size == 0); - working_set_uhash_add(general, working_set, file, index); - file->file_index = index; + file->canon.name = make_fixed_width_string(file->canon.name_); + copy(&file->canon.name, canon_filename); + b32 result = working_set_canon_add(general, working_set, file, file->canon.name); + Assert(result); AllowLocal(result); } internal void -buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set, - Editing_File *file, char *filename, u32 flags){ +buffer_unbind_file(Working_Set *working_set, Editing_File *file){ Assert(file->name.live_name.size == 0 && file->name.source_path.size == 0 && file->name.extension.size == 0); - Assert(uhash_equal(file->file_index, uhash_zero())); + Assert(file->canon.name.size != 0); - Unique_Hash index = system->track_file(filename, flags); - if (!uhash_equal(index, uhash_zero())){ - working_set_uhash_add(general, working_set, file, index); - file->file_index = index; - } -} - -internal void -buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_File *file){ - Assert(file->name.live_name.size == 0 && - file->name.source_path.size == 0 && - file->name.extension.size == 0); - Assert(!uhash_equal(file->file_index, uhash_zero())); - - system->untrack_file(file->file_index); - working_set_uhash_remove(working_set, file->file_index); - file->file_index = uhash_zero(); + working_set_canon_remove(working_set, file->canon.name); + file->canon.name.size = 0; } internal void buffer_bind_name(General_Memory *general, Working_Set *working_set, - Editing_File *file, char *filename){ + Editing_File *file, String filename){ Assert(file->name.live_name.size == 0 && file->name.source_path.size == 0 && file->name.extension.size == 0); @@ -1004,7 +932,8 @@ buffer_bind_name(General_Memory *general, Working_Set *working_set, copy(&file->name.source_path, new_name.source_path); copy(&file->name.extension, new_name.extension); - working_set_name_add(general, working_set, file, file->name.live_name); + b32 result = working_set_name_add(general, working_set, file, file->name.live_name); + Assert(result); AllowLocal(result); } internal void diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 4a5acfc1..7e786cdb 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -780,22 +780,8 @@ starts_new_line(u8 character){ return (character == '\n'); } -#if 0 -inline void -file_synchronize_times(System_Functions *system, Editing_File *file, char *filename){ - u64 stamp = system->file_time_stamp(filename); - if (stamp > 0){ - file->state.last_4ed_write_time = stamp; - file->state.last_4ed_edit_time = stamp; - file->state.last_sys_write_time = stamp; - } - file->state.sync = buffer_get_sync(file); -} -#endif - inline void file_synchronize_times(System_Functions *system, Editing_File *file){ - system->now_file_time(&file->state.last_sync); file->state.sync = SYNC_GOOD; } @@ -803,7 +789,12 @@ internal b32 save_file_to_name(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename){ b32 result = 0; - if (!uhash_equal(file->file_index, uhash_zero())){ + if (!filename){ + terminate_with_null(&file->canon.name); + filename = file->canon.name.str; + } + + if (filename){ i32 max = 0, size = 0; b32 dos_write_mode = file->settings.dos_write_mode; char *data = 0; @@ -840,12 +831,7 @@ save_file_to_name(System_Functions *system, Mem_Options *mem, Editing_File *file buffer_stringify(buffer, 0, size, data); } - if (filename){ - result = system->save_file_by_name(filename, data, size); - } - else{ - result = system->save_file(file->file_index, data, size); - } + result = system->save_file(filename, data, size); file_mark_clean(file); @@ -856,7 +842,7 @@ save_file_to_name(System_Functions *system, Mem_Options *mem, Editing_File *file file_synchronize_times(system, file); } - + return(result); } @@ -868,25 +854,27 @@ save_file(System_Functions *system, Mem_Options *mem, Editing_File *file){ internal b32 buffer_link_to_new_file(System_Functions *system, General_Memory *general, Working_Set *working_set, - Editing_File *file, char *filename){ + Editing_File *file, String filename){ b32 result = 0; - Unique_Hash index = system->track_file(filename, TrackFileFlag_ExistingOrNew); - if (!uhash_equal(index, uhash_zero())){ + + Editing_File_Canon_Name canon_name; + if (get_canon_name(system, &canon_name, filename)){ buffer_unbind_name(working_set, file); - if (!uhash_equal(file->file_index, uhash_zero())){ - buffer_unbind_file(system, working_set, file); + if (file->canon.name.size != 0){ + buffer_unbind_file(working_set, file); } - buffer_bind_file(system, general, working_set, file, filename, TrackFileFlag_ExistingOrNew); + buffer_bind_file(general, working_set, file, canon_name.name); buffer_bind_name(general, working_set, file, filename); result = 1; } + return(result); } inline b32 file_save_and_set_names(System_Functions *system, Mem_Options *mem, Working_Set *working_set, Editing_File *file, - char *filename){ + String filename){ b32 result = buffer_link_to_new_file(system, &mem->general, working_set, file, filename); if (result){ result = save_file(system, mem, file); @@ -3226,46 +3214,50 @@ internal void view_open_file(System_Functions *system, Models *models, View *view, String filename){ Working_Set *working_set = &models->working_set; Editing_File *file = 0; - Unique_Hash index = {0}; if (terminate_with_null(&filename)){ - if (system->get_file_index(filename.str, &index)){ - file = working_set_uhash_contains(working_set, index); - } - else{ - index = system->track_file(filename.str, TrackFileFlag_ExistingOrFail); - if (!uhash_equal(index, uhash_zero())){ - Mem_Options *mem = &models->mem; - General_Memory *general = &mem->general; + Editing_File_Canon_Name canon_name; + if (get_canon_name(system, &canon_name, filename)){ + file = working_set_canon_contains(working_set, canon_name.name); + + if (!file){ - file = working_set_alloc_always(working_set, general); - - buffer_bind_file(system, general, working_set, file, index); - buffer_bind_name(general, working_set, file, filename.str); - - i32 size = system->file_size(index); - Partition *part = &mem->part; - char *buffer = 0; - b32 gen_buffer = 0; - Temp_Memory temp = begin_temp_memory(part); - - buffer = push_array(part, char, size); - - if (buffer == 0){ - buffer = (char*)general_memory_allocate(general, size); - Assert(buffer); - gen_buffer = 1; + Plat_Handle handle; + if (system->load_handle(canon_name.name.str, &handle)){ + Mem_Options *mem = &models->mem; + General_Memory *general = &mem->general; + + file = working_set_alloc_always(working_set, general); + + buffer_bind_file(general, working_set, file, canon_name.name); + buffer_bind_name(general, working_set, file, filename); + + i32 size = system->load_size(handle); + Partition *part = &mem->part; + char *buffer = 0; + b32 gen_buffer = 0; + + Temp_Memory temp = begin_temp_memory(part); + + buffer = push_array(part, char, size); + if (buffer == 0){ + buffer = (char*)general_memory_allocate(general, size); + Assert(buffer); + gen_buffer = 1; + } + + if (system->load_file(handle, buffer, size)){ + init_normal_file(system, models, file, buffer, size); + } + + system->load_close(handle); + + if (gen_buffer){ + general_memory_free(general, buffer); + } + + end_temp_memory(temp); } - - system->load_file(index, buffer, size); - - init_normal_file(system, models, file, buffer, size); - - if (gen_buffer){ - general_memory_free(general, buffer); - } - - end_temp_memory(temp); } } } @@ -3278,7 +3270,7 @@ view_open_file(System_Functions *system, Models *models, View *view, String file internal void view_interactive_save_as(System_Functions *system, Models *models, Editing_File *file, String filename){ if (terminate_with_null(&filename)){ - file_save_and_set_names(system, &models->mem, &models->working_set, file, filename.str); + file_save_and_set_names(system, &models->mem, &models->working_set, file, filename); } } @@ -3286,23 +3278,25 @@ internal void view_interactive_new_file(System_Functions *system, Models *models, View *view, String filename){ Working_Set *working_set = &models->working_set; Editing_File *file = 0; - Unique_Hash index = {0}; if (terminate_with_null(&filename)){ - if (system->get_file_index(filename.str, &index)){ - file = working_set_uhash_contains(working_set, index); - file_clear(system, models, file); - } - else{ - index = system->track_file(filename.str, TrackFileFlag_NewAlways); - if (!uhash_equal(index, uhash_zero())){ + Editing_File_Canon_Name canon_name; + + if (get_canon_name(system, &canon_name, filename)){ + + file = working_set_canon_contains(working_set, canon_name.name); + if (file){ + file_clear(system, models, file); + } + else{ + Mem_Options *mem = &models->mem; General_Memory *general = &mem->general; file = working_set_alloc_always(working_set, general); - buffer_bind_file(system, general, working_set, file, index); - buffer_bind_name(general, working_set, file, filename.str); + buffer_bind_file(general, working_set, file, canon_name.name); + buffer_bind_name(general, working_set, file, filename); init_normal_file(system, models, file, 0, 0); } @@ -3320,7 +3314,7 @@ kill_file(System_Functions *system, Models *models, Editing_File *file){ if (file && !file->settings.never_kill){ buffer_unbind_name(working_set, file); - buffer_unbind_file(system, working_set, file); + buffer_unbind_file(working_set, file); file_close(system, &models->mem.general, file); working_set_free_file(working_set, file); @@ -3682,7 +3676,12 @@ get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhausti loop->full_path.size = loop->r; append(&loop->full_path, result.info->filename); terminate_with_null(&loop->full_path); - file = working_set_uhash_contains(system, working_set, loop->full_path.str); + + Editing_File_Canon_Name canon_name; + + if (get_canon_name(system, &canon_name, loop->full_path)){ + file = working_set_canon_contains(working_set, canon_name.name); + } String filename = make_string(result.info->filename, result.info->filename_len, result.info->filename_len+1); @@ -4651,8 +4650,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su // Time Watcher { string.size = 0; - u64 time = 0; - system->now_file_time(&time); + u64 time = system->now_time(); append(&string, "last redraw: "); append_u64_to_str(&string, time); diff --git a/4ed_system.h b/4ed_system.h index 247bde43..4b9f4513 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -13,24 +13,14 @@ struct Plat_Handle{ u32 d[4]; }; -inline int -handle_equal(Plat_Handle a, Plat_Handle b){ - int result = (memcmp(&a, &b, sizeof(a)) == 0); +inline Plat_Handle +handle_zero(void){ + Plat_Handle result = {0}; return(result); } -struct Unique_Hash{ - u32 d[4]; -}; - -inline Unique_Hash -uhash_zero(){ - Unique_Hash r = {0}; - return(r); -} - inline int -uhash_equal(Unique_Hash a, Unique_Hash b){ +handle_equal(Plat_Handle a, Plat_Handle b){ int result = (memcmp(&a, &b, sizeof(a)) == 0); return(result); } @@ -39,35 +29,33 @@ uhash_equal(Unique_Hash a, Unique_Hash b){ #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); -#define Sys_Add_Listener_Sig(name) Unique_Hash name(char *filename) -typedef Sys_Add_Listener_Sig(System_Track_File); +#define Sys_Get_Canonical_Sig(name) i32 name(char *filename, i32 len, char *buffer, i32 max) +typedef Sys_Get_Canonical_Sig(System_Get_Canonical); -#define Sys_Remove_Listener_Sig(name) i32 name(char *filename) -typedef Sys_Remove_Listener_Sig(System_Untrack_File); +#define Sys_Add_Listener_Sig(name) b32 name(char *filename) +typedef Sys_Add_Listener_Sig(System_Add_Listener); -#define Sys_Get_File_Index_Sig(name) i32 name(char *filename, Unique_Hash *index) -typedef Sys_Get_File_Index_Sig(System_Get_File_Index); +#define Sys_Remove_Listener_Sig(name) b32 name(char *filename) +typedef Sys_Remove_Listener_Sig(System_Remove_Listener); -#define Sys_Get_File_Time_Sig(name) i32 name(Unique_Hash index, u64 *time) -typedef Sys_Get_File_Time_Sig(System_Get_File_Time); +#define Sys_Load_Handle_Sig(name) b32 name(char *filename, Plat_Handle *handle_out) +typedef Sys_Load_Handle_Sig(System_Load_Handle); -#define Sys_Now_File_Time_Sig(name) void name(u64 *time) -typedef Sys_Now_File_Time_Sig(System_Now_File_Time); +#define Sys_Load_Size_Sig(name) u32 name(Plat_Handle handle) +typedef Sys_Load_Size_Sig(System_Load_Size); -#define Sys_Get_Changed_File_Sig(name) i32 name(Unique_Hash *index) -typedef Sys_Get_Changed_File_Sig(System_Get_Changed_File); - -#define Sys_File_Size_Sig(name) u32 name(Unique_Hash index) -typedef Sys_File_Size_Sig(System_File_Size); - -#define Sys_Load_File_Sig(name) i32 name(Unique_Hash index, char *buffer, i32 size) +#define Sys_Load_File_Sig(name) b32 name(Plat_Handle handle, char *buffer, u32 size) typedef Sys_Load_File_Sig(System_Load_File); -#define Sys_Save_File_Sig(name) i32 name(Unique_Hash index, char *buffer, i32 size) +#define Sys_Load_Close_Sig(name) b32 name(Plat_Handle handle) +typedef Sys_Load_Close_Sig(System_Load_Close); + +#define Sys_Save_File_Sig(name) b32 name(char *filename, char *buffer, u32 size) typedef Sys_Save_File_Sig(System_Save_File); -#define Sys_Save_File_By_Name_Sig(name) i32 name(char *filename, char *buffer, i32 size) -typedef Sys_Save_File_By_Name_Sig(System_Save_File_By_Name); + +#define Sys_Now_Time_Sig(name) u64 name() +typedef Sys_Now_Time_Sig(System_Now_Time); #define Sys_Post_Clipboard_Sig(name) void name(String str) @@ -221,18 +209,19 @@ typedef INTERNAL_Sys_Debug_Message_Sig(INTERNAL_System_Debug_Message); struct System_Functions{ - // files (tracked api): 11 + // files (tracked api): 9 System_Set_File_List *set_file_list; - System_Track_File *track_file; - System_Untrack_File *untrack_file; - System_Get_File_Index *get_file_index; - System_Get_File_Time *get_file_time; - System_Now_File_Time *now_file_time; - System_Get_Changed_File *get_changed_file; - System_File_Size *file_size; + System_Get_Canonical *get_canonical; + System_Add_Listener *add_listener; + System_Remove_Listener *remove_listener; + System_Load_Handle *load_handle; + System_Load_Size *load_size; System_Load_File *load_file; + System_Load_Close *load_close; System_Save_File *save_file; - System_Save_File_By_Name *save_file_by_name; + + // time: 1 + System_Now_Time *now_time; // 4coder_custom.h: 7 Memory_Allocate_Function *memory_allocate; diff --git a/build_all.bat b/build_all.bat index cb12e157..6b7c1cf4 100644 --- a/build_all.bat +++ b/build_all.bat @@ -32,7 +32,7 @@ REM call "%CODE_DIR%\buildsuper.bat" ..\4vim\4coder_chronal.cpp if %ERRORLEVEL% neq 0 (set FirstError=1) set EXPORTS=/EXPORT:app_get_functions -REM cl %OPTS% %INCLUDES% %DEFINES% %CODE_DIR%\4ed_app_target.cpp %* /Fe4ed_app /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS% +cl %OPTS% %INCLUDES% %DEFINES% %CODE_DIR%\4ed_app_target.cpp %* /Fe4ed_app /LD /link /INCREMENTAL:NO /OPT:REF %EXPORTS% if %ERRORLEVEL% neq 0 (set FirstError=1) cl %OPTS% %INCLUDES% %DEFINES% %CODE_DIR%\win32_4ed.cpp %LIBS% %ICON% %* /Fe4ed /link /NODEFAULTLIB:library diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 1cccf6c0..d79f3a0c 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -144,6 +144,11 @@ enum CV_ID{ CV_COUNT }; +struct Drive_Strings{ + char *prefix_[26]; + char **prefix; +}; + struct Win32_Vars{ System_Functions system; App_Functions app; @@ -197,7 +202,7 @@ struct Win32_Vars{ void *track_table; u32 track_table_size; u32 track_node_size; - + Drive_Strings dstrings; #if FRED_INTERNAL CRITICAL_SECTION DEBUG_sysmem_lock; @@ -1023,22 +1028,8 @@ Sys_Set_File_List_Sig(system_set_file_list){ } } -inline Unique_Hash -to_uhash(File_Index index){ - Unique_Hash r; - *(File_Index*)(&r) = index; - return(r); -} - -inline File_Index -to_findex(Unique_Hash index){ - File_Index r; - *(Unique_Hash*)(&r) = index; - return(r); -} - internal b32 -handle_track_out_of_memory(i32 val, Unique_Hash *index, File_Index get_index){ +handle_track_out_of_memory(i32 val){ b32 result = 0; switch (val){ @@ -1059,100 +1050,160 @@ handle_track_out_of_memory(i32 val, Unique_Hash *index, File_Index get_index){ expand_track_system_listeners(&win32vars.track, node_expansion, win32vars.track_node_size); }break; - case FileTrack_Good: - { - *index = to_uhash(get_index); - result = 1; - }break; - default: result = 1; break; } return(result); } -internal -Sys_Track_File_Sig(system_track_file){ - Unique_Hash index = {0}; +internal void +set_volume_prefix(Drive_Strings *dstrings, char *vol){ + char c = vol[0]; + if (dstrings->prefix[c]){ + system_free_memory(dstrings->prefix[c]); + } - switch (flags){ - case TrackFileFlag_ExistingOrFail: - { - File_Index get_index = {0}; - File_Time time = 0; - for (;;){ - i32 result = begin_tracking_file(&win32vars.track, filename, &get_index, &time); - if (handle_track_out_of_memory(result, &index, get_index)){ - goto track_end; - } - } - }break; + HANDLE hdir = CreateFile( + vol, + GENERIC_READ, + FILE_SHARE_DELETE|FILE_SHARE_WRITE|FILE_SHARE_READ, + 0, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + 0); + + if (hdir != INVALID_HANDLE_VALUE){ + char *s = 0; + DWORD len = GetFinalPathNameByHandle(hdir, 0, 0, 0); + len = len + 1; + s = (char*)system_get_memory(len); + len = GetFinalPathNameByHandle(hdir, s, len, 0); + s[len] = 0; + if (s[len-1] == '\\') s[len-1] = 0; + dstrings->prefix[c] = s + 4; + CloseHandle(hdir); + } + else{ + dstrings->prefix[c] = 0; + } +} + +internal void +win32_init_drive_strings(Drive_Strings *dstrings){ + dstrings->prefix = dstrings->prefix_ - 'A'; + + char vol[4] = "A:\\"; + for (char c = 'A'; c <= 'Z'; ++c){ + vol[0] = c; + set_volume_prefix(dstrings, vol); + } +} + +// NOTE(allen): This does not chase down symbolic links because doing so +// would require a lot of heavy duty OS calls. I've decided to give up +// a little ground on always recognizing files as equivalent in exchange +// for the ability to handle them very quickly when nothing strange is +// going on. +static int32_t +win32_canonical_ansi_name(Drive_Strings *dstrings, char *src, i32 len, char *dst, i32 max){ + char *wrt = dst; + char *wrt_stop = dst + max; + char *src_stop = src + len; + char c = 0; + char **prefix_array = dstrings->prefix; + char *prefix = 0; + + if (len >= 2 && max > 0){ + c = src[0]; + if (c >= 'a' && c <= 'z'){ + c -= 'a' - 'A'; + } - case TrackFileFlag_NewOrFail: - { - File_Index get_index = {0}; - File_Time time = 0; - File_Temp_Handle handle = {0}; - i32 result = get_file_temp_handle(filename, &handle); - if (result == FileTrack_FileNotFound){ - for (;;){ - result = begin_tracking_new_file(&win32vars.track, filename, &get_index, &time); - if (handle_track_out_of_memory(result, &index, get_index)){ - goto track_end; - } + if (c >= 'A' && c <= 'Z' && src[1] == ':'){ + prefix = prefix_array[c]; + if (prefix){ + for (;*prefix;){ + *(wrt++) = *(prefix++); + if (wrt == wrt_stop) goto fail; } } else{ - finish_with_temp_handle(handle); + *(wrt++) = c; + if (wrt == wrt_stop) goto fail; + *(wrt++) = ':'; + if (wrt == wrt_stop) goto fail; } - }break; - - case TrackFileFlag_NewAlways: - { - File_Index get_index = {0}; - File_Time time = 0; - for (;;){ - i32 result = begin_tracking_new_file(&win32vars.track, filename, &get_index, &time); - if (handle_track_out_of_memory(result, &index, get_index)){ - goto track_end; + src += 2; + + for (; src < src_stop; ++src){ + c = src[0]; + + if (c >= 'A' && c <= 'Z'){ + c += 'a' - 'A'; } - } - }break; - - case TrackFileFlag_ExistingOrNew: - { - File_Index get_index = {0}; - File_Time time = 0; - File_Temp_Handle handle = {0}; - i32 result = get_file_temp_handle(filename, &handle); - if (result == FileTrack_FileNotFound){ - for (;;){ - result = begin_tracking_new_file(&win32vars.track, filename, &get_index, &time); - if (handle_track_out_of_memory(result, &index, get_index)){ - goto track_end; + + if (c == '/' || c == '\\'){ + c = '\\'; + if (wrt > dst && wrt[-1] == '\\'){ + continue; + } + else if (src[1] == '.'){ + if (src[2] == '\\' || src[2] == '/'){ + src += 1; + } + else if (src[2] == '.' && (src[3] == '\\' || src[3] == '/')){ + src += 2; + while (wrt > dst && wrt[0] != '\\'){ + --wrt; + } + if (wrt == dst) goto fail; + } } } + + *wrt = c; + ++wrt; + if (wrt == wrt_stop) goto fail; } - else{ - for (;;){ - result = begin_tracking_from_handle(&win32vars.track, filename, handle, &get_index, &time); - if (handle_track_out_of_memory(result, &index, get_index)){ - goto track_end; - } - } - } - }break; + } } - track_end:; + if (0){ + fail:; + wrt = dst; + } - return(index); + int32_t result = (int32_t)(wrt - dst); + return(result); } internal -Sys_Untrack_File_Sig(system_untrack_file){ +Sys_Get_Canonical_Sig(system_get_canonical){ + i32 result = win32_canonical_ansi_name(&win32vars.dstrings, filename, len, buffer, max); + return(result); +} + +internal +Sys_Add_Listener_Sig(system_add_listener){ + b32 result = 0; + + for (;;){ + i32 track_result = add_listener(&win32vars.track, filename); + if (handle_track_out_of_memory(track_result)){ + if (track_result == FileTrack_Good){ + result = 1; + } + break; + } + } + + return(result); +} + +internal +Sys_Remove_Listener_Sig(system_remove_listener){ i32 result = 0; - i32 track_result = stop_tracking_file(&win32vars.track, to_findex(index)); + i32 track_result = remove_listener(&win32vars.track, filename); if (track_result == FileTrack_Good){ result = 1; } @@ -1160,64 +1211,64 @@ Sys_Untrack_File_Sig(system_untrack_file){ } internal -Sys_Get_File_Index_Sig(system_get_file_index){ - i32 result = 0; - File_Index get_index = {0}; - i32 track_result = get_tracked_file_index(&win32vars.track, filename, &get_index); - if (track_result == FileTrack_Good){ - *index = to_uhash(get_index); +Sys_Load_Handle_Sig(system_load_handle){ + b32 result = 0; + HANDLE file = CreateFile(filename, + GENERIC_READ, + 0, + 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + 0); + + if (file != INVALID_HANDLE_VALUE){ + *(HANDLE*)handle_out = file; result = 1; } + return(result); } internal -Sys_Get_File_Time_Sig(system_get_file_time){ - i32 result = 0; - u64 get_time = 0; - File_Index findex = to_findex(index); - i32 track_result = get_tracked_file_time(&win32vars.track, findex, &get_time); - if (track_result == FileTrack_Good){ - *time = get_time; - result = 1; +Sys_Load_Size_Sig(system_load_size){ + u32 result = 0; + HANDLE file = *(HANDLE*)(&handle); + + DWORD hi = 0; + DWORD lo = GetFileSize(file, &hi); + + if (hi == 0){ + result = lo; } + return(result); } -internal -Sys_Now_File_Time_Sig(system_now_file_time){ - get_file_time_now(time); -} - -internal -Sys_Get_Changed_File_Sig(system_get_changed_file){ - i32 result = 0; - File_Index get_index = {0}; - i32 track_result = get_change_event(&win32vars.track, &get_index); - if (track_result == FileTrack_Good){ - *index = to_uhash(get_index); - result = 1; - } - return(result); -} - -internal -Sys_File_Size_Sig(system_file_size){ - u32 size = 0; - File_Index findex = to_findex(index); - i32 track_result = get_tracked_file_size(&win32vars.track, findex, &size); - if (track_result != FileTrack_Good){ - size = 0; - } - return(size); -} - internal Sys_Load_File_Sig(system_load_file){ - i32 result = 0; - File_Index findex = to_findex(index); - i32 track_result = get_tracked_file_data(&win32vars.track, findex, buffer, size); - if (track_result == FileTrack_Good){ + b32 result = 0; + HANDLE file = *(HANDLE*)(&handle); + + DWORD read_size = 0; + + if (ReadFile(file, + buffer, + size, + &read_size, + 0)){ + if (read_size == size){ + result = 1; + } + } + + return(result); +} + +internal +Sys_Load_Close_Sig(system_load_close){ + b32 result = 0; + HANDLE file = *(HANDLE*)(&handle); + if (CloseHandle(file)){ result = 1; } return(result); @@ -1225,24 +1276,36 @@ Sys_Load_File_Sig(system_load_file){ internal Sys_Save_File_Sig(system_save_file){ - i32 result = 0; - File_Index findex = to_findex(index); - File_Time time = 0; - i32 track_result = rewrite_tracked_file(&win32vars.track, findex, buffer, size, &time); - if (track_result == FileTrack_Good){ + b32 result = 0; + HANDLE file = CreateFile(filename, + GENERIC_WRITE, + 0, + 0, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + 0); + + if (file != INVALID_HANDLE_VALUE){ + DWORD written_total = 0; + DWORD written_size = 0; + result = 1; + + while (written_total < size){ + if (!WriteFile(file, buffer, size, &written_size, 0)){ + result = 0; + break; + } + written_total += written_size; + } } + return(result); } internal -Sys_Save_File_By_Name_Sig(system_save_file_by_name){ - i32 result = 0; - File_Time time = 0; - i32 track_result = rewrite_arbitrary_file(&win32vars.track, filename, buffer, size, &time); - if (track_result == FileTrack_Good){ - result = 1; - } +Sys_Now_Time_Sig(system_now_time){ + u64 result = __rdtsc(); return(result); } @@ -1596,16 +1659,16 @@ Win32LoadAppCode(){ internal void Win32LoadSystemCode(){ win32vars.system.set_file_list = system_set_file_list; - win32vars.system.track_file = system_track_file; - win32vars.system.untrack_file = system_untrack_file; - win32vars.system.get_file_index = system_get_file_index; - win32vars.system.get_file_time = system_get_file_time; - win32vars.system.now_file_time = system_now_file_time; - win32vars.system.get_changed_file = system_get_changed_file; - win32vars.system.file_size = system_file_size; + win32vars.system.get_canonical = system_get_canonical; + win32vars.system.add_listener = system_add_listener; + win32vars.system.remove_listener = system_remove_listener; + win32vars.system.load_handle = system_load_handle; + win32vars.system.load_size = system_load_size; win32vars.system.load_file = system_load_file; + win32vars.system.load_close = system_load_close; win32vars.system.save_file = system_save_file; - win32vars.system.save_file_by_name = system_save_file_by_name; + + win32vars.system.now_time = system_now_time; win32vars.system.memory_allocate = Memory_Allocate; win32vars.system.file_exists = File_Exists; @@ -2064,7 +2127,6 @@ WinMain(HINSTANCE hInstance, memset(&win32vars, 0, sizeof(win32vars)); - // // Threads and Coroutines // @@ -2127,6 +2189,10 @@ WinMain(HINSTANCE hInstance, win32vars.coroutine_data[i].next = win32vars.coroutine_data + i + 1; } + // + // Volume Initialization + // + win32_init_drive_strings(&win32vars.dstrings); // // Memory Initialization