class Paludis::BlockDepSpec

A BlockDepSpec represents a block on a package name (for example, 'app-editors/vim'), possibly with associated version and SLOT restrictions.

Public Class Methods

new(p1, p2) click to toggle source
VALUE
    block_dep_spec_new(VALUE self, VALUE str, VALUE spec)
    {
        std::shared_ptr<const WrappedSpecBase> * ptr(0);
        try
        {
            std::shared_ptr<const PackageDepSpec> pkg(value_to_package_dep_spec(spec));
            ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<BlockDepSpec>>(
                        std::make_shared<BlockDepSpec>(StringValuePtr(str), *pkg)));
            VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr));
            rb_obj_call_init(tdata, 2, &str);
            return tdata;
        }
        catch (const std::exception & e)
        {
            delete ptr;
            exception_to_ruby_exception(e);
        }
    }

    /*
     * call-seq:
     *     blocking -> DepSpec
     *
     * Fetch the DepSpec we're blocking.
     */
    VALUE
    block_dep_spec_blocking(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * p;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, p);
        return package_dep_spec_to_value(*std::make_shared<PackageDepSpec>(
                    std::static_pointer_cast<const WrappedSpec<BlockDepSpec> >(*p)->spec()->blocking()));
    }

    template <typename A_>
    struct DepSpecThings
    {
        static VALUE
        dep_spec_new_0(VALUE self)
        {
            std::shared_ptr<const WrappedSpecBase> * ptr(0);
            try
            {
                ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<A_>>(std::make_shared<A_>()));
                VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr));
                rb_obj_call_init(tdata, 0, &self);
                return tdata;
            }
            catch (const std::exception & e)
            {
                delete ptr;
                exception_to_ruby_exception(e);
            }
        }

        static VALUE
        dep_spec_new_1(VALUE self, VALUE s)
        {
            std::shared_ptr<const WrappedSpecBase> * ptr(0);
            try
            {
                ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<A_>>(std::make_shared<A_>(StringValuePtr(s))));
                VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr));
                rb_obj_call_init(tdata, 1, &s);
                return tdata;
            }
            catch (const std::exception & e)
            {
                delete ptr;
                exception_to_ruby_exception(e);
            }
        }
    };

    /*
     * Document-method: condition_met?
     * call-seq:
     *     condition_met?(Environment, PackageID) -> true or false
     *
     * Whether our condition is met.
     */
    /*
     * Document-method: condition_meetable?
     * call-seq:
     *     condition_meetable?(Environment, PackageID) -> true or false
     *
     * Whether our condition is meetable.
     */
    template <bool (ConditionalDepSpec::* f_) (const Environment * const, const std::shared_ptr<const PackageID> &) const>
    struct ConditionalDepSpecBoolFunc
    {
        static VALUE func(VALUE self, VALUE env, VALUE id)
        {
            std::shared_ptr<WrappedSpecBase> * p;
            Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, p);
            std::shared_ptr<Environment> e(value_to_environment(env));
            std::shared_ptr<const PackageID> i(value_to_package_id(id));
            return ((*std::static_pointer_cast<const WrappedSpec<ConditionalDepSpec> >(*p)->spec().get()).*f_)(e.get(), i) ? Qtrue : Qfalse;
        }
    };

    /*
     * call-seq:
     *     package -> QualifiedPackageName or Nil
     *
     * Fetch the package name.
     */
    VALUE
    package_dep_spec_package(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->package_ptr()))
            return Qnil;
        return qualified_package_name_to_value(*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->package_ptr());
    }

    /*
     * call-seq:
     *     package_name_part -> String or Nil
     *
     * Fetch the package name part.
     */
    VALUE
    package_dep_spec_package_name_part(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->package_name_part_ptr()))
            return Qnil;
        return rb_str_new2(stringify(*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->
                    package_name_part_ptr()).c_str());
    }

    /*
     * call-seq:
     *     category_name_part -> String or Nil
     *
     * Fetch the category name part.
     */
    VALUE
    package_dep_spec_category_name_part(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->category_name_part_ptr()))
            return Qnil;
        return rb_str_new2(stringify(*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->
                    category_name_part_ptr()).c_str());
    }

    /*
     * call-seq:
     *     text -> String
     *
     * Fetch our text.
     */
    VALUE
    string_dep_spec_text(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return rb_str_new2(stringify(std::static_pointer_cast<const StringDepSpec>((*ptr)->base_spec())->text()).c_str());
    }

    /*
     * call-seq:
     *     to_s -> String
     *
     * Fetch a string representation of ourself.
     */
    template <typename T_>
    VALUE dep_spec_to_s(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return rb_str_new2(stringify(*std::static_pointer_cast<const WrappedSpec<T_> >(*ptr)->spec()).c_str());
    }

    /*
     * call-seq:
     *     slot_requirement -> SlotRequirement or Nil
     *
     * Fetch the slot requirement.
     */
    VALUE
    package_dep_spec_slot_requirement_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->slot_requirement_ptr()))
            return Qnil;
        return slot_requirement_to_value(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->slot_requirement_ptr());
    }

    /*
     * call-seq:
     *     in_repository -> String or Nil
     *
     * Fetch the in-repository name.
     */
    VALUE
    package_dep_spec_in_repository_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->in_repository_ptr()))
            return Qnil;
        return rb_str_new2(stringify((*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->in_repository_ptr())).c_str());
    }

    /*
     * call-seq:
     *     from_repository -> String or Nil
     *
     * Fetch the from-repository name.
     */
    VALUE
    package_dep_spec_from_repository_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->from_repository_ptr()))
            return Qnil;
        return rb_str_new2(stringify((*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->from_repository_ptr())).c_str());
    }

    /*
     * call-seq:
     *     installable_to_repository -> Hash or Nil
     *
     * Fetch the installable-to-repository requirement.
     */
    VALUE
    package_dep_spec_installable_to_repository(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        std::shared_ptr<const InstallableToRepository> i2r(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installable_to_repository_ptr());
        if (! i2r)
            return Qnil;
        VALUE result(rb_hash_new());
        rb_hash_aset(result, ID2SYM(rb_intern("repository")),
            rb_str_new2(stringify(i2r->repository()).c_str()));
        rb_hash_aset(result, ID2SYM(rb_intern("include_masked?")),
            i2r->include_masked() ? Qtrue : Qfalse);
        return result;
    }

    /*
     * call-seq:
     *     installed_at_path -> String or Nil
     *
     * Fetch the installed-at-path requirement.
     */
    VALUE
    package_dep_spec_installed_at_path(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installed_at_path_ptr()))
            return Qnil;
        return rb_str_new2(stringify((*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installed_at_path_ptr())).c_str());
    }

    /*
     * call-seq:
     *     installable_to_path -> Hash or Nil
     *
     * Fetch the installable-to-path requirement.
     */
    VALUE
    package_dep_spec_installable_to_path(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        std::shared_ptr<const InstallableToPath> i2p(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installable_to_path_ptr());
        if (! i2p)
            return Qnil;
        VALUE result(rb_hash_new());
        rb_hash_aset(result, ID2SYM(rb_intern("path")),
            rb_str_new2(stringify(i2p->path()).c_str()));
        rb_hash_aset(result, ID2SYM(rb_intern("include_masked?")),
            i2p->include_masked() ? Qtrue : Qfalse);
        return result;
    }

    /*
     * call-seq:
     *     version_requirements -> Array
     *
     * Fetch the version requirements. E.g. [ {:operator => '=', :spec => VersionSpec.new('0.1') } ]
     */
    VALUE
    package_dep_spec_version_requirements_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        VALUE result(rb_ary_new());
        VALUE result_hash;
        if (std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->version_requirements_ptr())
            for (VersionRequirements::ConstIterator i(std::static_pointer_cast<const PackageDepSpec>((*ptr)->base_spec())->
                        version_requirements_ptr()->begin()),
                    i_end(std::static_pointer_cast<const PackageDepSpec>((*ptr)->base_spec())->version_requirements_ptr()->end()) ;
                    i != i_end; ++i)
            {
                result_hash = rb_hash_new();
                rb_hash_aset(result_hash, ID2SYM(rb_intern("operator")),
                    rb_str_new2(stringify(i->version_operator()).c_str()));
                rb_hash_aset(result_hash, ID2SYM(rb_intern("spec")),
                    version_spec_to_value(i->version_spec()));
                rb_ary_push(result, result_hash);
            }
        return result;
    }

#ifdef CIARANM_REMOVED_THIS
    /*
     * call-seq:
     *     use_requirements -> Array
     *
     * Fetch the use requirements. E.g. [ {:flag => 'a', :state => true } ]
     */
    VALUE
    package_dep_spec_use_requirements(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        VALUE result(rb_ary_new());
        VALUE result_hash;
        if (std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->use_requirements_ptr())
            for (UseRequirements::ConstIterator
                    i(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->use_requirements_ptr()->begin()),
                    i_end(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->use_requirements_ptr()->end()) ;
                    i != i_end; ++i)
            {
                result_hash = rb_hash_new();
                rb_hash_aset(result_hash, ID2SYM(rb_intern("flag")),
                    rb_str_new2(stringify(i->first).c_str()));
                rb_hash_aset(result_hash, ID2SYM(rb_intern("state")),
                        i->second == use_disabled ? Qfalse : Qtrue);

                rb_ary_push(result, result_hash);
            }
        return result;
    }
#endif

    VALUE
    package_dep_spec_version_requirements_mode(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return INT2FIX(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->version_requirements_mode());
    }

    /*
     * Document-method: original_url
     *     call-seq: original_url -> String
     *
     * The original URL (that is, the text to the left of the arrow, if present,
     * or the entire text otherwise).
     */
    /*
     * Document-method: renamed_url_suffix
     *     call-seq: renamed_url_suffix -> String
     *
     * The renamed URL filename (that is, the text to the right of the arrow,
     * if present, or an empty string otherwise).
     */
    /*
     * Document-method: filename
     *     call-seq: filename -> String
     *
     * The filename (that is, the renamed URL suffix, if present, or the text
     * after the final / in the original URL otherwise).
     */
    template <std::string (FetchableURIDepSpec::* m_) () const>
    struct FetchableURIDepSpecStringValue
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<WrappedSpecBase> * ptr;
            Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
            std::shared_ptr<const FetchableURIDepSpec> f_ptr(std::static_pointer_cast<const FetchableURIDepSpec>((*ptr)->base_spec()));
            return rb_str_new2(((f_ptr.get())->*(m_))().c_str());
        }
    };

    template <typename T_>
    struct Composite
    {
        /*
         * call-seq:
         *     each {|contents_entry| block}
         *
         * Iterate through our entries.
         */
        static VALUE
        each(VALUE self)
        {
            std::shared_ptr<WrappedSpecBase> * ptr;
            Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);

            if ((*ptr)->children())
                for (WrappedSpecBase::Children::const_iterator i((*ptr)->children()->begin()), i_end((*ptr)->children()->end()) ;
                        i != i_end ; ++i)
                {
                    std::shared_ptr<const WrappedSpecBase> * newptr(new std::shared_ptr<const WrappedSpecBase>(i->second));
                    rb_yield(Data_Wrap_Struct(i->first, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, newptr));
                }
            return self;
        }
    };

    /*
     * call-seq:
     *     name -> String
     *
     * Fetch our set name.
     */
    VALUE
    named_set_dep_spec_name(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return rb_str_new2(stringify(std::static_pointer_cast<const WrappedSpec<NamedSetDepSpec> >(*ptr)->spec()->text()).c_str());
    }

    /*
     * Document-method: parse_user_package_dep_spec
     *
     * call-seq:
     *     parse_user_package_dep_spec(String, Env, Array) -> PackageDepSpec
     *     parse_user_package_dep_spec(String, Env, Array, Filter) -> PackageDepSpec
     *
     * Return a PackageDepSpec parsed from user input. The third parameter is either an empty
     * array, or can contain :allow_wildcards to allow wildcards, :throw_if_set to get a
     * GotASetNotAPackageDepSpec exception if the string is a set name and :no_disambiguation
     * to disallow disambiguation (require an explicit category). The Filter, if
     * provided, is used to restrict disambiguation as per
     * Environment#fetch_unique_qualified_package_name.
     *
     */
    VALUE paludis_parse_user_dep_spec(int argc, VALUE * argv, VALUE)
    {
        std::shared_ptr<const WrappedSpecBase> * ptr(0);

        if (argc < 3 || argc > 4)
            rb_raise(rb_eArgError, "parse_user_package_dep_spec expects three to four arguments, but got %d", argc);

        try
        {
            std::string s(StringValuePtr(argv[0]));
            std::shared_ptr<Environment> e(value_to_environment(argv[1]));

            Check_Type(argv[2], T_ARRAY);
            UserPackageDepSpecOptions o;
            for (int i(0) ; i < RARRAY_LEN(argv[2]) ; ++i)
            {
                VALUE entry(rb_ary_entry(argv[2], i));
                Check_Type(entry, T_SYMBOL);
                if (SYM2ID(entry) == rb_intern("allow_wildcards"))
                    o += updso_allow_wildcards;
                else if (SYM2ID(entry) == rb_intern("throw_if_set"))
                    o += updso_throw_if_set;
                else if (SYM2ID(entry) == rb_intern("no_disambiguation"))
                    o += updso_no_disambiguation;
                else
                    rb_raise(rb_eArgError, "Unknown parse_user_package_dep_spec option '%s'", RSTRING_PTR(rb_obj_as_string(entry)));
            }

            Filter f(
                    argc >= 4 ?
                    value_to_filter(argv[3]) :
                    filter::All()
                    );

            ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<PackageDepSpec>>(
                        std::make_shared<PackageDepSpec>(parse_user_package_dep_spec(s, e.get(), o, f))));
            return Data_Wrap_Struct(c_package_dep_spec, 0,
                    &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr);
        }
        catch (const std::exception & e)
        {
            delete ptr;
            exception_to_ruby_exception(e);
        }

    }

    VALUE
    slot_exact_requirement_slot(VALUE self)
    {
        std::shared_ptr<const SlotExactPartialRequirement> * ptr;
        Data_Get_Struct(self, std::shared_ptr<const SlotExactPartialRequirement>, ptr);
        return rb_str_new2(stringify((*ptr)->slot()).c_str());
    }

    void do_register_dep_spec()
    {
        /*
         * Document-class: Paludis::DepSpec
         *
         * Base class for a dependencies spec.
         */
        c_dep_spec = rb_define_class_under(c_paludis_module, "DepSpec", rb_cObject);
        rb_funcall(c_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));

        /*
         * Document-class: Paludis::AllDepSpec
         *
         * Represents a ( first second third ) or top level group of dependency specs. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_all_dep_spec = rb_define_class_under(c_paludis_module, "AllDepSpec", c_dep_spec);
        rb_funcall(c_all_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_all_dep_spec, rb_mEnumerable);
        rb_define_method(c_all_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::AnyDepSpec
         *
         * Represents a "|| ( )" dependency block. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_any_dep_spec = rb_define_class_under(c_paludis_module, "AnyDepSpec", c_dep_spec);
        rb_funcall(c_any_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_any_dep_spec, rb_mEnumerable);
        rb_define_method(c_any_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::ExactlyOneDepSpec
         *
         * Represents a "^^ ( )" dependency block. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_exactly_one_dep_spec = rb_define_class_under(c_paludis_module, "ExactlyOneDepSpec", c_dep_spec);
        rb_funcall(c_exactly_one_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_exactly_one_dep_spec, rb_mEnumerable);
        rb_define_method(c_exactly_one_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::AtMostOneDepSpec
         *
         * Represents a "?? ( )" dependency block. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_at_most_one = rb_define_class_under(c_paludis_module, "AtMostOneDepSpec", c_dep_spec);
        rb_funcall(c_at_most_one, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_at_most_one, rb_mEnumerable);
        rb_define_method(c_at_most_one, "each", template_methods, 0);

        /*
         * Document-class: Paludis::ConditionalDepSpec
         *
         * Represents a use? ( ) dependency spec. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_conditional_dep_spec = rb_define_class_under(c_paludis_module, "ConditionalDepSpec", c_dep_spec);
        rb_funcall(c_conditional_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_conditional_dep_spec, rb_mEnumerable);
        /*
         * Document-method: condition
         *
         * call-seq:
         *     confition -> String
         *
         * Our condition
         */
        VALUE (* conditional_dep_spec_to_s) (VALUE) = &dep_spec_to_s<ConditionalDepSpec>;
        rb_define_method(c_conditional_dep_spec, "condition", conditional_dep_spec_to_s, 0);
        rb_define_alias(c_conditional_dep_spec, "to_s", "condition");
        rb_define_method(c_conditional_dep_spec, "condition_met?",                     template_methods, 2);
        rb_define_method(c_conditional_dep_spec, "condition_meetable?",                     template_methods, 2);
        rb_define_method(c_conditional_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::StringDepSpec
         *
         * A StringDepSpec represents a non-composite dep spec with an associated piece of text.
         */
        c_string_dep_spec = rb_define_class_under(c_paludis_module, "StringDepSpec", c_dep_spec);
        rb_funcall(c_string_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_string_dep_spec, "text", string_dep_spec_text, 0);

        /*
         * Document-class: Paludis::FetchableURIDepSpec
         *
         * A FetchableURIDepSpec represents a fetchable URI spec.
         */
        c_fetchable_uri_dep_spec = rb_define_class_under(c_paludis_module, "FetchableURIDepSpec", c_string_dep_spec);
        rb_funcall(c_fetchable_uri_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* fetchable_uri_dep_spec_to_s) (VALUE) = &dep_spec_to_s<FetchableURIDepSpec>;
        rb_define_method(c_fetchable_uri_dep_spec, "to_s", fetchable_uri_dep_spec_to_s, 0);
        rb_define_method(c_fetchable_uri_dep_spec, "original_url",                template_methods, 0);
        rb_define_method(c_fetchable_uri_dep_spec, "renamed_url_suffix",                template_methods, 0);
        rb_define_method(c_fetchable_uri_dep_spec, "filename",                template_methods, 0);

        /*
         * Document-class: Paludis::SimpleURIDepSpec
         *
         * A SimpleURIDepSpec represents a simple URI spec.
         */
        c_simple_uri_dep_spec = rb_define_class_under(c_paludis_module, "SimpleURIDepSpec", c_string_dep_spec);
        rb_funcall(c_simple_uri_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* simple_uri_dep_spec_to_s) (VALUE) = &dep_spec_to_s<SimpleURIDepSpec>;
        rb_define_method(c_simple_uri_dep_spec, "to_s", simple_uri_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::LicenseDepSpec
         *
         * A LicenseDepSpec represents a license dep spec.
         */
        c_license_dep_spec = rb_define_class_under(c_paludis_module, "LicenseDepSpec", c_string_dep_spec);
        rb_funcall(c_license_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* license_dep_spec_to_s) (VALUE) = &dep_spec_to_s<LicenseDepSpec>;
        rb_define_method(c_license_dep_spec, "to_s", license_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::NamedSetDepSpec
         *
         * A NamedSetDepSpec represents a fetchable URI spec.
         */
        c_named_set_dep_spec = rb_define_class_under(c_paludis_module, "NamedSetDepSpec", c_string_dep_spec);
        rb_funcall(c_named_set_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* named_set_dep_spec_to_s) (VALUE) = &dep_spec_to_s<NamedSetDepSpec>;
        rb_define_method(c_named_set_dep_spec, "to_s", named_set_dep_spec_to_s, 0);
        rb_define_method(c_named_set_dep_spec, "name", named_set_dep_spec_name, 0);


        /*
         * Document-class: Paludis::PackageDepSpec
         *
         * A PackageDepSpec represents a package name (for example, 'app-editors/vim'),
         * possibly with associated version and SLOT restrictions. To create a PackageDepSpec,
         * use Paludis::parse_user_package_dep_spec.
         */
        c_package_dep_spec = rb_define_class_under(c_paludis_module, "PackageDepSpec", c_string_dep_spec);
        rb_define_method(c_package_dep_spec, "package", package_dep_spec_package, 0);
        rb_define_method(c_package_dep_spec, "package_name_part", package_dep_spec_package_name_part, 0);
        rb_define_method(c_package_dep_spec, "category_name_part", package_dep_spec_category_name_part, 0);
        rb_define_method(c_package_dep_spec, "slot_requirement", package_dep_spec_slot_requirement_ptr, 0);
        rb_define_method(c_package_dep_spec, "in_repository", package_dep_spec_in_repository_ptr, 0);
        rb_define_method(c_package_dep_spec, "from_repository", package_dep_spec_from_repository_ptr, 0);
        rb_define_method(c_package_dep_spec, "installable_to_repository", package_dep_spec_installable_to_repository, 0);
        rb_define_method(c_package_dep_spec, "installed_at_path", package_dep_spec_installed_at_path, 0);
        rb_define_method(c_package_dep_spec, "installable_to_path", package_dep_spec_installable_to_path, 0);
        rb_define_method(c_package_dep_spec, "version_requirements", package_dep_spec_version_requirements_ptr, 0);
        rb_define_method(c_package_dep_spec, "version_requirements_mode", package_dep_spec_version_requirements_mode, 0);
#ifdef CIARANM_REMOVED_THIS
        rb_define_method(c_package_dep_spec, "use_requirements", package_dep_spec_use_requirements, 0);
#endif
        VALUE (* package_dep_spec_to_s) (VALUE) = &dep_spec_to_s<PackageDepSpec>;
        rb_define_method(c_package_dep_spec, "to_s", package_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::PlainTextDepSpec
         *
         * A PlainTextDepSpec represents a plain text entry (for example, a URI in SRC_URI).
         */
        c_plain_text_dep_spec = rb_define_class_under(c_paludis_module, "PlainTextDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_plain_text_dep_spec, "new", template_methods, 1);
        rb_define_method(c_plain_text_dep_spec, "initialize", dep_spec_init_1, 1);
        VALUE (* plain_text_dep_spec_to_s) (VALUE) = &dep_spec_to_s<PlainTextDepSpec>;
        rb_define_method(c_plain_text_dep_spec, "to_s", plain_text_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::DependenciesLabelsDepSpec
         *
         * A DependenciesLabelsDepSpec holds dependencies labels.
         */
        c_dependencies_labels_dep_spec = rb_define_class_under(c_paludis_module, "DependenciesLabelsDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_dependencies_labels_dep_spec, "new", template_methods, 0);
        rb_define_method(c_dependencies_labels_dep_spec, "initialize", dep_spec_init_0, 0);
        VALUE (* dependencies_labels_dep_spec_to_s) (VALUE) = &dep_spec_to_s<DependenciesLabelsDepSpec>;
        rb_define_method(c_dependencies_labels_dep_spec, "to_s", dependencies_labels_dep_spec_to_s, 0);
        rb_define_method(c_dependencies_labels_dep_spec, "labels", dependencies_labels_dep_spec_labels, 0);

        /*
         * Document-class: Paludis::URILabelsDepSpec
         *
         * A URILabelsDepSpec holds URI labels.
         */
        c_uri_labels_dep_spec = rb_define_class_under(c_paludis_module, "URILabelsDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_uri_labels_dep_spec, "new", template_methods, 0);
        rb_define_method(c_uri_labels_dep_spec, "initialize", dep_spec_init_0, 0);
        VALUE (* uri_labels_dep_spec_to_s) (VALUE) = &dep_spec_to_s<URILabelsDepSpec>;
        rb_define_method(c_uri_labels_dep_spec, "to_s", uri_labels_dep_spec_to_s, 0);
        rb_define_method(c_uri_labels_dep_spec, "labels", uri_labels_dep_spec_labels, 0);

        /*
         * Document-class: Paludis::PlainTextLabelDepSpec
         *
         * A PlainTextLabelDepSpec holds a plain text label.
         */
        c_plain_text_label_dep_spec = rb_define_class_under(c_paludis_module, "PlainTextLabelDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_plain_text_label_dep_spec, "new", template_methods, 1);
        rb_define_method(c_plain_text_label_dep_spec, "initialize", dep_spec_init_1, 1);
        VALUE (* plain_text_dep_label_spec_to_s) (VALUE) = &dep_spec_to_s<PlainTextLabelDepSpec>;
        rb_define_method(c_plain_text_label_dep_spec, "to_s", plain_text_dep_label_spec_to_s, 0);

        /*
         * Document-class: Paludis::BlockDepSpec
         *
         * A BlockDepSpec represents a block on a package name (for example, 'app-editors/vim'), possibly with
         * associated version and SLOT restrictions.
         */
        c_block_dep_spec = rb_define_class_under(c_paludis_module, "BlockDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_block_dep_spec, "new", block_dep_spec_new, 2);
        rb_define_method(c_block_dep_spec, "initialize", dep_spec_init_1, 2);
        rb_define_method(c_block_dep_spec, "blocking", block_dep_spec_blocking, 0);
        VALUE (* block_dep_spec_to_s) (VALUE) = &dep_spec_to_s<BlockDepSpec>;
        rb_define_method(c_block_dep_spec, "to_s", block_dep_spec_to_s, 0);

        /*
         * Document-module: Paludis::VersionRequirementsMode
         *
         * What sort of VersionRequirements to we have.
         *
         */
        c_version_requirements_mode = rb_define_module_under(c_paludis_module, "VersionRequirementsMode");
        for (VersionRequirementsMode l(static_cast<VersionRequirementsMode>(0)), l_end(last_vr) ; l != l_end ;
                l = static_cast<VersionRequirementsMode>(static_cast<int>(l) + 1))
            rb_define_const(c_version_requirements_mode, value_case_to_RubyCase(stringify(l)).c_str(), INT2FIX(l));


        rb_define_module_function(c_paludis_module, "parse_user_package_dep_spec", paludis_parse_user_dep_spec, -1);

        /*
         * Document-class: Paludis::SlotRequirement
         *
         * A SlotRequirement
         */
        c_slot_requirement = rb_define_class_under(c_paludis_module, "SlotRequirement", rb_cObject);
        rb_funcall(c_slot_requirement, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_slot_requirement, "as_string", Common<std::shared_ptr<const SlotRequirement> >::to_s_via_ptr, 0);
        rb_define_method(c_slot_requirement, "to_s", Common<std::shared_ptr<const SlotRequirement> >::to_s_via_ptr, 0);

        /*
         * Document-class: Paludis::SlotExactPartialRequirement
         *
         * An exact slot requirement (:slot)
         */
        c_slot_exact_partial_requirement = rb_define_class_under(c_paludis_module, "SlotExactPartialRequirement", c_slot_requirement);
        rb_define_method(c_slot_exact_partial_requirement, "slot", slot_exact_requirement_slot, 0);

        /*
         * Document-class: Paludis::SlotExactFullRequirement
         *
         * An exact slot requirement (:slot/sub)
         */
        c_slot_exact_full_requirement = rb_define_class_under(c_paludis_module, "SlotExactFullRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotAnyPartialLockedRequirement
         *
         * A partial locked slot requirement (:slot=)
         */
        c_slot_any_partial_locked_requirement = rb_define_class_under(c_paludis_module, "SlotAnyPartialLockedRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotAnyAtAllLockedRequirement
         *
         * An any locked slot requirement (:=)
         */
        c_slot_any_at_all_locked_requirement = rb_define_class_under(c_paludis_module, "SlotAnyAtAllLockedRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotAnyUnlockedRequirement
         *
         * An any unlocked slot requirement (:*)
         */
        c_slot_any_unlocked_requirement = rb_define_class_under(c_paludis_module, "SlotAnyUnlockedRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotUnknownRewrittenRequirement
         *
         * An unknown rewritten slot requirement (either := or :slot=)
         */
        c_slot_unknown_rewritten_requirement = rb_define_class_under(c_paludis_module, "SlotUnknownRewrittenRequirement", c_slot_requirement);
    }
}

Public Instance Methods

blocking → DepSpec click to toggle source

Fetch the DepSpec we're blocking.

VALUE
    block_dep_spec_blocking(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * p;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, p);
        return package_dep_spec_to_value(*std::make_shared<PackageDepSpec>(
                    std::static_pointer_cast<const WrappedSpec<BlockDepSpec> >(*p)->spec()->blocking()));
    }

    template <typename A_>
    struct DepSpecThings
    {
        static VALUE
        dep_spec_new_0(VALUE self)
        {
            std::shared_ptr<const WrappedSpecBase> * ptr(0);
            try
            {
                ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<A_>>(std::make_shared<A_>()));
                VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr));
                rb_obj_call_init(tdata, 0, &self);
                return tdata;
            }
            catch (const std::exception & e)
            {
                delete ptr;
                exception_to_ruby_exception(e);
            }
        }

        static VALUE
        dep_spec_new_1(VALUE self, VALUE s)
        {
            std::shared_ptr<const WrappedSpecBase> * ptr(0);
            try
            {
                ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<A_>>(std::make_shared<A_>(StringValuePtr(s))));
                VALUE tdata(Data_Wrap_Struct(self, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr));
                rb_obj_call_init(tdata, 1, &s);
                return tdata;
            }
            catch (const std::exception & e)
            {
                delete ptr;
                exception_to_ruby_exception(e);
            }
        }
    };

    /*
     * Document-method: condition_met?
     * call-seq:
     *     condition_met?(Environment, PackageID) -> true or false
     *
     * Whether our condition is met.
     */
    /*
     * Document-method: condition_meetable?
     * call-seq:
     *     condition_meetable?(Environment, PackageID) -> true or false
     *
     * Whether our condition is meetable.
     */
    template <bool (ConditionalDepSpec::* f_) (const Environment * const, const std::shared_ptr<const PackageID> &) const>
    struct ConditionalDepSpecBoolFunc
    {
        static VALUE func(VALUE self, VALUE env, VALUE id)
        {
            std::shared_ptr<WrappedSpecBase> * p;
            Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, p);
            std::shared_ptr<Environment> e(value_to_environment(env));
            std::shared_ptr<const PackageID> i(value_to_package_id(id));
            return ((*std::static_pointer_cast<const WrappedSpec<ConditionalDepSpec> >(*p)->spec().get()).*f_)(e.get(), i) ? Qtrue : Qfalse;
        }
    };

    /*
     * call-seq:
     *     package -> QualifiedPackageName or Nil
     *
     * Fetch the package name.
     */
    VALUE
    package_dep_spec_package(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->package_ptr()))
            return Qnil;
        return qualified_package_name_to_value(*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->package_ptr());
    }

    /*
     * call-seq:
     *     package_name_part -> String or Nil
     *
     * Fetch the package name part.
     */
    VALUE
    package_dep_spec_package_name_part(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->package_name_part_ptr()))
            return Qnil;
        return rb_str_new2(stringify(*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->
                    package_name_part_ptr()).c_str());
    }

    /*
     * call-seq:
     *     category_name_part -> String or Nil
     *
     * Fetch the category name part.
     */
    VALUE
    package_dep_spec_category_name_part(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->category_name_part_ptr()))
            return Qnil;
        return rb_str_new2(stringify(*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->
                    category_name_part_ptr()).c_str());
    }

    /*
     * call-seq:
     *     text -> String
     *
     * Fetch our text.
     */
    VALUE
    string_dep_spec_text(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return rb_str_new2(stringify(std::static_pointer_cast<const StringDepSpec>((*ptr)->base_spec())->text()).c_str());
    }

    /*
     * call-seq:
     *     to_s -> String
     *
     * Fetch a string representation of ourself.
     */
    template <typename T_>
    VALUE dep_spec_to_s(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return rb_str_new2(stringify(*std::static_pointer_cast<const WrappedSpec<T_> >(*ptr)->spec()).c_str());
    }

    /*
     * call-seq:
     *     slot_requirement -> SlotRequirement or Nil
     *
     * Fetch the slot requirement.
     */
    VALUE
    package_dep_spec_slot_requirement_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->slot_requirement_ptr()))
            return Qnil;
        return slot_requirement_to_value(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->slot_requirement_ptr());
    }

    /*
     * call-seq:
     *     in_repository -> String or Nil
     *
     * Fetch the in-repository name.
     */
    VALUE
    package_dep_spec_in_repository_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->in_repository_ptr()))
            return Qnil;
        return rb_str_new2(stringify((*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->in_repository_ptr())).c_str());
    }

    /*
     * call-seq:
     *     from_repository -> String or Nil
     *
     * Fetch the from-repository name.
     */
    VALUE
    package_dep_spec_from_repository_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->from_repository_ptr()))
            return Qnil;
        return rb_str_new2(stringify((*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->from_repository_ptr())).c_str());
    }

    /*
     * call-seq:
     *     installable_to_repository -> Hash or Nil
     *
     * Fetch the installable-to-repository requirement.
     */
    VALUE
    package_dep_spec_installable_to_repository(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        std::shared_ptr<const InstallableToRepository> i2r(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installable_to_repository_ptr());
        if (! i2r)
            return Qnil;
        VALUE result(rb_hash_new());
        rb_hash_aset(result, ID2SYM(rb_intern("repository")),
            rb_str_new2(stringify(i2r->repository()).c_str()));
        rb_hash_aset(result, ID2SYM(rb_intern("include_masked?")),
            i2r->include_masked() ? Qtrue : Qfalse);
        return result;
    }

    /*
     * call-seq:
     *     installed_at_path -> String or Nil
     *
     * Fetch the installed-at-path requirement.
     */
    VALUE
    package_dep_spec_installed_at_path(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        if (! bool(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installed_at_path_ptr()))
            return Qnil;
        return rb_str_new2(stringify((*std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installed_at_path_ptr())).c_str());
    }

    /*
     * call-seq:
     *     installable_to_path -> Hash or Nil
     *
     * Fetch the installable-to-path requirement.
     */
    VALUE
    package_dep_spec_installable_to_path(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        std::shared_ptr<const InstallableToPath> i2p(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->installable_to_path_ptr());
        if (! i2p)
            return Qnil;
        VALUE result(rb_hash_new());
        rb_hash_aset(result, ID2SYM(rb_intern("path")),
            rb_str_new2(stringify(i2p->path()).c_str()));
        rb_hash_aset(result, ID2SYM(rb_intern("include_masked?")),
            i2p->include_masked() ? Qtrue : Qfalse);
        return result;
    }

    /*
     * call-seq:
     *     version_requirements -> Array
     *
     * Fetch the version requirements. E.g. [ {:operator => '=', :spec => VersionSpec.new('0.1') } ]
     */
    VALUE
    package_dep_spec_version_requirements_ptr(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        VALUE result(rb_ary_new());
        VALUE result_hash;
        if (std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->version_requirements_ptr())
            for (VersionRequirements::ConstIterator i(std::static_pointer_cast<const PackageDepSpec>((*ptr)->base_spec())->
                        version_requirements_ptr()->begin()),
                    i_end(std::static_pointer_cast<const PackageDepSpec>((*ptr)->base_spec())->version_requirements_ptr()->end()) ;
                    i != i_end; ++i)
            {
                result_hash = rb_hash_new();
                rb_hash_aset(result_hash, ID2SYM(rb_intern("operator")),
                    rb_str_new2(stringify(i->version_operator()).c_str()));
                rb_hash_aset(result_hash, ID2SYM(rb_intern("spec")),
                    version_spec_to_value(i->version_spec()));
                rb_ary_push(result, result_hash);
            }
        return result;
    }

#ifdef CIARANM_REMOVED_THIS
    /*
     * call-seq:
     *     use_requirements -> Array
     *
     * Fetch the use requirements. E.g. [ {:flag => 'a', :state => true } ]
     */
    VALUE
    package_dep_spec_use_requirements(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        VALUE result(rb_ary_new());
        VALUE result_hash;
        if (std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->use_requirements_ptr())
            for (UseRequirements::ConstIterator
                    i(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->use_requirements_ptr()->begin()),
                    i_end(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->use_requirements_ptr()->end()) ;
                    i != i_end; ++i)
            {
                result_hash = rb_hash_new();
                rb_hash_aset(result_hash, ID2SYM(rb_intern("flag")),
                    rb_str_new2(stringify(i->first).c_str()));
                rb_hash_aset(result_hash, ID2SYM(rb_intern("state")),
                        i->second == use_disabled ? Qfalse : Qtrue);

                rb_ary_push(result, result_hash);
            }
        return result;
    }
#endif

    VALUE
    package_dep_spec_version_requirements_mode(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return INT2FIX(std::static_pointer_cast<const WrappedSpec<PackageDepSpec> >(*ptr)->spec()->version_requirements_mode());
    }

    /*
     * Document-method: original_url
     *     call-seq: original_url -> String
     *
     * The original URL (that is, the text to the left of the arrow, if present,
     * or the entire text otherwise).
     */
    /*
     * Document-method: renamed_url_suffix
     *     call-seq: renamed_url_suffix -> String
     *
     * The renamed URL filename (that is, the text to the right of the arrow,
     * if present, or an empty string otherwise).
     */
    /*
     * Document-method: filename
     *     call-seq: filename -> String
     *
     * The filename (that is, the renamed URL suffix, if present, or the text
     * after the final / in the original URL otherwise).
     */
    template <std::string (FetchableURIDepSpec::* m_) () const>
    struct FetchableURIDepSpecStringValue
    {
        static VALUE
        fetch(VALUE self)
        {
            std::shared_ptr<WrappedSpecBase> * ptr;
            Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
            std::shared_ptr<const FetchableURIDepSpec> f_ptr(std::static_pointer_cast<const FetchableURIDepSpec>((*ptr)->base_spec()));
            return rb_str_new2(((f_ptr.get())->*(m_))().c_str());
        }
    };

    template <typename T_>
    struct Composite
    {
        /*
         * call-seq:
         *     each {|contents_entry| block}
         *
         * Iterate through our entries.
         */
        static VALUE
        each(VALUE self)
        {
            std::shared_ptr<WrappedSpecBase> * ptr;
            Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);

            if ((*ptr)->children())
                for (WrappedSpecBase::Children::const_iterator i((*ptr)->children()->begin()), i_end((*ptr)->children()->end()) ;
                        i != i_end ; ++i)
                {
                    std::shared_ptr<const WrappedSpecBase> * newptr(new std::shared_ptr<const WrappedSpecBase>(i->second));
                    rb_yield(Data_Wrap_Struct(i->first, 0, &Common<std::shared_ptr<const WrappedSpecBase> >::free, newptr));
                }
            return self;
        }
    };

    /*
     * call-seq:
     *     name -> String
     *
     * Fetch our set name.
     */
    VALUE
    named_set_dep_spec_name(VALUE self)
    {
        std::shared_ptr<WrappedSpecBase> * ptr;
        Data_Get_Struct(self, std::shared_ptr<WrappedSpecBase>, ptr);
        return rb_str_new2(stringify(std::static_pointer_cast<const WrappedSpec<NamedSetDepSpec> >(*ptr)->spec()->text()).c_str());
    }

    /*
     * Document-method: parse_user_package_dep_spec
     *
     * call-seq:
     *     parse_user_package_dep_spec(String, Env, Array) -> PackageDepSpec
     *     parse_user_package_dep_spec(String, Env, Array, Filter) -> PackageDepSpec
     *
     * Return a PackageDepSpec parsed from user input. The third parameter is either an empty
     * array, or can contain :allow_wildcards to allow wildcards, :throw_if_set to get a
     * GotASetNotAPackageDepSpec exception if the string is a set name and :no_disambiguation
     * to disallow disambiguation (require an explicit category). The Filter, if
     * provided, is used to restrict disambiguation as per
     * Environment#fetch_unique_qualified_package_name.
     *
     */
    VALUE paludis_parse_user_dep_spec(int argc, VALUE * argv, VALUE)
    {
        std::shared_ptr<const WrappedSpecBase> * ptr(0);

        if (argc < 3 || argc > 4)
            rb_raise(rb_eArgError, "parse_user_package_dep_spec expects three to four arguments, but got %d", argc);

        try
        {
            std::string s(StringValuePtr(argv[0]));
            std::shared_ptr<Environment> e(value_to_environment(argv[1]));

            Check_Type(argv[2], T_ARRAY);
            UserPackageDepSpecOptions o;
            for (int i(0) ; i < RARRAY_LEN(argv[2]) ; ++i)
            {
                VALUE entry(rb_ary_entry(argv[2], i));
                Check_Type(entry, T_SYMBOL);
                if (SYM2ID(entry) == rb_intern("allow_wildcards"))
                    o += updso_allow_wildcards;
                else if (SYM2ID(entry) == rb_intern("throw_if_set"))
                    o += updso_throw_if_set;
                else if (SYM2ID(entry) == rb_intern("no_disambiguation"))
                    o += updso_no_disambiguation;
                else
                    rb_raise(rb_eArgError, "Unknown parse_user_package_dep_spec option '%s'", RSTRING_PTR(rb_obj_as_string(entry)));
            }

            Filter f(
                    argc >= 4 ?
                    value_to_filter(argv[3]) :
                    filter::All()
                    );

            ptr = new std::shared_ptr<const WrappedSpecBase>(std::make_shared<WrappedSpec<PackageDepSpec>>(
                        std::make_shared<PackageDepSpec>(parse_user_package_dep_spec(s, e.get(), o, f))));
            return Data_Wrap_Struct(c_package_dep_spec, 0,
                    &Common<std::shared_ptr<const WrappedSpecBase> >::free, ptr);
        }
        catch (const std::exception & e)
        {
            delete ptr;
            exception_to_ruby_exception(e);
        }

    }

    VALUE
    slot_exact_requirement_slot(VALUE self)
    {
        std::shared_ptr<const SlotExactPartialRequirement> * ptr;
        Data_Get_Struct(self, std::shared_ptr<const SlotExactPartialRequirement>, ptr);
        return rb_str_new2(stringify((*ptr)->slot()).c_str());
    }

    void do_register_dep_spec()
    {
        /*
         * Document-class: Paludis::DepSpec
         *
         * Base class for a dependencies spec.
         */
        c_dep_spec = rb_define_class_under(c_paludis_module, "DepSpec", rb_cObject);
        rb_funcall(c_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));

        /*
         * Document-class: Paludis::AllDepSpec
         *
         * Represents a ( first second third ) or top level group of dependency specs. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_all_dep_spec = rb_define_class_under(c_paludis_module, "AllDepSpec", c_dep_spec);
        rb_funcall(c_all_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_all_dep_spec, rb_mEnumerable);
        rb_define_method(c_all_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::AnyDepSpec
         *
         * Represents a "|| ( )" dependency block. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_any_dep_spec = rb_define_class_under(c_paludis_module, "AnyDepSpec", c_dep_spec);
        rb_funcall(c_any_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_any_dep_spec, rb_mEnumerable);
        rb_define_method(c_any_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::ExactlyOneDepSpec
         *
         * Represents a "^^ ( )" dependency block. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_exactly_one_dep_spec = rb_define_class_under(c_paludis_module, "ExactlyOneDepSpec", c_dep_spec);
        rb_funcall(c_exactly_one_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_exactly_one_dep_spec, rb_mEnumerable);
        rb_define_method(c_exactly_one_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::AtMostOneDepSpec
         *
         * Represents a "?? ( )" dependency block. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_at_most_one = rb_define_class_under(c_paludis_module, "AtMostOneDepSpec", c_dep_spec);
        rb_funcall(c_at_most_one, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_at_most_one, rb_mEnumerable);
        rb_define_method(c_at_most_one, "each", template_methods, 0);

        /*
         * Document-class: Paludis::ConditionalDepSpec
         *
         * Represents a use? ( ) dependency spec. Includes
         * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
         */
        c_conditional_dep_spec = rb_define_class_under(c_paludis_module, "ConditionalDepSpec", c_dep_spec);
        rb_funcall(c_conditional_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_include_module(c_conditional_dep_spec, rb_mEnumerable);
        /*
         * Document-method: condition
         *
         * call-seq:
         *     confition -> String
         *
         * Our condition
         */
        VALUE (* conditional_dep_spec_to_s) (VALUE) = &dep_spec_to_s<ConditionalDepSpec>;
        rb_define_method(c_conditional_dep_spec, "condition", conditional_dep_spec_to_s, 0);
        rb_define_alias(c_conditional_dep_spec, "to_s", "condition");
        rb_define_method(c_conditional_dep_spec, "condition_met?",                     template_methods, 2);
        rb_define_method(c_conditional_dep_spec, "condition_meetable?",                     template_methods, 2);
        rb_define_method(c_conditional_dep_spec, "each", template_methods, 0);

        /*
         * Document-class: Paludis::StringDepSpec
         *
         * A StringDepSpec represents a non-composite dep spec with an associated piece of text.
         */
        c_string_dep_spec = rb_define_class_under(c_paludis_module, "StringDepSpec", c_dep_spec);
        rb_funcall(c_string_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_string_dep_spec, "text", string_dep_spec_text, 0);

        /*
         * Document-class: Paludis::FetchableURIDepSpec
         *
         * A FetchableURIDepSpec represents a fetchable URI spec.
         */
        c_fetchable_uri_dep_spec = rb_define_class_under(c_paludis_module, "FetchableURIDepSpec", c_string_dep_spec);
        rb_funcall(c_fetchable_uri_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* fetchable_uri_dep_spec_to_s) (VALUE) = &dep_spec_to_s<FetchableURIDepSpec>;
        rb_define_method(c_fetchable_uri_dep_spec, "to_s", fetchable_uri_dep_spec_to_s, 0);
        rb_define_method(c_fetchable_uri_dep_spec, "original_url",                template_methods, 0);
        rb_define_method(c_fetchable_uri_dep_spec, "renamed_url_suffix",                template_methods, 0);
        rb_define_method(c_fetchable_uri_dep_spec, "filename",                template_methods, 0);

        /*
         * Document-class: Paludis::SimpleURIDepSpec
         *
         * A SimpleURIDepSpec represents a simple URI spec.
         */
        c_simple_uri_dep_spec = rb_define_class_under(c_paludis_module, "SimpleURIDepSpec", c_string_dep_spec);
        rb_funcall(c_simple_uri_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* simple_uri_dep_spec_to_s) (VALUE) = &dep_spec_to_s<SimpleURIDepSpec>;
        rb_define_method(c_simple_uri_dep_spec, "to_s", simple_uri_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::LicenseDepSpec
         *
         * A LicenseDepSpec represents a license dep spec.
         */
        c_license_dep_spec = rb_define_class_under(c_paludis_module, "LicenseDepSpec", c_string_dep_spec);
        rb_funcall(c_license_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* license_dep_spec_to_s) (VALUE) = &dep_spec_to_s<LicenseDepSpec>;
        rb_define_method(c_license_dep_spec, "to_s", license_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::NamedSetDepSpec
         *
         * A NamedSetDepSpec represents a fetchable URI spec.
         */
        c_named_set_dep_spec = rb_define_class_under(c_paludis_module, "NamedSetDepSpec", c_string_dep_spec);
        rb_funcall(c_named_set_dep_spec, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        VALUE (* named_set_dep_spec_to_s) (VALUE) = &dep_spec_to_s<NamedSetDepSpec>;
        rb_define_method(c_named_set_dep_spec, "to_s", named_set_dep_spec_to_s, 0);
        rb_define_method(c_named_set_dep_spec, "name", named_set_dep_spec_name, 0);


        /*
         * Document-class: Paludis::PackageDepSpec
         *
         * A PackageDepSpec represents a package name (for example, 'app-editors/vim'),
         * possibly with associated version and SLOT restrictions. To create a PackageDepSpec,
         * use Paludis::parse_user_package_dep_spec.
         */
        c_package_dep_spec = rb_define_class_under(c_paludis_module, "PackageDepSpec", c_string_dep_spec);
        rb_define_method(c_package_dep_spec, "package", package_dep_spec_package, 0);
        rb_define_method(c_package_dep_spec, "package_name_part", package_dep_spec_package_name_part, 0);
        rb_define_method(c_package_dep_spec, "category_name_part", package_dep_spec_category_name_part, 0);
        rb_define_method(c_package_dep_spec, "slot_requirement", package_dep_spec_slot_requirement_ptr, 0);
        rb_define_method(c_package_dep_spec, "in_repository", package_dep_spec_in_repository_ptr, 0);
        rb_define_method(c_package_dep_spec, "from_repository", package_dep_spec_from_repository_ptr, 0);
        rb_define_method(c_package_dep_spec, "installable_to_repository", package_dep_spec_installable_to_repository, 0);
        rb_define_method(c_package_dep_spec, "installed_at_path", package_dep_spec_installed_at_path, 0);
        rb_define_method(c_package_dep_spec, "installable_to_path", package_dep_spec_installable_to_path, 0);
        rb_define_method(c_package_dep_spec, "version_requirements", package_dep_spec_version_requirements_ptr, 0);
        rb_define_method(c_package_dep_spec, "version_requirements_mode", package_dep_spec_version_requirements_mode, 0);
#ifdef CIARANM_REMOVED_THIS
        rb_define_method(c_package_dep_spec, "use_requirements", package_dep_spec_use_requirements, 0);
#endif
        VALUE (* package_dep_spec_to_s) (VALUE) = &dep_spec_to_s<PackageDepSpec>;
        rb_define_method(c_package_dep_spec, "to_s", package_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::PlainTextDepSpec
         *
         * A PlainTextDepSpec represents a plain text entry (for example, a URI in SRC_URI).
         */
        c_plain_text_dep_spec = rb_define_class_under(c_paludis_module, "PlainTextDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_plain_text_dep_spec, "new", template_methods, 1);
        rb_define_method(c_plain_text_dep_spec, "initialize", dep_spec_init_1, 1);
        VALUE (* plain_text_dep_spec_to_s) (VALUE) = &dep_spec_to_s<PlainTextDepSpec>;
        rb_define_method(c_plain_text_dep_spec, "to_s", plain_text_dep_spec_to_s, 0);

        /*
         * Document-class: Paludis::DependenciesLabelsDepSpec
         *
         * A DependenciesLabelsDepSpec holds dependencies labels.
         */
        c_dependencies_labels_dep_spec = rb_define_class_under(c_paludis_module, "DependenciesLabelsDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_dependencies_labels_dep_spec, "new", template_methods, 0);
        rb_define_method(c_dependencies_labels_dep_spec, "initialize", dep_spec_init_0, 0);
        VALUE (* dependencies_labels_dep_spec_to_s) (VALUE) = &dep_spec_to_s<DependenciesLabelsDepSpec>;
        rb_define_method(c_dependencies_labels_dep_spec, "to_s", dependencies_labels_dep_spec_to_s, 0);
        rb_define_method(c_dependencies_labels_dep_spec, "labels", dependencies_labels_dep_spec_labels, 0);

        /*
         * Document-class: Paludis::URILabelsDepSpec
         *
         * A URILabelsDepSpec holds URI labels.
         */
        c_uri_labels_dep_spec = rb_define_class_under(c_paludis_module, "URILabelsDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_uri_labels_dep_spec, "new", template_methods, 0);
        rb_define_method(c_uri_labels_dep_spec, "initialize", dep_spec_init_0, 0);
        VALUE (* uri_labels_dep_spec_to_s) (VALUE) = &dep_spec_to_s<URILabelsDepSpec>;
        rb_define_method(c_uri_labels_dep_spec, "to_s", uri_labels_dep_spec_to_s, 0);
        rb_define_method(c_uri_labels_dep_spec, "labels", uri_labels_dep_spec_labels, 0);

        /*
         * Document-class: Paludis::PlainTextLabelDepSpec
         *
         * A PlainTextLabelDepSpec holds a plain text label.
         */
        c_plain_text_label_dep_spec = rb_define_class_under(c_paludis_module, "PlainTextLabelDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_plain_text_label_dep_spec, "new", template_methods, 1);
        rb_define_method(c_plain_text_label_dep_spec, "initialize", dep_spec_init_1, 1);
        VALUE (* plain_text_dep_label_spec_to_s) (VALUE) = &dep_spec_to_s<PlainTextLabelDepSpec>;
        rb_define_method(c_plain_text_label_dep_spec, "to_s", plain_text_dep_label_spec_to_s, 0);

        /*
         * Document-class: Paludis::BlockDepSpec
         *
         * A BlockDepSpec represents a block on a package name (for example, 'app-editors/vim'), possibly with
         * associated version and SLOT restrictions.
         */
        c_block_dep_spec = rb_define_class_under(c_paludis_module, "BlockDepSpec", c_string_dep_spec);
        rb_define_singleton_method(c_block_dep_spec, "new", block_dep_spec_new, 2);
        rb_define_method(c_block_dep_spec, "initialize", dep_spec_init_1, 2);
        rb_define_method(c_block_dep_spec, "blocking", block_dep_spec_blocking, 0);
        VALUE (* block_dep_spec_to_s) (VALUE) = &dep_spec_to_s<BlockDepSpec>;
        rb_define_method(c_block_dep_spec, "to_s", block_dep_spec_to_s, 0);

        /*
         * Document-module: Paludis::VersionRequirementsMode
         *
         * What sort of VersionRequirements to we have.
         *
         */
        c_version_requirements_mode = rb_define_module_under(c_paludis_module, "VersionRequirementsMode");
        for (VersionRequirementsMode l(static_cast<VersionRequirementsMode>(0)), l_end(last_vr) ; l != l_end ;
                l = static_cast<VersionRequirementsMode>(static_cast<int>(l) + 1))
            rb_define_const(c_version_requirements_mode, value_case_to_RubyCase(stringify(l)).c_str(), INT2FIX(l));


        rb_define_module_function(c_paludis_module, "parse_user_package_dep_spec", paludis_parse_user_dep_spec, -1);

        /*
         * Document-class: Paludis::SlotRequirement
         *
         * A SlotRequirement
         */
        c_slot_requirement = rb_define_class_under(c_paludis_module, "SlotRequirement", rb_cObject);
        rb_funcall(c_slot_requirement, rb_intern("private_class_method"), 1, rb_str_new2("new"));
        rb_define_method(c_slot_requirement, "as_string", Common<std::shared_ptr<const SlotRequirement> >::to_s_via_ptr, 0);
        rb_define_method(c_slot_requirement, "to_s", Common<std::shared_ptr<const SlotRequirement> >::to_s_via_ptr, 0);

        /*
         * Document-class: Paludis::SlotExactPartialRequirement
         *
         * An exact slot requirement (:slot)
         */
        c_slot_exact_partial_requirement = rb_define_class_under(c_paludis_module, "SlotExactPartialRequirement", c_slot_requirement);
        rb_define_method(c_slot_exact_partial_requirement, "slot", slot_exact_requirement_slot, 0);

        /*
         * Document-class: Paludis::SlotExactFullRequirement
         *
         * An exact slot requirement (:slot/sub)
         */
        c_slot_exact_full_requirement = rb_define_class_under(c_paludis_module, "SlotExactFullRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotAnyPartialLockedRequirement
         *
         * A partial locked slot requirement (:slot=)
         */
        c_slot_any_partial_locked_requirement = rb_define_class_under(c_paludis_module, "SlotAnyPartialLockedRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotAnyAtAllLockedRequirement
         *
         * An any locked slot requirement (:=)
         */
        c_slot_any_at_all_locked_requirement = rb_define_class_under(c_paludis_module, "SlotAnyAtAllLockedRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotAnyUnlockedRequirement
         *
         * An any unlocked slot requirement (:*)
         */
        c_slot_any_unlocked_requirement = rb_define_class_under(c_paludis_module, "SlotAnyUnlockedRequirement", c_slot_requirement);

        /*
         * Document-class: Paludis::SlotUnknownRewrittenRequirement
         *
         * An unknown rewritten slot requirement (either := or :slot=)
         */
        c_slot_unknown_rewritten_requirement = rb_define_class_under(c_paludis_module, "SlotUnknownRewrittenRequirement", c_slot_requirement);
    }
}