149 lines
4.1 KiB
C
149 lines
4.1 KiB
C
#include <bshell/command/cmdlet.h>
|
|
#include <bshell/command/command.h>
|
|
#include <bshell/runtime/pipeline.h>
|
|
#include <bshell/runtime/runtime.h>
|
|
#include <bshell/runtime/scope.h>
|
|
#include <bshell/status.h>
|
|
#include <fx/reflection/assembly.h>
|
|
#include <fx/reflection/function.h>
|
|
#include <fx/string.h>
|
|
#include <fx/vector.h>
|
|
|
|
#define BSHELL_TYPE_GET_COMMAND (bshell_get_command_get_type())
|
|
|
|
fx_type_id bshell_get_command_get_type(void);
|
|
|
|
FX_DECLARE_TYPE(bshell_get_command);
|
|
|
|
FX_TYPE_CLASS_DECLARATION_BEGIN(bshell_get_command)
|
|
FX_TYPE_CLASS_DECLARATION_END(bshell_get_command)
|
|
|
|
struct bshell_get_command_p {
|
|
bool c_eof;
|
|
};
|
|
|
|
static enum bshell_status begin_processing(
|
|
bshell_cmdlet *cmdlet,
|
|
enum bshell_command_position position)
|
|
{
|
|
struct bshell_get_command_p *p
|
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_COMMAND);
|
|
return BSHELL_SUCCESS;
|
|
}
|
|
|
|
static enum bshell_status process_record(
|
|
bshell_cmdlet *cmdlet,
|
|
bshell_pipeline *pipeline,
|
|
struct bshell_runtime *rt)
|
|
{
|
|
struct bshell_get_command_p *p
|
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_COMMAND);
|
|
if (p->c_eof) {
|
|
return BSHELL_SUCCESS;
|
|
}
|
|
|
|
const fx_iterator *aliases = fx_iterator_begin(rt->rt_aliases);
|
|
fx_foreach(item_v, aliases)
|
|
{
|
|
fx_hashtable_item *item;
|
|
fx_value_get_object(item_v, &item);
|
|
const fx_value *alias_v = fx_hashtable_item_get_value(item);
|
|
bshell_pipeline_write_value(pipeline, *alias_v, false);
|
|
}
|
|
fx_iterator_unref(aliases);
|
|
|
|
struct bshell_runtime_scope *scope
|
|
= bshell_runtime_get_current_scope(rt);
|
|
while (scope) {
|
|
fx_hashtable *function_map
|
|
= bshell_runtime_scope_get_functions(scope);
|
|
const fx_iterator *functions = fx_iterator_begin(function_map);
|
|
fx_foreach(item_v, functions)
|
|
{
|
|
fx_hashtable_item *item;
|
|
fx_value_get_object(item_v, &item);
|
|
const fx_value *func_v
|
|
= fx_hashtable_item_get_value(item);
|
|
bshell_pipeline_write_value(pipeline, *func_v, false);
|
|
}
|
|
fx_iterator_unref(functions);
|
|
|
|
scope = bshell_runtime_get_parent_scope(rt, scope);
|
|
}
|
|
|
|
fx_iterator *assemblies = fx_assembly_get_all();
|
|
fx_foreach(asm_v, assemblies)
|
|
{
|
|
fx_assembly *assembly = NULL;
|
|
fx_value_get_object(asm_v, &assembly);
|
|
fx_iterator *types = fx_assembly_get_types(assembly);
|
|
fx_foreach(v, types)
|
|
{
|
|
fx_type *ty = NULL;
|
|
fx_value_get_object(v, &ty);
|
|
fx_type_flags ty_flags = fx_type_get_flags(ty);
|
|
bool is_abstract = (ty_flags & FX_TYPE_F_ABSTRACT) != 0;
|
|
if (is_abstract) {
|
|
continue;
|
|
}
|
|
|
|
bshell_command_class *cmd = fx_type_get_interface(
|
|
ty,
|
|
BSHELL_TYPE_COMMAND);
|
|
if (!cmd) {
|
|
continue;
|
|
}
|
|
|
|
fx_value callable = FX_VALUE_OBJECT(
|
|
fx_object_create(fx_type_get_id(ty)));
|
|
bshell_pipeline_write_value(pipeline, callable, false);
|
|
fx_value_unset(&callable);
|
|
}
|
|
|
|
fx_iterator_unref(types);
|
|
}
|
|
|
|
fx_iterator_unref(assemblies);
|
|
p->c_eof = true;
|
|
|
|
return BSHELL_SUCCESS;
|
|
}
|
|
|
|
static enum bshell_status end_processing(bshell_cmdlet *cmdlet)
|
|
{
|
|
struct bshell_get_command_p *p
|
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_COMMAND);
|
|
|
|
return BSHELL_SUCCESS;
|
|
}
|
|
|
|
static void init(fx_object *obj, void *priv)
|
|
{
|
|
}
|
|
|
|
FX_TYPE_CLASS_BEGIN(bshell_get_command)
|
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
|
|
FX_INTERFACE_ENTRY(to_string) = NULL;
|
|
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
|
|
|
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(bshell_cmdlet, BSHELL_TYPE_CMDLET)
|
|
FX_INTERFACE_ENTRY(c_verb) = BSHELL_VERB_GET;
|
|
FX_INTERFACE_ENTRY(c_noun) = "Command";
|
|
FX_TYPE_VTABLE_INTERFACE_END(bshell_cmdlet, BSHELL_TYPE_CMDLET)
|
|
|
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(bshell_command, BSHELL_TYPE_COMMAND)
|
|
FX_INTERFACE_ENTRY(c_begin_processing) = begin_processing;
|
|
FX_INTERFACE_ENTRY(c_process_record) = process_record;
|
|
FX_INTERFACE_ENTRY(c_end_processing) = end_processing;
|
|
FX_TYPE_VTABLE_INTERFACE_END(bshell_cmdlet, BSHELL_TYPE_CMDLET)
|
|
FX_TYPE_CLASS_END(bshell_get_command)
|
|
|
|
FX_TYPE_DEFINITION_BEGIN(bshell_get_command)
|
|
FX_TYPE_ID(0x4f862cc3, 0xf3d3, 0x4f04, 0xb68e, 0x8764079f03c4);
|
|
FX_TYPE_NAME("bshell.core.get_command");
|
|
FX_TYPE_EXTENDS(BSHELL_TYPE_CMDLET);
|
|
FX_TYPE_CLASS(bshell_get_command_class);
|
|
FX_TYPE_INSTANCE_INIT(init);
|
|
FX_TYPE_INSTANCE_PRIVATE(struct bshell_get_command_p);
|
|
FX_TYPE_DEFINITION_END(bshell_get_command)
|