file tracker version 2 fully integrated

master
Allen Webster 2016-08-26 13:52:35 -04:00
parent 426b8d5576
commit fc76531ca1
7 changed files with 506 additions and 516 deletions

82
4ed.cpp
View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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