Productivity Acceleration: project.4coder helpers

master
Allen Webster 2017-11-09 13:30:24 -05:00
parent dbb945753b
commit bcff1f1f9f
8 changed files with 443 additions and 14 deletions

View File

@ -742,6 +742,18 @@ static Extension_List treat_as_code_exts = {0};
static bool32 automatically_load_project = false; static bool32 automatically_load_project = false;
static char default_compiler_bat_space[256];
static String default_compiler_bat = make_fixed_width_string(default_compiler_bat_space);
static char default_flags_bat_space[1024];
static String default_flags_bat = make_fixed_width_string(default_flags_bat_space);
static char default_compiler_sh_space[256];
static String default_compiler_sh = make_fixed_width_string(default_compiler_sh_space);
static char default_flags_sh_space[1024];
static String default_flags_sh = make_fixed_width_string(default_flags_sh_space);
static bool32 static bool32
get_current_name(char **name_out, int32_t *len_out){ get_current_name(char **name_out, int32_t *len_out){
bool32 result = false; bool32 result = false;
@ -813,6 +825,15 @@ process_config_file(Application_Links *app){
Partition *part = &global_part; Partition *part = &global_part;
FILE *file = fopen("config.4coder", "rb"); FILE *file = fopen("config.4coder", "rb");
static bool32 has_initialized = false;
if (!has_initialized){
has_initialized = true;
copy(&default_compiler_bat, "cl");
copy(&default_flags_bat, "");
copy(&default_compiler_sh, "g++");
copy(&default_flags_bat, "");
}
if (file == 0){ if (file == 0){
char space[256]; char space[256];
int32_t size = get_4ed_path(app, space, sizeof(space)); int32_t size = get_4ed_path(app, space, sizeof(space));
@ -868,6 +889,10 @@ process_config_file(Application_Links *app){
config_string_var(item, "default_font_name", 0, &default_font_name); config_string_var(item, "default_font_name", 0, &default_font_name);
config_string_var(item, "user_name", 0, &user_name); config_string_var(item, "user_name", 0, &user_name);
config_string_var(item, "default_compiler_bat", 0, &default_compiler_bat);
config_string_var(item, "default_flags_bat", 0, &default_flags_bat);
config_string_var(item, "default_compiler_sh", 0, &default_compiler_sh);
config_string_var(item, "default_flags_sh", 0, &default_flags_sh);
char str_space[512]; char str_space[512];
String str = make_fixed_width_string(str_space); String str = make_fixed_width_string(str_space);

View File

@ -516,6 +516,9 @@ CUSTOM_COMMAND_SIG(execute_arbitrary_command){
else if (match_ss(bar.string, make_lit_string("remap"))){ else if (match_ss(bar.string, make_lit_string("remap"))){
exec_command(app, remap_interactive); exec_command(app, remap_interactive);
} }
else if (match_ss(bar.string, make_lit_string("new project"))){
exec_command(app, setup_new_project);
}
else{ else{
print_message(app, literal("unrecognized command\n")); print_message(app, literal("unrecognized command\n"));
} }

View File

@ -1,5 +1,5 @@
/* /*
4coder_string.h - Version 1.0.102 4coder_string.h - Version 1.0.107
no warranty implied; use at your own risk no warranty implied; use at your own risk
This software is in the public domain. Where that dedication is not This software is in the public domain. Where that dedication is not
@ -42,7 +42,7 @@ typedef int32_t b32_4tech;
#if !defined(Assert) #if !defined(Assert)
# define Assert(n) do{ if (!(n)) *(int*)0 = 0xA11E; }while(0) # define Assert(n) do{ if (!(n)) *(int*)0 = 0xA11E; }while(0)
#endif #endif
// standard preamble end // standard preamble end
#if !defined(FSTRING_LINK) #if !defined(FSTRING_LINK)
# define FSTRING_LINK static # define FSTRING_LINK static
@ -169,6 +169,10 @@ FSTRING_INLINE b32_4tech append_sc(String *dest, char *src);
FSTRING_LINK b32_4tech terminate_with_null(String *str); FSTRING_LINK b32_4tech terminate_with_null(String *str);
FSTRING_LINK b32_4tech append_padding(String *dest, char c, i32_4tech target_size); FSTRING_LINK b32_4tech append_padding(String *dest, char c, i32_4tech target_size);
FSTRING_LINK void replace_char(String *str, char replace, char with); FSTRING_LINK void replace_char(String *str, char replace, char with);
FSTRING_LINK void replace_str_ss(String *str, String replace, String with);
FSTRING_LINK void replace_str_sc(String *str, String replace, char *with);
FSTRING_LINK void replace_str_cs(String *str, char *replace, String with);
FSTRING_LINK void replace_str_cc(String *str, char *replace, char *with);
FSTRING_LINK void to_lower_cc(char *src, char *dst); FSTRING_LINK void to_lower_cc(char *src, char *dst);
FSTRING_LINK void to_lower_ss(String *dst, String src); FSTRING_LINK void to_lower_ss(String *dst, String src);
FSTRING_LINK void to_lower_s(String *str); FSTRING_LINK void to_lower_s(String *str);
@ -272,6 +276,10 @@ FSTRING_LINK b32_4tech append_partial(String *dest, String src){retu
FSTRING_LINK b32_4tech append(String *dest, char c){return(append_s_char(dest,c));} FSTRING_LINK b32_4tech append(String *dest, char c){return(append_s_char(dest,c));}
FSTRING_INLINE b32_4tech append(String *dest, String src){return(append_ss(dest,src));} FSTRING_INLINE b32_4tech append(String *dest, String src){return(append_ss(dest,src));}
FSTRING_INLINE b32_4tech append(String *dest, char *src){return(append_sc(dest,src));} FSTRING_INLINE b32_4tech append(String *dest, char *src){return(append_sc(dest,src));}
FSTRING_LINK void replace_str(String *str, String replace, String with){return(replace_str_ss(str,replace,with));}
FSTRING_LINK void replace_str(String *str, String replace, char *with){return(replace_str_sc(str,replace,with));}
FSTRING_LINK void replace_str(String *str, char *replace, String with){return(replace_str_cs(str,replace,with));}
FSTRING_LINK void replace_str(String *str, char *replace, char *with){return(replace_str_cc(str,replace,with));}
FSTRING_LINK void to_lower(char *src, char *dst){return(to_lower_cc(src,dst));} FSTRING_LINK void to_lower(char *src, char *dst){return(to_lower_cc(src,dst));}
FSTRING_LINK void to_lower(String *dst, String src){return(to_lower_ss(dst,src));} FSTRING_LINK void to_lower(String *dst, String src){return(to_lower_ss(dst,src));}
FSTRING_LINK void to_lower(String *str){return(to_lower_s(str));} FSTRING_LINK void to_lower(String *str){return(to_lower_s(str));}
@ -1472,6 +1480,85 @@ replace_char(String *str, char replace, char with){
} }
#endif #endif
#if !defined(FSTRING_GUARD)
void
block_move(void *a_ptr, void *b_ptr, i32_4tech s){
u8_4tech *a = (u8_4tech*)a_ptr;
u8_4tech *b = (u8_4tech*)b_ptr;
if (a < b){
for (i32_4tech i = 0; i < s; ++i, ++a, ++b){
*a = *b;
}
}
else if (a > b){
a = a + s - 1;
b = b + s - 1;
for (i32_4tech i = 0; i < s; ++i, --a, --b){
*a = *b;
}
}
}
void
replace_range_str(String *str, i32_4tech first, i32_4tech one_past_last, String with){
i32_4tech shift = with.size - (one_past_last - first);
i32_4tech new_size = str->size + shift;
if (new_size <= str->memory_size){
if (shift != 0){
char *tail = str->str + one_past_last;
char *new_tail_pos = tail + shift;
block_move(new_tail_pos, tail, str->size - one_past_last);
}
block_move(str->str + first, with.str, with.size);
str->size += shift;
}
}
#endif
#if defined(FSTRING_IMPLEMENTATION)
FSTRING_LINK void
replace_str_ss(String *str, String replace, String with){
i32_4tech i = 0;
for (;;){
i = find_substr_s(*str, i, replace);
if (i >= str->size){
break;
}
replace_range_str(str, i, i + replace.size, with);
i += with.size;
}
}
#endif
#if defined(FSTRING_IMPLEMENTATION)
FSTRING_LINK void
replace_str_sc(String *str, String replace, char *with){
String w = make_string_slowly(with);
replace_str_ss(str, replace, w);
}
#endif
#if defined(FSTRING_IMPLEMENTATION)
FSTRING_LINK void
replace_str_cs(String *str, char *replace, String with){
String r = make_string_slowly(replace);
replace_str_ss(str, r, with);
}
#endif
#if defined(FSTRING_IMPLEMENTATION)
FSTRING_LINK void
replace_str_cc(String *str, char *replace, char *with){
String r = make_string_slowly(replace);
String w = make_string_slowly(with);
replace_str_ss(str, r, w);
}
#endif
#if defined(FSTRING_IMPLEMENTATION) #if defined(FSTRING_IMPLEMENTATION)
FSTRING_LINK void FSTRING_LINK void
@ -2062,7 +2149,6 @@ remove_last_folder(String *str){
} }
#endif #endif
// TODO(allen): Add hash-table extension to string sets.
#if defined(FSTRING_IMPLEMENTATION) #if defined(FSTRING_IMPLEMENTATION)
FSTRING_LINK b32_4tech FSTRING_LINK b32_4tech

View File

@ -1,20 +1,20 @@
/* /*
4coder_project_commands.cpp - Commands for loading and using a project. 4coder_project_commands.cpp - commands for loading and using a project.
TYPE: 'drop-in-command-pack' type: 'drop-in-command-pack'
*/ */
// TOP // top
#if !defined(FCODER_PROJECT_COMMANDS_CPP) #if !defined(fcoder_project_commands_cpp)
#define FCODER_PROJECT_COMMANDS_CPP #define fcoder_project_commands_cpp
#include "4coder_default_framework.h" #include "4coder_default_framework.h"
#include "4coder_lib/4coder_mem.h" #include "4coder_lib/4coder_mem.h"
#include "4coder_build_commands.cpp" #include "4coder_build_commands.cpp"
// TODO(allen): make this a string operation or a lexer operation or something // TODO(allen): Make this a string operation or a lexer operation or something
static void static void
interpret_escaped_string(char *dst, String src){ interpret_escaped_string(char *dst, String src){
int32_t mode = 0; int32_t mode = 0;
@ -46,6 +46,8 @@ interpret_escaped_string(char *dst, String src){
dst[j] = 0; dst[j] = 0;
} }
///////////////////////////////
static void static void
close_all_files_with_extension(Application_Links *app, Partition *scratch_part, char **extension_list, int32_t extension_count){ close_all_files_with_extension(Application_Links *app, Partition *scratch_part, char **extension_list, int32_t extension_count){
Temp_Memory temp = begin_temp_memory(scratch_part); Temp_Memory temp = begin_temp_memory(scratch_part);
@ -91,8 +93,7 @@ close_all_files_with_extension(Application_Links *app, Partition *scratch_part,
for (int32_t i = 0; i < buffers_to_close_count; ++i){ for (int32_t i = 0; i < buffers_to_close_count; ++i){
kill_buffer(app, buffer_identifier(buffers_to_close[i]), true, 0); kill_buffer(app, buffer_identifier(buffers_to_close[i]), true, 0);
} }
} }while(do_repeat);
while(do_repeat);
end_temp_memory(temp); end_temp_memory(temp);
} }
@ -186,6 +187,8 @@ CUSTOM_COMMAND_SIG(close_all_code){
close_all_files_with_extension(app, &global_part, extension_list, extension_count); close_all_files_with_extension(app, &global_part, extension_list, extension_count);
} }
///////////////////////////////
static void static void
load_project_from_config_data(Application_Links *app, Partition *part, char *config_data, int32_t config_data_size, String project_dir){ load_project_from_config_data(Application_Links *app, Partition *part, char *config_data, int32_t config_data_size, String project_dir){
Temp_Memory temp = begin_temp_memory(part); Temp_Memory temp = begin_temp_memory(part);
@ -447,6 +450,8 @@ CUSTOM_COMMAND_SIG(load_project){
end_temp_memory(temp); end_temp_memory(temp);
} }
///////////////////////////////
static void static void
exec_project_fkey_command(Application_Links *app, int32_t command_ind){ exec_project_fkey_command(Application_Links *app, int32_t command_ind){
Fkey_Command *fkey = &current_project.fkey_commands[command_ind]; Fkey_Command *fkey = &current_project.fkey_commands[command_ind];
@ -530,6 +535,238 @@ CUSTOM_COMMAND_SIG(project_go_to_root_directory){
} }
} }
///////////////////////////////
struct Project_Setup_Status{
bool32 bat_exists;
bool32 sh_exists;
bool32 project_exists;
bool32 everything_exists;
};
static Project_Setup_Status
project_is_setup(Application_Links *app, char *dir, int32_t dir_len, int32_t dir_capacity){
Project_Setup_Status result = {0};
Temp_Memory temp = begin_temp_memory(&global_part);
static int32_t needed_extra_space = 15;
String str = {0};
if (dir_capacity >= dir_len + needed_extra_space){
str = make_string_cap(dir, dir_len, dir_capacity);
}
else{
char *space = push_array(&global_part, char, dir_len + needed_extra_space);
str = make_string_cap(space, 0, dir_len + needed_extra_space);
copy(&str, make_string(dir, dir_len));
}
str.size = dir_len;
append(&str, "/build.bat");
result.bat_exists = file_exists(app, str.str, str.size);
str.size = dir_len;
append(&str, "/build.sh");
result.sh_exists = file_exists(app, str.str, str.size);
str.size = dir_len;
append(&str, "/project.4coder");
result.project_exists = file_exists(app, str.str, str.size);
result.everything_exists = result.bat_exists && result.sh_exists && result.project_exists;
end_temp_memory(temp);
return(result);
}
// TODO(allen): For this purpose we shouldn't go this far.
// Instead just let the CWD of the running script be the code home.
static char get_code_home[] =
"# Store the real CWD\n"
"REAL_PWD=\"$PWD\"\n\n"
"# Find the code home folder\n"
"TARGET_FILE=\"$0\"\n"
"cd `dirname $TARGET_FILE`\n"
"TARGET_FILE=`basename $TARGET_FILE`\n"
"while [ -L \"$TARGET_FILE\" ]\n"
"do\n"
"TARGET_FILE=`readlink $TARGET_FILE`\n"
"cd `dirname $TARGET_FILE`\n"
"TARGET_FILE=`basename $TARGET_FILE`\n"
"done\n"
"PHYS_DIR=`pwd -P`\n"
"SCRIPT_FILE=$PHYS_DIR/$TARGET_FILE\n"
"CODE_HOME=$(dirname \"$SCRIPT_FILE\")\n\n"
"# Restore the PWD\n"
"cd \"$REAL_PWD\"\n\n";
// TODO(allen): Stop using stdio.h, switch to a 4coder buffer API for all file manipulation.
#include <stdio.h>
CUSTOM_COMMAND_SIG(setup_new_project){
char space[4096];
String str = make_fixed_width_string(space);
str.size = directory_get_hot(app, str.str, str.memory_size);
int32_t dir_size = str.size;
Project_Setup_Status status = project_is_setup(app, str.str, dir_size, str.memory_size);
if (!status.everything_exists){
// Query the User for Key File Names
Query_Bar code_file_bar = {0};
Query_Bar output_dir_bar = {0};
Query_Bar binary_file_bar = {0};
char code_file_space[1024];
char output_dir_space[1024];
char binary_file_space[1024];
if (!status.bat_exists || !status.sh_exists){
code_file_bar.prompt = make_lit_string("Build Target: ");
code_file_bar.string = make_fixed_width_string(code_file_space);
if (!query_user_string(app, &code_file_bar)) return;
if (code_file_bar.string.size == 0) return;
}
output_dir_bar.prompt = make_lit_string("Output Directory: ");
output_dir_bar.string = make_fixed_width_string(output_dir_space);
if (!query_user_string(app, &output_dir_bar)) return;
if (output_dir_bar.string.size == 0){
copy(&output_dir_bar.string, ".");
}
binary_file_bar.prompt = make_lit_string("Binary Output: ");
binary_file_bar.string = make_fixed_width_string(binary_file_space);
if (!query_user_string(app, &binary_file_bar)) return;
if (binary_file_bar.string.size == 0) return;
String code_file = code_file_bar.string;
String output_dir = output_dir_bar.string;
String binary_file = binary_file_bar.string;
// Generate Scripts
if (!status.bat_exists){
replace_char(&code_file, '/', '\\');
replace_char(&output_dir, '/', '\\');
replace_char(&binary_file, '/', '\\');
str.size = dir_size;
append(&str, "/build.bat");
terminate_with_null(&str);
FILE *bat_script = fopen(str.str, "wb");
if (bat_script != 0){
fprintf(bat_script, "@echo off\n\n");
fprintf(bat_script, "SET OPTS=%.*s\n",
default_flags_bat.size, default_flags_bat.str);
fprintf(bat_script, "SET CODE_HOME=%%cd%%\n");
fprintf(bat_script, "pushd %.*s\n",
output_dir.size, output_dir.str);
fprintf(bat_script, "%.*s %%OPTS%% %%CODE_HOME%%\\%.*s -Fe%.*s\n",
default_compiler_bat.size, default_compiler_bat.str,
code_file.size, code_file.str,
binary_file.size, binary_file.str);
fprintf(bat_script, "popd\n");
fclose(bat_script);
}
else{
print_message(app, literal("could not create build.bat for new project\n"));
}
replace_char(&code_file, '\\', '/');
replace_char(&output_dir, '\\', '/');
replace_char(&binary_file, '\\', '/');
}
else{
print_message(app, literal("build.bat already exists, no changes made to it\n"));
}
if (!status.sh_exists){
str.size = dir_size;
append(&str, "/build.sh");
terminate_with_null(&str);
FILE *sh_script = fopen(str.str, "wb");
if (sh_script != 0){
fprintf(sh_script, "#!/bin/bash\n\n");
fprintf(sh_script, get_code_home);
fprintf(sh_script, "OPTS=%.*s\n",
default_flags_sh.size, default_flags_sh.str);
fprintf(sh_script, "pushd %.*s\n",
output_dir.size, output_dir.str);
fprintf(sh_script, "%.*s $OPTS $CODE_HOME/%.*s -o %.*s\n",
default_compiler_sh.size, default_compiler_sh.str,
code_file.size, code_file.str,
binary_file.size, binary_file.str);
fprintf(sh_script, "popd\n");
fclose(sh_script);
}
else{
print_message(app, literal("could not create build.sh for new project\n"));
}
}
else{
print_message(app, literal("build.sh already exists, no changes made to it\n"));
}
if (!status.project_exists){
str.size = dir_size;
append(&str, "/project.4coder");
terminate_with_null(&str);
FILE *project_script = fopen(str.str, "wb");
if (project_script != 0){
fprintf(project_script, "extensions = \".c.cpp.h.m.bat.sh.4coder\";\n");
fprintf(project_script, "open_recursively = true;\n\n");
replace_str(&code_file, "/", "\\\\");
replace_str(&output_dir, "/", "\\\\");
replace_str(&binary_file, "/", "\\\\");
fprintf(project_script,
"fkey_command_win[1] = {\"build.bat\", \"*compilation*\", true , true };\n");
fprintf(project_script,
"fkey_command_win[2] = {\"%.*s\\\\%.*s\", \"*run*\", false , true };\n",
output_dir.size, output_dir.str,
binary_file.size, binary_file.str);
replace_str(&code_file, "\\\\", "/");
replace_str(&output_dir, "\\\\", "/");
replace_str(&binary_file, "\\\\", "/");
fprintf(project_script, "fkey_command_linux[1] = {\"build.sh\", \"*compilation*\", true , true };\n");
fprintf(project_script,
"fkey_command_linux[2] = {\"%.*s/%.*s\", \"*run*\", false , true };\n",
output_dir.size, output_dir.str,
binary_file.size, binary_file.str);
fprintf(project_script, "fkey_command_mac[1] = {\"build.sh\", \"*compilation*\", true , true };\n");
fprintf(project_script,
"fkey_command_mac[2] = {\"%.*s/%.*s\", \"*run*\", false , true };\n",
output_dir.size, output_dir.str,
binary_file.size, binary_file.str);
fclose(project_script);
}
else{
print_message(app, literal("could not create project.4coder for new project\n"));
}
}
else{
print_message(app, literal("project.4coder already exists, no changes made to it\n"));
}
}
else{
print_message(app, literal("project already setup, no changes made\n"));
}
}
#endif #endif
// BOTTOM // BOTTOM

View File

@ -1,5 +1,5 @@
extensions=".c.cpp.h.m.bat.sh.4coder"; extensions = ".c.cpp.h.m.bat.sh.4coder";
open_recursively=true; open_recursively = true;
fkey_command_win[1] = {"echo build: x64 & build.bat", "*compilation*" , true , true }; fkey_command_win[1] = {"echo build: x64 & build.bat", "*compilation*" , true , true };
fkey_command_win[2] = {"build_site.bat" , "*site*" , false, true }; fkey_command_win[2] = {"build_site.bat" , "*site*" , false, true };

View File

@ -35,3 +35,10 @@ automatically_load_project = false;
// Keyboard AltGr setting // Keyboard AltGr setting
lalt_lctrl_is_altgr = false; lalt_lctrl_is_altgr = false;
// Project setup configuration
default_compiler_bat = "cl";
default_flags_bat = "-FC -GR- -EHa- -nologo -Zi";
default_compiler_sh = "g++";
default_flags_sh = "-g";

View File

@ -1,5 +1,5 @@
1 1
0 0
104 108

View File

@ -1246,6 +1246,77 @@ DOC(This call replaces all occurances of character in str with another character
} }
} }
#if !defined(FSTRING_GUARD)
void
block_move(void *a_ptr, void *b_ptr, i32_4tech s){
u8_4tech *a = (u8_4tech*)a_ptr;
u8_4tech *b = (u8_4tech*)b_ptr;
if (a < b){
for (i32_4tech i = 0; i < s; ++i, ++a, ++b){
*a = *b;
}
}
else if (a > b){
a = a + s - 1;
b = b + s - 1;
for (i32_4tech i = 0; i < s; ++i, --a, --b){
*a = *b;
}
}
}
void
replace_range_str(String *str, i32_4tech first, i32_4tech one_past_last, String with){
i32_4tech shift = with.size - (one_past_last - first);
i32_4tech new_size = str->size + shift;
if (new_size <= str->memory_size){
if (shift != 0){
char *tail = str->str + one_past_last;
char *new_tail_pos = tail + shift;
block_move(new_tail_pos, tail, str->size - one_past_last);
}
block_move(str->str + first, with.str, with.size);
str->size += shift;
}
}
#endif
CPP_NAME(replace_str)
API_EXPORT FSTRING_LINK void
replace_str_ss(String *str, String replace, String with){
i32_4tech i = 0;
for (;;){
i = find_substr_s(*str, i, replace);
if (i >= str->size){
break;
}
replace_range_str(str, i, i + replace.size, with);
i += with.size;
}
}
CPP_NAME(replace_str)
API_EXPORT FSTRING_LINK void
replace_str_sc(String *str, String replace, char *with){
String w = make_string_slowly(with);
replace_str_ss(str, replace, w);
}
CPP_NAME(replace_str)
API_EXPORT FSTRING_LINK void
replace_str_cs(String *str, char *replace, String with){
String r = make_string_slowly(replace);
replace_str_ss(str, r, with);
}
CPP_NAME(replace_str)
API_EXPORT FSTRING_LINK void
replace_str_cc(String *str, char *replace, char *with){
String r = make_string_slowly(replace);
String w = make_string_slowly(with);
replace_str_ss(str, r, w);
}
CPP_NAME(to_lower) CPP_NAME(to_lower)
API_EXPORT FSTRING_LINK void API_EXPORT FSTRING_LINK void
to_lower_cc(char *src, char *dst)/* to_lower_cc(char *src, char *dst)/*