2017-01-29 00:03:23 +00:00
/*
4 coder_build_commands . cpp - Commands for building .
TYPE : ' drop - in - command - pack '
*/
// TOP
# if !defined(FCODER_BUILD_COMMANDS_CPP)
# define FCODER_BUILD_COMMANDS_CPP
# include "4coder_helper/4coder_helper.h"
# include "4coder_default_framework.h"
// NOTE(allen|a4.0.9): This is provided to establish a default method of getting
// a "build directory". This function tries to setup the build directory in the
// directory of the given buffer, if it cannot get that information it get's the
// 4coder hot directory.
//
// There is no requirement that a custom build system in 4coder actually use the
// directory given by this function.
enum Get_Build_Directory_Result {
BuildDir_None ,
BuildDir_AtFile ,
BuildDir_AtHot
} ;
static int32_t
get_build_directory ( Application_Links * app , Buffer_Summary * buffer , String * dir_out ) {
int32_t result = BuildDir_None ;
2017-02-12 06:01:01 +00:00
if ( buffer ! = 0 & & buffer - > file_name ! = 0 ) {
2017-01-29 00:03:23 +00:00
if ( ! match_cc ( buffer - > file_name , buffer - > buffer_name ) ) {
2017-02-12 06:01:01 +00:00
char * file_name = buffer - > file_name ;
int32_t file_name_len = buffer - > file_name_len ;
String dir = make_string_cap ( file_name , file_name_len , file_name_len + 1 ) ;
2017-01-29 00:03:23 +00:00
remove_last_folder ( & dir ) ;
append_ss ( dir_out , dir ) ;
result = BuildDir_AtFile ;
}
}
if ( ! result ) {
int32_t len = directory_get_hot ( app , dir_out - > str ,
dir_out - > memory_size - dir_out - > size ) ;
2017-02-06 13:49:00 +00:00
if ( dir_out - > size + len < dir_out - > memory_size ) {
2017-01-29 00:03:23 +00:00
dir_out - > size + = len ;
result = BuildDir_AtHot ;
}
}
return ( result ) ;
}
// TODO(allen): Better names for the "standard build search" family.
static int32_t
standard_build_search ( Application_Links * app , View_Summary * view , Buffer_Summary * active_buffer , String * dir , String * command , int32_t perform_backup , int32_t use_path_in_command , String filename , String commandname ) {
int32_t result = false ;
for ( ; ; ) {
int32_t old_size = dir - > size ;
append_ss ( dir , filename ) ;
if ( file_exists ( app , dir - > str , dir - > size ) ) {
dir - > size = old_size ;
if ( use_path_in_command ) {
append_s_char ( command , ' " ' ) ;
append_ss ( command , * dir ) ;
append_ss ( command , commandname ) ;
append_s_char ( command , ' " ' ) ;
}
else {
append_ss ( command , commandname ) ;
}
char space [ 512 ] ;
String message = make_fixed_width_string ( space ) ;
append_ss ( & message , make_lit_string ( " Building with: " ) ) ;
append_ss ( & message , * command ) ;
append_s_char ( & message , ' \n ' ) ;
print_message ( app , message . str , message . size ) ;
2017-02-06 13:49:00 +00:00
if ( automatically_save_changes_on_build ) {
save_all_dirty_buffers ( app ) ;
}
2017-01-29 00:03:23 +00:00
exec_system_command ( app , view , buffer_identifier ( literal ( " *compilation* " ) ) , dir - > str , dir - > size , command - > str , command - > size , CLI_OverlapWithConflict ) ;
result = true ;
break ;
}
dir - > size = old_size ;
if ( directory_cd ( app , dir - > str , & dir - > size , dir - > memory_size , literal ( " .. " ) ) = = 0 ) {
if ( perform_backup ) {
dir - > size = directory_get_hot ( app , dir - > str , dir - > memory_size ) ;
char backup_space [ 256 ] ;
String backup_command = make_fixed_width_string ( backup_space ) ;
append_ss ( & backup_command , make_lit_string ( " echo could not find " ) ) ;
append_ss ( & backup_command , filename ) ;
exec_system_command ( app , view , buffer_identifier ( literal ( " *compilation* " ) ) , dir - > str , dir - > size , backup_command . str , backup_command . size , CLI_OverlapWithConflict ) ;
}
break ;
}
}
return ( result ) ;
}
# if defined(_WIN32)
// NOTE(allen): Build search rule for windows.
static int32_t
execute_standard_build_search ( Application_Links * app , View_Summary * view ,
Buffer_Summary * active_buffer ,
String * dir , String * command , int32_t perform_backup ) {
int32_t result = standard_build_search ( app , view , active_buffer , dir , command , perform_backup , true , make_lit_string ( " build.bat " ) , make_lit_string ( " build " ) ) ;
return ( result ) ;
}
2017-06-27 02:47:00 +00:00
# elif defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
2017-01-29 00:03:23 +00:00
2017-06-27 02:47:00 +00:00
// NOTE(allen): Build search rule for linux and mac.
2017-01-29 00:03:23 +00:00
static int32_t
execute_standard_build_search ( Application_Links * app , View_Summary * view , Buffer_Summary * active_buffer , String * dir , String * command , bool32 perform_backup ) {
char dir_space [ 512 ] ;
String dir_copy = make_fixed_width_string ( dir_space ) ;
copy ( & dir_copy , * dir ) ;
int32_t result = standard_build_search ( app , view , active_buffer , dir , command , 0 , 1 , make_lit_string ( " build.sh " ) , make_lit_string ( " build.sh " ) ) ;
if ( ! result ) {
result = standard_build_search ( app , view , active_buffer , & dir_copy , command , perform_backup , 0 , make_lit_string ( " Makefile " ) , make_lit_string ( " make " ) ) ;
}
return ( result ) ;
}
# else
# error No build search rule for this platform.
# endif
// NOTE(allen): This searches first using the active file's directory,
// then if no build script is found, it searches from 4coders hot directory.
static void
execute_standard_build ( Application_Links * app , View_Summary * view , Buffer_Summary * active_buffer ) {
char dir_space [ 512 ] ;
String dir = make_fixed_width_string ( dir_space ) ;
char command_str_space [ 512 ] ;
String command = make_fixed_width_string ( command_str_space ) ;
int32_t build_dir_type = get_build_directory ( app , active_buffer , & dir ) ;
if ( build_dir_type = = BuildDir_AtFile ) {
if ( ! execute_standard_build_search ( app , view , active_buffer , & dir , & command , false ) ) {
dir . size = 0 ;
command . size = 0 ;
build_dir_type = get_build_directory ( app , 0 , & dir ) ;
}
}
if ( build_dir_type = = BuildDir_AtHot ) {
execute_standard_build_search ( app , view , active_buffer , & dir , & command , true ) ;
}
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( build_search )
CUSTOM_DOC ( " Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. " )
{
2017-01-29 00:03:23 +00:00
uint32_t access = AccessAll ;
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
execute_standard_build ( app , & view , & buffer ) ;
prev_location = null_location ;
lock_jump_buffer ( literal ( " *compilation* " ) ) ;
}
# define GET_COMP_BUFFER(app) get_buffer_by_name(app, literal("*compilation*"), AccessAll)
static View_Summary
get_or_open_build_panel ( Application_Links * app ) {
View_Summary view = { 0 } ;
Buffer_Summary buffer = GET_COMP_BUFFER ( app ) ;
if ( buffer . exists ) {
view = get_first_view_with_buffer ( app , buffer . buffer_id ) ;
}
if ( ! view . exists ) {
view = open_special_note_view ( app ) ;
}
return ( view ) ;
}
static void
set_fancy_compilation_buffer_font ( Application_Links * app ) {
Buffer_Summary comp_buffer = get_buffer_by_name ( app , literal ( " *compilation* " ) , AccessAll ) ;
buffer_set_font ( app , & comp_buffer , literal ( " Inconsolata " ) ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( build_in_build_panel )
CUSTOM_DOC ( " Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view. " )
{
2017-01-29 00:03:23 +00:00
uint32_t access = AccessAll ;
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
View_Summary build_view = get_or_open_build_panel ( app ) ;
execute_standard_build ( app , & build_view , & buffer ) ;
set_fancy_compilation_buffer_font ( app ) ;
prev_location = null_location ;
lock_jump_buffer ( literal ( " *compilation* " ) ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( close_build_panel )
CUSTOM_DOC ( " If the special build panel is open, closes it. " )
{
2017-01-29 00:03:23 +00:00
close_special_note_view ( app ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( change_to_build_panel )
CUSTOM_DOC ( " If the special build panel is open, makes the build panel the active panel. " )
{
2017-01-29 00:03:23 +00:00
View_Summary view = open_special_note_view ( app , false ) ;
if ( ! view . exists ) {
Buffer_Summary buffer = GET_COMP_BUFFER ( app ) ;
if ( buffer . exists ) {
view = open_special_note_view ( app ) ;
view_set_buffer ( app , & view , buffer . buffer_id , 0 ) ;
}
}
if ( view . exists ) {
set_active_view ( app , & view ) ;
}
}
# endif
// BOTTOM