cleaned up the child process updating and CLI list managing
This commit is contained in:
parent
bd2ef80f30
commit
a1b0f805d1
|
@ -1,7 +1,7 @@
|
|||
struct Application_Links;
|
||||
#define GLOBAL_SET_SETTING_SIG(n) bool32 n(Application_Links *app, Global_Setting_ID setting, int32_t value)
|
||||
#define EXEC_COMMAND_SIG(n) bool32 n(Application_Links *app, Command_ID command_id)
|
||||
#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||
#define EXEC_SYSTEM_COMMAND_SIG(n) bool32 n(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
|
||||
#define CLIPBOARD_COUNT_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id)
|
||||
#define CLIPBOARD_INDEX_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len)
|
||||
|
@ -394,7 +394,7 @@ app_links->send_exit_signal_ = Send_Exit_Signal;} while(false)
|
|||
#if defined(ALLOW_DEP_4CODER)
|
||||
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting(app, setting, value));}
|
||||
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command(app, command_id));}
|
||||
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command(app, view, buffer, path, path_len, command, command_len, flags));}
|
||||
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command(app, view, buffer_id, path, path_len, command, command_len, flags));}
|
||||
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post(app, clipboard_id, str, len));}
|
||||
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count(app, clipboard_id));}
|
||||
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index(app, clipboard_id, item_index, out, len));}
|
||||
|
@ -471,7 +471,7 @@ static inline void send_exit_signal(Application_Links *app){(app->send_exit_sign
|
|||
#else
|
||||
static inline bool32 global_set_setting(Application_Links *app, Global_Setting_ID setting, int32_t value){return(app->global_set_setting_(app, setting, value));}
|
||||
static inline bool32 exec_command(Application_Links *app, Command_ID command_id){return(app->exec_command_(app, command_id));}
|
||||
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command_(app, view, buffer, path, path_len, command, command_len, flags));}
|
||||
static inline bool32 exec_system_command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags){return(app->exec_system_command_(app, view, buffer_id, path, path_len, command, command_len, flags));}
|
||||
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post_(app, clipboard_id, str, len));}
|
||||
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count_(app, clipboard_id));}
|
||||
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index_(app, clipboard_id, item_index, out, len));}
|
||||
|
|
150
4ed.cpp
150
4ed.cpp
|
@ -145,29 +145,18 @@ global_const char messages[] =
|
|||
#define DEFAULT_DISPLAY_WIDTH 672
|
||||
#define DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH 550
|
||||
|
||||
typedef enum App_State{
|
||||
enum App_State{
|
||||
APP_STATE_EDIT,
|
||||
APP_STATE_RESIZING,
|
||||
// never below this
|
||||
APP_STATE_COUNT
|
||||
} App_State;
|
||||
};
|
||||
|
||||
typedef struct App_State_Resizing{
|
||||
struct App_State_Resizing{
|
||||
Panel_Divider *divider;
|
||||
} App_State_Resizing;
|
||||
};
|
||||
|
||||
typedef struct CLI_Process{
|
||||
CLI_Handles cli;
|
||||
Editing_File *out_file;
|
||||
b32 cursor_at_end;
|
||||
} CLI_Process;
|
||||
|
||||
typedef struct CLI_List{
|
||||
CLI_Process *procs;
|
||||
i32 count, max;
|
||||
} CLI_List;
|
||||
|
||||
typedef struct Command_Data{
|
||||
struct Command_Data{
|
||||
Models *models;
|
||||
struct App_Vars *vars;
|
||||
System_Functions *system;
|
||||
|
@ -175,9 +164,9 @@ typedef struct Command_Data{
|
|||
|
||||
i32 screen_width, screen_height;
|
||||
Key_Event_Data key;
|
||||
} Command_Data;
|
||||
};
|
||||
|
||||
typedef enum Input_Types{
|
||||
enum Input_Types{
|
||||
Input_AnyKey,
|
||||
Input_Esc,
|
||||
Input_MouseMove,
|
||||
|
@ -185,18 +174,18 @@ typedef enum Input_Types{
|
|||
Input_MouseRightButton,
|
||||
Input_MouseWheel,
|
||||
Input_Count
|
||||
} Input_Types;
|
||||
};
|
||||
|
||||
typedef struct Consumption_Record{
|
||||
struct Consumption_Record{
|
||||
b32 consumed;
|
||||
char consumer[32];
|
||||
} Consumption_Record;
|
||||
};
|
||||
|
||||
typedef struct Available_Input{
|
||||
struct Available_Input{
|
||||
Key_Input_Data *keys;
|
||||
Mouse_State *mouse;
|
||||
Consumption_Record records[Input_Count];
|
||||
} Available_Input;
|
||||
};
|
||||
|
||||
internal Available_Input
|
||||
init_available_input(Key_Input_Data *keys, Mouse_State *mouse){
|
||||
|
@ -297,14 +286,14 @@ struct App_Vars{
|
|||
};
|
||||
global_const App_Vars null_app_vars = {0};
|
||||
|
||||
typedef enum Coroutine_Type{
|
||||
enum Coroutine_Type{
|
||||
Co_View,
|
||||
Co_Command
|
||||
} Coroutine_Type;
|
||||
typedef struct App_Coroutine_State{
|
||||
};
|
||||
struct App_Coroutine_State{
|
||||
void *co;
|
||||
i32 type;
|
||||
} App_Coroutine_State;
|
||||
};
|
||||
|
||||
inline App_Coroutine_State
|
||||
get_state(Application_Links *app){
|
||||
|
@ -1353,68 +1342,13 @@ App_Init_Sig(app_init){
|
|||
hot_directory_init(&models->hot_directory, current_directory);
|
||||
|
||||
// NOTE(allen): child proc list setup
|
||||
i32 max_children = 16;
|
||||
partition_align(partition, 8);
|
||||
vars->cli_processes.procs = push_array(partition, CLI_Process, max_children);
|
||||
vars->cli_processes.max = max_children;
|
||||
vars->cli_processes.count = 0;
|
||||
vars->cli_processes = make_cli_list(partition, 16);
|
||||
|
||||
// NOTE(allen): init GUI keys
|
||||
models->user_up_key = key_up;
|
||||
models->user_down_key = key_down;
|
||||
}
|
||||
|
||||
internal i32
|
||||
update_cli_handle_without_file(System_Functions *system, Models *models, CLI_Handles *cli, char *dest, i32 max){
|
||||
i32 result = 0;
|
||||
u32 amount = 0;
|
||||
|
||||
system->cli_begin_update(cli);
|
||||
if (system->cli_update_step(cli, dest, max, &amount)){
|
||||
result = 1;
|
||||
}
|
||||
|
||||
if (system->cli_end_update(cli)){
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
internal i32
|
||||
update_cli_handle_with_file(System_Functions *system, Models *models, CLI_Handles *cli, Editing_File *file, char *dest, i32 max, b32 cursor_at_end){
|
||||
i32 result = 0;
|
||||
u32 amount = 0;
|
||||
|
||||
system->cli_begin_update(cli);
|
||||
if (system->cli_update_step(cli, dest, max, &amount)){
|
||||
amount = eol_in_place_convert_in(dest, amount);
|
||||
output_file_append(system, models, file, make_string(dest, amount), cursor_at_end);
|
||||
result = 1;
|
||||
}
|
||||
|
||||
if (system->cli_end_update(cli)){
|
||||
char str_space[256];
|
||||
String str = make_fixed_width_string(str_space);
|
||||
append_ss(&str, make_lit_string("exited with code "));
|
||||
append_int_to_str(&str, cli->exit);
|
||||
output_file_append(system, models, file, str, cursor_at_end);
|
||||
result = -1;
|
||||
}
|
||||
|
||||
if (cursor_at_end){
|
||||
i32 new_cursor = buffer_size(&file->state.buffer);
|
||||
for (View_Iter iter = file_view_iter_init(&models->layout, file, 0);
|
||||
file_view_iter_good(iter);
|
||||
iter = file_view_iter_next(iter)){
|
||||
view_cursor_move(system, iter.view, new_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
App_Step_Sig(app_step){
|
||||
PRFL_BEGIN_FRAME();
|
||||
|
||||
|
@ -1595,30 +1529,48 @@ App_Step_Sig(app_step){
|
|||
|
||||
// NOTE(allen): update child processes
|
||||
if (input->dt > 0){
|
||||
Partition *scratch = &models->mem.part;
|
||||
|
||||
CLI_List *list = &vars->cli_processes;
|
||||
|
||||
Temp_Memory temp = begin_temp_memory(&models->mem.part);
|
||||
CLI_Process **procs_to_free = push_array(scratch, CLI_Process*, list->count);
|
||||
u32 proc_free_count = 0;
|
||||
|
||||
u32 max = KB(128);
|
||||
char *dest = push_array(&models->mem.part, char, max);
|
||||
char *dest = push_array(scratch, char, max);
|
||||
|
||||
i32 count = vars->cli_processes.count;
|
||||
for (i32 i = 0; i < count; ++i){
|
||||
CLI_Process *proc = vars->cli_processes.procs + i;
|
||||
Editing_File *file = proc->out_file;
|
||||
CLI_Process *proc_ptr = list->procs;
|
||||
for (u32 i = 0; i < list->count; ++i, ++proc_ptr){
|
||||
Editing_File *file = proc_ptr->out_file;
|
||||
|
||||
CLI_Handles *cli = &proc_ptr->cli;
|
||||
|
||||
u32 amount = 0;
|
||||
system->cli_begin_update(cli);
|
||||
if (system->cli_update_step(cli, dest, max, &amount)){
|
||||
if (file != 0){
|
||||
i32 r = update_cli_handle_with_file(
|
||||
system, models, &proc->cli, file, dest, max, proc->cursor_at_end);
|
||||
if (r < 0){
|
||||
*proc = vars->cli_processes.procs[--count];
|
||||
--i;
|
||||
}
|
||||
}
|
||||
else{
|
||||
update_cli_handle_without_file(
|
||||
system, models, &proc->cli, dest, max);
|
||||
amount = eol_in_place_convert_in(dest, amount);
|
||||
output_file_append(system, models, file, make_string(dest, amount), proc_ptr->cursor_at_end);
|
||||
}
|
||||
}
|
||||
|
||||
vars->cli_processes.count = count;
|
||||
if (system->cli_end_update(cli)){
|
||||
if (file != 0){
|
||||
char str_space[256];
|
||||
String str = make_fixed_width_string(str_space);
|
||||
append(&str, make_lit_string("exited with code "));
|
||||
append_int_to_str(&str, cli->exit);
|
||||
output_file_append(system, models, file, str, proc_ptr->cursor_at_end);
|
||||
}
|
||||
procs_to_free[proc_free_count++] = proc_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < proc_free_count; ++i){
|
||||
cli_list_free_proc(list, procs_to_free[i]);
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
}
|
||||
|
||||
|
|
|
@ -216,10 +216,10 @@ DOC_SEE(Command_ID)
|
|||
|
||||
// TODO(allen): This is a bit of a mess and needs to be fixed.
|
||||
API_EXPORT bool32
|
||||
Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||
Exec_System_Command(Application_Links *app, View_Summary *view, Buffer_Identifier buffer_id, char *path, int32_t path_len, char *command, int32_t command_len, Command_Line_Interface_Flag flags)
|
||||
/*
|
||||
DOC_PARAM(view, If the view parameter is non-null it specifies a view to display the command's output buffer, otherwise the command will still work but if there is a buffer capturing the output it will not automatically be displayed.)
|
||||
DOC_PARAM(buffer, The buffer the command will output to is specified by the buffer parameter. See Buffer_Identifier for information on how this type specifies a buffer. The command will cause a crash if no buffer is specified.)
|
||||
DOC_PARAM(buffer_id, The buffer the command will output to is specified by the buffer parameter. See Buffer_Identifier for information on how this type specifies a buffer. The command will cause a crash if no buffer is specified.)
|
||||
DOC_PARAM(path, The path parameter specifies the current working directory in which the command shall be executed. The string need not be null terminated.)
|
||||
DOC_PARAM(path_len, The parameter path_len specifies the length of the path string.)
|
||||
DOC_PARAM(command, The command parameter specifies the command that shall be executed. The string need not be null terminated.)
|
||||
|
@ -239,63 +239,67 @@ DOC_SEE(Command_Line_Interface_Flag)
|
|||
System_Functions *system = cmd->system;
|
||||
App_Vars *vars = cmd->vars;
|
||||
Models *models = cmd->models;
|
||||
Partition *part = &models->mem.part;
|
||||
General_Memory *general = &models->mem.general;
|
||||
Working_Set *working_set = &models->working_set;
|
||||
|
||||
bool32 result = true;
|
||||
char feedback_space[256];
|
||||
String feedback_str = make_fixed_width_string(feedback_space);
|
||||
|
||||
Working_Set *working_set = &models->working_set;
|
||||
CLI_Process *procs = vars->cli_processes.procs, *proc = 0;
|
||||
Editing_File *file = 0;
|
||||
b32 bind_to_new_view = true;
|
||||
General_Memory *general = &models->mem.general;
|
||||
|
||||
Partition *part = &models->mem.part;
|
||||
Temp_Memory temp = begin_temp_memory(part);
|
||||
|
||||
bool32 result = true;
|
||||
{
|
||||
// NOTE(allen): Check that it is possible to store a new child process.
|
||||
if (!cli_list_has_space(&vars->cli_processes)){
|
||||
append(&feedback_str, make_lit_string("ERROR: no available process slot\n"));
|
||||
result = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
View *vptr = imp_get_view(cmd, view);
|
||||
// NOTE(allen): Try to get the buffer that was specified if it exists.
|
||||
Editing_File *file = get_file_from_identifier(system, working_set, buffer_id);
|
||||
|
||||
if (vars->cli_processes.count < vars->cli_processes.max){
|
||||
file = get_file_from_identifier(system, working_set, buffer);
|
||||
|
||||
if (file){
|
||||
// NOTE(allen): If the file exists check that it is legal.
|
||||
if (file != 0){
|
||||
if (file->settings.read_only == 0){
|
||||
append_ss(&feedback_str, make_lit_string("ERROR: "));
|
||||
append_ss(&feedback_str, file->name.live_name);
|
||||
append_ss(&feedback_str, make_lit_string(" is not a read-only buffer\n"));
|
||||
do_feedback_message(system, models, feedback_str);
|
||||
append(&feedback_str, make_lit_string("ERROR: "));
|
||||
append(&feedback_str, file->name.live_name);
|
||||
append(&feedback_str, make_lit_string(" is not a read-only buffer\n"));
|
||||
result = false;
|
||||
goto done;
|
||||
}
|
||||
if (file->settings.never_kill){
|
||||
append_ss(&feedback_str, make_lit_string("The buffer "));
|
||||
append_ss(&feedback_str, file->name.live_name);
|
||||
append_ss(&feedback_str, make_lit_string(" is not killable"));
|
||||
do_feedback_message(system, models, feedback_str);
|
||||
append(&feedback_str, make_lit_string("ERROR: The buffer "));
|
||||
append(&feedback_str, file->name.live_name);
|
||||
append(&feedback_str, make_lit_string(" is not killable"));
|
||||
result = false;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
else if (buffer.name){
|
||||
|
||||
// NOTE(allen): If the buffer is specified by name but does not already exist, then create it.
|
||||
if (file == 0 && buffer_id.name){
|
||||
file = working_set_alloc_always(working_set, general);
|
||||
if (file == 0){
|
||||
append_ss(&feedback_str, make_lit_string("ERROR: unable to allocate a new buffer\n"));
|
||||
do_feedback_message(system, models, feedback_str);
|
||||
append(&feedback_str, make_lit_string("ERROR: unable to allocate a new buffer\n"));
|
||||
result = false;
|
||||
goto done;
|
||||
}
|
||||
String name = make_string_terminated(part, buffer.name, buffer.name_len);
|
||||
|
||||
String name = make_string_terminated(part, buffer_id.name, buffer_id.name_len);
|
||||
buffer_bind_name(general, working_set, file, name);
|
||||
init_read_only_file(system, models, file);
|
||||
}
|
||||
|
||||
// NOTE(allen): If there are conflicts in output buffer with an existing child process resolve it.
|
||||
if (file != 0){
|
||||
i32 proc_count = vars->cli_processes.count;
|
||||
for (i32 i = 0; i < proc_count; ++i){
|
||||
if (procs[i].out_file == file){
|
||||
CLI_List *list = &vars->cli_processes;
|
||||
CLI_Process *proc_ptr = list->procs;
|
||||
for (u32 i = 0; i < list->count; ++i, ++proc_ptr){
|
||||
if (proc_ptr->out_file == file){
|
||||
if (flags & CLI_OverlapWithConflict){
|
||||
procs[i].out_file = 0;
|
||||
proc_ptr->out_file = 0;
|
||||
}
|
||||
else{
|
||||
file = 0;
|
||||
|
@ -304,30 +308,41 @@ DOC_SEE(Command_Line_Interface_Flag)
|
|||
}
|
||||
}
|
||||
|
||||
if (file){
|
||||
if (file == 0){
|
||||
append(&feedback_str, "did not begin command-line command because the target buffer is already in use\n");
|
||||
result = false;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): If we have an output file, prepare it for child proc output.
|
||||
if (file != 0){
|
||||
file_clear(system, models, file);
|
||||
file->settings.unimportant = true;
|
||||
}
|
||||
|
||||
// NOTE(allen): If we have an output file and we need to bring it up in a new view, do so.
|
||||
if (file != 0){
|
||||
b32 bind_to_new_view = true;
|
||||
if (!(flags & CLI_AlwaysBindToView)){
|
||||
View_Iter iter = file_view_iter_init(&models->layout, file, 0);
|
||||
if (file_view_iter_good(iter)){
|
||||
bind_to_new_view = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (bind_to_new_view){
|
||||
View *vptr = imp_get_view(cmd, view);
|
||||
if (vptr != 0){
|
||||
view_set_file(system, vptr, file, models);
|
||||
view_show_file(vptr);
|
||||
}
|
||||
else{
|
||||
#define MSG "did not begin command-line command because the target buffer is already in use\n"
|
||||
String msg = make_lit_string(MSG);
|
||||
#undef MSG
|
||||
append_ss(&feedback_str, msg);
|
||||
do_feedback_message(system, models, feedback_str);
|
||||
result = false;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): Figure out the root path for the command.
|
||||
String path_string = {0};
|
||||
if (!path){
|
||||
if (path == 0){
|
||||
terminate_with_null(&models->hot_directory.string);
|
||||
path_string = models->hot_directory.string;
|
||||
}
|
||||
|
@ -335,46 +350,27 @@ DOC_SEE(Command_Line_Interface_Flag)
|
|||
path_string = make_string_terminated(part, path, path_len);
|
||||
}
|
||||
|
||||
{
|
||||
// NOTE(allen): Figure out the command string.
|
||||
String command_string = {0};
|
||||
|
||||
if (!command){
|
||||
#define NO_SCRIPT " echo no script specified"
|
||||
command_string.str = NO_SCRIPT;
|
||||
command_string.size = sizeof(NO_SCRIPT)-1;
|
||||
#undef NO_SCRIPT
|
||||
if (command == 0){
|
||||
command_string = make_lit_string(" echo no script specified");
|
||||
}
|
||||
else{
|
||||
command_string = make_string_terminated(part, command, command_len);
|
||||
}
|
||||
|
||||
if (vptr != 0 && bind_to_new_view){
|
||||
view_set_file(system, vptr, file, models);
|
||||
view_show_file(vptr);
|
||||
}
|
||||
|
||||
proc = procs + vars->cli_processes.count++;
|
||||
proc->out_file = file;
|
||||
if (flags & CLI_CursorAtEnd){
|
||||
proc->cursor_at_end = 1;
|
||||
}
|
||||
else{
|
||||
proc->cursor_at_end = 0;
|
||||
}
|
||||
|
||||
if (!system->cli_call(path_string.str, command_string.str, &proc->cli)){
|
||||
--vars->cli_processes.count;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
append_ss(&feedback_str, make_lit_string("ERROR: no available process slot\n"));
|
||||
do_feedback_message(system, models, feedback_str);
|
||||
// NOTE(allen): Attept to execute the command.
|
||||
if (!cli_list_call(system, &vars->cli_processes, path_string.str, command_string.str, file, ((flags & CLI_CursorAtEnd) != 0))){
|
||||
append(&feedback_str, "ERROR: Failed to make the cli call\n");
|
||||
result = false;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:;
|
||||
if (!result){
|
||||
do_feedback_message(system, models, feedback_str);
|
||||
}
|
||||
|
||||
end_temp_memory(temp);
|
||||
return(result);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
#include "4ed_hot_directory.cpp"
|
||||
#include "4ed_parse_contexts.cpp"
|
||||
|
||||
#include "4ed_cli.cpp"
|
||||
|
||||
#include "4ed_gui.h"
|
||||
#include "4ed_gui.cpp"
|
||||
#include "4ed_layout.cpp"
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Mr. 4th Dimention - Allen Webster
|
||||
*
|
||||
* 17.07.2017
|
||||
*
|
||||
* CLI handling code.
|
||||
*
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FRED_CLI_CPP)
|
||||
#define FRED_CLI_CPP
|
||||
|
||||
struct CLI_Process{
|
||||
CLI_Handles cli;
|
||||
Editing_File *out_file;
|
||||
b32 cursor_at_end;
|
||||
};
|
||||
|
||||
struct CLI_List{
|
||||
CLI_Process *procs;
|
||||
u32 count;
|
||||
u32 max;
|
||||
};
|
||||
|
||||
inline CLI_List
|
||||
make_cli_list(Partition *part, u32 max){
|
||||
CLI_List list = {0};
|
||||
partition_align(part, 8);
|
||||
list.procs = push_array(part, CLI_Process, max);
|
||||
list.max = max;
|
||||
return(list);
|
||||
}
|
||||
|
||||
inline b32
|
||||
cli_list_call(System_Functions *system, CLI_List *list, char *path, char *command, Editing_File *file, b32 cursor_at_end){
|
||||
b32 result = false;
|
||||
|
||||
if (list->count < list->max){
|
||||
CLI_Process *proc = &list->procs[list->count++];
|
||||
proc->out_file = file;
|
||||
proc->cursor_at_end = cursor_at_end;
|
||||
result = system->cli_call(path, command, &proc->cli);
|
||||
if (!result){
|
||||
--list->count;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline void
|
||||
cli_list_free_proc(CLI_List *list, CLI_Process *proc){
|
||||
Assert(proc >= list->procs);
|
||||
Assert(proc < list->procs + list->count);
|
||||
*proc = list->procs[--list->count];
|
||||
}
|
||||
|
||||
inline b32
|
||||
cli_list_has_space(CLI_List *list){
|
||||
b32 has_space = (list->count < list->max);
|
||||
return(has_space);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
Loading…
Reference in New Issue