4ed_file_view.cpp now compiles
parent
904f72a065
commit
25fba14574
|
@ -1654,6 +1654,7 @@ isearch(Application_Links *app, int start_reversed){
|
|||
int reverse = start_reversed;
|
||||
int pos = view.cursor.pos;
|
||||
int start_pos = pos;
|
||||
int first_pos = pos;
|
||||
Range match = make_range(pos, pos);
|
||||
|
||||
char bar_string_space[256];
|
||||
|
@ -1756,7 +1757,7 @@ isearch(Application_Links *app, int start_reversed){
|
|||
}
|
||||
app->view_set_highlight(app, &view, 0, 0, false);
|
||||
if (in.abort){
|
||||
app->view_set_cursor(app, &view, seek_pos(start_pos), true);
|
||||
app->view_set_cursor(app, &view, seek_pos(first_pos), true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,15 +170,12 @@ table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compar
|
|||
static uint32_t
|
||||
tbl_string_hash(void *item, void *arg){
|
||||
String *string = (String*)item;
|
||||
char *str;
|
||||
int32_t i,len;
|
||||
char *str = string->str;
|
||||
int32_t i = 0, len = string->size;
|
||||
uint32_t x = 5381;
|
||||
char c;
|
||||
(void)arg;
|
||||
|
||||
str = string->str;
|
||||
len = string->size;
|
||||
i = 0;
|
||||
while (i < len){
|
||||
c = str[i++];
|
||||
x = ((x << 5) + x) + c;
|
||||
|
|
352
4ed_file.cpp
352
4ed_file.cpp
|
@ -188,6 +188,7 @@ struct Editing_File{
|
|||
Editing_File_Name name;
|
||||
Buffer_Slot_ID id;
|
||||
u64 unique_buffer_id;
|
||||
Unique_Hash file_index;
|
||||
};
|
||||
|
||||
struct Non_File_Table_Entry{
|
||||
|
@ -208,7 +209,8 @@ struct Working_Set{
|
|||
File_Node free_sentinel;
|
||||
File_Node used_sentinel;
|
||||
|
||||
Table table;
|
||||
Table uhash_table;
|
||||
Table name_table;
|
||||
|
||||
String clipboards[64];
|
||||
i32 clipboard_size, clipboard_max_size;
|
||||
|
@ -219,42 +221,6 @@ struct Working_Set{
|
|||
File_Node *sync_check_iter;
|
||||
};
|
||||
|
||||
struct File_Entry{
|
||||
String short_name;
|
||||
String long_name;
|
||||
Buffer_Slot_ID id;
|
||||
};
|
||||
|
||||
struct File_Entry_Comparison{
|
||||
File_Entry entry;
|
||||
Unique_Hash hash;
|
||||
b32 use_hash;
|
||||
};
|
||||
|
||||
internal i32
|
||||
tbl_file_compare(void *a, void *b, void *arg){
|
||||
File_Entry_Comparison *fa = (File_Entry_Comparison*)a;
|
||||
File_Entry *fb = (File_Entry*)b;
|
||||
System_Functions *system = (System_Functions*)arg;
|
||||
Unique_Hash uhash;
|
||||
i32 result = 1;
|
||||
b32 success;
|
||||
|
||||
if (fa->use_hash){
|
||||
uhash = system->file_unique_hash(fb->long_name, &success);
|
||||
if (success && uhash_equal(uhash, fa->hash)){
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (match(fa->entry.short_name, fb->short_name)){
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
//
|
||||
// File_Edit_Positions stuff
|
||||
//
|
||||
|
@ -382,6 +348,48 @@ 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;
|
||||
File_Name_Entry *fb = (File_Name_Entry*)b;
|
||||
|
||||
i32 result = 1;
|
||||
if (match(*fa, fb->name)){
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16 number_of_files){
|
||||
Buffer_Slot_ID id;
|
||||
|
@ -434,7 +442,7 @@ working_set_alloc(Working_Set *working_set){
|
|||
++working_set->file_count;
|
||||
}
|
||||
|
||||
return result;
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal Editing_File*
|
||||
|
@ -472,7 +480,7 @@ working_set_free_file(Working_Set *working_set, Editing_File *file){
|
|||
inline Editing_File*
|
||||
working_set_index(Working_Set *working_set, Buffer_Slot_ID id){
|
||||
Editing_File *result = 0;
|
||||
File_Array *array;
|
||||
File_Array *array = 0;
|
||||
|
||||
if (id.part[1] >= 0 && id.part[1] < working_set->array_count){
|
||||
array = working_set->file_arrays + id.part[1];
|
||||
|
@ -486,8 +494,7 @@ working_set_index(Working_Set *working_set, Buffer_Slot_ID id){
|
|||
|
||||
inline Editing_File*
|
||||
working_set_index(Working_Set *working_set, i32 id){
|
||||
Editing_File *result;
|
||||
result = working_set_index(working_set, to_file_id(id));
|
||||
Editing_File *result = working_set_index(working_set, to_file_id(id));
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
@ -510,45 +517,54 @@ working_set_get_active_file(Working_Set *working_set, i32 id){
|
|||
|
||||
internal void
|
||||
working_set_init(Working_Set *working_set, Partition *partition, General_Memory *general){
|
||||
Editing_File *files, *null_file;
|
||||
void *mem;
|
||||
i32 mem_size, table_size;
|
||||
|
||||
i32 item_size = sizeof(File_Entry);
|
||||
i16 init_count = 16;
|
||||
i16 array_init_count = 256;
|
||||
|
||||
dll_init_sentinel(&working_set->free_sentinel);
|
||||
dll_init_sentinel(&working_set->used_sentinel);
|
||||
|
||||
|
||||
working_set->array_max = array_init_count;
|
||||
working_set->file_arrays = push_array(partition, File_Array, array_init_count);
|
||||
|
||||
files = push_array(partition, Editing_File, init_count);
|
||||
|
||||
Editing_File *files = push_array(partition, Editing_File, init_count);
|
||||
working_set_extend_memory(working_set, files, init_count);
|
||||
|
||||
null_file = working_set_index(working_set, 0);
|
||||
dll_remove(&null_file->node);
|
||||
null_file->is_dummy = 1;
|
||||
++working_set->file_count;
|
||||
|
||||
table_size = working_set->file_max;
|
||||
mem_size = table_required_mem_size(table_size, item_size);
|
||||
mem = general_memory_allocate(general, mem_size);
|
||||
memset(mem, 0, mem_size);
|
||||
table_init_memory(&working_set->table, mem, table_size, item_size);
|
||||
|
||||
// NOTE(allen): init null file
|
||||
{
|
||||
Editing_File *null_file = working_set_index(working_set, 0);
|
||||
dll_remove(&null_file->node);
|
||||
null_file->is_dummy = 1;
|
||||
++working_set->file_count;
|
||||
}
|
||||
|
||||
// NOTE(allen): init uhash table
|
||||
{
|
||||
i32 item_size = sizeof(File_Uhash_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);
|
||||
}
|
||||
|
||||
// NOTE(allen): init name table
|
||||
{
|
||||
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->name_table, mem, table_size, item_size);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
working_set__grow_if_needed(Table *table, General_Memory *general, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
|
||||
Table btable;
|
||||
i32 new_max, mem_size;
|
||||
void *mem;
|
||||
|
||||
if (table_at_capacity(table)){
|
||||
new_max = table->max * 2;
|
||||
mem_size = table_required_mem_size(new_max, table->item_size);
|
||||
mem = general_memory_allocate(general, mem_size);
|
||||
Table btable = {0};
|
||||
i32 new_max = table->max * 2;
|
||||
i32 mem_size = table_required_mem_size(new_max, table->item_size);
|
||||
void *mem = general_memory_allocate(general, mem_size);
|
||||
table_init_memory(&btable, mem, new_max, table->item_size);
|
||||
table_clear(&btable);
|
||||
table_rehash(table, &btable, 0, hash_func, comp_func);
|
||||
|
@ -557,6 +573,80 @@ 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, String name){
|
||||
Editing_File *file = 0;
|
||||
Unique_Hash index = {0};
|
||||
if (system->get_file_index(name.str, &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){
|
||||
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);
|
||||
if (entry){
|
||||
result = working_set_index(working_set, entry->id);
|
||||
}
|
||||
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
inline void
|
||||
working_set__entry_comp(System_Functions *system, String filename, File_Entry_Comparison *out){
|
||||
out->entry.long_name = filename;
|
||||
|
@ -572,7 +662,6 @@ working_set_contains(System_Functions *system, Working_Set *working_set, String
|
|||
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);
|
||||
}
|
||||
|
@ -602,6 +691,7 @@ working_set_remove(System_Functions *system, Working_Set *working_set, String fi
|
|||
system->file_untrack(filename);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO(allen): Pick better first options.
|
||||
internal Editing_File*
|
||||
|
@ -609,6 +699,7 @@ working_set_lookup_file(Working_Set *working_set, String string){
|
|||
Editing_File *file = 0;
|
||||
|
||||
{
|
||||
// TODO(allen): use the name table for this
|
||||
File_Node *node, *used_nodes;
|
||||
used_nodes = &working_set->used_sentinel;
|
||||
for (dll_items(node, used_nodes)){
|
||||
|
@ -800,5 +891,130 @@ file_get_sync(Editing_File *file){
|
|||
return (file->state.sync);
|
||||
}
|
||||
|
||||
internal void
|
||||
editing_file_name_init(Editing_File_Name *name){
|
||||
name->live_name = make_fixed_width_string(name->live_name_);
|
||||
name->source_path = make_fixed_width_string(name->source_path_);
|
||||
name->extension = make_fixed_width_string(name->extension_);
|
||||
}
|
||||
|
||||
internal void
|
||||
buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, String filename){
|
||||
Assert(name->live_name.str != 0);
|
||||
|
||||
copy_checked(&name->source_path, filename);
|
||||
copy(&name->live_name, front_of_directory(filename));
|
||||
|
||||
if (name->source_path.size == name->live_name.size){
|
||||
name->extension.size = 0;
|
||||
}
|
||||
else{
|
||||
String ext = file_extension(filename);
|
||||
copy(&name->extension, ext);
|
||||
}
|
||||
|
||||
{
|
||||
i32 original_len = name->live_name.size;
|
||||
i32 file_x = 0;
|
||||
b32 hit_conflict = 1;
|
||||
while (hit_conflict){
|
||||
hit_conflict = 0;
|
||||
|
||||
File_Node *used_nodes = &working_set->used_sentinel, *node;
|
||||
for (dll_items(node, used_nodes)){
|
||||
Editing_File *file_ptr = (Editing_File*)node;
|
||||
if (file_is_ready(file_ptr)){
|
||||
if (match(name->live_name, file_ptr->name.live_name)){
|
||||
++file_x;
|
||||
hit_conflict = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hit_conflict){
|
||||
name->live_name.size = original_len;
|
||||
append(&name->live_name, " <");
|
||||
append_int_to_str(&name->live_name, file_x);
|
||||
append(&name->live_name, ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, char *filename){
|
||||
String f = make_string_slowly(filename);
|
||||
buffer_get_new_name(working_set, name, f);
|
||||
}
|
||||
|
||||
internal void
|
||||
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
||||
Editing_File *file, Unique_Hash index){
|
||||
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()));
|
||||
|
||||
working_set_uhash_add(general, working_set, file, index);
|
||||
file->file_index = index;
|
||||
}
|
||||
|
||||
internal void
|
||||
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
||||
Editing_File *file, char *filename, u32 flags){
|
||||
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()));
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
internal void
|
||||
buffer_bind_name(General_Memory *general, Working_Set *working_set,
|
||||
Editing_File *file, char *filename){
|
||||
Assert(file->name.live_name.size == 0 &&
|
||||
file->name.source_path.size == 0 &&
|
||||
file->name.extension.size == 0);
|
||||
|
||||
Editing_File_Name new_name;
|
||||
editing_file_name_init(&new_name);
|
||||
buffer_get_new_name(working_set, &new_name, filename);
|
||||
|
||||
editing_file_name_init(&file->name);
|
||||
copy(&file->name.live_name, new_name.live_name);
|
||||
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);
|
||||
}
|
||||
|
||||
internal void
|
||||
buffer_unbind_name(Working_Set *working_set, Editing_File *file){
|
||||
Assert(file->name.live_name.size != 0);
|
||||
working_set_name_remove(working_set, file->name.live_name);
|
||||
file->name.live_name.size = 0;
|
||||
file->name.source_path.size = 0;
|
||||
file->name.extension.size = 0;
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -780,71 +780,6 @@ starts_new_line(u8 character){
|
|||
return (character == '\n');
|
||||
}
|
||||
|
||||
inline void
|
||||
file_init_strings(Editing_File *file){
|
||||
file->name.source_path = make_fixed_width_string(file->name.source_path_);
|
||||
file->name.live_name = make_fixed_width_string(file->name.live_name_);
|
||||
file->name.extension = make_fixed_width_string(file->name.extension_);
|
||||
}
|
||||
|
||||
internal void
|
||||
file_set_name(Working_Set *working_set, Editing_File *file, String filename){
|
||||
String ext;
|
||||
|
||||
Assert(file->name.live_name.str != 0);
|
||||
|
||||
copy_checked(&file->name.source_path, filename);
|
||||
|
||||
copy(&file->name.live_name, front_of_directory(filename));
|
||||
|
||||
if (file->name.source_path.size == file->name.live_name.size){
|
||||
file->name.extension.size = 0;
|
||||
}
|
||||
else{
|
||||
ext = file_extension(filename);
|
||||
copy(&file->name.extension, ext);
|
||||
}
|
||||
|
||||
{
|
||||
File_Node *node, *used_nodes;
|
||||
Editing_File *file_ptr;
|
||||
i32 file_x, original_len;
|
||||
b32 hit_conflict;
|
||||
|
||||
used_nodes = &working_set->used_sentinel;
|
||||
original_len = file->name.live_name.size;
|
||||
hit_conflict = 1;
|
||||
file_x = 0;
|
||||
while (hit_conflict){
|
||||
hit_conflict = 0;
|
||||
for (dll_items(node, used_nodes)){
|
||||
file_ptr = (Editing_File*)node;
|
||||
if (file_ptr != file && file_is_ready(file_ptr)){
|
||||
if (match(file->name.live_name, file_ptr->name.live_name)){
|
||||
++file_x;
|
||||
hit_conflict = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hit_conflict){
|
||||
file->name.live_name.size = original_len;
|
||||
append(&file->name.live_name, " <");
|
||||
append_int_to_str(&file->name.live_name, file_x);
|
||||
append(&file->name.live_name, ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
file_set_name(Working_Set *working_set, Editing_File *file, char *filename){
|
||||
String f = make_string_slowly(filename);
|
||||
file_set_name(working_set, file, f);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
inline void
|
||||
file_synchronize_times(System_Functions *system, Editing_File *file, char *filename){
|
||||
|
@ -860,61 +795,80 @@ file_synchronize_times(System_Functions *system, Editing_File *file, char *filen
|
|||
|
||||
inline void
|
||||
file_synchronize_times(System_Functions *system, Editing_File *file){
|
||||
file->state.last_sync = system->now_time_stamp();
|
||||
system->now_file_time(&file->state.last_sync);
|
||||
file->state.sync = SYNC_GOOD;
|
||||
}
|
||||
|
||||
internal b32
|
||||
file_save(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename){
|
||||
file_save(System_Functions *system, Mem_Options *mem, Editing_File *file){
|
||||
b32 result = 0;
|
||||
|
||||
i32 max = 0, size = 0;
|
||||
b32 dos_write_mode = file->settings.dos_write_mode;
|
||||
char *data = 0;
|
||||
Buffer_Type *buffer = &file->state.buffer;
|
||||
|
||||
if (dos_write_mode){
|
||||
max = buffer_size(buffer) + buffer->line_count + 1;
|
||||
}
|
||||
else{
|
||||
max = buffer_size(buffer);
|
||||
}
|
||||
|
||||
b32 used_general = 0;
|
||||
Temp_Memory temp = begin_temp_memory(&mem->part);
|
||||
char empty = 0;
|
||||
if (max == 0){
|
||||
data = ∅
|
||||
}
|
||||
else{
|
||||
data = (char*)push_array(&mem->part, char, max);
|
||||
if (!uhash_equal(file->file_index, uhash_zero())){
|
||||
i32 max = 0, size = 0;
|
||||
b32 dos_write_mode = file->settings.dos_write_mode;
|
||||
char *data = 0;
|
||||
Buffer_Type *buffer = &file->state.buffer;
|
||||
|
||||
if (!data){
|
||||
used_general = 1;
|
||||
data = (char*)general_memory_allocate(&mem->general, max);
|
||||
if (dos_write_mode){
|
||||
max = buffer_size(buffer) + buffer->line_count + 1;
|
||||
}
|
||||
}
|
||||
Assert(data);
|
||||
|
||||
if (dos_write_mode){
|
||||
size = buffer_convert_out(buffer, data, max);
|
||||
}
|
||||
else{
|
||||
size = max;
|
||||
buffer_stringify(buffer, 0, size, data);
|
||||
else{
|
||||
max = buffer_size(buffer);
|
||||
}
|
||||
|
||||
b32 used_general = 0;
|
||||
Temp_Memory temp = begin_temp_memory(&mem->part);
|
||||
char empty = 0;
|
||||
if (max == 0){
|
||||
data = ∅
|
||||
}
|
||||
else{
|
||||
data = (char*)push_array(&mem->part, char, max);
|
||||
|
||||
if (!data){
|
||||
used_general = 1;
|
||||
data = (char*)general_memory_allocate(&mem->general, max);
|
||||
}
|
||||
}
|
||||
Assert(data);
|
||||
|
||||
if (dos_write_mode){
|
||||
size = buffer_convert_out(buffer, data, max);
|
||||
}
|
||||
else{
|
||||
size = max;
|
||||
buffer_stringify(buffer, 0, size, data);
|
||||
}
|
||||
|
||||
result = system->save_file(file->file_index, data, size);
|
||||
|
||||
file_mark_clean(file);
|
||||
|
||||
if (used_general){
|
||||
general_memory_free(&mem->general, data);
|
||||
}
|
||||
end_temp_memory(temp);
|
||||
|
||||
file_synchronize_times(system, file);
|
||||
}
|
||||
|
||||
result = system->file_save(filename, data, size);
|
||||
|
||||
file_mark_clean(file);
|
||||
|
||||
if (used_general){
|
||||
general_memory_free(&mem->general, data);
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal b32
|
||||
buffer_link_to_new_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
||||
Editing_File *file, char *filename){
|
||||
b32 result = 0;
|
||||
Unique_Hash index = system->track_file(filename, TrackFileFlag_ExistingOrNew);
|
||||
if (!uhash_equal(index, uhash_zero())){
|
||||
buffer_unbind_name(working_set, file);
|
||||
if (!uhash_equal(file->file_index, uhash_zero())){
|
||||
buffer_unbind_file(system, working_set, file);
|
||||
}
|
||||
buffer_bind_file(system, general, working_set, file, filename, TrackFileFlag_ExistingOrNew);
|
||||
buffer_bind_name(general, working_set, file, filename);
|
||||
result = 1;
|
||||
}
|
||||
end_temp_memory(temp);
|
||||
|
||||
file_synchronize_times(system, file);
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
@ -922,12 +876,11 @@ inline b32
|
|||
file_save_and_set_names(System_Functions *system, Mem_Options *mem,
|
||||
Working_Set *working_set, Editing_File *file,
|
||||
char *filename){
|
||||
b32 result = 0;
|
||||
result = file_save(system, mem, file, filename);
|
||||
b32 result = buffer_link_to_new_file(system, &mem->general, working_set, file, filename);
|
||||
if (result){
|
||||
file_set_name(working_set, file, filename);
|
||||
result = file_save(system, mem, file);
|
||||
}
|
||||
return result;
|
||||
return(result);
|
||||
}
|
||||
|
||||
enum{
|
||||
|
@ -1054,7 +1007,6 @@ file_create_from_string(System_Functions *system, Models *models,
|
|||
String val, b8 read_only = 0){
|
||||
|
||||
Font_Set *font_set = models->font_set;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
General_Memory *general = &models->mem.general;
|
||||
Partition *part = &models->mem.part;
|
||||
Buffer_Init_Type init;
|
||||
|
@ -1074,16 +1026,12 @@ file_create_from_string(System_Functions *system, Models *models,
|
|||
Assert(scratch_size > 0);
|
||||
|
||||
b32 init_success = buffer_end_init(&init, part->base + part->pos, scratch_size);
|
||||
AllowLocal(init_success);
|
||||
Assert(init_success);
|
||||
AllowLocal(init_success); Assert(init_success);
|
||||
|
||||
if (buffer_size(&file->state.buffer) < val.size){
|
||||
file->settings.dos_write_mode = 1;
|
||||
}
|
||||
|
||||
file_init_strings(file);
|
||||
file_set_name(working_set, file, (char*)name);
|
||||
|
||||
file_synchronize_times(system, file);
|
||||
|
||||
i16 font_id = models->global_font.font_id;
|
||||
|
@ -1129,15 +1077,6 @@ file_create_from_string(System_Functions *system, Models *models,
|
|||
file->settings.is_initialized = 1;
|
||||
}
|
||||
|
||||
#undef TEST_TIME_MAX
|
||||
|
||||
internal b32
|
||||
file_create_empty(System_Functions *system,
|
||||
Models *models, Editing_File *file, char *filename){
|
||||
file_create_from_string(system, models, file, filename, string_zero());
|
||||
return (1);
|
||||
}
|
||||
|
||||
internal b32
|
||||
file_create_read_only(System_Functions *system,
|
||||
Models *models, Editing_File *file, char *filename){
|
||||
|
@ -3232,7 +3171,6 @@ view_show_file(View *view){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
internal String
|
||||
make_string_terminated(Partition *part, char *str, i32 len){
|
||||
char *space = (char*)push_array(part, char, len + 1);
|
||||
|
@ -3243,68 +3181,9 @@ make_string_terminated(Partition *part, char *str, i32 len){
|
|||
return(string);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_save_file(System_Functions *system, Models *models,
|
||||
Editing_File *file, View *view, String filename, b32 save_as){
|
||||
Mem_Options *mem = &models->mem;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(&mem->part);
|
||||
|
||||
String filename_string =
|
||||
make_string_terminated(&mem->part, filename.str, filename.size);
|
||||
|
||||
if (!file){
|
||||
if (view){
|
||||
file = view->file_data.file;
|
||||
}
|
||||
else{
|
||||
file = working_set_lookup_file(working_set, filename_string);
|
||||
}
|
||||
}
|
||||
|
||||
if (file && (file_get_sync(file) != SYNC_GOOD || save_as)){
|
||||
if (file_save(system, mem, file, filename_string.str)){
|
||||
if (save_as){
|
||||
file_set_name(working_set, file, filename_string.str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
internal void
|
||||
view_new_file(System_Functions *system, Models *models,
|
||||
View *view, String string){
|
||||
Working_Set *working_set = &models->working_set;
|
||||
General_Memory *general = &models->mem.general;
|
||||
|
||||
Editing_File *file = working_set_alloc_always(working_set, general);
|
||||
file_create_empty(system, models, file, string.str);
|
||||
working_set_add(system, working_set, file, general);
|
||||
|
||||
view_set_file(view, file, models);
|
||||
view_show_file(view);
|
||||
view->map = get_map(models, file->settings.base_map_id);
|
||||
|
||||
Open_File_Hook_Function *new_file_fnc = models->hook_new_file;
|
||||
if (new_file_fnc){
|
||||
new_file_fnc(&models->app_links, file->id.id);
|
||||
}
|
||||
file->settings.is_initialized = 1;
|
||||
|
||||
#if BUFFER_EXPERIMENT_SCALPEL <= 0
|
||||
if (file->settings.tokens_exist && file->state.token_stack.tokens == 0){
|
||||
file_first_lex_parallel(system, general, file);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void
|
||||
init_normal_file(System_Functions *system, Models *models, Editing_File *file,
|
||||
char *buffer, i32 size){
|
||||
|
||||
General_Memory *general = &models->mem.general;
|
||||
|
||||
String val = make_string(buffer, size);
|
||||
|
@ -3322,77 +3201,106 @@ init_normal_file(System_Functions *system, Models *models, Editing_File *file,
|
|||
}
|
||||
|
||||
internal void
|
||||
view_open_file(System_Functions *system, Models *models,
|
||||
View *view, String filename){
|
||||
view_interactive_open_file(System_Functions *system, Models *models, View *view, String filename){
|
||||
Working_Set *working_set = &models->working_set;
|
||||
General_Memory *general = &models->mem.general;
|
||||
Partition *part = &models->mem.part;
|
||||
Editing_File *file = 0;
|
||||
Unique_Hash index = {0};
|
||||
|
||||
Editing_File *file = working_set_contains(system, working_set, filename);
|
||||
|
||||
if (file == 0){
|
||||
File_Loading loading = system->file_load_begin(filename.str);
|
||||
|
||||
if (loading.exists){
|
||||
b32 in_general_mem = 0;
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
char *buffer = push_array(part, char, loading.size);
|
||||
|
||||
// TODO(allen): How will we get temporary space for large
|
||||
// buffers? The main partition isn't always big enough
|
||||
// but getting a general block this large and copying it
|
||||
// then freeing it is *super* dumb!
|
||||
if (buffer == 0){
|
||||
buffer = (char*)general_memory_allocate(general, loading.size);
|
||||
if (buffer != 0){
|
||||
in_general_mem = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (system->file_load_end(loading, buffer)){
|
||||
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;
|
||||
|
||||
file = working_set_alloc_always(working_set, general);
|
||||
if (file){
|
||||
file_init_strings(file);
|
||||
file_set_name(working_set, file, filename.str);
|
||||
working_set_add(system, working_set, file, general);
|
||||
|
||||
init_normal_file(system, models, file,
|
||||
buffer, loading.size);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (in_general_mem){
|
||||
general_memory_free(general, buffer);
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
}
|
||||
|
||||
if (file){
|
||||
if (view){
|
||||
view_set_file(view, file, models);
|
||||
view_show_file(view);
|
||||
}
|
||||
view_set_file(view, file, models);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
kill_file(System_Functions *system, Models *models,
|
||||
Editing_File *file, String string){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 (!file && string.str){
|
||||
file = working_set_lookup_file(working_set, string);
|
||||
if (!file){
|
||||
file = working_set_contains(system, working_set, string);
|
||||
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())){
|
||||
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);
|
||||
|
||||
init_normal_file(system, models, file, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (file){
|
||||
view_set_file(view, file, models);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
kill_file(System_Functions *system, Models *models, Editing_File *file){
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
if (file && !file->settings.never_kill){
|
||||
working_set_remove(system, working_set, file->name.source_path);
|
||||
buffer_unbind_name(working_set, file);
|
||||
buffer_unbind_file(system, working_set, file);
|
||||
file_close(system, &models->mem.general, file);
|
||||
working_set_free_file(&models->working_set, file);
|
||||
working_set_free_file(working_set, file);
|
||||
|
||||
File_Node *used = &models->working_set.used_sentinel;
|
||||
File_Node *node = used->next;
|
||||
|
@ -3412,25 +3320,29 @@ kill_file(System_Functions *system, Models *models,
|
|||
}
|
||||
}
|
||||
|
||||
internal b32
|
||||
try_kill_file(System_Functions *system, Models *models,
|
||||
Editing_File *file, View *view, String string){
|
||||
|
||||
b32 kill_dialogue = false;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
if (!file && string.str){
|
||||
file = working_set_lookup_file(working_set, string);
|
||||
if (!file){
|
||||
file = working_set_contains(system, working_set, string);
|
||||
}
|
||||
internal void
|
||||
kill_file_by_name(System_Functions *system, Models *models, String name){
|
||||
Editing_File *file = working_set_name_contains(&models->working_set, name);
|
||||
if (file){
|
||||
kill_file(system, models, file);
|
||||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
save_file_by_name(System_Functions *system, Models *models, String name){
|
||||
Editing_File *file = working_set_name_contains(&models->working_set, name);
|
||||
if (file){
|
||||
file_save(system, &models->mem, file);
|
||||
}
|
||||
}
|
||||
|
||||
internal b32
|
||||
interactive_try_kill_file(System_Functions *system, Models *models, View *view, String name){
|
||||
b32 kill_dialogue = false;
|
||||
|
||||
Editing_File *file = working_set_name_contains(&models->working_set, name);
|
||||
if (file && !file->settings.never_kill){
|
||||
if (buffer_needs_save(file)){
|
||||
if (view == 0){
|
||||
view = models->layout.panels[models->layout.active_panel].view;
|
||||
}
|
||||
view_show_interactive(system, view,
|
||||
IAct_Sure_To_Kill, IInt_Sure_To_Kill,
|
||||
make_lit_string("Are you sure?"));
|
||||
|
@ -3438,7 +3350,7 @@ try_kill_file(System_Functions *system, Models *models,
|
|||
kill_dialogue = true;
|
||||
}
|
||||
else{
|
||||
kill_file(system, models, file, string_zero());
|
||||
kill_file(system, models, file);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3448,37 +3360,28 @@ try_kill_file(System_Functions *system, Models *models,
|
|||
internal void
|
||||
interactive_view_complete(System_Functions *system, View *view, String dest, i32 user_action){
|
||||
Models *models = view->persistent.models;
|
||||
//Editing_File *old_file = view->file_data.file;
|
||||
|
||||
switch (view->action){
|
||||
case IAct_Open:
|
||||
view_open_file(system, models, view, dest);
|
||||
//touch_file(&models->working_set, old_file);
|
||||
view_interactive_open_file(system, models, view, dest);
|
||||
view_show_file(view);
|
||||
break;
|
||||
|
||||
case IAct_Save_As:
|
||||
view_save_file(system, models, 0, view, dest, 1);
|
||||
view_interactive_save_as(system, models, view->file_data.file, dest);
|
||||
view_show_file(view);
|
||||
break;
|
||||
|
||||
case IAct_New:
|
||||
if (dest.size > 0 && !char_is_slash(dest.str[dest.size-1])){
|
||||
view_new_file(system, models, view, dest);
|
||||
view_interactive_new_file(system, models, view, dest);
|
||||
view_show_file(view);
|
||||
}break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IAct_Switch:
|
||||
{
|
||||
//touch_file(&models->working_set, old_file);
|
||||
|
||||
Editing_File *file = 0;
|
||||
String string = dest;
|
||||
|
||||
file = working_set_lookup_file(&models->working_set, string);
|
||||
if (!file){
|
||||
file = working_set_contains(system, &models->working_set, string);
|
||||
}
|
||||
Editing_File *file = working_set_name_contains(&models->working_set, dest);
|
||||
if (file){
|
||||
view_set_file(view, file, models);
|
||||
}
|
||||
|
@ -3487,7 +3390,7 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32
|
|||
break;
|
||||
|
||||
case IAct_Kill:
|
||||
if (!try_kill_file(system, models, 0, 0, dest)){
|
||||
if (!interactive_try_kill_file(system, models, view, dest)){
|
||||
view_show_file(view);
|
||||
}
|
||||
break;
|
||||
|
@ -3511,7 +3414,7 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32
|
|||
case IAct_Sure_To_Kill:
|
||||
switch (user_action){
|
||||
case 0:
|
||||
kill_file(system, models, 0, dest);
|
||||
kill_file_by_name(system, models, dest);
|
||||
view_show_file(view);
|
||||
break;
|
||||
|
||||
|
@ -3520,8 +3423,8 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32
|
|||
break;
|
||||
|
||||
case 2:
|
||||
view_save_file(system, models, 0, 0, dest, 0);
|
||||
kill_file(system, models, 0, dest);
|
||||
save_file_by_name(system, models, dest);
|
||||
kill_file_by_name(system, models, dest);
|
||||
view_show_file(view);
|
||||
break;
|
||||
}
|
||||
|
@ -3746,7 +3649,7 @@ 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_contains(system, working_set, loop->full_path);
|
||||
file = working_set_uhash_contains(system, working_set, loop->full_path);
|
||||
|
||||
String filename = make_string(result.info->filename,
|
||||
result.info->filename_len, result.info->filename_len+1);
|
||||
|
@ -4715,7 +4618,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
|
|||
// Time Watcher
|
||||
{
|
||||
string.size = 0;
|
||||
u64 time = system->now_time_stamp();
|
||||
u64 time = 0;
|
||||
system->now_file_time(&time);
|
||||
|
||||
append(&string, "last redraw: ");
|
||||
append_u64_to_str(&string, time);
|
||||
|
|
Loading…
Reference in New Issue