2017-01-29 00:03:23 +00:00
/*
2017-11-09 18:30:24 +00:00
4 coder_project_commands . cpp - commands for loading and using a project .
2017-01-29 00:03:23 +00:00
*/
2018-05-08 07:14:23 +00:00
// TOP
2017-01-29 00:03:23 +00:00
2020-12-31 07:43:25 +00:00
# if 1
2019-10-25 06:17:54 +00:00
global Project current_project = { } ;
2020-03-11 23:22:37 +00:00
global Arena current_project_arena = { } ;
2020-12-31 07:43:25 +00:00
# endif
2018-05-09 05:22:33 +00:00
///////////////////////////////
2021-01-01 23:33:03 +00:00
function Match_Pattern_List
prj_pattern_list_from_extension_array ( Arena * arena , String_Const_u8_Array list ) {
Match_Pattern_List result = { } ;
2020-12-05 20:32:56 +00:00
for ( i32 i = 0 ;
i < list . count ;
+ + i ) {
2021-01-01 23:33:03 +00:00
Match_Pattern_Node * node = push_array ( arena , Match_Pattern_Node , 1 ) ;
sll_queue_push ( result . first , result . last , node ) ;
result . count + = 1 ;
String_Const_u8 str = push_stringf ( arena , " *.%.*s " , string_expand ( list . vals [ i ] ) ) ;
node - > pattern . absolutes = string_split_wildcards ( arena , str ) ;
2018-05-08 07:14:23 +00:00
}
2021-01-01 23:33:03 +00:00
return ( result ) ;
}
function Match_Pattern_List
prj_pattern_list_from_var ( Arena * arena , Variable_Handle var ) {
Match_Pattern_List result = { } ;
for ( Vars_Children ( child_var , var ) ) {
Match_Pattern_Node * node = push_array ( arena , Match_Pattern_Node , 1 ) ;
sll_queue_push ( result . first , result . last , node ) ;
result . count + = 1 ;
String_Const_u8 str = vars_string_from_var ( arena , child_var ) ;
node - > pattern . absolutes = string_split_wildcards ( arena , str ) ;
}
return ( result ) ;
2018-05-09 05:22:33 +00:00
}
///////////////////////////////
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
close_all_files_with_extension ( Application_Links * app , String_Const_u8_Array extension_array ) {
Scratch_Block scratch ( app ) ;
2017-01-29 00:03:23 +00:00
2019-06-01 23:33:31 +00:00
i32 buffers_to_close_max = Thousand ( 100 ) ;
Buffer_ID * buffers_to_close = push_array ( scratch , Buffer_ID , buffers_to_close_max ) ;
2018-05-09 05:22:33 +00:00
2019-04-05 02:03:36 +00:00
b32 do_repeat = false ;
2018-05-09 05:22:33 +00:00
do {
2019-06-01 23:33:31 +00:00
i32 buffers_to_close_count = 0 ;
2019-04-05 02:03:36 +00:00
do_repeat = false ;
2018-05-09 05:22:33 +00:00
2019-10-18 02:54:02 +00:00
for ( Buffer_ID buffer = get_buffer_next ( app , 0 , Access_Always ) ;
2019-04-05 02:03:36 +00:00
buffer ! = 0 ;
2019-10-18 02:54:02 +00:00
buffer = get_buffer_next ( app , buffer , Access_Always ) ) {
2019-04-05 02:03:36 +00:00
b32 is_match = true ;
2018-05-09 05:22:33 +00:00
if ( extension_array . count > 0 ) {
2019-06-01 23:33:31 +00:00
Temp_Memory name_temp = begin_temp ( scratch ) ;
2019-06-02 03:07:57 +00:00
String_Const_u8 file_name = push_buffer_file_name ( app , scratch , buffer ) ;
2019-04-05 02:03:36 +00:00
is_match = false ;
if ( file_name . size > 0 ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 extension = string_file_extension ( file_name ) ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < extension_array . count ; + + i ) {
2019-06-01 23:33:31 +00:00
if ( string_match ( extension , extension_array . strings [ i ] ) ) {
2019-04-05 02:03:36 +00:00
is_match = true ;
2018-05-09 05:22:33 +00:00
break ;
}
}
}
2019-06-01 23:33:31 +00:00
end_temp ( name_temp ) ;
2018-05-09 05:22:33 +00:00
}
if ( is_match ) {
if ( buffers_to_close_count > = buffers_to_close_max ) {
2019-04-05 02:03:36 +00:00
do_repeat = true ;
2018-05-09 05:22:33 +00:00
break ;
}
2019-04-05 02:03:36 +00:00
buffers_to_close [ buffers_to_close_count + + ] = buffer ;
2018-05-09 05:22:33 +00:00
}
2017-01-29 00:03:23 +00:00
}
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < buffers_to_close_count ; + + i ) {
2019-06-19 02:31:59 +00:00
buffer_kill ( app , buffers_to_close [ i ] , BufferKill_AlwaysKill ) ;
2017-01-29 00:03:23 +00:00
}
2018-05-09 05:22:33 +00:00
} while ( do_repeat ) ;
2017-01-29 00:03:23 +00:00
}
2019-10-25 06:17:54 +00:00
function b32
2021-01-01 23:33:03 +00:00
match_in_pattern_list ( String_Const_u8 string , Match_Pattern_List list ) {
2019-02-26 23:08:42 +00:00
b32 found_match = false ;
2021-01-01 23:33:03 +00:00
for ( Match_Pattern_Node * node = list . first ;
node ! = 0 ;
node = node - > next ) {
if ( string_wildcard_match ( node - > pattern . absolutes , string , StringMatch_Exact ) ) {
2018-05-26 07:49:37 +00:00
found_match = true ;
break ;
}
}
return ( found_match ) ;
}
2019-10-25 06:17:54 +00:00
function void
open_files_pattern_match__recursive ( Application_Links * app , String_Const_u8 path ,
2021-01-01 23:33:03 +00:00
Match_Pattern_List whitelist , Match_Pattern_List blacklist , u32 flags ) {
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
2019-10-25 06:17:54 +00:00
2019-10-26 20:48:50 +00:00
ProfileScopeNamed ( app , " get file list " , profile_get_file_list ) ;
2019-10-08 01:42:23 +00:00
File_List list = system_get_file_list ( scratch , path ) ;
2019-10-26 20:48:50 +00:00
ProfileCloseNow ( profile_get_file_list ) ;
2018-05-09 05:22:33 +00:00
2019-08-04 00:49:40 +00:00
File_Info * * info = list . infos ;
2019-02-26 23:08:42 +00:00
for ( u32 i = 0 ; i < list . count ; + + i , + + info ) {
2019-08-04 00:49:40 +00:00
String_Const_u8 file_name = ( * * info ) . file_name ;
if ( HasFlag ( ( * * info ) . attributes . flags , FileAttribute_IsDirectory ) ) {
2021-01-01 23:33:03 +00:00
if ( ( flags & OpenAllFilesFlag_Recursive ) = = 0 ) {
continue ;
}
if ( match_in_pattern_list ( file_name , blacklist ) ) {
continue ;
}
String_Const_u8 new_path = push_u8_stringf ( scratch , " %.*s%.*s/ " , string_expand ( path ) , string_expand ( file_name ) ) ;
2019-12-18 00:19:03 +00:00
open_files_pattern_match__recursive ( app , new_path , whitelist , blacklist , flags ) ;
2018-05-09 05:22:33 +00:00
}
else {
2021-01-01 23:33:03 +00:00
if ( ! match_in_pattern_list ( file_name , whitelist ) ) {
2018-05-26 07:49:37 +00:00
continue ;
2018-05-09 05:22:33 +00:00
}
2021-01-01 23:33:03 +00:00
if ( match_in_pattern_list ( file_name , blacklist ) ) {
2018-05-26 07:49:37 +00:00
continue ;
2018-05-09 05:22:33 +00:00
}
2021-01-01 23:33:03 +00:00
String_Const_u8 full_path = push_u8_stringf ( scratch , " %.*s%.*s " , string_expand ( path ) , string_expand ( file_name ) ) ;
2019-06-19 02:31:59 +00:00
create_buffer ( app , full_path , 0 ) ;
2017-01-29 00:03:23 +00:00
}
}
}
2021-01-01 23:33:03 +00:00
// TODO(allen): dumb name
function Match_Pattern_List
2019-06-01 23:33:31 +00:00
get_standard_blacklist ( Arena * arena ) {
String_Const_u8 dot = string_u8_litexpr ( " .* " ) ;
String_Const_u8_Array black_array = { } ;
black_array . strings = & dot ;
2018-05-26 07:49:37 +00:00
black_array . count = 1 ;
2021-01-01 23:33:03 +00:00
return ( prj_pattern_list_from_extension_array ( arena , black_array ) ) ;
2018-05-26 07:49:37 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2021-01-01 23:33:03 +00:00
open_files_pattern_match ( Application_Links * app , String_Const_u8 dir ,
Match_Pattern_List whitelist , Match_Pattern_List blacklist , u32 flags ) {
2019-10-22 07:15:49 +00:00
ProfileScope ( app , " open all files in directory pattern " ) ;
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
String_Const_u8 directory = dir ;
if ( ! character_is_slash ( string_get_character ( directory , directory . size - 1 ) ) ) {
2019-06-18 22:56:09 +00:00
directory = push_u8_stringf ( scratch , " %.*s/ " , string_expand ( dir ) ) ;
2018-05-30 07:58:22 +00:00
}
2019-10-25 06:17:54 +00:00
open_files_pattern_match__recursive ( app , directory , whitelist , blacklist , flags ) ;
2018-05-26 07:49:37 +00:00
}
2019-10-25 06:17:54 +00:00
function void
open_files_with_extension ( Application_Links * app , String_Const_u8 dir , String_Const_u8_Array array , u32 flags ) {
2019-06-01 23:33:31 +00:00
Scratch_Block scratch ( app ) ;
2021-01-01 23:33:03 +00:00
Match_Pattern_List whitelist = prj_pattern_list_from_extension_array ( scratch , array ) ;
Match_Pattern_List blacklist = get_standard_blacklist ( scratch ) ;
2019-10-25 06:17:54 +00:00
open_files_pattern_match ( app , dir , whitelist , blacklist , flags ) ;
2018-05-09 05:22:33 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
open_all_files_in_hot_with_extension ( Application_Links * app , String_Const_u8_Array array , u32 flags ) {
Scratch_Block scratch ( app ) ;
String_Const_u8 hot = push_hot_directory ( app , scratch ) ;
String_Const_u8 directory = hot ;
if ( ! character_is_slash ( string_get_character ( hot , hot . size - 1 ) ) ) {
2019-06-18 22:56:09 +00:00
directory = push_u8_stringf ( scratch , " %.*s/ " , string_expand ( hot ) ) ;
2018-05-30 07:58:22 +00:00
}
2019-10-25 06:17:54 +00:00
open_files_with_extension ( app , hot , array , flags ) ;
2018-05-09 05:22:33 +00:00
}
///////////////////////////////
2018-05-08 07:14:23 +00:00
2019-10-25 06:17:54 +00:00
function void
2021-01-01 23:33:03 +00:00
parse_project__extract_pattern_list ( Arena * arena , Config * parsed , char * root_variable_name , Match_Pattern_List * list_out ) {
2018-05-26 07:49:37 +00:00
Config_Compound * compound = 0 ;
if ( config_compound_var ( parsed , root_variable_name , 0 , & compound ) ) {
2018-05-30 20:27:47 +00:00
Config_Get_Result_List list = typed_string_array_reference_list ( arena , parsed , compound ) ;
2021-01-01 23:33:03 +00:00
for ( Config_Get_Result_Node * cfg_node = list . first ;
cfg_node ! = 0 ;
cfg_node = cfg_node - > next ) {
Match_Pattern_Node * node = push_array ( arena , Match_Pattern_Node , 1 ) ;
sll_queue_push ( list_out - > first , list_out - > last , node ) ;
list_out - > count + = 1 ;
String_Const_u8 str = push_string_copy ( arena , cfg_node - > result . string ) ;
node - > pattern . absolutes = string_split_wildcards ( arena , str ) ;
2018-05-26 07:49:37 +00:00
}
}
}
2019-10-25 06:17:54 +00:00
function Project_OS_Match_Level
2019-06-01 23:33:31 +00:00
parse_project__version_1__os_match ( String_Const_u8 str , String_Const_u8 this_os_str ) {
if ( string_match ( str , this_os_str ) ) {
2018-06-16 20:57:32 +00:00
return ( ProjectOSMatchLevel_ActiveMatch ) ;
}
2019-06-01 23:33:31 +00:00
else if ( string_match ( str , string_u8_litexpr ( " all " ) ) ) {
2018-06-16 20:57:32 +00:00
return ( ProjectOSMatchLevel_ActiveMatch ) ;
}
2019-06-01 23:33:31 +00:00
else if ( string_match ( str , string_u8_litexpr ( " default " ) ) ) {
2018-06-16 20:57:32 +00:00
return ( ProjectOSMatchLevel_PassiveMatch ) ;
}
return ( ProjectOSMatchLevel_NoMatch ) ;
}
2019-10-25 06:17:54 +00:00
function Project *
2019-11-07 05:58:08 +00:00
parse_project__config_data__version_1 ( Application_Links * app , Arena * arena , String_Const_u8 root_dir , Config * parsed ) {
2019-06-01 23:33:31 +00:00
Project * project = push_array_zero ( arena , Project , 1 ) ;
2018-05-26 07:49:37 +00:00
// Set new project directory
2019-07-13 00:43:17 +00:00
project - > dir = push_string_copy ( arena , root_dir ) ;
2018-05-26 07:49:37 +00:00
// project_name
{
2019-06-01 23:33:31 +00:00
String_Const_u8 str = { } ;
2018-05-26 07:49:37 +00:00
if ( config_string_var ( parsed , " project_name " , 0 , & str ) ) {
2019-07-13 00:43:17 +00:00
project - > name = push_string_copy ( arena , str ) ;
2018-05-26 07:49:37 +00:00
}
2018-06-02 23:02:14 +00:00
else {
2019-06-01 23:33:31 +00:00
project - > name = SCu8 ( " " ) ;
2018-06-02 23:02:14 +00:00
}
2018-05-26 07:49:37 +00:00
}
// patterns
2021-01-01 23:33:03 +00:00
parse_project__extract_pattern_list ( arena , parsed , " patterns " , & project - > pattern_list ) ;
2018-05-26 07:49:37 +00:00
// blacklist_patterns
2021-01-01 23:33:03 +00:00
parse_project__extract_pattern_list ( arena , parsed , " blacklist_patterns " , & project - > blacklist_pattern_list ) ;
2018-05-26 07:49:37 +00:00
// load_paths
{
Config_Compound * compound = 0 ;
if ( config_compound_var ( parsed , " load_paths " , 0 , & compound ) ) {
2019-02-26 23:08:42 +00:00
b32 found_match = false ;
2018-06-16 20:57:32 +00:00
Config_Compound * best_paths = 0 ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; ; + + i ) {
2018-05-30 20:27:47 +00:00
Config_Iteration_Step_Result result = typed_array_iteration_step ( parsed , compound , ConfigRValueType_Compound , i ) ;
if ( result . step = = Iteration_Skip ) {
2018-05-26 07:49:37 +00:00
continue ;
}
2018-05-30 20:27:47 +00:00
else if ( result . step = = Iteration_Quit ) {
2018-05-26 07:49:37 +00:00
break ;
}
2018-05-30 20:27:47 +00:00
Config_Compound * paths_option = result . get . compound ;
2018-05-26 07:49:37 +00:00
Config_Compound * paths = 0 ;
if ( config_compound_compound_member ( parsed , paths_option , " paths " , 0 , & paths ) ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 str = { } ;
2018-05-26 07:49:37 +00:00
if ( config_compound_string_member ( parsed , paths_option , " os " , 1 , & str ) ) {
2020-12-30 23:27:53 +00:00
Project_OS_Match_Level r = parse_project__version_1__os_match ( str , string_u8_litexpr ( OS_NAME ) ) ;
2018-06-16 20:57:32 +00:00
if ( r = = ProjectOSMatchLevel_ActiveMatch ) {
found_match = true ;
best_paths = paths ;
break ;
}
else if ( r = = ProjectOSMatchLevel_PassiveMatch ) {
if ( ! found_match ) {
found_match = true ;
best_paths = paths ;
}
2018-05-26 07:49:37 +00:00
}
}
}
2018-06-16 20:57:32 +00:00
}
if ( found_match ) {
Config_Get_Result_List list = typed_compound_array_reference_list ( arena , parsed , best_paths ) ;
2018-05-26 07:49:37 +00:00
2018-06-16 20:57:32 +00:00
project - > load_path_array . paths = push_array ( arena , Project_File_Load_Path , list . count ) ;
project - > load_path_array . count = list . count ;
Project_File_Load_Path * dst = project - > load_path_array . paths ;
for ( Config_Get_Result_Node * node = list . first ;
node ! = 0 ;
node = node - > next , + + dst ) {
Config_Compound * src = node - > result . compound ;
2019-09-27 23:56:05 +00:00
block_zero_struct ( dst ) ;
2018-06-16 20:57:32 +00:00
dst - > recursive = true ;
dst - > relative = true ;
2018-05-26 07:49:37 +00:00
2019-06-01 23:33:31 +00:00
String_Const_u8 str = { } ;
2018-06-16 20:57:32 +00:00
if ( config_compound_string_member ( parsed , src , " path " , 0 , & str ) ) {
2019-07-13 00:43:17 +00:00
dst - > path = push_string_copy ( arena , str ) ;
2018-05-21 06:12:08 +00:00
}
2018-06-16 20:57:32 +00:00
config_compound_bool_member ( parsed , src , " recursive " , 1 , & dst - > recursive ) ;
config_compound_bool_member ( parsed , src , " relative " , 2 , & dst - > relative ) ;
2018-05-26 07:49:37 +00:00
}
}
}
}
// command_list
{
Config_Compound * compound = 0 ;
if ( config_compound_var ( parsed , " command_list " , 0 , & compound ) ) {
2018-05-30 20:27:47 +00:00
Config_Get_Result_List list = typed_compound_array_reference_list ( arena , parsed , compound ) ;
2018-05-26 07:49:37 +00:00
2018-05-30 20:27:47 +00:00
project - > command_array . commands = push_array ( arena , Project_Command , list . count ) ;
project - > command_array . count = list . count ;
2018-05-26 07:49:37 +00:00
Project_Command * dst = project - > command_array . commands ;
2018-05-30 20:27:47 +00:00
for ( Config_Get_Result_Node * node = list . first ;
node ! = 0 ;
node = node - > next , + + dst ) {
2019-06-01 23:33:31 +00:00
u8 * pos = node - > result . pos ;
2018-05-30 20:27:47 +00:00
Config_Compound * src = node - > result . compound ;
2019-06-01 23:33:31 +00:00
block_zero_struct ( dst ) ;
2018-05-26 07:49:37 +00:00
2019-02-26 23:08:42 +00:00
b32 can_emit_command = true ;
2018-05-30 20:27:47 +00:00
2018-11-20 08:18:54 +00:00
Config_Get_Result cmd_result = { } ;
2018-06-02 04:06:13 +00:00
Config_Compound * cmd_set = 0 ;
2019-06-01 23:33:31 +00:00
u8 * cmd_pos = 0 ;
String_Const_u8 cmd_str = { } ;
String_Const_u8 out = { } ;
2019-02-26 23:08:42 +00:00
b32 footer_panel = false ;
b32 save_dirty_files = true ;
b32 cursor_at_end = false ;
2019-06-01 23:33:31 +00:00
String_Const_u8 name = { } ;
2018-05-30 20:27:47 +00:00
if ( ! config_compound_string_member ( parsed , src , " name " , 0 , & name ) ) {
can_emit_command = false ;
2020-11-25 00:58:29 +00:00
def_config_push_error ( arena , parsed , pos , " a command must have a string type name member " ) ;
2018-05-30 20:27:47 +00:00
goto finish_command ;
}
2020-05-01 14:38:57 +00:00
cmd_result = config_compound_member ( parsed , src , string_u8_litexpr ( " cmd " ) , 1 ) ;
if ( cmd_result . success & & cmd_result . type = = ConfigRValueType_Compound ) {
2018-06-02 04:06:13 +00:00
cmd_set = cmd_result . compound ;
cmd_pos = cmd_result . pos ;
}
else {
2018-05-30 20:27:47 +00:00
can_emit_command = false ;
2020-11-25 00:58:29 +00:00
def_config_push_error ( arena , parsed , pos , " a command must have an array type cmd member " ) ;
2018-05-30 20:27:47 +00:00
goto finish_command ;
}
can_emit_command = false ;
2019-02-26 23:08:42 +00:00
for ( i32 j = 0 ; ; + + j ) {
2018-05-30 20:27:47 +00:00
Config_Iteration_Step_Result result = typed_array_iteration_step ( parsed , cmd_set , ConfigRValueType_Compound , j ) ;
if ( result . step = = Iteration_Skip ) {
continue ;
2018-05-21 06:12:08 +00:00
}
2018-05-30 20:27:47 +00:00
else if ( result . step = = Iteration_Quit ) {
break ;
2018-05-21 06:12:08 +00:00
}
2018-05-30 20:27:47 +00:00
Config_Compound * cmd_option = result . get . compound ;
2018-05-21 06:12:08 +00:00
2019-06-01 23:33:31 +00:00
String_Const_u8 cmd = { } ;
2018-05-30 20:27:47 +00:00
if ( config_compound_string_member ( parsed , cmd_option , " cmd " , 0 , & cmd ) ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 str = { } ;
2018-05-30 20:27:47 +00:00
if ( config_compound_string_member ( parsed , cmd_option , " os " , 1 , & str ) ) {
2020-12-30 23:27:53 +00:00
Project_OS_Match_Level r = parse_project__version_1__os_match ( str , string_u8_litexpr ( OS_NAME ) ) ;
2018-06-16 20:57:32 +00:00
if ( r = = ProjectOSMatchLevel_ActiveMatch ) {
can_emit_command = true ;
cmd_str = cmd ;
break ;
}
else if ( r = = ProjectOSMatchLevel_PassiveMatch ) {
if ( ! can_emit_command ) {
can_emit_command = true ;
cmd_str = cmd ;
}
2018-05-26 07:49:37 +00:00
}
}
}
2018-05-30 20:27:47 +00:00
}
2018-06-02 04:06:13 +00:00
if ( ! can_emit_command ) {
2020-11-25 00:58:29 +00:00
def_config_push_error ( arena , parsed , cmd_pos , " no usable command strings found in cmd " ) ;
2018-06-02 04:06:13 +00:00
goto finish_command ;
2018-05-26 07:49:37 +00:00
}
2018-05-30 20:27:47 +00:00
2018-06-02 04:06:13 +00:00
config_compound_string_member ( parsed , src , " out " , 2 , & out ) ;
config_compound_bool_member ( parsed , src , " footer_panel " , 3 , & footer_panel ) ;
config_compound_bool_member ( parsed , src , " save_dirty_files " , 4 ,
& save_dirty_files ) ;
config_compound_bool_member ( parsed , src , " cursor_at_end " , 5 ,
& cursor_at_end ) ;
2019-07-13 00:43:17 +00:00
dst - > name = push_string_copy ( arena , name ) ;
dst - > cmd = push_string_copy ( arena , cmd_str ) ;
dst - > out = push_string_copy ( arena , out ) ;
2018-06-02 04:06:13 +00:00
dst - > footer_panel = footer_panel ;
dst - > save_dirty_files = save_dirty_files ;
dst - > cursor_at_end = cursor_at_end ;
2018-05-30 20:27:47 +00:00
finish_command : ;
2018-05-26 07:49:37 +00:00
}
}
}
// fkey_command
{
2019-02-26 23:08:42 +00:00
for ( i32 i = 1 ; i < = 16 ; + + i ) {
2019-06-01 23:33:31 +00:00
String_Const_u8 name = { } ;
2019-02-26 23:08:42 +00:00
i32 index = - 1 ;
2018-05-26 07:49:37 +00:00
if ( config_string_var ( parsed , " fkey_command " , i , & name ) ) {
2019-02-26 23:08:42 +00:00
i32 count = project - > command_array . count ;
2018-05-26 07:49:37 +00:00
Project_Command * command_ptr = project - > command_array . commands ;
2019-02-26 23:08:42 +00:00
for ( i32 j = 0 ; j < count ; + + j , + + command_ptr ) {
2019-06-01 23:33:31 +00:00
if ( string_match ( command_ptr - > name , name ) ) {
2018-05-26 07:49:37 +00:00
index = j ;
break ;
2018-05-21 06:12:08 +00:00
}
}
2017-11-15 00:06:00 +00:00
}
2018-05-26 07:49:37 +00:00
project - > fkey_commands [ i - 1 ] = index ;
2017-06-20 20:37:45 +00:00
}
2018-05-19 22:05:31 +00:00
}
2018-05-26 07:49:37 +00:00
project - > loaded = true ;
return ( project ) ;
}
2019-10-25 06:17:54 +00:00
function void
2021-01-01 23:33:03 +00:00
project_deep_copy__pattern_list ( Arena * arena , Match_Pattern_List * src_list , Match_Pattern_List * dst_list ) {
for ( Match_Pattern_Node * src_node = src_list - > first ;
src_node ! = 0 ;
src_node = src_node - > next ) {
Match_Pattern_Node * dst_node = push_array ( arena , Match_Pattern_Node , 1 ) ;
sll_queue_push ( dst_list - > first , dst_list - > last , dst_node ) ;
dst_list - > count + = 1 ;
for ( Node_String_Const_u8 * node = src_node - > pattern . absolutes . first ;
2019-06-01 23:33:31 +00:00
node ! = 0 ;
node = node - > next ) {
2020-02-08 02:22:14 +00:00
String_Const_u8 string = push_string_copy ( arena , node - > string ) ;
2021-01-01 23:33:03 +00:00
string_list_push ( arena , & dst_node - > pattern . absolutes , string ) ;
2018-05-26 07:49:37 +00:00
}
}
}
2019-10-25 06:17:54 +00:00
function Project
2019-06-01 23:33:31 +00:00
project_deep_copy__inner ( Arena * arena , Project * project ) {
2018-11-20 08:18:54 +00:00
Project result = { } ;
2019-07-13 00:43:17 +00:00
result . dir = push_string_copy ( arena , project - > dir ) ;
result . name = push_string_copy ( arena , project - > name ) ;
2021-01-01 23:33:03 +00:00
project_deep_copy__pattern_list ( arena , & project - > pattern_list , & result . pattern_list ) ;
project_deep_copy__pattern_list ( arena , & project - > blacklist_pattern_list , & result . blacklist_pattern_list ) ;
2018-05-26 07:49:37 +00:00
{
2019-02-26 23:08:42 +00:00
i32 path_count = project - > load_path_array . count ;
2018-05-26 07:49:37 +00:00
result . load_path_array . paths = push_array ( arena , Project_File_Load_Path , path_count ) ;
result . load_path_array . count = path_count ;
Project_File_Load_Path * dst = result . load_path_array . paths ;
Project_File_Load_Path * src = project - > load_path_array . paths ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < path_count ; + + i , + + dst , + + src ) {
2019-07-13 00:43:17 +00:00
dst - > path = push_string_copy ( arena , src - > path ) ;
2018-05-26 07:49:37 +00:00
dst - > recursive = src - > recursive ;
dst - > relative = src - > relative ;
}
}
{
2019-02-26 23:08:42 +00:00
i32 command_count = project - > command_array . count ;
2019-06-01 23:33:31 +00:00
result . command_array . commands = push_array_zero ( arena , Project_Command , command_count ) ;
2018-05-26 07:49:37 +00:00
result . command_array . count = command_count ;
Project_Command * dst = result . command_array . commands ;
Project_Command * src = project - > command_array . commands ;
2019-02-26 23:08:42 +00:00
for ( i32 i = 0 ; i < command_count ; + + i , + + dst , + + src ) {
2018-05-26 07:49:37 +00:00
if ( src - > name . str ! = 0 ) {
2019-07-13 00:43:17 +00:00
dst - > name = push_string_copy ( arena , src - > name ) ;
2018-05-26 07:49:37 +00:00
}
if ( src - > cmd . str ! = 0 ) {
2019-07-13 00:43:17 +00:00
dst - > cmd = push_string_copy ( arena , src - > cmd ) ;
2018-05-26 07:49:37 +00:00
}
if ( src - > out . str ! = 0 ) {
2019-07-13 00:43:17 +00:00
dst - > out = push_string_copy ( arena , src - > out ) ;
2018-05-26 07:49:37 +00:00
}
dst - > footer_panel = src - > footer_panel ;
dst - > save_dirty_files = src - > save_dirty_files ;
2018-06-02 00:29:36 +00:00
dst - > cursor_at_end = src - > cursor_at_end ;
2018-05-26 07:49:37 +00:00
}
}
2019-09-27 23:56:05 +00:00
block_copy_array ( result . fkey_commands , project - > fkey_commands ) ;
2018-05-26 07:49:37 +00:00
result . loaded = true ;
return ( result ) ;
}
2019-10-25 06:17:54 +00:00
function Project
2019-06-01 23:33:31 +00:00
project_deep_copy ( Arena * arena , Project * project ) {
Temp_Memory restore_point = begin_temp ( arena ) ;
2018-05-26 07:49:37 +00:00
Project result = project_deep_copy__inner ( arena , project ) ;
if ( ! result . loaded ) {
2019-06-01 23:33:31 +00:00
end_temp ( restore_point ) ;
block_zero_struct ( & result ) ;
2018-05-26 07:49:37 +00:00
}
return ( result ) ;
}
2020-11-25 08:41:30 +00:00
// NOTE(allen): string list join ("flatten") doesn't really work... :(
function String_Const_u8
prj_join_pattern_string ( Arena * arena , List_String_Const_u8 list ) {
String_Const_u8 pattern_string = { } ;
pattern_string . size = list . total_size + list . node_count - 1 ;
pattern_string . str = push_array ( arena , u8 , pattern_string . size + 1 ) ;
u8 * ptr = pattern_string . str ;
Node_String_Const_u8 * node = list . first ;
if ( node ! = 0 ) {
for ( ; ; ) {
block_copy ( ptr , node - > string . str , node - > string . size ) ;
ptr + = node - > string . size ;
node = node - > next ;
if ( node = = 0 ) {
break ;
}
* ptr = ' * ' ;
ptr + = 1 ;
}
}
pattern_string . str [ pattern_string . size ] = 0 ;
return ( pattern_string ) ;
}
2020-12-06 00:54:33 +00:00
function String_Const_u8
prj_sanitize_string ( Arena * arena , String_Const_u8 string ) {
String_Const_u8 result = { } ;
if ( string . size > 0 ) {
result . size = string . size ;
result . str = push_array ( arena , u8 , result . size + 2 ) ;
u8 * in = string . str ;
u8 * out = result . str ;
if ( character_is_base10 ( * in ) ) {
* out = ' _ ' ;
out + = 1 ;
result . size + = 1 ;
}
for ( u64 i = 0 ; i < string . size ; i + = 1 , in + = 1 , out + = 1 ) {
u8 c = * in ;
if ( ! character_is_alpha_numeric ( c ) ) {
c = ' _ ' ;
}
* out = c ;
}
result . str [ result . size ] = 0 ;
}
return ( result ) ;
}
2020-12-05 20:32:56 +00:00
function Variable_Handle
prj_version_1_to_version_2 ( Application_Links * app , Config * parsed , Project * project ) {
Scratch_Block scratch ( app ) ;
String_ID project_id = vars_save_string_lit ( " prj_config " ) ;
2020-12-31 00:55:11 +00:00
String_ID version_id = vars_save_string ( str8_lit ( " version " ) ) ;
String_ID project_name_id = vars_save_string ( str8_lit ( " project_name " ) ) ;
String_ID patterns_id = vars_save_string ( str8_lit ( " patterns " ) ) ;
String_ID blacklist_patterns_id = vars_save_string ( str8_lit ( " blacklist_patterns " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID load_paths_id = vars_save_string ( str8_lit ( " load_paths " ) ) ;
String_ID path_id = vars_save_string ( str8_lit ( " path " ) ) ;
String_ID recursive_id = vars_save_string ( str8_lit ( " recursive " ) ) ;
String_ID relative_id = vars_save_string ( str8_lit ( " relative " ) ) ;
String_ID true_id = vars_save_string ( str8_lit ( " true " ) ) ;
String_ID false_id = vars_save_string ( str8_lit ( " false " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID out_id = vars_save_string ( str8_lit ( " out " ) ) ;
String_ID footer_panel_id = vars_save_string ( str8_lit ( " footer_panel " ) ) ;
String_ID save_dirty_files_id = vars_save_string ( str8_lit ( " save_dirty_files " ) ) ;
String_ID cursor_at_end_id = vars_save_string ( str8_lit ( " cursor_at_end " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID fkey_command_id = vars_save_string ( str8_lit ( " fkey_command " ) ) ;
2020-12-05 20:32:56 +00:00
2020-12-31 00:55:11 +00:00
String_ID os_id = vars_save_string ( str8_lit ( OS_NAME ) ) ; ;
2020-12-05 20:32:56 +00:00
Variable_Handle proj_var = vars_new_variable ( vars_get_root ( ) , project_id , vars_save_string ( parsed - > file_name ) ) ;
if ( parsed - > version ! = 0 ) {
String_Const_u8 version_str = push_stringf ( scratch , " %d " , * parsed - > version ) ;
vars_new_variable ( proj_var , version_id , vars_save_string ( version_str ) ) ;
}
vars_new_variable ( proj_var , project_name_id , vars_save_string ( project - > name ) ) ;
// load paterns
struct PatternVars {
String_ID id ;
2021-01-01 23:33:03 +00:00
Match_Pattern_List list ;
2020-12-05 20:32:56 +00:00
} ;
PatternVars pattern_vars [ ] = {
2021-01-01 23:33:03 +00:00
{ patterns_id , project - > pattern_list } ,
{ blacklist_patterns_id , project - > blacklist_pattern_list } ,
2020-12-05 20:32:56 +00:00
} ;
PatternVars * pattern_var = pattern_vars ;
PatternVars * opl = pattern_vars + ArrayCount ( pattern_vars ) ;
for ( ; pattern_var < opl ; pattern_var + = 1 ) {
Variable_Handle patterns = vars_new_variable ( proj_var , pattern_var - > id ) ;
2021-01-01 23:33:03 +00:00
i32 i = 0 ;
for ( Match_Pattern_Node * node = pattern_var - > list . first ;
node ! = 0 ;
node = node - > next , i + = 1 ) {
String_Const_u8 pattern_string = prj_join_pattern_string ( scratch , node - > pattern . absolutes ) ;
2020-12-05 20:32:56 +00:00
String_ID key = vars_save_string ( push_stringf ( scratch , " %d " , i ) ) ;
String_ID pattern_id = vars_save_string ( pattern_string ) ;
vars_new_variable ( patterns , key , pattern_id ) ;
}
}
// load paths
{
Variable_Handle load_paths = vars_new_variable ( proj_var , load_paths_id ) ;
Variable_Handle os_var = vars_new_variable ( load_paths , os_id ) ;
i32 count = project - > load_path_array . count ;
Project_File_Load_Path * load_path = project - > load_path_array . paths ;
for ( i32 i = 0 ; i < count ; i + = 1 , load_path + = 1 ) {
String_ID key = vars_save_string ( push_stringf ( scratch , " %d " , i ) ) ;
Variable_Handle path_var = vars_new_variable ( os_var , key ) ;
vars_new_variable ( path_var , path_id , vars_save_string ( load_path - > path ) ) ;
vars_new_variable ( path_var , recursive_id , load_path - > recursive ? true_id : false_id ) ;
vars_new_variable ( path_var , relative_id , load_path - > recursive ? true_id : false_id ) ;
}
}
// commands
{
i32 count = project - > command_array . count ;
Project_Command * cmd = project - > command_array . commands ;
for ( i32 i = 0 ; i < count ; i + = 1 , cmd + = 1 ) {
2020-12-06 00:54:33 +00:00
String_Const_u8 cmd_name = prj_sanitize_string ( scratch , cmd - > name ) ;
Variable_Handle cmd_var = vars_new_variable ( proj_var , vars_save_string ( cmd_name ) ) ;
2020-12-05 20:32:56 +00:00
vars_new_variable ( cmd_var , os_id , vars_save_string ( cmd - > cmd ) ) ;
vars_new_variable ( cmd_var , out_id , vars_save_string ( cmd - > out ) ) ;
vars_new_variable ( cmd_var , footer_panel_id , cmd - > footer_panel ? true_id : false_id ) ;
vars_new_variable ( cmd_var , save_dirty_files_id , cmd - > save_dirty_files ? true_id : false_id ) ;
vars_new_variable ( cmd_var , cursor_at_end_id , cmd - > cursor_at_end ? true_id : false_id ) ;
}
}
// fkey_commands
{
Variable_Handle fkeys_var = vars_new_variable ( proj_var , fkey_command_id ) ;
for ( i32 i = 0 ; i < 16 ; i + = 1 ) {
i32 cmd_index = project - > fkey_commands [ i ] ;
if ( 0 < = cmd_index & & cmd_index < project - > command_array . count ) {
Project_Command * cmd = project - > command_array . commands + cmd_index ;
if ( cmd - > name . size > 0 ) {
2020-12-06 00:54:33 +00:00
String_Const_u8 cmd_name = prj_sanitize_string ( scratch , cmd - > name ) ;
2020-12-05 20:32:56 +00:00
String_ID key = vars_save_string ( push_stringf ( scratch , " %d " , i ) ) ;
2020-12-06 00:54:33 +00:00
String_ID val = vars_save_string ( cmd_name ) ;
2020-12-05 20:32:56 +00:00
vars_new_variable ( fkeys_var , key , val ) ;
}
}
}
}
2020-12-06 00:54:33 +00:00
2020-12-05 20:32:56 +00:00
return ( proj_var ) ;
}
2020-12-31 07:43:25 +00:00
function String_Const_u8
prj_path_from_project ( Arena * arena , Variable_Handle project ) {
String_Const_u8 project_full_path = vars_string_from_var ( arena , project ) ;
String_Const_u8 project_dir = string_remove_last_folder ( project_full_path ) ;
return ( project_dir ) ;
}
2020-12-05 20:32:56 +00:00
2019-10-25 06:17:54 +00:00
function void
2020-12-06 00:54:33 +00:00
prj_exec_command ( Application_Links * app , Variable_Handle cmd_var ) {
Scratch_Block scratch ( app ) ;
2020-12-30 23:27:53 +00:00
String_ID os_id = vars_save_string_lit ( OS_NAME ) ;
2020-12-06 00:54:33 +00:00
String_Const_u8 cmd = vars_string_from_var ( scratch , vars_read_key ( cmd_var , os_id ) ) ;
if ( cmd . size > 0 ) {
String_ID out_id = vars_save_string_lit ( " out " ) ;
String_ID footer_panel_id = vars_save_string_lit ( " footer_panel " ) ;
String_ID save_dirty_files_id = vars_save_string_lit ( " save_dirty_files " ) ;
String_ID cursor_at_end_id = vars_save_string_lit ( " cursor_at_end " ) ;
2018-05-08 07:14:23 +00:00
2020-12-06 00:54:33 +00:00
b32 save_dirty_files = vars_b32_from_var ( vars_read_key ( cmd_var , save_dirty_files_id ) ) ;
2018-05-26 07:49:37 +00:00
if ( save_dirty_files ) {
2018-05-08 07:14:23 +00:00
save_all_dirty_buffers ( app ) ;
}
2019-03-17 23:11:37 +00:00
u32 flags = CLI_OverlapWithConflict | CLI_SendEndSignal ;
2020-12-06 00:54:33 +00:00
b32 cursor_at_end = vars_b32_from_var ( vars_read_key ( cmd_var , cursor_at_end_id ) ) ;
2018-06-02 00:29:36 +00:00
if ( cursor_at_end ) {
flags | = CLI_CursorAtEnd ;
}
2018-05-08 07:14:23 +00:00
2020-12-06 00:54:33 +00:00
View_ID view = 0 ;
Buffer_Identifier buffer_id = { } ;
2019-02-26 23:08:42 +00:00
b32 set_fancy_font = false ;
2020-12-06 00:54:33 +00:00
String_Const_u8 out = vars_string_from_var ( scratch , vars_read_key ( cmd_var , out_id ) ) ;
if ( out . size > 0 ) {
buffer_id = buffer_identifier ( out ) ;
2018-05-08 07:14:23 +00:00
2020-12-06 00:54:33 +00:00
b32 footer_panel = vars_b32_from_var ( vars_read_key ( cmd_var , footer_panel_id ) ) ;
2018-05-26 07:49:37 +00:00
if ( footer_panel ) {
2018-05-09 05:22:33 +00:00
view = get_or_open_build_panel ( app ) ;
2020-12-06 00:54:33 +00:00
if ( string_match ( out , string_u8_litexpr ( " *compilation* " ) ) ) {
2018-05-08 07:14:23 +00:00
set_fancy_font = true ;
}
}
else {
2019-04-15 19:43:58 +00:00
Buffer_ID buffer = buffer_identifier_to_id ( app , buffer_id ) ;
view = get_first_view_with_buffer ( app , buffer ) ;
if ( view = = 0 ) {
2019-10-18 02:54:02 +00:00
view = get_active_view ( app , Access_Always ) ;
2019-04-15 19:43:58 +00:00
}
2018-05-08 07:14:23 +00:00
}
2019-06-01 23:33:31 +00:00
block_zero_struct ( & prev_location ) ;
2020-12-06 00:54:33 +00:00
lock_jump_buffer ( app , out ) ;
2018-05-08 07:14:23 +00:00
}
else {
// TODO(allen): fix the exec_system_command call so it can take a null buffer_id.
2019-06-01 23:33:31 +00:00
buffer_id = buffer_identifier ( string_u8_litexpr ( " *dump* " ) ) ;
2018-05-08 07:14:23 +00:00
}
2020-12-31 07:43:25 +00:00
Variable_Handle parent = vars_parent ( cmd_var ) ;
String_Const_u8 project_dir = prj_path_from_project ( scratch , parent ) ;
exec_system_command ( app , view , buffer_id , project_dir , cmd , flags ) ;
2018-05-08 07:14:23 +00:00
if ( set_fancy_font ) {
set_fancy_compilation_buffer_font ( app ) ;
}
}
}
2020-12-06 00:54:33 +00:00
function Variable_Handle
prj_command_from_name ( Application_Links * app , String_Const_u8 cmd_name ) {
Scratch_Block scratch ( app ) ;
String_ID cmd_name_id = vars_save_string ( cmd_name ) ;
Variable_Handle cmd = def_get_config_var ( cmd_name_id ) ;
return ( cmd ) ;
2018-06-16 20:57:32 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2020-12-06 00:54:33 +00:00
prj_exec_command_name ( Application_Links * app , String_Const_u8 cmd_name ) {
Scratch_Block scratch ( app ) ;
Variable_Handle cmd = prj_command_from_name ( app , cmd_name ) ;
prj_exec_command ( app , cmd ) ;
2018-06-16 20:57:32 +00:00
}
2019-10-25 06:17:54 +00:00
function void
2020-12-06 00:54:33 +00:00
prj_exec_command_fkey_index ( Application_Links * app , i32 fkey_index ) {
// TODO(allen): ideally if one fkey_command is missing this index the fallback
// can be continued.
Variable_Handle fkeys = def_get_config_var ( vars_save_string_lit ( " fkey_command " ) ) ;
// TODO(allen): Ideally I could just pass fkey_index right to vars_read_key
// in a case like this.
Scratch_Block scratch ( app ) ;
String_Const_u8 fkey_index_str = push_stringf ( scratch , " %d " , fkey_index ) ;
String_ID fkey_index_id = vars_save_string ( fkey_index_str ) ;
Variable_Handle cmd_name_var = vars_read_key ( fkeys , fkey_index_id ) ;
String_Const_u8 cmd_name = vars_string_from_var ( scratch , cmd_name_var ) ;
prj_exec_command_name ( app , cmd_name ) ;
2018-06-16 20:57:32 +00:00
}
2018-05-09 07:10:07 +00:00
////////////////////////////////
CUSTOM_COMMAND_SIG ( close_all_code )
CUSTOM_DOC ( " Closes any buffer with a filename ending with an extension configured to be recognized as a code file type. " )
{
2020-11-26 18:45:53 +00:00
Scratch_Block scratch ( app ) ;
String_Const_u8 treat_as_code = def_get_config_string ( scratch , vars_save_string_lit ( " treat_as_code " ) ) ;
String_Const_u8_Array extensions = parse_extension_line_to_extension_list ( app , scratch , treat_as_code ) ;
close_all_files_with_extension ( app , extensions ) ;
2018-05-09 07:10:07 +00:00
}
CUSTOM_COMMAND_SIG ( open_all_code )
CUSTOM_DOC ( " Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config. " )
{
2020-11-26 18:45:53 +00:00
Scratch_Block scratch ( app ) ;
String_Const_u8 treat_as_code = def_get_config_string ( scratch , vars_save_string_lit ( " treat_as_code " ) ) ;
String_Const_u8_Array extensions = parse_extension_line_to_extension_list ( app , scratch , treat_as_code ) ;
open_all_files_in_hot_with_extension ( app , extensions , 0 ) ;
2018-05-09 07:10:07 +00:00
}
CUSTOM_COMMAND_SIG ( open_all_code_recursive )
CUSTOM_DOC ( " Works as open_all_code but also runs in all subdirectories. " )
{
2020-11-26 18:45:53 +00:00
Scratch_Block scratch ( app ) ;
String_Const_u8 treat_as_code = def_get_config_string ( scratch , vars_save_string_lit ( " treat_as_code " ) ) ;
String_Const_u8_Array extensions = parse_extension_line_to_extension_list ( app , scratch , treat_as_code ) ;
open_all_files_in_hot_with_extension ( app , extensions , OpenAllFilesFlag_Recursive ) ;
2018-05-09 07:10:07 +00:00
}
2018-05-08 07:14:23 +00:00
///////////////////////////////
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( load_project )
CUSTOM_DOC ( " Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents. " )
{
2019-10-22 07:15:49 +00:00
ProfileScope ( app , " load project " ) ;
2018-05-09 05:22:33 +00:00
save_all_dirty_buffers ( app ) ;
2020-12-31 00:27:59 +00:00
Scratch_Block scratch ( app ) ;
2020-12-31 07:43:25 +00:00
// NOTE(allen): Load the project file from the hot directory
2020-12-31 00:27:59 +00:00
String_Const_u8 project_path = push_hot_directory ( app , scratch ) ;
2020-12-31 07:43:25 +00:00
File_Name_Data dump = dump_file_search_up_path ( app , scratch , project_path , string_u8_litexpr ( " project.4coder " ) ) ;
String_Const_u8 project_root = string_remove_last_folder ( dump . file_name ) ;
if ( dump . data . str = = 0 ) {
print_message ( app , string_u8_litexpr ( " Did not find project.4coder. \n " ) ) ;
2020-12-31 00:27:59 +00:00
}
2020-12-31 07:43:25 +00:00
// NOTE(allen): Parse config data out of project file
2021-01-01 23:33:03 +00:00
Config * config_parse = 0 ;
2020-12-31 07:53:21 +00:00
Variable_Handle proj_var = vars_get_nil ( ) ;
2020-12-31 07:43:25 +00:00
if ( dump . data . str ! = 0 ) {
Token_Array array = token_array_from_text ( app , scratch , dump . data ) ;
if ( array . tokens ! = 0 ) {
2021-01-01 23:33:03 +00:00
config_parse = def_config_parse ( app , scratch , dump . file_name , dump . data , array ) ;
if ( config_parse ! = 0 ) {
2020-12-31 07:43:25 +00:00
i32 version = 0 ;
2021-01-01 23:33:03 +00:00
if ( config_parse - > version ! = 0 ) {
version = * config_parse - > version ;
2020-12-31 00:27:59 +00:00
}
2021-01-01 23:33:03 +00:00
2020-12-31 07:43:25 +00:00
switch ( version ) {
2020-12-31 07:53:21 +00:00
case 0 :
2020-12-31 07:43:25 +00:00
case 1 :
{
2021-01-01 23:33:03 +00:00
Project * project = parse_project__config_data__version_1 ( app , scratch , project_root , config_parse ) ;
proj_var = prj_version_1_to_version_2 ( app , config_parse , project ) ;
2020-12-31 07:53:21 +00:00
} break ;
default :
{
2021-01-01 23:33:03 +00:00
proj_var = def_fill_var_from_config ( app , vars_get_root ( ) , vars_save_string_lit ( " prj_config " ) , config_parse ) ;
2020-12-31 07:43:25 +00:00
} break ;
2020-12-31 00:27:59 +00:00
}
2021-01-01 23:33:03 +00:00
2020-12-31 00:27:59 +00:00
}
}
}
2021-01-01 23:33:03 +00:00
// NOTE(allen): Print Project
2020-12-31 07:53:21 +00:00
if ( ! vars_is_nil ( proj_var ) ) {
vars_print ( app , proj_var ) ;
print_message ( app , string_u8_litexpr ( " \n " ) ) ;
}
2021-01-01 23:33:03 +00:00
// NOTE(allen): Print Errors
if ( config_parse ! = 0 ) {
String_Const_u8 error_text = config_stringize_errors ( app , scratch , config_parse ) ;
if ( error_text . size > 0 ) {
print_message ( app , string_u8_litexpr ( " Project errors: \n " ) ) ;
print_message ( app , error_text ) ;
print_message ( app , string_u8_litexpr ( " \n " ) ) ;
2020-12-31 00:27:59 +00:00
}
}
2021-01-01 23:33:03 +00:00
// TODO(allen): this is dummy dumb dumb and don't need to be like this.
// NOTE(allen): Set the normal search list's project slot
String_Const_u8 project_dir = prj_path_from_project ( scratch , proj_var ) ;
if ( current_project_arena . base_allocator = = 0 ) {
current_project_arena = make_arena_system ( ) ;
}
linalloc_clear ( & current_project_arena ) ;
def_search_project_path = push_string_copy ( & current_project_arena , project_dir ) ;
// NOTE(allen): Open All Project Files
Variable_Handle load_paths_var = vars_read_key ( proj_var , vars_save_string_lit ( " load_paths " ) ) ;
Variable_Handle load_paths_os_var = vars_read_key ( load_paths_var , vars_save_string_lit ( OS_NAME ) ) ;
String_ID path_id = vars_save_string_lit ( " path " ) ;
String_ID recursive_id = vars_save_string_lit ( " recursive " ) ;
String_ID relative_id = vars_save_string_lit ( " relative " ) ;
Variable_Handle whitelist_var = vars_read_key ( proj_var , vars_save_string_lit ( " patterns " ) ) ;
Variable_Handle blacklist_var = vars_read_key ( proj_var , vars_save_string_lit ( " blacklist_patterns " ) ) ;
Match_Pattern_List whitelist = prj_pattern_list_from_var ( scratch , whitelist_var ) ;
Match_Pattern_List blacklist = prj_pattern_list_from_var ( scratch , blacklist_var ) ;
for ( Variable_Handle load_path_var = vars_first_child ( load_paths_os_var ) ;
! vars_is_nil ( load_path_var ) ;
load_path_var = vars_next_sibling ( load_path_var ) ) {
Variable_Handle path_var = vars_read_key ( load_path_var , path_id ) ;
Variable_Handle recursive_var = vars_read_key ( load_path_var , recursive_id ) ;
Variable_Handle relative_var = vars_read_key ( load_path_var , relative_id ) ;
String_Const_u8 path = vars_string_from_var ( scratch , path_var ) ;
b32 recursive = vars_b32_from_var ( recursive_var ) ;
b32 relative = vars_b32_from_var ( relative_var ) ;
u32 flags = 0 ;
if ( recursive ) {
flags | = OpenAllFilesFlag_Recursive ;
2020-12-31 00:27:59 +00:00
}
2020-12-31 07:43:25 +00:00
2021-01-01 23:33:03 +00:00
String_Const_u8 file_dir = path ;
if ( relative ) {
List_String_Const_u8 file_dir_list = { } ;
string_list_push ( scratch , & file_dir_list , project_dir ) ;
string_list_push_overlap ( scratch , & file_dir_list , ' / ' , path ) ;
string_list_push_overlap ( scratch , & file_dir_list , ' / ' , SCu8 ( ) ) ;
file_dir = string_list_flatten ( scratch , file_dir_list , StringFill_NullTerminate ) ;
2020-12-31 00:27:59 +00:00
}
2021-01-01 23:33:03 +00:00
open_files_pattern_match ( app , file_dir , whitelist , blacklist , flags ) ;
}
// NOTE(allen): Set Window Title
Variable_Handle proj_name_var = vars_read_key ( proj_var , vars_save_string_lit ( " project_name " ) ) ;
String_ID proj_name_id = vars_key_id_from_var ( proj_var ) ;
if ( proj_name_id ! = 0 ) {
String_Const_u8 proj_name = vars_read_string ( scratch , proj_name_id ) ;
String_Const_u8 title = push_u8_stringf ( scratch , " 4coder project: %.*s " , string_expand ( proj_name ) ) ;
set_window_title ( app , title ) ;
2020-12-31 00:27:59 +00:00
}
2017-11-21 18:25:19 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( project_fkey_command )
CUSTOM_DOC ( " Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command. " )
{
2019-10-22 07:15:49 +00:00
ProfileScope ( app , " project fkey command " ) ;
2019-10-14 22:57:47 +00:00
User_Input input = get_current_input ( app ) ;
2019-02-26 23:08:42 +00:00
b32 got_ind = false ;
i32 ind = 0 ;
2019-10-10 18:21:47 +00:00
if ( input . event . kind = = InputEventKind_KeyStroke ) {
if ( KeyCode_F1 < = input . event . key . code & & input . event . key . code < = KeyCode_F16 ) {
ind = ( input . event . key . code - KeyCode_F1 ) ;
got_ind = true ;
}
else if ( KeyCode_1 < = input . event . key . code & & input . event . key . code < = KeyCode_9 ) {
ind = ( input . event . key . code - ' 1 ' ) ;
got_ind = true ;
}
else if ( input . event . key . code = = KeyCode_0 ) {
ind = 9 ;
got_ind = true ;
}
if ( got_ind ) {
2020-12-06 00:54:33 +00:00
prj_exec_command_fkey_index ( app , ind ) ;
2019-10-10 18:21:47 +00:00
}
2017-01-29 00:03:23 +00:00
}
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( project_go_to_root_directory )
CUSTOM_DOC ( " Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns. " )
{
2021-01-06 03:54:41 +00:00
Scratch_Block scratch ( app ) ;
Variable_Handle prj_var = vars_read_key ( vars_get_root ( ) , vars_save_string_lit ( " prj_config " ) ) ;
String_Const_u8 prj_dir = prj_path_from_project ( scratch , prj_var ) ;
set_hot_directory ( app , prj_dir ) ;
2017-06-20 20:37:45 +00:00
}
2017-11-09 18:30:24 +00:00
///////////////////////////////
2019-10-25 06:17:54 +00:00
function Project_Setup_Status
2019-06-01 23:33:31 +00:00
project_is_setup ( Application_Links * app , String_Const_u8 script_path , String_Const_u8 script_file ) {
2018-11-20 08:18:54 +00:00
Project_Setup_Status result = { } ;
2019-06-01 23:33:31 +00:00
{
Scratch_Block scratch ( app ) ;
2019-06-18 22:56:09 +00:00
String_Const_u8 bat_path = push_u8_stringf ( scratch , " %.*s/%.*s.bat " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
result . bat_exists = file_exists ( app , bat_path ) ;
}
{
Scratch_Block scratch ( app ) ;
2019-06-18 22:56:09 +00:00
String_Const_u8 sh_path = push_u8_stringf ( scratch , " %.*s/%.*s.sh " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
result . sh_exists = file_exists ( app , sh_path ) ;
}
{
Scratch_Block scratch ( app ) ;
2019-06-18 22:56:09 +00:00
String_Const_u8 project_path = push_u8_stringf ( scratch , " %.*s/project.4coder " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ) ;
result . sh_exists = file_exists ( app , project_path ) ;
}
result . everything_exists = ( result . bat_exists & & result . sh_exists & & result . project_exists ) ;
2017-11-09 18:30:24 +00:00
return ( result ) ;
}
2019-10-25 06:17:54 +00:00
function Project_Key_Strings
2018-06-02 00:29:36 +00:00
project_key_strings_query_user ( Application_Links * app ,
2019-02-26 23:08:42 +00:00
b32 get_script_file , b32 get_code_file ,
2019-06-01 23:33:31 +00:00
u8 * script_file_space , i32 script_file_cap ,
u8 * code_file_space , i32 code_file_cap ,
u8 * output_dir_space , i32 output_dir_cap ,
u8 * binary_file_space , i32 binary_file_cap ) {
2018-11-20 08:18:54 +00:00
Project_Key_Strings keys = { } ;
2017-11-09 18:30:24 +00:00
2019-10-13 20:17:22 +00:00
Query_Bar_Group bar_group ( app ) ;
2018-11-20 08:18:54 +00:00
Query_Bar script_file_bar = { } ;
Query_Bar code_file_bar = { } ;
Query_Bar output_dir_bar = { } ;
Query_Bar binary_file_bar = { } ;
2018-06-02 00:29:36 +00:00
if ( get_script_file ) {
2019-06-01 23:33:31 +00:00
script_file_bar . prompt = string_u8_litexpr ( " Script Name: " ) ;
2019-12-18 03:38:08 +00:00
script_file_bar . string = SCu8 ( script_file_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
script_file_bar . string_capacity = script_file_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & script_file_bar ) ) return ( keys ) ;
if ( script_file_bar . string . size = = 0 ) return ( keys ) ;
}
if ( get_code_file ) {
2019-06-01 23:33:31 +00:00
code_file_bar . prompt = string_u8_litexpr ( " Build Target: " ) ;
2019-12-18 03:38:08 +00:00
code_file_bar . string = SCu8 ( code_file_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
code_file_bar . string_capacity = code_file_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & code_file_bar ) ) return ( keys ) ;
if ( code_file_bar . string . size = = 0 ) return ( keys ) ;
}
2019-06-01 23:33:31 +00:00
output_dir_bar . prompt = string_u8_litexpr ( " Output Directory: " ) ;
2019-12-18 03:38:08 +00:00
output_dir_bar . string = SCu8 ( output_dir_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
output_dir_bar . string_capacity = output_dir_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & output_dir_bar ) ) return ( keys ) ;
2019-06-01 23:33:31 +00:00
if ( output_dir_bar . string . size = = 0 & & output_dir_cap > 0 ) {
output_dir_bar . string . str [ 0 ] = ' . ' ;
output_dir_bar . string . size = 1 ;
2018-06-02 00:29:36 +00:00
}
2019-06-01 23:33:31 +00:00
binary_file_bar . prompt = string_u8_litexpr ( " Binary Output: " ) ;
2019-12-18 03:38:08 +00:00
binary_file_bar . string = SCu8 ( binary_file_space , ( u64 ) 0 ) ;
2019-06-01 23:33:31 +00:00
binary_file_bar . string_capacity = binary_file_cap ;
2018-06-02 00:29:36 +00:00
if ( ! query_user_string ( app , & binary_file_bar ) ) return ( keys ) ;
if ( binary_file_bar . string . size = = 0 ) return ( keys ) ;
keys . success = true ;
keys . script_file = script_file_bar . string ;
keys . code_file = code_file_bar . string ;
keys . output_dir = output_dir_bar . string ;
keys . binary_file = binary_file_bar . string ;
return ( keys ) ;
}
2019-10-25 06:17:54 +00:00
function b32
2019-06-01 23:33:31 +00:00
project_generate_bat_script ( Arena * scratch , String_Const_u8 opts , String_Const_u8 compiler ,
String_Const_u8 script_path , String_Const_u8 script_file ,
String_Const_u8 code_file , String_Const_u8 output_dir , String_Const_u8 binary_file ) {
2019-02-26 23:08:42 +00:00
b32 success = false ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2018-06-02 00:29:36 +00:00
2019-07-13 00:43:17 +00:00
String_Const_u8 cf = push_string_copy ( scratch , code_file ) ;
String_Const_u8 od = push_string_copy ( scratch , output_dir ) ;
String_Const_u8 bf = push_string_copy ( scratch , binary_file ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
cf = string_mod_replace_character ( cf , ' / ' , ' \\ ' ) ;
od = string_mod_replace_character ( od , ' / ' , ' \\ ' ) ;
bf = string_mod_replace_character ( bf , ' / ' , ' \\ ' ) ;
2018-06-02 00:29:36 +00:00
2019-06-18 22:56:09 +00:00
String_Const_u8 file_name = push_u8_stringf ( scratch , " %.*s/%.*s.bat " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
FILE * bat_script = fopen ( ( char * ) file_name . str , " wb " ) ;
2018-06-02 00:29:36 +00:00
if ( bat_script ! = 0 ) {
fprintf ( bat_script , " @echo off \n \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( bat_script , " set opts=%.*s \n " , ( i32 ) opts . size , opts . str ) ;
2018-06-02 00:29:36 +00:00
fprintf ( bat_script , " set code=%%cd%% \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( bat_script , " pushd %.*s \n " , ( i32 ) od . size , od . str ) ;
2018-06-02 00:29:36 +00:00
fprintf ( bat_script , " %.*s %%opts%% %%code%% \\ %.*s -Fe%.*s \n " ,
2019-06-01 23:33:31 +00:00
( i32 ) compiler . size , compiler . str , ( i32 ) cf . size , cf . str , ( i32 ) bf . size , bf . str ) ;
2018-06-02 00:29:36 +00:00
fprintf ( bat_script , " popd \n " ) ;
fclose ( bat_script ) ;
success = true ;
}
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-06-02 00:29:36 +00:00
return ( success ) ;
}
2019-10-25 06:17:54 +00:00
function b32
2019-06-01 23:33:31 +00:00
project_generate_sh_script ( Arena * scratch , String_Const_u8 opts , String_Const_u8 compiler ,
String_Const_u8 script_path , String_Const_u8 script_file ,
String_Const_u8 code_file , String_Const_u8 output_dir , String_Const_u8 binary_file ) {
2019-02-26 23:08:42 +00:00
b32 success = false ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
String_Const_u8 cf = code_file ;
String_Const_u8 od = output_dir ;
String_Const_u8 bf = binary_file ;
2018-06-02 00:29:36 +00:00
2019-06-18 22:56:09 +00:00
String_Const_u8 file_name = push_u8_stringf ( scratch , " %.*s/%.*s.sh " ,
2019-06-01 23:33:31 +00:00
string_expand ( script_path ) ,
string_expand ( script_file ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
FILE * sh_script = fopen ( ( char * ) file_name . str , " wb " ) ;
2018-06-02 00:29:36 +00:00
if ( sh_script ! = 0 ) {
fprintf ( sh_script , " #!/bin/bash \n \n " ) ;
fprintf ( sh_script , " code= \" $PWD \" \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( sh_script , " opts=%.*s \n " , string_expand ( opts ) ) ;
fprintf ( sh_script , " cd %.*s > /dev/null \n " , string_expand ( od ) ) ;
fprintf ( sh_script , " %.*s $opts $code/%.*s -o %.*s \n " , string_expand ( compiler ) , string_expand ( cf ) , string_expand ( bf ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( sh_script , " cd $code > /dev/null \n " ) ;
fclose ( sh_script ) ;
success = true ;
}
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-06-02 00:29:36 +00:00
return ( success ) ;
}
2019-10-25 06:17:54 +00:00
function b32
2019-06-01 23:33:31 +00:00
project_generate_project_4coder_file ( Arena * scratch , String_Const_u8 script_path , String_Const_u8 script_file , String_Const_u8 output_dir , String_Const_u8 binary_file ) {
2019-02-26 23:08:42 +00:00
b32 success = false ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
Temp_Memory temp = begin_temp ( scratch ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
String_Const_u8 od = output_dir ;
String_Const_u8 bf = binary_file ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
String_Const_u8 od_win = string_replace ( scratch , od ,
string_u8_litexpr ( " / " ) , string_u8_litexpr ( " \\ " ) ) ;
String_Const_u8 bf_win = string_replace ( scratch , bf ,
string_u8_litexpr ( " / " ) , string_u8_litexpr ( " \\ " ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-18 22:56:09 +00:00
String_Const_u8 file_name = push_u8_stringf ( scratch , " %.*s/project.4coder " , string_expand ( script_path ) ) ;
2018-06-02 00:29:36 +00:00
2019-06-01 23:33:31 +00:00
FILE * out = fopen ( ( char * ) file_name . str , " wb " ) ;
2018-06-02 00:29:36 +00:00
if ( out ! = 0 ) {
fprintf ( out , " version(1); \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( out , " project_name = \" %.*s \" ; \n " , string_expand ( binary_file ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " patterns = { \n " ) ;
fprintf ( out , " \" *.c \" , \n " ) ;
fprintf ( out , " \" *.cpp \" , \n " ) ;
fprintf ( out , " \" *.h \" , \n " ) ;
fprintf ( out , " \" *.m \" , \n " ) ;
fprintf ( out , " \" *.bat \" , \n " ) ;
fprintf ( out , " \" *.sh \" , \n " ) ;
fprintf ( out , " \" *.4coder \" , \n " ) ;
fprintf ( out , " }; \n " ) ;
2018-06-02 23:02:14 +00:00
fprintf ( out , " blacklist_patterns = { \n " ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " \" .* \" , \n " ) ;
fprintf ( out , " }; \n " ) ;
fprintf ( out , " load_paths_base = { \n " ) ;
2018-06-02 23:02:14 +00:00
fprintf ( out , " { \" . \" , .relative = true, .recursive = true, }, \n " ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " }; \n " ) ;
fprintf ( out , " load_paths = { \n " ) ;
fprintf ( out , " { load_paths_base, .os = \" win \" , }, \n " ) ;
fprintf ( out , " { load_paths_base, .os = \" linux \" , }, \n " ) ;
fprintf ( out , " { load_paths_base, .os = \" mac \" , }, \n " ) ;
fprintf ( out , " }; \n " ) ;
fprintf ( out , " \n " ) ;
fprintf ( out , " command_list = { \n " ) ;
fprintf ( out , " { .name = \" build \" , \n " ) ;
fprintf ( out , " .out = \" *compilation* \" , .footer_panel = true, .save_dirty_files = true, \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( out , " .cmd = { { \" %.*s.bat \" , .os = \" win \" }, \n " , string_expand ( script_file ) ) ;
fprintf ( out , " { \" ./%.*s.sh \" , .os = \" linux \" }, \n " , string_expand ( script_file ) ) ;
fprintf ( out , " { \" ./%.*s.sh \" , .os = \" mac \" }, }, }, \n " , string_expand ( script_file ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " { .name = \" run \" , \n " ) ;
fprintf ( out , " .out = \" *run* \" , .footer_panel = false, .save_dirty_files = false, \n " ) ;
2019-06-01 23:33:31 +00:00
fprintf ( out , " .cmd = { { \" %.*s \\ \\ %.*s \" , .os = \" win \" }, \n " , string_expand ( od_win ) , string_expand ( bf_win ) ) ;
fprintf ( out , " { \" %.*s/%.*s \" , .os = \" linux \" }, \n " , string_expand ( od ) , string_expand ( bf ) ) ;
fprintf ( out , " { \" %.*s/%.*s \" , .os = \" mac \" }, }, }, \n " , string_expand ( od ) , string_expand ( bf ) ) ;
2018-06-02 00:29:36 +00:00
fprintf ( out , " }; \n " ) ;
fprintf ( out , " fkey_command[1] = \" build \" ; \n " ) ;
fprintf ( out , " fkey_command[2] = \" run \" ; \n " ) ;
fclose ( out ) ;
success = true ;
}
2019-06-01 23:33:31 +00:00
end_temp ( temp ) ;
2018-06-02 00:29:36 +00:00
return ( success ) ;
}
2019-10-25 06:17:54 +00:00
function void
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( Application_Links * app , b32 do_project_file , b32 do_bat_script , b32 do_sh_script ) {
2019-10-01 02:06:21 +00:00
Scratch_Block scratch ( app ) ;
2019-06-01 23:33:31 +00:00
String_Const_u8 script_path = push_hot_directory ( app , scratch ) ;
2018-06-02 00:29:36 +00:00
2019-02-26 23:08:42 +00:00
b32 needs_to_do_work = false ;
2018-11-20 08:18:54 +00:00
Project_Setup_Status status = { } ;
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2019-06-01 23:33:31 +00:00
status = project_is_setup ( app , script_path , string_u8_litexpr ( " build " ) ) ;
2018-06-02 00:29:36 +00:00
needs_to_do_work =
! status . project_exists | |
( do_bat_script & & ! status . bat_exists ) | |
( do_sh_script & & ! status . sh_exists ) ;
}
else {
needs_to_do_work = true ;
}
if ( needs_to_do_work ) {
// Query the User for Key File Names
2019-06-01 23:33:31 +00:00
u8 script_file_space [ 1024 ] ;
u8 code_file_space [ 1024 ] ;
u8 output_dir_space [ 1024 ] ;
u8 binary_file_space [ 1024 ] ;
2017-11-09 18:30:24 +00:00
2019-02-26 23:08:42 +00:00
b32 get_script_file = ! do_project_file ;
b32 get_code_file =
2018-06-02 00:29:36 +00:00
( do_bat_script & & ! status . bat_exists ) | |
( do_sh_script & & ! status . sh_exists ) ;
2017-11-09 18:30:24 +00:00
2019-06-01 23:33:31 +00:00
Project_Key_Strings keys = { } ;
keys = project_key_strings_query_user ( app , get_script_file , get_code_file ,
script_file_space , sizeof ( script_file_space ) ,
code_file_space , sizeof ( code_file_space ) ,
output_dir_space , sizeof ( output_dir_space ) ,
binary_file_space , sizeof ( binary_file_space ) ) ;
2017-11-09 18:30:24 +00:00
2018-06-02 00:29:36 +00:00
if ( ! keys . success ) {
return ;
}
2017-11-09 18:30:24 +00:00
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2019-06-01 23:33:31 +00:00
keys . script_file = string_u8_litexpr ( " build " ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
2018-06-02 00:29:36 +00:00
if ( ! do_project_file ) {
2019-06-01 23:33:31 +00:00
status = project_is_setup ( app , script_path , keys . script_file ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
// Generate Scripts
2018-06-02 00:29:36 +00:00
if ( do_bat_script ) {
if ( ! status . bat_exists ) {
2020-11-26 03:20:36 +00:00
String_Const_u8 default_flags_bat = def_get_config_string ( scratch , vars_save_string_lit ( " default_flags_bat " ) ) ;
String_Const_u8 default_compiler_bat = def_get_config_string ( scratch , vars_save_string_lit ( " default_compiler_bat " ) ) ;
if ( ! project_generate_bat_script ( scratch , default_flags_bat , default_compiler_bat ,
2018-06-02 00:29:36 +00:00
script_path , keys . script_file ,
keys . code_file , keys . output_dir , keys . binary_file ) ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " could not create build.bat for new project \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
else {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " the batch script already exists, no changes made to it \n " ) ) ;
2017-11-09 18:30:24 +00:00
}
}
2018-06-02 00:29:36 +00:00
if ( do_sh_script ) {
if ( ! status . bat_exists ) {
2020-11-26 03:20:36 +00:00
String_Const_u8 default_flags_sh = def_get_config_string ( scratch , vars_save_string_lit ( " default_flags_sh " ) ) ;
String_Const_u8 default_compiler_sh = def_get_config_string ( scratch , vars_save_string_lit ( " default_compiler_sh " ) ) ;
if ( ! project_generate_sh_script ( scratch , default_flags_sh , default_compiler_sh ,
2018-06-02 00:29:36 +00:00
script_path , keys . script_file ,
keys . code_file , keys . output_dir , keys . binary_file ) ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " could not create build.sh for new project \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
else {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " the shell script already exists, no changes made to it \n " ) ) ;
2017-11-09 18:30:24 +00:00
}
}
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
if ( ! status . project_exists ) {
2019-06-01 23:33:31 +00:00
if ( ! project_generate_project_4coder_file ( scratch ,
script_path ,
keys . script_file ,
keys . output_dir ,
keys . binary_file ) ) {
print_message ( app , string_u8_litexpr ( " could not create project.4coder for new project \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
else {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " project.4coder already exists, no changes made to it \n " ) ) ;
2017-11-09 18:30:24 +00:00
}
}
}
else {
2018-06-02 00:29:36 +00:00
if ( do_project_file ) {
2019-06-01 23:33:31 +00:00
print_message ( app , string_u8_litexpr ( " project already setup, no changes made \n " ) ) ;
2018-06-02 00:29:36 +00:00
}
2017-11-09 18:30:24 +00:00
}
2018-06-02 00:29:36 +00:00
}
CUSTOM_COMMAND_SIG ( setup_new_project )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , true , true , true ) ;
2017-11-21 18:25:19 +00:00
load_project ( app ) ;
2017-11-09 18:30:24 +00:00
}
2018-06-02 00:29:36 +00:00
CUSTOM_COMMAND_SIG ( setup_build_bat )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build batch script. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , false , true , false ) ;
2018-06-02 00:29:36 +00:00
}
CUSTOM_COMMAND_SIG ( setup_build_sh )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build shell script. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , false , false , true ) ;
2018-06-02 00:29:36 +00:00
}
CUSTOM_COMMAND_SIG ( setup_build_bat_and_sh )
CUSTOM_DOC ( " Queries the user for several configuration options and initializes a new build batch script. " )
{
2019-06-01 23:33:31 +00:00
project_setup_scripts__generic ( app , false , true , true ) ;
2018-06-02 00:29:36 +00:00
}
2018-09-17 18:47:06 +00:00
///////////////////////////////
2020-12-30 23:21:39 +00:00
function Variable_Handle
2020-03-11 23:22:37 +00:00
get_project_command_from_user ( Application_Links * app , Project * project , String_Const_u8 query ) {
2020-12-30 23:21:39 +00:00
Variable_Handle result = vars_get_nil ( ) ;
2019-10-25 23:33:50 +00:00
if ( project ! = 0 ) {
Scratch_Block scratch ( app ) ;
2020-02-29 23:38:38 +00:00
Lister_Block lister ( app , scratch ) ;
2019-10-25 23:33:50 +00:00
lister_set_query ( lister , query ) ;
2020-02-29 23:38:38 +00:00
lister_set_default_handlers ( lister ) ;
2019-10-25 23:33:50 +00:00
Project_Command * proj_cmd = project - > command_array . commands ;
i32 count = project - > command_array . count ;
for ( i32 i = 0 ; i < count ; i + = 1 , proj_cmd + = 1 ) {
2020-12-06 00:54:33 +00:00
lister_add_item ( lister , proj_cmd - > name , proj_cmd - > cmd , proj_cmd , 0 ) ;
2019-10-25 23:33:50 +00:00
}
Lister_Result l_result = run_lister ( app , lister ) ;
if ( ! l_result . canceled ) {
2020-12-06 00:54:33 +00:00
Project_Command * result_proj_cmd = ( Project_Command * ) l_result . user_data ;
2020-12-31 00:36:59 +00:00
if ( result_proj_cmd ! = 0 ) {
String_Const_u8 cmd_name = prj_sanitize_string ( scratch , result_proj_cmd - > name ) ;
result = prj_command_from_name ( app , cmd_name ) ;
}
2019-10-25 23:33:50 +00:00
}
}
return ( result ) ;
}
2018-09-17 18:47:06 +00:00
CUSTOM_COMMAND_SIG ( project_command_lister )
CUSTOM_DOC ( " Open a lister of all commands in the currently loaded project. " )
{
2019-06-01 23:33:31 +00:00
if ( current_project . loaded ) {
2020-12-30 23:21:39 +00:00
Variable_Handle proj_cmd =
get_project_command_from_user ( app , & current_project , string_u8_litexpr ( " Command: " ) ) ;
if ( ! vars_is_nil ( proj_cmd ) ) {
prj_exec_command ( app , proj_cmd ) ;
2019-06-01 23:33:31 +00:00
}
2018-09-17 18:47:06 +00:00
}
}
2017-01-29 00:03:23 +00:00
// BOTTOM