#include #include #include #include #include #include #include #include struct bshell_command_p { fx_value *cmd_args; size_t cmd_nr_args; bool cmd_args_reversed; }; static void init(fx_object *obj, void *priv) { } static void command_set_args( struct bshell_command_p *cmd, fx_value *args, size_t nr_args) { cmd->cmd_args = args; cmd->cmd_nr_args = nr_args; cmd->cmd_args_reversed = false; } static void command_set_args_reverse( struct bshell_command_p *cmd, fx_value *args, size_t nr_args) { cmd->cmd_args = args; cmd->cmd_nr_args = nr_args; cmd->cmd_args_reversed = true; } static const fx_value *command_get_arg( struct bshell_command_p *cmd, size_t index) { if (index >= cmd->cmd_nr_args) { return NULL; } if (cmd->cmd_args_reversed) { return &cmd->cmd_args[cmd->cmd_nr_args - index - 1]; } return &cmd->cmd_args[index]; } static fx_status get_command_type( const fx_value *cmd_v, const fx_property *prop, fx_value *out) { bshell_command *cmd = NULL; fx_value_get_object(cmd_v, &cmd); bshell_command_class *cmd_class = fx_object_get_interface(cmd, BSHELL_TYPE_COMMAND); *out = FX_CSTR(cmd_class->c_command_type); return FX_SUCCESS; } static fx_status get_name( const fx_value *cmd_v, const fx_property *prop, fx_value *out) { bshell_command *cmd = NULL; fx_value_get_object(cmd_v, &cmd); bshell_command_class *cmd_class = fx_object_get_interface(cmd, BSHELL_TYPE_COMMAND); fx_string *result = fx_string_create(); const fx_type *ty = fx_type_get_by_id(fx_object_query_type(cmd)); if (cmd_class->c_get_description) { cmd_class->c_get_description(cmd, result); } else if (cmd_class->c_get_description_static) { cmd_class->c_get_description_static(ty, result); } else if (cmd_class->c_get_callable_name) { cmd_class->c_get_callable_name(cmd, result); } else if (cmd_class->c_get_callable_name_static) { cmd_class->c_get_callable_name_static(ty, result); } *out = FX_VALUE_OBJECT(result); return FX_SUCCESS; } static fx_status get_version( const fx_value *cmd_v, const fx_property *prop, fx_value *out) { bshell_command *cmd = NULL; fx_value_get_object(cmd_v, &cmd); const fx_type *ty = fx_type_get_by_id(fx_object_query_type(cmd)); const fx_assembly *assembly = fx_type_get_assembly(ty); long major = 0, minor = 0, build = 0, revision = 0; fx_assembly_get_version(assembly, &major, &minor, &build, &revision); fx_string *result = fx_string_create(); if (revision != 0) { fx_string_append_cstrf( result, "%ld.%ld.%ld.%ld", major, minor, build, revision); } else { fx_string_append_cstrf( result, "%ld.%ld.%ld", major, minor, build); } *out = FX_VALUE_OBJECT(result); return FX_SUCCESS; } static fx_status get_source( const fx_value *cmd_v, const fx_property *prop, fx_value *out) { bshell_command *cmd = NULL; fx_value_get_object(cmd_v, &cmd); const fx_type *ty = fx_type_get_by_id(fx_object_query_type(cmd)); const fx_assembly *assembly = fx_type_get_assembly(ty); *out = FX_CSTR(fx_assembly_get_name(assembly)); return FX_SUCCESS; } extern const fx_assembly *bshell_runtime_assembly_get(void); bshell_command *bshell_command_find_static(const char *name) { fx_string *target_name = fx_string_create(); fx_string *call_name = fx_string_create_from_cstr(name); fx_string_transform_lowercase(call_name); bshell_command *result = NULL; 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); if (fx_type_id_compare( fx_type_get_id(ty), BSHELL_TYPE_COMMAND) == 0) { continue; } bshell_command_class *cmd = fx_type_get_interface( ty, BSHELL_TYPE_COMMAND); if (!cmd || !cmd->c_get_callable_name_static) { continue; } fx_string_clear(target_name); cmd->c_get_callable_name_static(ty, target_name); if (!fx_strcmp_nocase( fx_string_get_cstr(call_name), fx_string_get_cstr(target_name))) { result = fx_object_create(fx_type_get_id(ty)); break; } } fx_iterator_unref(types); } fx_iterator_unref(assemblies); fx_string_unref(call_name); fx_string_unref(target_name); return result; } void bshell_command_set_args( bshell_command *cmd, fx_value *args, size_t nr_args) { FX_CLASS_DISPATCH_STATIC_V( BSHELL_TYPE_COMMAND, command_set_args, cmd, args, nr_args); } void bshell_command_set_args_reverse( bshell_command *cmd, fx_value *args, size_t nr_args) { FX_CLASS_DISPATCH_STATIC_V( BSHELL_TYPE_COMMAND, command_set_args_reverse, cmd, args, nr_args); } const fx_value *bshell_command_get_arg(bshell_command *cmd, size_t index) { FX_CLASS_DISPATCH_STATIC( BSHELL_TYPE_COMMAND, command_get_arg, cmd, index); } enum bshell_status bshell_command_begin_processing(bshell_command *command) { FX_CLASS_DISPATCH_VIRTUAL_0( bshell_command, BSHELL_TYPE_COMMAND, BSHELL_ERR_NOT_SUPPORTED, c_begin_processing, command); } enum bshell_status bshell_command_process_record( bshell_command *command, bshell_pipeline *pipeline, struct bshell_runtime *rt) { FX_CLASS_DISPATCH_VIRTUAL( bshell_command, BSHELL_TYPE_COMMAND, BSHELL_ERR_NOT_SUPPORTED, c_process_record, command, pipeline, rt); } enum bshell_status bshell_command_end_processing(bshell_command *command) { FX_CLASS_DISPATCH_VIRTUAL_0( bshell_command, BSHELL_TYPE_COMMAND, BSHELL_ERR_NOT_SUPPORTED, c_end_processing, command); } FX_TYPE_CLASS_BEGIN(bshell_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_PROPERTY("command_type", get_command_type, NULL); FX_TYPE_PROPERTY("name", get_name, NULL); FX_TYPE_PROPERTY("version", get_version, NULL); FX_TYPE_PROPERTY("source", get_source, NULL); FX_TYPE_CLASS_END(bshell_command) FX_TYPE_DEFINITION_BEGIN(bshell_command) FX_TYPE_ID(0x5c50630d, 0x7535, 0x40ed, 0xbae5, 0x88aabc274d79); FX_TYPE_FLAGS(FX_TYPE_F_ABSTRACT); FX_TYPE_NAME("bshell.runtime.command"); FX_TYPE_CLASS(bshell_command_class); FX_TYPE_INSTANCE_INIT(init); FX_TYPE_INSTANCE_PRIVATE(struct bshell_command_p); FX_TYPE_DEFINITION_END(bshell_command)