setting up better organization for file system

This commit is contained in:
Allen Webster 2017-01-03 15:05:35 -05:00
parent 5f00639970
commit 1ef304558e
15 changed files with 1376 additions and 1317 deletions

View File

@ -2019,6 +2019,7 @@ typedef struct Absolutes{
static void
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
if (name.size != 0){
int32_t count = 0;
int32_t max = ArrayCount(absolutes->a) - 1;
if (implicit_last) --max;
@ -2061,11 +2062,17 @@ get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_
}
absolutes->count = count;
}
else{
absolutes->count = 0;
}
}
static fstr_bool
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
fstr_bool r = 1;
if (absolutes->count > 0){
String *a = absolutes->a;
fstr_bool (*match_func)(char*, String);
@ -2118,6 +2125,7 @@ wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
}
}
}
}
return(r);
}

View File

@ -1732,7 +1732,7 @@ App_Init_Sig(app_init){
models->layout.active_panel = p.id;
String hdbase = make_fixed_width_string(models->hot_dir_base_);
hot_directory_init(&models->hot_directory, hdbase, current_directory, system->slash);
hot_directory_init(&models->hot_directory, hdbase, current_directory);
// NOTE(allen): child proc list setup
i32 max_children = 16;
@ -2870,7 +2870,7 @@ App_Step_Sig(app_step){
// end-of-app_step
}
external App_Get_Functions_Sig(app_get_functions){
extern "C" App_Get_Functions_Sig(app_get_functions){
App_Functions result = {};
result.read_command_line = app_read_command_line;

View File

@ -45,7 +45,10 @@
#include "buffer/4coder_gap_buffer.cpp"
#define Buffer_Type Gap_Buffer
#include "buffer/4coder_buffer_abstract.cpp"
#include "4ed_file.cpp"
#include "file/4coder_file.cpp"
#include "file/4coder_working_set.cpp"
#include "file/4coder_hot_directory.cpp"
#include "4ed_gui.cpp"
#include "4ed_layout.cpp"

View File

@ -11,8 +11,10 @@
#define FRED_DEFINES_H
#include <string.h>
#include <stdint.h>
#if !defined (FRED_TYPES)
#include <stdint.h>
#define FRED_TYPES
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
@ -34,12 +36,12 @@ typedef double real64;
typedef float f32;
typedef double f64;
#define external extern "C"
#define internal static
#define globalvar static
#define persist static
#define globalconst static const
#endif
#define COMP_ID_(a,b,c,d) (d << 24) | (c << 16) | (b << 8) | a
#define COMPOSE_ID(a,b,c,d) (COMP_ID_((a),(b),(c),(d)))

View File

@ -596,11 +596,9 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll,
}
internal void
view_set_cursor(View *view, Full_Cursor cursor,
b32 set_preferred_x, b32 unwrapped_lines){
view_set_cursor(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
edit_pos_set_cursor_(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
edit_pos_set_cursor(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
GUI_Scroll_Vars scroll = view->edit_pos->scroll;
if (view_move_view_to_cursor(view, &scroll, 0)){
view->edit_pos->scroll = scroll;
@ -609,11 +607,9 @@ view_set_cursor(View *view, Full_Cursor cursor,
}
internal void
view_set_scroll(View *view,
GUI_Scroll_Vars scroll){
view_set_scroll(View *view, GUI_Scroll_Vars scroll){
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
edit_pos_set_scroll_(view->edit_pos, scroll);
edit_pos_set_scroll(view->edit_pos, scroll);
Full_Cursor cursor = view->edit_pos->cursor;
if (view_move_cursor_to_view(view, view->edit_pos->scroll,
&cursor, view->edit_pos->preferred_x)){
@ -623,15 +619,11 @@ view_set_scroll(View *view,
}
internal void
view_set_cursor_and_scroll(View *view,
Full_Cursor cursor,
b32 set_preferred_x,
b32 unwrapped_lines,
GUI_Scroll_Vars scroll){
view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines, GUI_Scroll_Vars scroll){
File_Edit_Positions *edit_pos = view->edit_pos;
if (edit_pos_move_to_front(view->file_data.file, edit_pos)){
edit_pos_set_cursor_(edit_pos, cursor, set_preferred_x, unwrapped_lines);
edit_pos_set_scroll_(edit_pos, scroll);
edit_pos_set_cursor(edit_pos, cursor, set_preferred_x, unwrapped_lines);
edit_pos_set_scroll(edit_pos, scroll);
edit_pos->last_set_type = EditPos_None;
}
}
@ -1251,12 +1243,15 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16
}
else if (type == CPP_TOKEN_PARENTHESE_OPEN){
if (on_left){
guess = 0;
guess = 100;
}
else{
if (other_is_words){
guess = 100;
}
else{
guess = 0;
}
}
}
else if (type == CPP_TOKEN_SEMICOLON){
@ -3700,7 +3695,7 @@ view_show_interactive(System_Functions *system, View *view,
view->map = &models->map_ui;
hot_directory_clean_end(&models->hot_directory);
hot_directory_reload(system, &models->hot_directory, &models->working_set);
hot_directory_reload(system, &models->hot_directory);
view->changed_context_in_step = 1;
}
@ -4271,11 +4266,10 @@ get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhausti
file = working_set_canon_contains(working_set, canon_name.name);
}
String filename = make_string_cap(result.info->filename,
result.info->filename_len, result.info->filename_len+1);
String filename = make_string_cap(result.info->filename, result.info->filename_len, result.info->filename_len+1);
result.is_folder = (result.info->folder != 0);
result.name_match = (filename_match(loop->front_name, &loop->absolutes, filename) != 0);
result.name_match = (wildcard_match_s(&loop->absolutes, filename, 0) != 0);
result.is_loaded = (file != 0 && file_is_ready(file));
result.message = null_string;
@ -4379,7 +4373,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, K
if (char_is_slash(end_character)){
mode.string->size = reverse_seek_slash(*mode.string) + 1;
mode.string->str[mode.string->size] = 0;
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
hot_directory_set(system, mode.hot_directory, *mode.string);
}
else{
mode.string->str[mode.string->size] = 0;
@ -4411,7 +4405,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, K
mode.string->size++;
mode.string->str[mode.string->size] = 0;
if (mode.type == SINGLE_LINE_FILE && char_is_slash(new_character)){
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
hot_directory_set(system, mode.hot_directory, *mode.string);
}
result.made_a_change = 1;
}
@ -5021,7 +5015,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
}
if (do_new_directory){
hot_directory_reload(system, hdir, &models->working_set);
hot_directory_reload(system, hdir);
}
gui_end_scrollable(target);
@ -5088,7 +5082,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
Editing_File *file = (Editing_File*)node;
Assert(!file->is_dummy);
if (filename_match(view->dest, &absolutes, file->name.live_name)){
if (wildcard_match_s(&absolutes, file->name.live_name, 0) != 0){
View_Iter iter = file_view_iter_init(layout, file, 0);
if (file_view_iter_good(iter)){
reserved_files[reserved_top++] = file;
@ -6530,7 +6524,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol
String m = gui_read_string(&ptr);
if (folder){
append_s_char(&f, system->slash);
append_s_char(&f, '/');
}
draw_fat_option_block(gui_target, target, view, font_id, gui_session.rect, b->id, f, m);

View File

@ -146,10 +146,10 @@ struct Thread_Exchange;
struct System_Functions;
#define Job_Callback_Sig(name) void name( \
System_Functions *system, \
Thread_Context *thread, \
Thread_Memory *memory, \
void *data[2])
System_Functions *system, \
Thread_Context *thread, \
Thread_Memory *memory, \
void *data[2])
typedef Job_Callback_Sig(Job_Callback);
struct Job_Data{
@ -258,9 +258,6 @@ struct System_Functions{
// debug: 1
INTERNAL_System_Get_Thread_States *internal_get_thread_states;
// non-function details
char slash;
};
// BOTTOM

434
file/4coder_file.cpp Normal file
View File

@ -0,0 +1,434 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 03.01.2017
*
* File layer for 4coder
*
*/
// TOP
//
// Edit Position Basics
//
enum Edit_Pos_Set_Type{
EditPos_None,
EditPos_CursorSet,
EditPos_ScrollSet
};
struct File_Edit_Positions{
GUI_Scroll_Vars scroll;
Full_Cursor cursor;
i32 mark;
f32 preferred_x;
i32 scroll_i;
i32 last_set_type;
b32 in_view;
};
static File_Edit_Positions null_edit_pos = {0};
internal void
edit_pos_set_cursor(File_Edit_Positions *edit_pos, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
edit_pos->cursor = cursor;
if (set_preferred_x){
edit_pos->preferred_x = cursor.wrapped_x;
if (unwrapped_lines){
edit_pos->preferred_x = cursor.unwrapped_x;
}
}
edit_pos->last_set_type = EditPos_CursorSet;
}
internal void
edit_pos_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
edit_pos->scroll = scroll;
edit_pos->last_set_type = EditPos_ScrollSet;
}
//
// Undo Basics
//
enum Edit_Type{
ED_NORMAL,
ED_REVERSE_NORMAL,
ED_UNDO,
ED_REDO,
};
struct Edit_Step{
Edit_Type type;
union{
struct{
b32 can_merge;
Buffer_Edit edit;
i32 next_block;
i32 prev_block;
};
struct{
i32 first_child;
i32 inverse_first_child;
i32 inverse_child_count;
i32 special_type;
};
};
i32 child_count;
};
struct Edit_Stack{
u8 *strings;
i32 size, max;
Edit_Step *edits;
i32 edit_count, edit_max;
};
struct Small_Edit_Stack{
u8 *strings;
i32 size, max;
Buffer_Edit *edits;
i32 edit_count, edit_max;
};
struct Undo_Data{
Edit_Stack undo;
Edit_Stack redo;
Edit_Stack history;
Small_Edit_Stack children;
i32 history_block_count, history_head_block;
i32 edit_history_cursor;
b32 current_block_normal;
};
//
// Highlighting Information
//
struct Text_Effect{
i32 start, end;
u32 color;
f32 seconds_down, seconds_max;
};
//
// Editing_File
//
struct Editing_File_Settings{
i32 base_map_id;
i32 display_width;
i32 minimum_base_display_width;
i32 wrap_indicator;
b32 dos_write_mode;
b32 virtual_white;
i16 font_id;
b8 unwrapped_lines;
b8 tokens_exist;
b8 is_initialized;
b8 unimportant;
b8 read_only;
b8 never_kill;
};
static Editing_File_Settings null_editing_file_settings = {0};
struct Editing_File_State{
Buffer_Type buffer;
i32 *wrap_line_index;
i32 wrap_max;
i32 *character_starts;
i32 character_start_max;
f32 *line_indents;
i32 line_indent_max;
i32 wrap_line_count;
i32 *wrap_positions;
i32 wrap_position_count;
i32 wrap_position_max;
Undo_Data undo;
Cpp_Token_Array token_array;
Cpp_Token_Array swap_array;
u32 lex_job;
b32 tokens_complete;
b32 still_lexing;
Text_Effect paste_effect;
Dirty_State dirty;
u32 ignore_behind_os;
File_Edit_Positions edit_pos_space[16];
File_Edit_Positions *edit_poss[16];
i32 edit_poss_count;
};
static Editing_File_State null_editing_file_state = {0};
struct Editing_File_Name{
char live_name_[256];
char source_path_[256];
char extension_[16];
String live_name;
String source_path;
String extension;
};
struct Editing_File_Canon_Name{
char name_[256];
String name;
};
struct File_Node{
File_Node *next, *prev;
};
union Buffer_Slot_ID{
i32 id;
i16 part[2];
};
inline Buffer_Slot_ID
to_file_id(i32 id){
Buffer_Slot_ID result;
result.id = id;
return(result);
}
struct Editing_File{
// NOTE(allen): node must be the first member of Editing_File!
File_Node node;
Editing_File_Settings settings;
struct{
b32 is_loading;
b32 is_dummy;
Editing_File_State state;
};
Editing_File_Name name;
Editing_File_Canon_Name canon;
Buffer_Slot_ID id;
u64 unique_buffer_id;
};
static Editing_File null_editing_file = {0};
//
// Manipulating a file's Edit_Pos array
//
internal i32
edit_pos_get_index(Editing_File *file, File_Edit_Positions *edit_pos){
i32 edit_pos_index = -1;
i32 count = file->state.edit_poss_count;
File_Edit_Positions **edit_poss = file->state.edit_poss;
for (i32 i = 0; i < count; ++i){
if (edit_poss[i] == edit_pos){
edit_pos_index = i;
break;
}
}
return(edit_pos_index);
}
internal b32
edit_pos_move_to_front(Editing_File *file, File_Edit_Positions *edit_pos){
b32 result = false;
if (file && edit_pos){
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
Assert(edit_pos_index != -1);
File_Edit_Positions **edit_poss = file->state.edit_poss;
memmove(edit_poss + 1, edit_poss, edit_pos_index*sizeof(*edit_poss));
edit_poss[0] = edit_pos;
result = true;
}
return(result);
}
internal b32
edit_pos_unset(Editing_File *file, File_Edit_Positions *edit_pos){
b32 result = false;
if (file && edit_pos){
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
Assert(edit_pos_index != -1);
i32 count = file->state.edit_poss_count;
File_Edit_Positions **edit_poss = file->state.edit_poss;
memmove(edit_poss + edit_pos_index,
edit_poss + edit_pos_index + 1,
(count - edit_pos_index - 1)*sizeof(*edit_poss));
edit_pos->in_view = false;
if (file->state.edit_poss_count > 1){
file->state.edit_poss_count -= 1;
}
result = true;
}
return(result);
}
internal File_Edit_Positions*
edit_pos_get_new(Editing_File *file, i32 index){
File_Edit_Positions *result = 0;
if (file && 0 <= index && index < 16){
result = file->state.edit_pos_space + index;
i32 edit_pos_index = edit_pos_get_index(file, result);
if (edit_pos_index == -1){
File_Edit_Positions **edit_poss = file->state.edit_poss;
i32 count = file->state.edit_poss_count;
if (count > 0){
if (edit_poss[0]->in_view){
memcpy(result, edit_poss[0], sizeof(*result));
memmove(edit_poss+1, edit_poss, sizeof(*edit_poss)*count);
file->state.edit_poss_count = count + 1;
}
else{
Assert(count == 1);
memcpy(result, edit_poss[0], sizeof(*result));
}
}
else{
memset(result, 0, sizeof(*result));
file->state.edit_poss_count = 1;
}
edit_poss[0] = result;
}
result->in_view = true;
}
return(result);
}
//
// Cursor Seeking
//
inline Partial_Cursor
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
return(result);
}
inline Partial_Cursor
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
return(result);
}
inline b32
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
b32 result = 1;
switch (seek.type){
case buffer_seek_pos:
{
*cursor = file_compute_cursor_from_pos(file, seek.pos);
}break;
case buffer_seek_line_char:
{
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
}break;
default:
{
result = 0;
}break;
}
return(result);
}
//
// Dirty Flags
//
inline b32
buffer_needs_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
if (file->state.dirty == DirtyState_UnsavedChanges){
result = 1;
}
}
return(result);
}
inline b32
buffer_can_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
if (file->state.dirty == DirtyState_UnsavedChanges ||
file->state.dirty == DirtyState_UnloadedChanges){
result = 1;
}
}
return(result);
}
inline b32
file_is_ready(Editing_File *file){
b32 result = 0;
if (file && file->is_loading == 0){
result = 1;
}
return(result);
}
inline void
file_set_to_loading(Editing_File *file){
file->state = null_editing_file_state;
file->settings = null_editing_file_settings;
file->is_loading = 1;
}
inline void
file_mark_clean(Editing_File *file){
if (file->state.dirty != DirtyState_UnloadedChanges){
file->state.dirty = DirtyState_UpToDate;
}
}
inline void
file_mark_dirty(Editing_File *file){
if (file->state.dirty != DirtyState_UnloadedChanges){
file->state.dirty = DirtyState_UnsavedChanges;
}
}
inline void
file_mark_behind_os(Editing_File *file){
file->state.dirty = DirtyState_UnloadedChanges;
}
inline Dirty_State
file_get_sync(Editing_File *file){
return (file->state.dirty);
}
// BOTTOM

View File

@ -0,0 +1,19 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 03.01.2017
*
* File layer for 4coder
*
*/
// TOP
#include "4coder_file.cpp"
int main(){
return(0);
}
// BOTTOM

View File

@ -0,0 +1,93 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 03.01.2017
*
* Hot_Directory data structure for 4coder
*
*/
// TOP
struct Hot_Directory{
String string;
File_List file_list;
};
internal void
hot_directory_clean_end(Hot_Directory *hot_directory){
String *str = &hot_directory->string;
if (str->size != 0 && str->str[str->size-1] != '/'){
str->size = reverse_seek_slash(*str) + 1;
str->str[str->size] = 0;
}
}
internal i32
hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){
File_Info *p = infos + pivot;
File_Info *a = infos + start;
for (i32 i = start; i < pivot; ++i, ++a){
i32 comp = 0;
comp = p->folder - a->folder;
if (comp == 0){
comp = compare_cc(a->filename, p->filename);
}
if (comp < 0){
Swap(File_Info, *a, infos[start]);
++start;
}
}
Swap(File_Info, *p, infos[start]);
return start;
}
internal void
hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){
i32 mid = hot_directory_quick_partition(infos, start, pivot);
if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1);
if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot);
}
inline void
hot_directory_fixup(Hot_Directory *hot_directory){
File_List *files = &hot_directory->file_list;
if (files->count >= 2){
hot_directory_quick_sort(files->infos, 0, files->count - 1);
}
}
inline void
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String str){
b32 success = copy_checked_ss(&hot_directory->string, str);
terminate_with_null(&hot_directory->string);
if (success){
if (str.size > 0){
system->set_file_list(&hot_directory->file_list, str);
}
else{
system->set_file_list(&hot_directory->file_list, make_string((char*)1, 0));
}
}
hot_directory_fixup(hot_directory);
}
inline void
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){
system->set_file_list(&hot_directory->file_list, hot_directory->string);
hot_directory_fixup(hot_directory);
}
internal void
hot_directory_init(Hot_Directory *hot_directory, String base, String dir){
hot_directory->string = base;
hot_directory->string.str[255] = 0;
hot_directory->string.size = 0;
copy_ss(&hot_directory->string, dir);
if (hot_directory->string.str[hot_directory->string.size-1] != '/'){
append_s_char(&hot_directory->string, '/');
}
}
// BOTTOM

View File

@ -1,193 +1,17 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 20.02.2016
* 03.01.2017
*
* File editing view for 4coder
* Working_Set data structure for 4coder
*
*/
// TOP
enum Edit_Pos_Set_Type{
EditPos_None,
EditPos_CursorSet,
EditPos_ScrollSet
};
struct File_Edit_Positions{
GUI_Scroll_Vars scroll;
Full_Cursor cursor;
i32 mark;
f32 preferred_x;
i32 scroll_i;
i32 last_set_type;
b32 in_view;
};
static File_Edit_Positions null_edit_pos = {0};
enum Edit_Type{
ED_NORMAL,
ED_REVERSE_NORMAL,
ED_UNDO,
ED_REDO,
};
struct Edit_Step{
Edit_Type type;
union{
struct{
b32 can_merge;
Buffer_Edit edit;
i32 next_block;
i32 prev_block;
};
struct{
i32 first_child;
i32 inverse_first_child;
i32 inverse_child_count;
i32 special_type;
};
};
i32 child_count;
};
struct Edit_Stack{
u8 *strings;
i32 size, max;
Edit_Step *edits;
i32 edit_count, edit_max;
};
struct Small_Edit_Stack{
u8 *strings;
i32 size, max;
Buffer_Edit *edits;
i32 edit_count, edit_max;
};
struct Undo_Data{
Edit_Stack undo;
Edit_Stack redo;
Edit_Stack history;
Small_Edit_Stack children;
i32 history_block_count, history_head_block;
i32 edit_history_cursor;
b32 current_block_normal;
};
struct Text_Effect{
i32 start, end;
u32 color;
f32 seconds_down, seconds_max;
};
// NOTE(allen): The Editing_File struct is now divided into two
// parts. Variables in the Settings part can be set even when the
// file is still streaming in, and persists thorugh all operations except
// for the initial allocation of the file.
struct Editing_File_Settings{
i32 base_map_id;
i32 display_width;
i32 minimum_base_display_width;
i32 wrap_indicator;
b32 dos_write_mode;
b32 virtual_white;
i16 font_id;
b8 unwrapped_lines;
b8 tokens_exist;
b8 is_initialized;
b8 unimportant;
b8 read_only;
b8 never_kill;
};
static Editing_File_Settings null_editing_file_settings = {0};
// NOTE(allen): This part of the Editing_File is cleared whenever
// the contents of the file is set.
struct Editing_File_State{
Buffer_Type buffer;
i32 *wrap_line_index;
i32 wrap_max;
i32 *character_starts;
i32 character_start_max;
f32 *line_indents;
i32 line_indent_max;
i32 wrap_line_count;
i32 *wrap_positions;
i32 wrap_position_count;
i32 wrap_position_max;
Undo_Data undo;
Cpp_Token_Array token_array;
Cpp_Token_Array swap_array;
u32 lex_job;
b32 tokens_complete;
b32 still_lexing;
Text_Effect paste_effect;
Dirty_State dirty;
u32 ignore_behind_os;
File_Edit_Positions edit_pos_space[16];
File_Edit_Positions *edit_poss[16];
i32 edit_poss_count;
};
static Editing_File_State null_editing_file_state = {0};
struct Editing_File_Name{
char live_name_[256];
char source_path_[256];
char extension_[16];
String live_name;
String source_path;
String extension;
};
struct Editing_File_Canon_Name{
char name_[256];
String name;
};
struct File_Node{
File_Node *next, *prev;
};
union Buffer_Slot_ID{
i32 id;
i16 part[2];
};
inline Buffer_Slot_ID
to_file_id(i32 id){
Buffer_Slot_ID result;
result.id = id;
return(result);
}
struct Editing_File{
// NOTE(allen): node must be the first member of Editing_File!
File_Node node;
Editing_File_Settings settings;
struct{
b32 is_loading;
b32 is_dummy;
Editing_File_State state;
};
Editing_File_Name name;
Editing_File_Canon_Name canon;
Buffer_Slot_ID id;
u64 unique_buffer_id;
};
//
// Working_Set of files
//
struct Non_File_Table_Entry{
String name;
@ -222,176 +46,12 @@ struct Working_Set{
i32 default_minimum_base_display_width;
};
//
// File_Edit_Positions stuff
//
internal void
edit_pos_set_cursor_(File_Edit_Positions *edit_pos,
Full_Cursor cursor,
b32 set_preferred_x,
b32 unwrapped_lines){
edit_pos->cursor = cursor;
if (set_preferred_x){
edit_pos->preferred_x = cursor.wrapped_x;
if (unwrapped_lines){
edit_pos->preferred_x = cursor.unwrapped_x;
}
}
edit_pos->last_set_type = EditPos_CursorSet;
}
internal void
edit_pos_set_scroll_(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
edit_pos->scroll = scroll;
edit_pos->last_set_type = EditPos_ScrollSet;
}
internal i32
edit_pos_get_index(Editing_File *file, File_Edit_Positions *edit_pos){
i32 edit_pos_index = -1;
i32 count = file->state.edit_poss_count;
File_Edit_Positions **edit_poss = file->state.edit_poss;
for (i32 i = 0; i < count; ++i){
if (edit_poss[i] == edit_pos){
edit_pos_index = i;
break;
}
}
return(edit_pos_index);
}
internal b32
edit_pos_move_to_front(Editing_File *file, File_Edit_Positions *edit_pos){
b32 result = false;
if (file && edit_pos){
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
Assert(edit_pos_index != -1);
File_Edit_Positions **edit_poss = file->state.edit_poss;
memmove(edit_poss + 1, edit_poss, edit_pos_index*sizeof(*edit_poss));
edit_poss[0] = edit_pos;
result = true;
}
return(result);
}
internal b32
edit_pos_unset(Editing_File *file, File_Edit_Positions *edit_pos){
b32 result = false;
if (file && edit_pos){
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
Assert(edit_pos_index != -1);
i32 count = file->state.edit_poss_count;
File_Edit_Positions **edit_poss = file->state.edit_poss;
memmove(edit_poss + edit_pos_index,
edit_poss + edit_pos_index + 1,
(count - edit_pos_index - 1)*sizeof(*edit_poss));
edit_pos->in_view = false;
if (file->state.edit_poss_count > 1){
file->state.edit_poss_count -= 1;
}
result = true;
}
return(result);
}
internal File_Edit_Positions*
edit_pos_get_new(Editing_File *file, i32 index){
File_Edit_Positions *result = 0;
if (file && 0 <= index && index < 16){
result = file->state.edit_pos_space + index;
i32 edit_pos_index = edit_pos_get_index(file, result);
if (edit_pos_index == -1){
File_Edit_Positions **edit_poss = file->state.edit_poss;
i32 count = file->state.edit_poss_count;
if (count > 0){
if (edit_poss[0]->in_view){
memcpy(result, edit_poss[0], sizeof(*result));
memmove(edit_poss+1, edit_poss, sizeof(*edit_poss)*count);
file->state.edit_poss_count = count + 1;
}
else{
Assert(count == 1);
memcpy(result, edit_poss[0], sizeof(*result));
}
}
else{
memset(result, 0, sizeof(*result));
file->state.edit_poss_count = 1;
}
edit_poss[0] = result;
}
result->in_view = true;
}
return(result);
}
//
// File Cursor Seeking
//
inline Partial_Cursor
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
return(result);
}
inline Partial_Cursor
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
return(result);
}
inline b32
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
b32 result = 1;
switch (seek.type){
case buffer_seek_pos:
{
*cursor = file_compute_cursor_from_pos(file, seek.pos);
}break;
case buffer_seek_line_char:
{
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
}break;
default:
{
result = 0;
}break;
}
return(result);
}
//
// Working_Set stuff
//
struct File_Name_Entry{
String name;
Buffer_Slot_ID id;
};
internal i32
tbl_name_compare(void *a, void *b, void *arg){
String *fa = (String*)a;
@ -431,12 +91,6 @@ working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16
}
}
inline Editing_File
editing_file_zero(){
Editing_File file = {0};
return(file);
}
internal Editing_File*
working_set_alloc(Working_Set *working_set){
Editing_File *result = 0;
@ -448,7 +102,7 @@ working_set_alloc(Working_Set *working_set){
dll_remove(node);
Buffer_Slot_ID id = result->id;
*result = editing_file_zero();
*result = null_editing_file;
result->id = id;
result->unique_buffer_id = ++working_set->unique_file_counter;
dll_insert(&working_set->used_sentinel, node);
@ -698,164 +352,10 @@ touch_file(Working_Set *working_set, Editing_File *file){
}
}
// Hot Directory
struct Hot_Directory{
String string;
File_List file_list;
// TODO(allen): eliminate slash
char slash;
};
internal void
hot_directory_clean_end(Hot_Directory *hot_directory){
String *str = &hot_directory->string;
if (str->size != 0 && str->str[str->size-1] != hot_directory->slash){
str->size = reverse_seek_slash(*str) + 1;
str->str[str->size] = 0;
}
}
internal i32
hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){
File_Info *p = infos + pivot;
File_Info *a = infos + start;
for (i32 i = start; i < pivot; ++i, ++a){
i32 comp = 0;
comp = p->folder - a->folder;
if (comp == 0){
comp = compare_cc(a->filename, p->filename);
}
if (comp < 0){
Swap(File_Info, *a, infos[start]);
++start;
}
}
Swap(File_Info, *p, infos[start]);
return start;
}
internal void
hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){
i32 mid = hot_directory_quick_partition(infos, start, pivot);
if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1);
if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot);
}
inline void
hot_directory_fixup(Hot_Directory *hot_directory, Working_Set *working_set){
File_List *files = &hot_directory->file_list;
if (files->count >= 2)
hot_directory_quick_sort(files->infos, 0, files->count - 1);
}
inline void
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory,
String str, Working_Set *working_set){
b32 success = copy_checked_ss(&hot_directory->string, str);
terminate_with_null(&hot_directory->string);
if (success){
if (str.size > 0){
system->set_file_list(&hot_directory->file_list, str);
}
else{
system->set_file_list(&hot_directory->file_list, make_string((char*)1, 0));
}
}
hot_directory_fixup(hot_directory, working_set);
}
inline void
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory, Working_Set *working_set){
system->set_file_list(&hot_directory->file_list, hot_directory->string);
hot_directory_fixup(hot_directory, working_set);
}
internal void
hot_directory_init(Hot_Directory *hot_directory, String base, String dir, char slash){
hot_directory->string = base;
hot_directory->string.str[255] = 0;
hot_directory->string.size = 0;
copy_ss(&hot_directory->string, dir);
append_s_char(&hot_directory->string, slash);
hot_directory->slash = slash;
}
struct Hot_Directory_Match{
String filename;
b32 is_folder;
};
internal b32
filename_match(String query, Absolutes *absolutes, String filename){
b32 result;
result = (query.size == 0);
if (!result) result = wildcard_match_s(absolutes, filename, 0);
return result;
}
inline b32
buffer_needs_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
if (file->state.dirty == DirtyState_UnsavedChanges){
result = 1;
}
}
return(result);
}
inline b32
buffer_can_save(Editing_File *file){
b32 result = 0;
if (!file->settings.unimportant){
if (file->state.dirty == DirtyState_UnsavedChanges ||
file->state.dirty == DirtyState_UnloadedChanges){
result = 1;
}
}
return(result);
}
inline b32
file_is_ready(Editing_File *file){
b32 result = 0;
if (file && file->is_loading == 0){
result = 1;
}
return(result);
}
inline void
file_set_to_loading(Editing_File *file){
file->state = null_editing_file_state;
file->settings = null_editing_file_settings;
file->is_loading = 1;
}
inline void
file_mark_clean(Editing_File *file){
if (file->state.dirty != DirtyState_UnloadedChanges){
file->state.dirty = DirtyState_UpToDate;
}
}
inline void
file_mark_dirty(Editing_File *file){
if (file->state.dirty != DirtyState_UnloadedChanges){
file->state.dirty = DirtyState_UnsavedChanges;
}
}
inline void
file_mark_behind_os(Editing_File *file){
file->state.dirty = DirtyState_UnloadedChanges;
}
inline Dirty_State
file_get_sync(Editing_File *file){
return (file->state.dirty);
}
//
// Name Binding
//
internal void
editing_file_name_init(Editing_File_Name *name){
@ -868,9 +368,7 @@ 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);
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);
@ -928,8 +426,7 @@ 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, String canon_filename){
buffer_bind_file(System_Functions *system, 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);
@ -956,8 +453,7 @@ buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_F
}
internal void
buffer_bind_name(System_Functions *system, General_Memory *general, Working_Set *working_set,
Editing_File *file, String filename){
buffer_bind_name(System_Functions *system, General_Memory *general, Working_Set *working_set, Editing_File *file, String filename){
Assert(file->name.live_name.size == 0 &&
file->name.source_path.size == 0 &&
file->name.extension.size == 0);
@ -984,5 +480,6 @@ buffer_unbind_name(Working_Set *working_set, Editing_File *file){
file->name.extension.size = 0;
}
// BOTTOM

11
file/run_tests.bat Normal file
View File

@ -0,0 +1,11 @@
@echo off
SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX
SET OPTS=%OPTS% /GR- /EHa- /nologo /FC
pushd ..\build
cl %OPTS% ..\code\file\4coder_file_tests.cpp /Zi /Fefile_test
popd
if %ERRORLEVEL% eq 0 (..\build\file_test)

View File

@ -1903,6 +1903,7 @@ typedef struct Absolutes{
static void
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
if (name.size != 0){
int32_t count = 0;
int32_t max = ArrayCount(absolutes->a) - 1;
if (implicit_last) --max;
@ -1945,11 +1946,17 @@ get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_
}
absolutes->count = count;
}
else{
absolutes->count = 0;
}
}
static fstr_bool
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
fstr_bool r = 1;
if (absolutes->count > 0){
String *a = absolutes->a;
fstr_bool (*match_func)(char*, String);
@ -2002,6 +2009,7 @@ wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
}
}
}
}
return(r);
}

View File

@ -116,15 +116,15 @@ struct Application_Links;
#define LinuxGetMemory(size) LinuxGetMemory_(size, __LINE__, __FILE__)
#if FRED_INTERNAL
#define LINUX_FN_DEBUG(fmt, ...) do { \
#define LINUX_FN_DEBUG(fmt, ...) do { \
fprintf(stderr, "%s: " fmt "\n", __func__, ##__VA_ARGS__); \
} while(0)
} while(0)
#else
#define LINUX_FN_DEBUG(fmt, ...)
#define LINUX_FN_DEBUG(fmt, ...)
#endif
#if (__cplusplus <= 199711L)
#define static_assert(x, ...)
#define static_assert(x, ...)
#endif
#define SUPPORT_DPI 1
@ -1429,7 +1429,6 @@ LinuxLoadAppCode(String* base_dir){
internal void
LinuxLoadSystemCode(){
// files
linuxvars.system.set_file_list = system_set_file_list;
linuxvars.system.get_canonical = system_get_canonical;
@ -1484,9 +1483,6 @@ LinuxLoadSystemCode(){
#if FRED_INTERNAL
linuxvars.system.internal_get_thread_states = internal_get_thread_states;
#endif
// non-function details
linuxvars.system.slash = '/';
}
internal void
@ -1541,13 +1537,13 @@ ctxErrorHandler( Display *dpy, XErrorEvent *ev )
#if FRED_INTERNAL
static void LinuxGLDebugCallback(
GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam
GLenum source,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
const GLchar* message,
const void* userParam
){
fprintf(stderr, "GL DEBUG: %s\n", message);
}
@ -1568,7 +1564,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig &bestFbc,
const char *glxExts = glXQueryExtensionsString(XDisplay, DefaultScreen(XDisplay));
#define GLXLOAD(x) x ## Proc x = (x ## Proc) glXGetProcAddressARB( (const GLubyte*) #x);
#define GLXLOAD(x) x ## Proc x = (x ## Proc) glXGetProcAddressARB( (const GLubyte*) #x);
GLXLOAD(glXCreateContextAttribsARB);
@ -2437,7 +2433,7 @@ LinuxGetXSettingsDPI(Display* dpy, int screen)
}
}
out:
out:
if(prop){
XFree(prop);
}
@ -2540,10 +2536,10 @@ LinuxX11WindowInit(int argc, char** argv, int* WinWidth, int* WinHeight)
sz_hints->max_width = sz_hints->max_height = (1UL << 16UL);
/* NOTE(inso): fluxbox thinks this is minimum, so don't set it
/* NOTE(inso): fluxbox thinks this is minimum, so don't set it
sz_hints->base_width = BASE_W;
sz_hints->base_height = BASE_H;
*/
*/
sz_hints->win_gravity = NorthWestGravity;
if (linuxvars.settings.set_window_pos){

View File

@ -4,7 +4,7 @@ extensions=".c.cpp.h.hpp.bat.sh";
fkey_command_win[1] = {"build.bat", "*compilation*", true};
fkey_command_win[2] = {"..\\misc\\run.bat", "*run*"};
fkey_command_win[3] = {"site\\build.bat", "*compilation*", true};
fkey_command_win[4] = {0, 0};
fkey_command_win[4] = {"file\\run_tests.bat", "*tests*"};
fkey_command_win[5] = {0, 0};
fkey_command_win[6] = {0, 0};
fkey_command_win[7] = {0, 0};

View File

@ -1374,8 +1374,6 @@ Win32LoadSystemCode(){
#if FRED_INTERNAL
win32vars.system.internal_get_thread_states = INTERNAL_get_thread_states;
#endif
win32vars.system.slash = '/';
}
internal void
@ -2052,8 +2050,7 @@ WinMain(HINSTANCE hInstance,
}
win32vars.window_handle =
CreateWindowA(window_class.lpszClassName,
WINDOW_NAME, window_style,
CreateWindowA(window_class.lpszClassName, WINDOW_NAME, window_style,
window_x, window_y,
window_rect.right - window_rect.left,
window_rect.bottom - window_rect.top,
@ -2371,6 +2368,6 @@ int main(int argc, char **argv){
HINSTANCE hInstance = GetModuleHandle(0);
#endif
// BOTTOM
// BOTTOM