Compare commits

...

2 Commits

2 changed files with 133 additions and 23 deletions
+13
View File
@@ -28,12 +28,25 @@ static void write_iterable(struct bshell_value_writer *w, const fx_value *value)
fx_iterator_unref(it);
}
static bool string_has_trailing_newline(const char *s)
{
long len = strlen(s);
if (len == 0) {
return false;
}
return s[len - 1] == '\n';
}
static void write_string(struct bshell_value_writer *w, const fx_value *value)
{
const char *str = NULL;
fx_value_get_cstr(value, &str);
fx_stream_write_cstr(w->w_dest, str, NULL);
if (!string_has_trailing_newline(str)) {
fx_stream_write_char(w->w_dest, '\n');
}
}
static void write_value(struct bshell_value_writer *w, const fx_value *value)
+119 -22
View File
@@ -77,11 +77,119 @@ static const fx_value *get_arg(struct bshell_cmdcall_p *cmdcall, size_t index)
return &cmdcall->cmd_args.items[cmdcall->cmd_args.count - index - 1];
}
static bshell_command *__resolve_call_target(
const char *callable_name,
struct bshell_runtime *rt)
static bshell_command *resolve_cmdlet(
struct bshell_cmdcall_p *cmdcall,
struct bshell_runtime *rt,
fx_string *cmd_name)
{
return bshell_runtime_find_command(rt, callable_name);
while (1) {
const char *cmd_name_cstr = fx_string_get_cstr(cmd_name);
bshell_command *cmd
= bshell_runtime_find_command(rt, cmd_name_cstr);
if (!cmd) {
break;
}
bshell_alias_class *alias
= fx_object_get_interface(cmd, BSHELL_TYPE_ALIAS);
if (alias) {
fx_string_clear(cmd_name);
fx_string_append_cstr(cmd_name, alias->a_target_name);
bshell_command_unref(cmd);
continue;
}
return cmd;
}
return NULL;
}
static const fx_string *get_path(void)
{
fx_process *self = fx_process_get_self();
if (!self) {
return NULL;
}
const fx_hashtable *env = fx_process_get_environment(self);
if (!env) {
return NULL;
}
const fx_value *path_v = fx_hashtable_get(env, &FX_CSTR("PATH"));
if (!path_v) {
return NULL;
}
const fx_string *path = NULL;
fx_value_get_object(path_v, (fx_object **)&path);
return path;
}
static bshell_command *resolve_native_command_local(
struct bshell_cmdcall_p *cmdcall,
struct bshell_runtime *rt,
fx_string *cmd_name)
{
const char *cmd_name_cstr = fx_string_get_cstr(cmd_name);
fx_path *cmd_path = fx_path_create_from_cstr(cmd_name_cstr);
if (!fx_path_is_file(cmd_path)) {
fx_path_unref(cmd_path);
return NULL;
}
bshell_command *result
= bshell_native_command_create(fx_path_ptr(cmd_path));
fx_path_unref(cmd_path);
return result;
}
static bshell_command *resolve_native_command(
struct bshell_cmdcall_p *cmdcall,
struct bshell_runtime *rt,
fx_string *cmd_name)
{
const char *cmd_name_cstr = fx_string_get_cstr(cmd_name);
if (cmd_name_cstr[0] == '/'
|| (cmd_name_cstr[0] == '.' && cmd_name_cstr[1] == '/')
|| (cmd_name_cstr[0] == '.' && cmd_name_cstr[1] == '.'
&& cmd_name_cstr[2] == '/')) {
return resolve_native_command_local(cmdcall, rt, cmd_name);
}
fx_path *cmd_name_path = fx_path_create_from_cstr(cmd_name_cstr);
const char *delim[] = {":"};
const fx_string *path = get_path();
const fx_iterator *it = fx_string_tokenise(
path,
delim,
sizeof delim / sizeof delim[0],
FX_STRING_TOK_F_NORMAL);
bshell_command *result = NULL;
fx_foreach(v, it)
{
const char *tok = NULL;
fx_value_get_cstr(v, &tok);
fx_path *dir_path = fx_path_create_from_cstr(tok);
const fx_path *parts[] = {dir_path, cmd_name_path};
fx_path *full_path
= fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path_unref(dir_path);
if (!fx_path_is_file(full_path)) {
fx_path_unref(full_path);
continue;
}
result = bshell_native_command_create(fx_path_ptr(full_path));
fx_path_unref(full_path);
break;
}
fx_iterator_unref(it);
return result;
}
static enum bshell_status resolve_call_target(
@@ -100,28 +208,17 @@ static enum bshell_status resolve_call_target(
fx_string *cmd_name_s = NULL;
fx_value_get_object(cmd_name_v, &cmd_name_s);
while (1) {
const char *cmd_name_cstr = fx_string_get_cstr(cmd_name_s);
bshell_command *cmd
= bshell_runtime_find_command(rt, cmd_name_cstr);
if (!cmd) {
break;
}
bshell_alias_class *alias
= fx_object_get_interface(cmd, BSHELL_TYPE_ALIAS);
if (alias) {
fx_string_clear(cmd_name_s);
fx_string_append_cstr(cmd_name_s, alias->a_target_name);
bshell_command_unref(cmd);
continue;
}
cmdcall->cmd_target = cmd;
if ((cmdcall->cmd_target = resolve_cmdlet(cmdcall, rt, cmd_name_s))) {
cmdcall->cmd_type = CMDCALL_CMDLET;
return BSHELL_SUCCESS;
}
if ((cmdcall->cmd_target
= resolve_native_command(cmdcall, rt, cmd_name_s))) {
cmdcall->cmd_type = CMDCALL_NATIVE;
return BSHELL_SUCCESS;
}
const char *cmd_name_cstr = fx_string_get_cstr(cmd_name_s);
#if BSHELL_INTERACTIVE == 1
fx_printf("[bold,bright_red]");