/* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* * Copyright (c) 2007, 2008 Richard Brown * Copyright (c) 2007, 2008, 2009, 2010, 2011 Ciaran McCreesh * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General * Public License version 2, as published by the Free Software Foundation. * * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include using namespace paludis; using namespace paludis::ruby; namespace { static VALUE c_package_id; static VALUE c_package_id_canonical_form; /* * call-seq: * canonical_form(form) -> String * * Return this PackageID in a PackageIDCanonicalForm. */ VALUE package_id_canonical_form(VALUE self, VALUE cf) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { return rb_str_new2(((*self_ptr)->canonical_form(static_cast(NUM2INT(cf)))).c_str()); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * name -> QualifiedPackageName * * Our name. */ VALUE package_id_name(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { return qualified_package_name_to_value((*self_ptr)->name()); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * uniquely_identifying_spec -> PackageDepSpec * * Our name. */ VALUE package_id_uniquely_identifying_spec(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { return package_dep_spec_to_value((*self_ptr)->uniquely_identifying_spec()); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * supports_action(action_test) -> true or false * * Returns whether we support an action. */ VALUE package_id_supports_action(VALUE self, VALUE test) { std::shared_ptr * self_ptr; std::shared_ptr test_ptr(value_to_supports_action_test_base(test)); Data_Get_Struct(self, std::shared_ptr, self_ptr); try { return (*self_ptr)->supports_action(*test_ptr) ? Qtrue : Qfalse; } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * perform_action(action) -> Nil * * Perform an action. */ VALUE package_id_perform_action(VALUE self, VALUE test) { std::shared_ptr * self_ptr; std::shared_ptr a_ptr(value_to_action(test)); Data_Get_Struct(self, std::shared_ptr, self_ptr); try { (*self_ptr)->perform_action(*a_ptr); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * version -> VersionSpec * * Our VersionSpec. */ VALUE package_id_version(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { return version_spec_to_value((*self_ptr)->version()); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * repository_name -> String * * Our Repository Name. */ VALUE package_id_repository_name(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { return rb_str_new2(stringify((*self_ptr)->repository_name()).c_str()); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * [String] -> MetadataKey or Nil * * The named metadata key. */ VALUE package_id_subscript(VALUE self, VALUE raw_name) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { PackageID::MetadataConstIterator it((*self_ptr)->find_metadata(StringValuePtr(raw_name))); if ((*self_ptr)->end_metadata() == it) return Qnil; return metadata_key_to_value(*it); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * each_metadata {|key| block } -> Nil * * Our metadata. */ VALUE package_id_each_metadata(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { for (PackageID::MetadataConstIterator it((*self_ptr)->begin_metadata()), it_end((*self_ptr)->end_metadata()); it_end != it; ++it) { VALUE val(metadata_key_to_value(*it)); if (Qnil != val) rb_yield(val); } } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * masks -> Array * * Our masks. */ VALUE package_id_masks(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); VALUE result(rb_ary_new()); try { for (PackageID::MasksConstIterator it((*self_ptr)->begin_masks()), it_end((*self_ptr)->end_masks()); it_end != it; ++it) { rb_ary_push(result, mask_to_value(*it)); } return result; } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * overridden_masks -> Array * * Our overridden masks. */ VALUE package_id_overridden_masks(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); VALUE result(rb_ary_new()); try { for (PackageID::OverriddenMasksConstIterator it((*self_ptr)->begin_overridden_masks()), it_end((*self_ptr)->end_overridden_masks()); it_end != it; ++it) { rb_ary_push(result, overridden_mask_to_value(*it)); } return result; } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * call-seq: * breaks_portage -> [:reason, :reason, ...] * * Do we break Portage, and if so, why? * * This method may be used by Environment implementations to apply a "we don't want packages that break Portage" mask. */ VALUE package_id_breaks_portage(VALUE self) { VALUE result(rb_ary_new()); std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { std::shared_ptr > breakages((*self_ptr)->breaks_portage()); if (breakages) for (Set::ConstIterator it(breakages->begin()), it_end(breakages->end()); it_end != it; ++it) rb_ary_push(result, ID2SYM(rb_intern(it->c_str()))); return result; } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * Document-method: contents * * call-seq: * contents -> Contents * * Our Contents */ VALUE package_id_contents(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { auto contents((*self_ptr)->contents()); if (! contents) return Qnil; else return contents_to_value(contents); } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } /* * Document-method: masked? * * call-seq: * masked? -> true or false * * Do we have any masks? */ template struct PackageIDBool { static VALUE fetch(VALUE self) { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); try { return (self_ptr->get()->*m_)() ? Qtrue : Qfalse; } catch (const std::exception &e) { exception_to_ruby_exception(e); } return Qnil; } }; /* * Document-method: keywords_key * * call-seq: * keywords_key -> MetadataCollectionKey * * Our keywords */ /* * Document-method: short_description_key * * call-seq: * short_description_key -> MetadataStringKey * * Our short description */ /* * Document-method: long_description_key * * call-seq: * long_description_key -> MetadataStringKey * * Our long description */ /* * Document-method: installed_time_key * * call-seq: * installed_time_key -> MetadataTimeKey * * Our installed time */ /* * Document-method: from_repositories_key * * call-seq: * from_repositories_key -> MetadataCollectionKey * * Our source origin repository */ /* * Document-method: dependencies_key * * call-seq: * dependencies_key -> MetadataDependencySpecTreeKey * * Our dependencies */ /* * Document-method: build_dependencies_key * * call-seq: * build_dependencies_key -> MetadataDependencySpecTreeKey * * Our build dependencies */ /* * Document-method: run_dependencies_key * * call-seq: * run_dependencies_key -> MetadataDependencySpecTreeKey * * Our run dependencies */ /* * Document-method: post_dependencies_key * * call-seq: * post_dependencies_key -> MetadataDependencySpecTreeKey * * Our post dependencies */ /* * Document-method: homepage_key * * call-seq: * homepage_key -> MetadataSimpleURISpecTreeKey * * Our homepage */ /* * Document-method: fetches_key * * call-seq: * fetches_key -> MetadataFetchableURISpecTreeKey * * Things we fetch */ /* * Document-method: choices_key * * call-seq: * choices_key -> MetadataChoicesKey * * Our choices */ template (PackageID::* m_) () const> struct KeyValue { static VALUE fetch(VALUE self) { try { std::shared_ptr * self_ptr; Data_Get_Struct(self, std::shared_ptr, self_ptr); std::shared_ptr ptr = (((**self_ptr).*m_)()); if (ptr) { return metadata_key_to_value(((**self_ptr).*m_)()); } } catch (const std::exception & e) { exception_to_ruby_exception(e); } return Qnil; } }; void do_register_package_id() { /* * Document-class: Paludis::PackageID * * Metadata about a package. */ c_package_id = rb_define_class_under(paludis_module(), "PackageID", rb_cObject); rb_funcall(c_package_id, rb_intern("private_class_method"), 1, rb_str_new2("new")); rb_define_method(c_package_id, "canonical_form", RUBY_FUNC_CAST(&package_id_canonical_form), 1); rb_define_method(c_package_id, "name", RUBY_FUNC_CAST(&package_id_name), 0); rb_define_method(c_package_id, "version", RUBY_FUNC_CAST(&package_id_version), 0); rb_define_method(c_package_id, "repository_name", RUBY_FUNC_CAST(&package_id_repository_name), 0); rb_define_method(c_package_id, "==", RUBY_FUNC_CAST(&Common >::equal_via_ptr), 1); rb_define_method(c_package_id, "[]", RUBY_FUNC_CAST(&package_id_subscript), 1); rb_define_method(c_package_id, "to_s", RUBY_FUNC_CAST(&Common >::to_s_via_ptr), 0); rb_define_method(c_package_id, "hash", RUBY_FUNC_CAST(&Common >::hash_via_ptr), 0); rb_define_method(c_package_id, "eql?", RUBY_FUNC_CAST(&Common >::equal_via_ptr), 1); rb_define_method(c_package_id, "supports_action", RUBY_FUNC_CAST(&package_id_supports_action), 1); rb_define_method(c_package_id, "perform_action", RUBY_FUNC_CAST(&package_id_perform_action), 1); rb_define_method(c_package_id, "each_metadata", RUBY_FUNC_CAST(&package_id_each_metadata), 0); rb_define_method(c_package_id, "masks", RUBY_FUNC_CAST(&package_id_masks), 0); rb_define_method(c_package_id, "overridden_masks", RUBY_FUNC_CAST(&package_id_overridden_masks), 0); rb_define_method(c_package_id, "masked?", RUBY_FUNC_CAST((&PackageIDBool<&PackageID::masked>::fetch)), 0); rb_define_method(c_package_id, "breaks_portage", RUBY_FUNC_CAST(&package_id_breaks_portage), 0); rb_define_method(c_package_id, "keywords_key", RUBY_FUNC_CAST((&KeyValue,&PackageID::keywords_key>::fetch)), 0); rb_define_method(c_package_id, "dependencies_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::dependencies_key>::fetch)), 0); rb_define_method(c_package_id, "build_dependencies_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::build_dependencies_key>::fetch)), 0); rb_define_method(c_package_id, "run_dependencies_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::run_dependencies_key>::fetch)), 0); rb_define_method(c_package_id, "post_dependencies_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::post_dependencies_key>::fetch)), 0); rb_define_method(c_package_id, "homepage_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::homepage_key>::fetch)), 0); rb_define_method(c_package_id, "short_description_key", RUBY_FUNC_CAST((&KeyValue, &PackageID::short_description_key>::fetch)), 0); rb_define_method(c_package_id, "long_description_key", RUBY_FUNC_CAST((&KeyValue, &PackageID::long_description_key>::fetch)), 0); rb_define_method(c_package_id, "installed_time_key", RUBY_FUNC_CAST((&KeyValue::fetch)), 0); rb_define_method(c_package_id, "from_repositories_key", RUBY_FUNC_CAST((&KeyValue >, &PackageID::from_repositories_key>::fetch)), 0); rb_define_method(c_package_id, "fs_location_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::fs_location_key>::fetch)), 0); rb_define_method(c_package_id, "fetches_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::fetches_key>::fetch)), 0); rb_define_method(c_package_id, "choices_key", RUBY_FUNC_CAST(( &KeyValue >, &PackageID::choices_key>::fetch)), 0); rb_define_method(c_package_id, "slot_key", RUBY_FUNC_CAST(( &KeyValue, &PackageID::slot_key>::fetch)), 0); rb_define_method(c_package_id, "behaviours_key", RUBY_FUNC_CAST(( &KeyValue >, &PackageID::behaviours_key>::fetch)), 0); rb_define_method(c_package_id, "uniquely_identifying_spec", RUBY_FUNC_CAST(&package_id_uniquely_identifying_spec), 0); rb_define_method(c_package_id, "contents", RUBY_FUNC_CAST(&package_id_contents), 0); /* * Document-module: Paludis::PackageIDCanonicalForm * * How to generate PackageID.canonical_form */ c_package_id_canonical_form = rb_define_module_under(paludis_module(), "PackageIDCanonicalForm"); for (PackageIDCanonicalForm l(static_cast(0)), l_end(last_idcf) ; l != l_end ; l = static_cast(static_cast(l) + 1)) rb_define_const(c_package_id_canonical_form, value_case_to_RubyCase(stringify(l)).c_str(), INT2FIX(l)); // cc_enum_special } } VALUE paludis::ruby::package_id_to_value(std::shared_ptr m) { std::shared_ptr * m_ptr(0); try { m_ptr = new std::shared_ptr(m); return Data_Wrap_Struct(c_package_id, 0, &Common >::free, m_ptr); } catch (const std::exception & e) { delete m_ptr; exception_to_ruby_exception(e); } } std::shared_ptr paludis::ruby::value_to_package_id(VALUE v, bool nil_ok) { if (nil_ok && rb_obj_is_kind_of(v, rb_cNilClass)) return std::shared_ptr(); if (rb_obj_is_kind_of(v, c_package_id)) { std::shared_ptr * v_ptr; Data_Get_Struct(v, std::shared_ptr, v_ptr); return *v_ptr; } else { rb_raise(rb_eTypeError, "Can't convert %s into PackageID", rb_obj_classname(v)); } } RegisterRubyClass::Register paludis_ruby_register_package_id PALUDIS_ATTRIBUTE((used)) (&do_register_package_id);