};
#endif
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-static const string system_arch (void);
-static const string canonical_arch (const string & arch);
-
-//---------------------------------------------------------------------------
-
-const Arch * Arch::Unknown = Arch::create ("unknown");
-const Arch * Arch::Any = Arch::create ("any");
-const Arch * Arch::Noarch = Arch::create ("noarch");
-const Arch * Arch::System = Arch::create (system_arch ());
-
-//---------------------------------------------------------------------------
-// architecture stuff
-
-static const string
-canonical_arch (const string & arch)
-{
- typedef struct { char *from; char *to; } canonical;
- // convert machine string to known_arch
-static canonical canonical_archs[] = {
- { "noarch", "noarch" },
- { "unknown", "unknown" },
- { "any", "any" },
- { "all", "any" },
- { "i386", "i386" },
- { "ix86", "i386" }, /* OpenPKG uses this */
- { "i486", "i486" },
- { "i586", "i586" },
- { "i686", "i686" },
- { "x86_64", "x86_64" },
- { "ia32e", "ia32e" },
- { "athlon", "athlon" },
- { "ppc", "ppc" },
- { "ppc64", "ppc64" },
- { "s390", "s390" },
- { "s390x", "s390x" },
- { "ia64", "ia64" },
- { "sparc", "sparc" },
- { "sun4c", "sparc" },
- { "sun4d", "sparc" },
- { "sun4m", "sparc" },
- { "sparc64", "sparc64" },
- { "sun4u", "sparc64" },
- { "sparcv9", "sparc64" },
- { 0 }
-};
-
- for (canonical *ptr = canonical_archs; ptr->from; ptr++) {
- if (arch == ptr->from) {
- return ptr->to;
- }
- }
-
- return "canonical";
-}
-
-
-static const string
-system_arch (void)
-{
- static struct utsname buf;
- static bool checked = false;
-
- if (!checked) {
- if (uname (&buf) < 0) {
- return NULL;
- }
- checked = true;
- }
-
- return string (buf.machine);
-}
-
-
-//---------------------------------------------------------------------------
-
-const string
-Arch::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-const string
-Arch::toString ( const Arch & arch )
-{
- return arch._arch;
-}
-
-
-ostream &
-Arch::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream & os, const Arch & arch)
-{
- return os << arch.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Arch::Arch( const string & a)
- : _arch (a)
-{
-}
-
-
-const Arch *
-Arch::create (const string & arch)
-{
-typedef std::map<const std::string, const Arch *> ArchTable;
-
- static ArchTable table;
- ArchTable::iterator pos = table.find (arch);
- if (pos != table.end()) {
- return pos->second;
- }
- const Arch *new_arch = new Arch(canonical_arch (arch));
- table.insert (ArchTable::value_type (arch, new_arch));
-
- return new_arch;
-}
-
-
-ArchList
-Arch::getCompatList () const
-{
- typedef struct {
- const char *arch;
- const char *compat_arch;
- } ArchAndCompatArch;
-
- /* _NOARCH should never be listed in this table (other than as the
- * terminator), as it will automatically be added. Every architecture
- * is implicitly compatible with itself. Compatible architectures
- * should be listed in most-preferred to least-preferred order. */
-
- static ArchAndCompatArch compat_table[] = {
- { "i486", "i386" },
- { "i586", "i486" },
- { "i586", "i386" },
- { "i686", "i586" },
- { "i686", "i486" },
- { "i686", "i386" },
- { "athlon", "i686" },
- { "athlon", "i586" },
- { "athlon", "i486" },
- { "athlon", "i386" },
- { "x86_64", "i686" },
- { "x86_64", "i586" },
- { "x86_64", "i486" },
- { "x86_64", "i386" },
- { "x86_64", "athlon" },
- { "x86_64", "ia32e" },
- { "ppc64", "ppc" },
- { "s390x", "s390" },
- { "sparc64", "sparc" },
- { 0 }
- };
-
-
- ArchAndCompatArch *iter;
- ArchList ret;
-
- ret.push_back (this); // be compatible with yourself
-
- iter = compat_table;
- while (iter->arch != NULL) {
- if (_arch == iter->arch) {
- ret.push_back (create (iter->compat_arch));
- }
- iter++;
- }
-
- return ret;
-}
-
-
-int
-Arch::getCompatScore (const ArchList & archlist) const
-{
- int score = 0;
-
- for (ArchList::const_iterator iter = archlist.begin(); iter != archlist.end(); iter++) {
- if (*iter == this) {
- return score;
- }
- score++;
- }
- return -1;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ static const string system_arch (void);
+ static const string canonical_arch (const string & arch);
+
+ //---------------------------------------------------------------------------
+
+ const Arch * Arch::Unknown = Arch::create ("unknown");
+ const Arch * Arch::Any = Arch::create ("any");
+ const Arch * Arch::Noarch = Arch::create ("noarch");
+ const Arch * Arch::System = Arch::create (system_arch ());
+
+ //---------------------------------------------------------------------------
+ // architecture stuff
+
+ static const string
+ canonical_arch (const string & arch)
+ {
+ typedef struct { char *from; char *to; } canonical;
+ // convert machine string to known_arch
+ static canonical canonical_archs[] = {
+ { "noarch", "noarch" },
+ { "unknown", "unknown" },
+ { "any", "any" },
+ { "all", "any" },
+ { "i386", "i386" },
+ { "ix86", "i386" }, /* OpenPKG uses this */
+ { "i486", "i486" },
+ { "i586", "i586" },
+ { "i686", "i686" },
+ { "x86_64", "x86_64" },
+ { "ia32e", "ia32e" },
+ { "athlon", "athlon" },
+ { "ppc", "ppc" },
+ { "ppc64", "ppc64" },
+ { "s390", "s390" },
+ { "s390x", "s390x" },
+ { "ia64", "ia64" },
+ { "sparc", "sparc" },
+ { "sun4c", "sparc" },
+ { "sun4d", "sparc" },
+ { "sun4m", "sparc" },
+ { "sparc64", "sparc64" },
+ { "sun4u", "sparc64" },
+ { "sparcv9", "sparc64" },
+ { 0 }
+ };
+
+ for (canonical *ptr = canonical_archs; ptr->from; ptr++) {
+ if (arch == ptr->from) {
+ return ptr->to;
+ }
+ }
+
+ return "canonical";
+ }
+
+
+ static const string
+ system_arch (void)
+ {
+ static struct utsname buf;
+ static bool checked = false;
+
+ if (!checked) {
+ if (uname (&buf) < 0) {
+ return NULL;
+ }
+ checked = true;
+ }
+
+ return string (buf.machine);
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ const string
+ Arch::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ const string
+ Arch::toString ( const Arch & arch )
+ {
+ return arch._arch;
+ }
+
+
+ ostream &
+ Arch::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream & os, const Arch & arch)
+ {
+ return os << arch.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Arch::Arch( const string & a)
+ : _arch (a)
+ {
+ }
+
+
+ const Arch *
+ Arch::create (const string & arch)
+ {
+ typedef std::map<const std::string, const Arch *> ArchTable;
+
+ static ArchTable table;
+ ArchTable::iterator pos = table.find (arch);
+ if (pos != table.end()) {
+ return pos->second;
+ }
+ const Arch *new_arch = new Arch(canonical_arch (arch));
+ table.insert (ArchTable::value_type (arch, new_arch));
+
+ return new_arch;
+ }
+
+
+ ArchList
+ Arch::getCompatList () const
+ {
+ typedef struct {
+ const char *arch;
+ const char *compat_arch;
+ } ArchAndCompatArch;
+
+ /* _NOARCH should never be listed in this table (other than as the
+ * terminator), as it will automatically be added. Every architecture
+ * is implicitly compatible with itself. Compatible architectures
+ * should be listed in most-preferred to least-preferred order. */
+
+ static ArchAndCompatArch compat_table[] = {
+ { "i486", "i386" },
+ { "i586", "i486" },
+ { "i586", "i386" },
+ { "i686", "i586" },
+ { "i686", "i486" },
+ { "i686", "i386" },
+ { "athlon", "i686" },
+ { "athlon", "i586" },
+ { "athlon", "i486" },
+ { "athlon", "i386" },
+ { "x86_64", "i686" },
+ { "x86_64", "i586" },
+ { "x86_64", "i486" },
+ { "x86_64", "i386" },
+ { "x86_64", "athlon" },
+ { "x86_64", "ia32e" },
+ { "ppc64", "ppc" },
+ { "s390x", "s390" },
+ { "sparc64", "sparc" },
+ { 0 }
+ };
+
+
+ ArchAndCompatArch *iter;
+ ArchList ret;
+
+ ret.push_back (this); // be compatible with yourself
+
+ iter = compat_table;
+ while (iter->arch != NULL) {
+ if (_arch == iter->arch) {
+ ret.push_back (create (iter->compat_arch));
+ }
+ iter++;
+ }
+
+ return ret;
+ }
+
+
+ int
+ Arch::getCompatScore (const ArchList & archlist) const
+ {
+ int score = 0;
+
+ for (ArchList::const_iterator iter = archlist.begin(); iter != archlist.end(); iter++) {
+ if (*iter == this) {
+ return score;
+ }
+ score++;
+ }
+ return -1;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <map>
#include <string>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-class Arch;
-typedef std::list<const Arch *> ArchList;
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Arch
-/**
- *
- **/
-class Arch {
-
- private:
-
- std::string _arch;
-
- explicit Arch( const std::string & a = "" );
-
- public:
- static const Arch *Any;
- static const Arch *Unknown;
- static const Arch *Noarch;
- static const Arch *System;
-
- static const Arch *create ( const std::string & arch ); // factory
- virtual ~Arch() {};
-
- // ---------------------------------- I/O
-
- static const std::string toString ( const Arch & arch );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<< ( std::ostream &, const Arch & arch);
-
- const std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- bool isAny (void) const { return this == Any; }
- bool isUnknown (void) const { return this == Unknown; }
- bool isNoarch (void) const { return this == Noarch; }
-
- ArchList getCompatList () const;
- int getCompatScore (const ArchList & archlist) const;
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ class Arch;
+ typedef std::list<const Arch *> ArchList;
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Arch
+ /**
+ *
+ **/
+ class Arch {
+
+ private:
+
+ std::string _arch;
+
+ explicit Arch( const std::string & a = "" );
+
+ public:
+ static const Arch *Any;
+ static const Arch *Unknown;
+ static const Arch *Noarch;
+ static const Arch *System;
+
+ static const Arch *create ( const std::string & arch ); // factory
+ virtual ~Arch() {};
+
+ // ---------------------------------- I/O
+
+ static const std::string toString ( const Arch & arch );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<< ( std::ostream &, const Arch & arch);
+
+ const std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ bool isAny (void) const { return this == Any; }
+ bool isUnknown (void) const { return this == Unknown; }
+ bool isNoarch (void) const { return this == Noarch; }
+
+ ArchList getCompatList () const;
+ int getCompatScore (const ArchList & archlist) const;
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Arch_h
#include <zypp/solver/detail/Channel.h>
#include <zypp/solver/detail/World.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(Channel);
-
-//---------------------------------------------------------------------------
-
-int Channel::_fake_id = 1;
-
-//---------------------------------------------------------------------------
-
-string
-Channel::asString ( void ) const
-{
- if (this == NULL) fprintf (stderr, "Channel::asString NULL\n");
- return toString (*this);
-}
-
-
-string
-Channel::toString ( const Channel & channel )
-{
- string res ("<channel '");
- res += "Type: ";
- switch (channel.type()) {
- case CHANNEL_TYPE_ANY: res += "any"; break;
- case CHANNEL_TYPE_SYSTEM: res += "system"; break;
- case CHANNEL_TYPE_NONSYSTEM: res += "non-system"; break;
-
- case CHANNEL_TYPE_UNKNOWN: res += "unknown"; break;
- case CHANNEL_TYPE_HELIX: res += "helix"; break;
- case CHANNEL_TYPE_DEBIAN: res += "debian"; break;
- case CHANNEL_TYPE_APTRPM: res += "apt-rpm"; break;
- case CHANNEL_TYPE_YAST: res += "yast"; break;
- case CHANNEL_TYPE_YUM: res += "yum"; break;
- }
- res += ", ";
-
- res += "Id: ";
- res += channel.id();
- if (channel.legacyId() != NULL
- && (*(channel.legacyId()) != 0)) {
- res += ", LegacyId: ";
- res += channel.legacyId();
- }
- res += ", Name: ";
- res += channel.name();
- res += ", Alias: ";
- res += channel.alias();
-
- if (channel.description() != NULL) {
- res += ", Description: ";
- res += channel.description();
- }
-
- res += ", Priority: ";
- res += stringutil::numstring (channel.priority());
- res += ", PriorityUnsubscribed: ";
- res += stringutil::numstring (channel.priorityUnsubscribed());
-
- if (channel.path() != NULL) {
- res += ", Path: ";
- res += channel.path();
- }
- if (channel.filePath() != NULL) {
- res += ", FilePath: ";
- res += channel.filePath();
- }
- if (channel.iconFile() != NULL) {
- res += ", IconFile: ";
- res += channel.iconFile();
- }
- if (channel.pkginfoFile() != NULL) {
- res += ", PkginfoFile: ";
- res += channel.pkginfoFile();
- }
- // list<char *> *_distro_targets; /* List of targets (char *) for this channel */
-
- res += ", LastUpdate: ";
- res += stringutil::numstring(channel.lastUpdate());
-
- if (channel.system()) res += ", System! ";
- if (channel.hidden()) res += ", Hidden! ";
- if (channel.immutable()) res += ", Immutable! ";
-
- return res + "'>";
-}
-
-
-ostream &
-Channel::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Channel& channel)
-{
- return os << channel.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Channel::Channel(const string & id, const string & name, const string & alias, const string & description)
- : _world (NULL)
- , _last_update (0)
- , _system (false)
- , _hidden (false)
- , _immutable (false)
-{
- if (id.empty()) {
- _id = stringutil::form( "fake-id-%d", _fake_id++).c_str();
- }
- else {
- _id = id;
- }
-
- if (name.empty()) {
- _name = "Unnamed Channel";
- }
- else {
- _name = name;
- }
-
- if (alias.empty()) {
- _alias = name;
- }
- else {
- _alias = alias;
- }
-
- if (description.empty()) {
- _description = "No description available.";
- }
- else {
- _description = description;
- }
-
- _type = CHANNEL_TYPE_UNKNOWN;
-
- _priority = -1;
- _priority_unsubscribed = -1;
-
-// if (getenv ("RC_SPEW")) fprintf (stderr, "Channel() [%p] (%s)\n", this, asString().c_str());
-}
-
-
-Channel::Channel (const XmlNodePtr node, int *subscribed, WorldPtr world)
- : _world (world)
- , _last_update (0)
- , _system (false)
- , _hidden (false)
- , _immutable (false)
-{
- static unsigned int dummy_id = 0xdeadbeef;
- const char *subscribed_str;
- const char *priority_str;
- const char *priority_unsubscribed_str;
-
- _name = node->getProp ("name");
- _alias = node->getProp ("alias");
-
- _id = node->getProp ("id");
- if (_id.empty()) {
- char *temp;
- asprintf (&temp, "dummy:%d", dummy_id);
- _id = temp;
- ++dummy_id;
- }
-
- subscribed_str = node->getProp ("subscribed");
- *subscribed = subscribed_str ? atoi (subscribed_str) : 0;
-
- priority_str = node->getProp ("priority_base");
- priority_unsubscribed_str = node->getProp ("priority_unsubd");
-
- _priority = priority_str ? atoi (priority_str) : 0;
- _priority_unsubscribed = priority_unsubscribed_str ? atoi (priority_unsubscribed_str) : 0;
-
- free ((void *)subscribed_str);
- free ((void *)priority_str);
- free ((void *)priority_unsubscribed_str);
-
-// if (getenv ("RC_SPEW")) fprintf (stderr, "Channel(xml) [%p] (%s)\n", this, asString().c_str());
-}
-
-
-Channel::~Channel()
-{
-}
-
-
-#if 0
-xmlNode *
-rc_channel_to_xml_node (RCChannel *channel)
-{
- xmlNode *node;
- char tmp[128];
-
- g_return_val_if_fail (channel != NULL, NULL);
-
- node = xmlNewNode (NULL, "channel");
-
- xmlNewProp (node, "id", rc_channel_get_id (channel));
-
- xmlNewProp (node, "name", rc_channel_get_name (channel));
-
- if (rc_channel_get_alias (channel))
- xmlNewProp (node, "alias", rc_channel_get_alias (channel));
-
- sprintf (tmp, "%d", rc_channel_is_subscribed (channel) ? 1 : 0);
- xmlNewProp (node, "subscribed", tmp);
-
- sprintf (tmp, "%d", rc_channel_get_priority (channel, true));
- xmlNewProp (node, "priority_base", tmp);
-
- sprintf (tmp, "%d", rc_channel_get_priority (channel, false));
- xmlNewProp (node, "priority_unsubd", tmp);
-
- return node;
-}
-#endif
-
-
-bool
-Channel::isSubscribed (void) const
-{
- if (_world == NULL)
- fprintf (stderr, "Channel::isSubscribed() without world\n");
- return _world->isSubscribed (this);
-}
-
-
-void
-Channel::setSubscription (bool subscribed)
-{
- if (_world == NULL)
- fprintf (stderr, "Channel::setSubscription() without world\n");
- _world->setSubscription (this, subscribed);
-}
-
-
-int
-Channel::priorityParse (const char *priority_cptr) const
-{
-#define DEFAULT_CHANNEL_PRIORITY 1600
-
- typedef struct {
- const char *str;
- int priority;
- } ChannelPriorityPair;
-
- ChannelPriorityPair channel_priority_table[] = {
- { "private", 6400 },
- { "ximian", 3200 },
- { "distro", 1600 },
- { "third_party", 800 },
- { "preview", 400 },
- { "untested", 200 },
- { "snapshot", 100 },
- { NULL, 0 }
- };
-
- const char *c;
- int i;
- bool is_numeric = true;
-
- if (priority_cptr && *priority_cptr) {
- c = priority_cptr;
- while (*c && is_numeric) {
- if (! isdigit (*c))
- is_numeric = false;
- c++;
- }
- if (is_numeric) {
- return atoi (priority_cptr);
- }
-
- for (i=0; channel_priority_table[i].str != NULL; ++i) {
- if (! strcasecmp (channel_priority_table[i].str, priority_cptr))
- return channel_priority_table[i].priority;
- }
-
- }
-
- return DEFAULT_CHANNEL_PRIORITY;
-}
-
-
-bool
-Channel::isWildcard (void) const
-{
- return _type == CHANNEL_TYPE_SYSTEM
- || _type == CHANNEL_TYPE_NONSYSTEM
- || _type == CHANNEL_TYPE_ANY;
-}
-
-
-bool
-Channel::equals (const Channel & channel) const
-{
- return equals (&channel);
-}
-
-bool
-Channel::equals (constChannelPtr channel) const
-{
- if (_type == CHANNEL_TYPE_ANY
- || channel->_type == CHANNEL_TYPE_ANY) {
- return true;
- }
-
- if (isWildcard () && channel->isWildcard ()) {
- return this == channel;
- }
-
- /* So at this point we know that between a and b there is
- at most one wildcard. */
-
- if (_type == CHANNEL_TYPE_SYSTEM) {
- return channel->system();
- }
- else if (_type == CHANNEL_TYPE_NONSYSTEM) {
- return !channel->system();
- }
-
- if (channel->_type == CHANNEL_TYPE_SYSTEM) {
- return system();
- }
- else if (channel->_type == CHANNEL_TYPE_NONSYSTEM) {
- return !system();
- }
-
- return hasEqualId (channel);
-}
-
-
-bool
-Channel::hasEqualId (const Channel & channel) const
-{
- return hasEqualId (&channel);
-}
-
-
-bool
-Channel::hasEqualId (constChannelPtr channel) const
-{
- return (channel->id () == _id);
-}
-
-
-void
-Channel::setPriorities (int subscribed_priority, int unsubscribed_priority)
-{
- if (immutable()) return;
-
- _priority = subscribed_priority;
- _priority_unsubscribed = unsubscribed_priority;
-}
-
-
-int
-Channel::getPriority(bool is_subscribed) const
-{
-#define UNSUBSCRIBED_CHANNEL_ADJUSTMENT(x) ((x)/2)
-
- int priority;
-
- priority = _priority;
- if (priority <= 0)
- priority = DEFAULT_CHANNEL_PRIORITY;
-
- if (!is_subscribed) {
- if (_priority_unsubscribed > 0) {
- priority = _priority_unsubscribed;
- } else {
- priority = UNSUBSCRIBED_CHANNEL_ADJUSTMENT (priority);
- }
- }
-
- return priority;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(Channel);
+
+ //---------------------------------------------------------------------------
+
+ int Channel::_fake_id = 1;
+
+ //---------------------------------------------------------------------------
+
+ string
+ Channel::asString ( void ) const
+ {
+ if (this == NULL) fprintf (stderr, "Channel::asString NULL\n");
+ return toString (*this);
+ }
+
+
+ string
+ Channel::toString ( const Channel & channel )
+ {
+ string res ("<channel '");
+ res += "Type: ";
+ switch (channel.type()) {
+ case CHANNEL_TYPE_ANY: res += "any"; break;
+ case CHANNEL_TYPE_SYSTEM: res += "system"; break;
+ case CHANNEL_TYPE_NONSYSTEM: res += "non-system"; break;
+
+ case CHANNEL_TYPE_UNKNOWN: res += "unknown"; break;
+ case CHANNEL_TYPE_HELIX: res += "helix"; break;
+ case CHANNEL_TYPE_DEBIAN: res += "debian"; break;
+ case CHANNEL_TYPE_APTRPM: res += "apt-rpm"; break;
+ case CHANNEL_TYPE_YAST: res += "yast"; break;
+ case CHANNEL_TYPE_YUM: res += "yum"; break;
+ }
+ res += ", ";
+
+ res += "Id: ";
+ res += channel.id();
+ if (channel.legacyId() != NULL
+ && (*(channel.legacyId()) != 0)) {
+ res += ", LegacyId: ";
+ res += channel.legacyId();
+ }
+ res += ", Name: ";
+ res += channel.name();
+ res += ", Alias: ";
+ res += channel.alias();
+
+ if (channel.description() != NULL) {
+ res += ", Description: ";
+ res += channel.description();
+ }
+
+ res += ", Priority: ";
+ res += stringutil::numstring (channel.priority());
+ res += ", PriorityUnsubscribed: ";
+ res += stringutil::numstring (channel.priorityUnsubscribed());
+
+ if (channel.path() != NULL) {
+ res += ", Path: ";
+ res += channel.path();
+ }
+ if (channel.filePath() != NULL) {
+ res += ", FilePath: ";
+ res += channel.filePath();
+ }
+ if (channel.iconFile() != NULL) {
+ res += ", IconFile: ";
+ res += channel.iconFile();
+ }
+ if (channel.pkginfoFile() != NULL) {
+ res += ", PkginfoFile: ";
+ res += channel.pkginfoFile();
+ }
+ // list<char *> *_distro_targets; /* List of targets (char *) for this channel */
+
+ res += ", LastUpdate: ";
+ res += stringutil::numstring(channel.lastUpdate());
+
+ if (channel.system()) res += ", System! ";
+ if (channel.hidden()) res += ", Hidden! ";
+ if (channel.immutable()) res += ", Immutable! ";
+
+ return res + "'>";
+ }
+
+
+ ostream &
+ Channel::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Channel& channel)
+ {
+ return os << channel.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Channel::Channel(const string & id, const string & name, const string & alias, const string & description)
+ : _world (NULL)
+ , _last_update (0)
+ , _system (false)
+ , _hidden (false)
+ , _immutable (false)
+ {
+ if (id.empty()) {
+ _id = stringutil::form( "fake-id-%d", _fake_id++).c_str();
+ }
+ else {
+ _id = id;
+ }
+
+ if (name.empty()) {
+ _name = "Unnamed Channel";
+ }
+ else {
+ _name = name;
+ }
+
+ if (alias.empty()) {
+ _alias = name;
+ }
+ else {
+ _alias = alias;
+ }
+
+ if (description.empty()) {
+ _description = "No description available.";
+ }
+ else {
+ _description = description;
+ }
+
+ _type = CHANNEL_TYPE_UNKNOWN;
+
+ _priority = -1;
+ _priority_unsubscribed = -1;
+
+ // if (getenv ("RC_SPEW")) fprintf (stderr, "Channel() [%p] (%s)\n", this, asString().c_str());
+ }
+
+
+ Channel::Channel (const XmlNodePtr node, int *subscribed, WorldPtr world)
+ : _world (world)
+ , _last_update (0)
+ , _system (false)
+ , _hidden (false)
+ , _immutable (false)
+ {
+ static unsigned int dummy_id = 0xdeadbeef;
+ const char *subscribed_str;
+ const char *priority_str;
+ const char *priority_unsubscribed_str;
+
+ _name = node->getProp ("name");
+ _alias = node->getProp ("alias");
+
+ _id = node->getProp ("id");
+ if (_id.empty()) {
+ char *temp;
+ asprintf (&temp, "dummy:%d", dummy_id);
+ _id = temp;
+ ++dummy_id;
+ }
+
+ subscribed_str = node->getProp ("subscribed");
+ *subscribed = subscribed_str ? atoi (subscribed_str) : 0;
+
+ priority_str = node->getProp ("priority_base");
+ priority_unsubscribed_str = node->getProp ("priority_unsubd");
+
+ _priority = priority_str ? atoi (priority_str) : 0;
+ _priority_unsubscribed = priority_unsubscribed_str ? atoi (priority_unsubscribed_str) : 0;
+
+ free ((void *)subscribed_str);
+ free ((void *)priority_str);
+ free ((void *)priority_unsubscribed_str);
+
+ // if (getenv ("RC_SPEW")) fprintf (stderr, "Channel(xml) [%p] (%s)\n", this, asString().c_str());
+ }
+
+
+ Channel::~Channel()
+ {
+ }
+
+
+ #if 0
+ xmlNode *
+ rc_channel_to_xml_node (RCChannel *channel)
+ {
+ xmlNode *node;
+ char tmp[128];
+
+ g_return_val_if_fail (channel != NULL, NULL);
+
+ node = xmlNewNode (NULL, "channel");
+
+ xmlNewProp (node, "id", rc_channel_get_id (channel));
+
+ xmlNewProp (node, "name", rc_channel_get_name (channel));
+
+ if (rc_channel_get_alias (channel))
+ xmlNewProp (node, "alias", rc_channel_get_alias (channel));
+
+ sprintf (tmp, "%d", rc_channel_is_subscribed (channel) ? 1 : 0);
+ xmlNewProp (node, "subscribed", tmp);
+
+ sprintf (tmp, "%d", rc_channel_get_priority (channel, true));
+ xmlNewProp (node, "priority_base", tmp);
+
+ sprintf (tmp, "%d", rc_channel_get_priority (channel, false));
+ xmlNewProp (node, "priority_unsubd", tmp);
+
+ return node;
+ }
+ #endif
+
+
+ bool
+ Channel::isSubscribed (void) const
+ {
+ if (_world == NULL)
+ fprintf (stderr, "Channel::isSubscribed() without world\n");
+ return _world->isSubscribed (this);
+ }
+
+
+ void
+ Channel::setSubscription (bool subscribed)
+ {
+ if (_world == NULL)
+ fprintf (stderr, "Channel::setSubscription() without world\n");
+ _world->setSubscription (this, subscribed);
+ }
+
+
+ int
+ Channel::priorityParse (const char *priority_cptr) const
+ {
+ #define DEFAULT_CHANNEL_PRIORITY 1600
+
+ typedef struct {
+ const char *str;
+ int priority;
+ } ChannelPriorityPair;
+
+ ChannelPriorityPair channel_priority_table[] = {
+ { "private", 6400 },
+ { "ximian", 3200 },
+ { "distro", 1600 },
+ { "third_party", 800 },
+ { "preview", 400 },
+ { "untested", 200 },
+ { "snapshot", 100 },
+ { NULL, 0 }
+ };
+
+ const char *c;
+ int i;
+ bool is_numeric = true;
+
+ if (priority_cptr && *priority_cptr) {
+ c = priority_cptr;
+ while (*c && is_numeric) {
+ if (! isdigit (*c))
+ is_numeric = false;
+ c++;
+ }
+ if (is_numeric) {
+ return atoi (priority_cptr);
+ }
+
+ for (i=0; channel_priority_table[i].str != NULL; ++i) {
+ if (! strcasecmp (channel_priority_table[i].str, priority_cptr))
+ return channel_priority_table[i].priority;
+ }
+
+ }
+
+ return DEFAULT_CHANNEL_PRIORITY;
+ }
+
+
+ bool
+ Channel::isWildcard (void) const
+ {
+ return _type == CHANNEL_TYPE_SYSTEM
+ || _type == CHANNEL_TYPE_NONSYSTEM
+ || _type == CHANNEL_TYPE_ANY;
+ }
+
+
+ bool
+ Channel::equals (const Channel & channel) const
+ {
+ return equals (&channel);
+ }
+
+ bool
+ Channel::equals (constChannelPtr channel) const
+ {
+ if (_type == CHANNEL_TYPE_ANY
+ || channel->_type == CHANNEL_TYPE_ANY) {
+ return true;
+ }
+
+ if (isWildcard () && channel->isWildcard ()) {
+ return this == channel;
+ }
+
+ /* So at this point we know that between a and b there is
+ at most one wildcard. */
+
+ if (_type == CHANNEL_TYPE_SYSTEM) {
+ return channel->system();
+ }
+ else if (_type == CHANNEL_TYPE_NONSYSTEM) {
+ return !channel->system();
+ }
+
+ if (channel->_type == CHANNEL_TYPE_SYSTEM) {
+ return system();
+ }
+ else if (channel->_type == CHANNEL_TYPE_NONSYSTEM) {
+ return !system();
+ }
+
+ return hasEqualId (channel);
+ }
+
+
+ bool
+ Channel::hasEqualId (const Channel & channel) const
+ {
+ return hasEqualId (&channel);
+ }
+
+
+ bool
+ Channel::hasEqualId (constChannelPtr channel) const
+ {
+ return (channel->id () == _id);
+ }
+
+
+ void
+ Channel::setPriorities (int subscribed_priority, int unsubscribed_priority)
+ {
+ if (immutable()) return;
+
+ _priority = subscribed_priority;
+ _priority_unsubscribed = unsubscribed_priority;
+ }
+
+
+ int
+ Channel::getPriority(bool is_subscribed) const
+ {
+ #define UNSUBSCRIBED_CHANNEL_ADJUSTMENT(x) ((x)/2)
+
+ int priority;
+
+ priority = _priority;
+ if (priority <= 0)
+ priority = DEFAULT_CHANNEL_PRIORITY;
+
+ if (!is_subscribed) {
+ if (_priority_unsubscribed > 0) {
+ priority = _priority_unsubscribed;
+ } else {
+ priority = UNSUBSCRIBED_CHANNEL_ADJUSTMENT (priority);
+ }
+ }
+
+ return priority;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/WorldPtr.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-typedef std::list<ChannelPtr> ChannelList;
-
-typedef bool (*ChannelFn) (constChannelPtr channel, void *data);
-typedef bool (*ChannelAndSubscribedFn) (ChannelPtr channel, bool flag, void *data);
-
-typedef enum {
-
- CHANNEL_TYPE_ANY = 0,
- CHANNEL_TYPE_SYSTEM,
- CHANNEL_TYPE_NONSYSTEM,
-
- CHANNEL_TYPE_UNKNOWN,
- CHANNEL_TYPE_HELIX,
- CHANNEL_TYPE_DEBIAN,
- CHANNEL_TYPE_APTRPM,
- CHANNEL_TYPE_YAST,
- CHANNEL_TYPE_YUM
-
-} ChannelType;
-
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Channel
-/**
- *
- **/
-
-class Channel : public CountedRep {
- REP_BODY(Channel);
-
- private:
- ChannelType _type;
-
- static int _fake_id;
-
- WorldPtr _world;
-
- std::string _id;
- std::string _legacy_id; // Old ID for RCE servers
-
- std::string _name;
- std::string _alias;
- std::string _description;
- // priority if channel is...
- int _priority; // subscribed
- int _priority_unsubscribed; // unsubscribed
-
- std::string _path;
- std::string _file_path;
- std::string _icon_file;
- std::string _pkginfo_file;
-
-// std::list<std::string > *_distro_targets; /* List of targets (std::string ) for this channel */
-
- time_t _last_update;
-
- bool _system;
- bool _hidden;
- bool _immutable;
-
- public:
-
- Channel (ChannelType type) : _type (type), _world(NULL) {}
-
- Channel(const std::string & id = "", const std::string & name = "", const std::string & alias = "", const std::string & description = "");
- Channel(const XmlNodePtr node, int *subscribed, WorldPtr world); //RCChannel *rc_channel_from_xml_node (xmlNode *channel_node);
-
- virtual ~Channel();
-
- // ---------------------------------- I/O
-
- const XmlNodePtr asXmlNode (void) const; // rc_channel_to_xml_node
-
- static std::string toString ( const Channel & edition );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Channel& );
-
- std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- ChannelType type(void) const { return _type; }
- void setType (ChannelType type) { _type = type; }
-
- const char *id (void) const { return _id.c_str(); }
- void setId (const char *id) { _id = std::string (id); }
-
- WorldPtr world (void) const { return _world; }
- void setWorld (WorldPtr world) { _world = world; }
-
- const char *legacyId (void) const { return _legacy_id.c_str(); } // Old ID for RCE servers
- void setLegacyId (const char *legacy_id) { _legacy_id = std::string (legacy_id); }
-
- const char *name (void) const { return _name.c_str(); }
- void setName (const char *name) { _name = std::string (name); }
-
- const char *alias (void) const { return _alias.c_str(); }
- void setAlias (const char *alias) { _alias = std::string (alias); }
-
- const char *description (void) const { return _description.c_str(); }
- void setDescription (const char *description) { _description = std::string (description); }
-
- int priority (void) const { return _priority; }
- void setPriority (int priority) { _priority = priority; }
-
- int priorityUnsubscribed (void) const { return _priority_unsubscribed; }
- void setPriorityUnsubscribed (int priority_unsubscribed) { _priority_unsubscribed = priority_unsubscribed; }
-
- const char *path (void) const { return _path.c_str(); }
- void setPath (const char *path) { _path = std::string (path); }
-
- const char *filePath (void) const { return _file_path.c_str(); }
- void setFilePath (const char *file_path) { _file_path = std::string (file_path); }
-
- const char *iconFile (void) const { return _icon_file.c_str(); }
- void setIconFile (const char *icon_file) { _icon_file = std::string (icon_file); }
-
- const char *pkginfoFile (void) const { return _pkginfo_file.c_str(); }
- void setPkginfoFile (const char *pkginfo_file) { _pkginfo_file = std::string (pkginfo_file); }
-
-// const std::list<char *> *distroTargets (void) const { return _distro_targets; }
-// void setDistroTargets (const std::list<char *> *distro_targets) { _distro_targets = distro_targets; }
-
- time_t lastUpdate (void) const { return _last_update; }
- void setLastUpdate (time_t last_update) { _last_update = last_update; }
-
- bool system (void) const { return _system; }
- void setSystem (bool system) { _system = system; }
- bool hidden (void) const { return _hidden; }
- void setHidden (bool hidden) { _hidden = hidden; }
- bool immutable (void) const { return _immutable; }
- void setImmutable (bool immutable) { _immutable = immutable; }
-
- //-----------------------------------------------------------------------
-
- bool isWildcard (void) const;
-
- virtual bool equals (const Channel & channel) const;
- virtual bool equals (constChannelPtr channel) const;
- bool hasEqualId (const Channel & channel) const;
- bool hasEqualId (constChannelPtr channel) const;
-
- //RCResItemSList *rc_channel_get_resItems (RCChannel *channel);
-
- // Distro target functions
-
- void addDistroTarget (const char *target);
- bool hasDistroTarget (const char *target) const;
-
- // Subscription management
-
- bool isSubscribed (void) const;
- void setSubscription (bool subscribed);
-
- int priorityParse (const char *priority_cptr) const;
- void setPriorities (int subd_priority, int unsubd_priority);
- int getPriority (bool is_subscribed) const;
-};
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef std::list<ChannelPtr> ChannelList;
+
+ typedef bool (*ChannelFn) (constChannelPtr channel, void *data);
+ typedef bool (*ChannelAndSubscribedFn) (ChannelPtr channel, bool flag, void *data);
+
+ typedef enum {
+
+ CHANNEL_TYPE_ANY = 0,
+ CHANNEL_TYPE_SYSTEM,
+ CHANNEL_TYPE_NONSYSTEM,
+
+ CHANNEL_TYPE_UNKNOWN,
+ CHANNEL_TYPE_HELIX,
+ CHANNEL_TYPE_DEBIAN,
+ CHANNEL_TYPE_APTRPM,
+ CHANNEL_TYPE_YAST,
+ CHANNEL_TYPE_YUM
+
+ } ChannelType;
+
+ ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Channel
+ /**
+ *
+ **/
+
+ class Channel : public CountedRep {
+ REP_BODY(Channel);
+
+ private:
+ ChannelType _type;
+
+ static int _fake_id;
+
+ WorldPtr _world;
+
+ std::string _id;
+ std::string _legacy_id; // Old ID for RCE servers
+
+ std::string _name;
+ std::string _alias;
+ std::string _description;
+ // priority if channel is...
+ int _priority; // subscribed
+ int _priority_unsubscribed; // unsubscribed
+
+ std::string _path;
+ std::string _file_path;
+ std::string _icon_file;
+ std::string _pkginfo_file;
+
+ // std::list<std::string > *_distro_targets; /* List of targets (std::string ) for this channel */
+
+ time_t _last_update;
+
+ bool _system;
+ bool _hidden;
+ bool _immutable;
+
+ public:
+
+ Channel (ChannelType type) : _type (type), _world(NULL) {}
+
+ Channel(const std::string & id = "", const std::string & name = "", const std::string & alias = "", const std::string & description = "");
+ Channel(const XmlNodePtr node, int *subscribed, WorldPtr world); //RCChannel *rc_channel_from_xml_node (xmlNode *channel_node);
+
+ virtual ~Channel();
+
+ // ---------------------------------- I/O
+
+ const XmlNodePtr asXmlNode (void) const; // rc_channel_to_xml_node
+
+ static std::string toString ( const Channel & edition );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Channel& );
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ ChannelType type(void) const { return _type; }
+ void setType (ChannelType type) { _type = type; }
+
+ const char *id (void) const { return _id.c_str(); }
+ void setId (const char *id) { _id = std::string (id); }
+
+ WorldPtr world (void) const { return _world; }
+ void setWorld (WorldPtr world) { _world = world; }
+
+ const char *legacyId (void) const { return _legacy_id.c_str(); } // Old ID for RCE servers
+ void setLegacyId (const char *legacy_id) { _legacy_id = std::string (legacy_id); }
+
+ const char *name (void) const { return _name.c_str(); }
+ void setName (const char *name) { _name = std::string (name); }
+
+ const char *alias (void) const { return _alias.c_str(); }
+ void setAlias (const char *alias) { _alias = std::string (alias); }
+
+ const char *description (void) const { return _description.c_str(); }
+ void setDescription (const char *description) { _description = std::string (description); }
+
+ int priority (void) const { return _priority; }
+ void setPriority (int priority) { _priority = priority; }
+
+ int priorityUnsubscribed (void) const { return _priority_unsubscribed; }
+ void setPriorityUnsubscribed (int priority_unsubscribed) { _priority_unsubscribed = priority_unsubscribed; }
+
+ const char *path (void) const { return _path.c_str(); }
+ void setPath (const char *path) { _path = std::string (path); }
+
+ const char *filePath (void) const { return _file_path.c_str(); }
+ void setFilePath (const char *file_path) { _file_path = std::string (file_path); }
+
+ const char *iconFile (void) const { return _icon_file.c_str(); }
+ void setIconFile (const char *icon_file) { _icon_file = std::string (icon_file); }
+
+ const char *pkginfoFile (void) const { return _pkginfo_file.c_str(); }
+ void setPkginfoFile (const char *pkginfo_file) { _pkginfo_file = std::string (pkginfo_file); }
+
+ // const std::list<char *> *distroTargets (void) const { return _distro_targets; }
+ // void setDistroTargets (const std::list<char *> *distro_targets) { _distro_targets = distro_targets; }
+
+ time_t lastUpdate (void) const { return _last_update; }
+ void setLastUpdate (time_t last_update) { _last_update = last_update; }
+
+ bool system (void) const { return _system; }
+ void setSystem (bool system) { _system = system; }
+ bool hidden (void) const { return _hidden; }
+ void setHidden (bool hidden) { _hidden = hidden; }
+ bool immutable (void) const { return _immutable; }
+ void setImmutable (bool immutable) { _immutable = immutable; }
+
+ //-----------------------------------------------------------------------
+
+ bool isWildcard (void) const;
+
+ virtual bool equals (const Channel & channel) const;
+ virtual bool equals (constChannelPtr channel) const;
+ bool hasEqualId (const Channel & channel) const;
+ bool hasEqualId (constChannelPtr channel) const;
+
+ //RCResItemSList *rc_channel_get_resItems (RCChannel *channel);
+
+ // Distro target functions
+
+ void addDistroTarget (const char *target);
+ bool hasDistroTarget (const char *target) const;
+
+ // Subscription management
+
+ bool isSubscribed (void) const;
+ void setSubscription (bool subscribed);
+
+ int priorityParse (const char *priority_cptr) const;
+ void setPriorities (int subd_priority, int unsubd_priority);
+ int getPriority (bool is_subscribed) const;
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Channel_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ChannelPtr
-// CLASS NAME : constChannelPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(Channel);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ChannelPtr
+ // CLASS NAME : constChannelPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(Channel);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+////////////////////////////////////////////////////////////////////////
#endif // _ChannelPtr_h
#include <zypp/solver/detail/OrDependency.h>
#include <zypp/solver/detail/Version.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(Dependency,Spec);
-
-//---------------------------------------------------------------------------
-
-#define RELATION_INVALID -1
-#define RELATION_ANY 0
-#define RELATION_EQUAL (1 << 0)
-#define RELATION_LESS (1 << 1)
-#define RELATION_GREATER (1 << 2)
-#define RELATION_NONE (1 << 3)
-
-const Relation & Relation::Invalid = Relation (RELATION_INVALID);
-const Relation & Relation::Any = Relation (RELATION_ANY);
-const Relation & Relation::Equal = Relation (RELATION_EQUAL);
-const Relation & Relation::NotEqual = Relation (RELATION_LESS|RELATION_GREATER);
-const Relation & Relation::Less = Relation (RELATION_LESS);
-const Relation & Relation::LessEqual = Relation (RELATION_LESS|RELATION_EQUAL);
-const Relation & Relation::Greater = Relation (RELATION_GREATER);
-const Relation & Relation::GreaterEqual = Relation (RELATION_GREATER|RELATION_EQUAL);
-const Relation & Relation::None = Relation (RELATION_NONE);
-
-
-const Relation &
-Relation::parse(const char *relation)
-{
- if (!strcmp (relation, "(any)"))
- return Any;
- else if (!strcmp (relation, "=") || !strcmp (relation, "eq"))
- return Equal;
- else if (!strcmp (relation, "<") || !strcmp(relation, "lt") || !strcmp(relation, "<"))
- return Less;
- else if (!strcmp (relation, "<=") || !strcmp(relation, "lte") || !strcmp(relation, "<="))
- return LessEqual;
- else if (!strcmp (relation, ">") || !strcmp(relation, "gt") || !strcmp(relation, ">"))
- return Greater;
- else if (!strcmp (relation, ">=") || !strcmp(relation, "gte") || !strcmp(relation, ">="))
- return GreaterEqual;
- else if (!strcmp (relation, "!=") || !strcmp(relation, "ne"))
- return NotEqual;
- else if (!strcmp (relation, "!!") || !strcmp(relation, "none"))
- return None;
- else
- return Invalid;
-}
-
-
-bool
-Relation::isEqual () const
-{
- return _op == RELATION_EQUAL;
-}
-
-
-string
-Relation::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Relation::toString ( const Relation & relation )
-{
- string res;
-
- switch (relation.op()) {
- case RELATION_INVALID: res = "(invalid)";
- break;
- case RELATION_ANY: res = "";
- break;
- case RELATION_EQUAL: res = "==";
- break;
- case RELATION_LESS|RELATION_GREATER: res = "!=";
- break;
- case RELATION_LESS: res = "<";
- break;
- case RELATION_LESS|RELATION_EQUAL: res = "<=";
- break;
- case RELATION_GREATER: res = ">";
- break;
- case RELATION_GREATER|RELATION_EQUAL: res = ">=";
- break;
- case RELATION_NONE: res = "!!";
- break;
- default:
- res = "??";
- res += stringutil::numstring (relation.op());
- res += "??";
- break;
- }
- return res;
-}
-
-
-string
-Relation::toWord ( const Relation & relation )
-{
- string res;
-
- switch (relation.op()) {
- case RELATION_INVALID: res = "(invalid)";
- break;
- case RELATION_ANY: res = "(any)";
- break;
- case RELATION_EQUAL: res = "equal to";
- break;
- case RELATION_LESS|RELATION_GREATER: res = "not equal to";
- break;
- case RELATION_LESS: res = "less than";
- break;
- case RELATION_LESS|RELATION_EQUAL: res = "less than or equal to";
- break;
- case RELATION_GREATER: res = "greater than";
- break;
- case RELATION_GREATER|RELATION_EQUAL: res = "greater than or equal to";
- break;
- case RELATION_NONE: res = "not installed";
- break;
- default:
- res = "??";
- res += stringutil::numstring (relation.op());
- res += "??";
- break;
- }
- return res;
-}
-
-
-ostream &
-Relation::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream & os, const Relation & relation)
-{
- return os << relation.asString();
-}
-
-//---------------------------------------------------------------------------
-
-string
-Dependency::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Dependency::toString ( const Dependency & dependency )
-{
- string res;
-
- res += dependency.name();
- if (dependency.relation() != Relation::Any) {
- res += " ";
- res += dependency.relation().asString();
- res += " ";
-
- res += dependency.edition()->asString();
- }
- if (dependency.orDep()) res += " [OR]";
- if (dependency.preDep()) res += " [PRE]";
-
- return res;
-}
-
-
-string
-Dependency::toString (const CDependencyList & dl)
-{
- string res("[");
- for (CDependencyList::const_iterator iter = dl.begin(); iter != dl.end(); iter++) {
- if (iter != dl.begin()) res += ", ";
- res += (*iter)->asString();
- }
- return res + "]";
-}
-
-
-
-
-ostream &
-Dependency::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Dependency& dependency)
-{
- return os << dependency.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Dependency::Dependency (const string & name, const Relation & relation, const Kind & kind,
- constChannelPtr channel,
- int epoch, const string & version, const string & release, const Arch * arch,
- bool or_dep, bool pre_dep)
- : Spec (kind, name, epoch, version, release, arch)
- , _relation (relation)
- , _channel (channel)
- , _or_dep (or_dep)
- , _pre_dep (pre_dep)
-{
-}
-
-
-Dependency::Dependency (const string & name, const Relation & relation, const Kind & kind,
- constChannelPtr channel, constEditionPtr edition, bool or_dep, bool pre_dep)
- : Spec (kind, name, edition)
- , _relation (relation)
- , _channel (channel)
- , _or_dep (or_dep)
- , _pre_dep (pre_dep)
-{
-}
-
-
-Dependency::Dependency (OrDependencyPtr or_dep)
- : Spec (Kind::Package, or_dep->name())
- , _relation (Relation::Any)
- , _channel (NULL)
- , _or_dep (false)
- , _pre_dep (true)
-{
- or_dep->addCreatedProvide (this);
-}
-
-
-Dependency::Dependency (constXmlNodePtr node)
- : Spec (Kind::Package, "")
- , _relation (Relation::Any)
- , _channel (new Channel(CHANNEL_TYPE_ANY))
- , _or_dep (false)
- , _pre_dep (false)
-{
- const char *tmp;
-
- if (!node->equals("dep")) {
- fprintf (stderr, "Dependency::Dependency bad node\n");
- abort();
- }
-
- setName(node->getProp ("name"));
- tmp = node->getProp ("op", NULL);
- if (tmp) {
- _relation = Relation::parse(tmp);
- setEpoch (node->getIntValueDefault ("epoch", -1));
- setVersion (node->getProp ("version"));
- setRelease (node->getProp ("release"));
- }
-
- tmp = node->getProp ("arch", NULL);
- if (tmp) {
- setArch (Arch::create (node->getProp ("arch")));
- } else {
- setArch (Arch::Unknown);
- }
-#if 0
- tmp = node->getProp ("kind", NULL);
- if (tmp) {
- setKind (Kind (node->getProp ("kind")));
- }
-#endif
- /* FIXME: should get channel from XML */
- /* FIXME: should get arch from XML */
-}
-
-
-Dependency::~Dependency()
-{
-}
-
-//---------------------------------------------------------------------------
-
-DependencyPtr parseXml (constXmlNodePtr node)
-{
- if (node->equals("dep")) {
- return new Dependency (node);
- } else if (node->equals("or")) {
- CDependencyList or_dep_list;
-
- node = node->children();
-
- while (node) {
- if (node->isElement()) {
- or_dep_list.push_back (new Dependency (node));
- }
-
- node = node->next();
- }
-
- OrDependencyPtr or_dep = OrDependency::fromDependencyList(or_dep_list);
- return new Dependency (or_dep);
- }
-
- fprintf (stderr, "Unhandled dependency [%s]\n", node->name());
-
- return NULL;
-}
-
-
-bool
-Dependency::verifyRelation (constDependencyPtr prov) const
-{
- int compare_ret = 0;
-if (getenv ("SPEW_DEP")) fprintf (stderr, "Dependency::verifyRelation(dep: %s, prov: %s)", asString().c_str(), prov->asString().c_str());
- /* No dependency can be met by a different token name */
- if (name() != prov->name()) {
-if (getenv ("SPEW_DEP")) fprintf (stderr, "-> wrong name\n");
- return false;
- }
-
- /* No dependency can be met by a different type */
- if (kind() != prov->kind()) {
-if (getenv ("SPEW_DEP")) fprintf (stderr, "-> wrong kind(dep: %s, prov: %s)\n", kind().asString().c_str(), prov->kind().asString().c_str());
- return false;
- }
-
- /* WARNING: RC_RELATION_NONE is NOT handled */
-
- /* No specific version in the req, so return */
- if (_relation == Relation::Any) {
-if (getenv ("SPEW_DEP")) fprintf (stderr, " (any) -> true\n");
- return true;
- }
-
- /* No specific version in the prov. In RPM this means it will satisfy
- * any version, but debian it will not satisfy a versioned dep */
- if (prov->relation() == Relation::Any) {
- if (GVersion.hasProperty (VERSION_PROP_PROVIDE_ANY)) {
-if (getenv ("SPEW_DEP")) fprintf (stderr, " provides (any) matches GVersion -> true\n");
- return true;
- }
- else {
-if (getenv ("SPEW_DEP")) fprintf (stderr, " provides (any) does not match GVersion -> false\n");
- return false;
- }
- }
-
- if (!channel()->equals (prov->channel()))
- {
-if (getenv ("SPEW_DEP")) fprintf (stderr, " wrong channel -> false\n");
- return false;
- }
-
- SpecPtr newdepspec;
- SpecPtr newprovspec;
-
- if (epoch() >= 0 && prov->epoch() >= 0) {
- /* HACK: This sucks, but I don't know a better way to compare elements one at a time */
- newdepspec = new Spec(kind(), "", epoch());
- newprovspec = new Spec(prov->kind(), "", prov->epoch());
- compare_ret = GVersion.compare (newprovspec, newdepspec);
- } else if (prov->epoch() > 0 ) {
- if (GVersion.hasProperty (VERSION_PROP_IGNORE_ABSENT_EPOCHS)) {
- compare_ret = 0;
- }
- else {
- compare_ret = 1;
- }
- } else if (epoch() > 0 ) {
- compare_ret = -1;
- }
-if (getenv ("SPEW_DEP")) fprintf (stderr, "epoch(%d), prov->epoch(%d) -> compare_ret %d\n", epoch(), prov->epoch(), compare_ret);
- if (compare_ret == 0) {
- if (GVersion.hasProperty (VERSION_PROP_ALWAYS_VERIFY_RELEASE)
- || (!(release().empty() || prov->release().empty()))) {
- newdepspec = new Spec(kind(), "", -1, version(), release());
- newprovspec = new Spec(prov->kind(), "", -1, prov->version(), prov->release());
- } else {
- newdepspec = new Spec(kind(), "", -1, version());
- newprovspec = new Spec(prov->kind(), "", -1, prov->version());
- }
- compare_ret = GVersion.compare (newprovspec, newdepspec);
- }
-if (getenv ("SPEW_DEP")) fprintf (stderr, " (compare result -> %d)", compare_ret);
-
- if (compare_ret < 0
- && ((prov->relation().op() & Relation::Greater.op())
- || (_relation.op() & Relation::Less.op())))
- {
-if (getenv ("SPEW_DEP")) fprintf (stderr, " -> true\n");
- return true;
- } else if (compare_ret > 0
- && ((prov->relation().op() & Relation::Less.op())
- || (_relation.op() & Relation::Greater.op())))
- {
-if (getenv ("SPEW_DEP")) fprintf (stderr, " -> true\n");
- return true;
- } else if (compare_ret == 0
- && (((prov->relation().op() & Relation::Equal.op()) && (_relation.op() & Relation::Equal.op()))
- || ((prov->relation().op() & Relation::Less.op()) && (_relation.op() & Relation::Less.op()))
- || ((prov->relation().op() & Relation::Greater.op()) && (_relation.op() & Relation::Greater.op()))))
- {
-if (getenv ("SPEW_DEP")) fprintf (stderr, " -> true\n");
- return true;
- }
-
-if (getenv ("SPEW_DEP")) fprintf (stderr, " -> false\n");
- return false;
-}
-
-//---------------------------------------------------------------------------
-
-#if 0
-xmlNode *
-rc_resItem_dep_or_slist_to_xml_node (RCResItemDepSList *dep)
-{
- xmlNode *or_node;
- const RCResItemDepSList *dep_iter;
-
- or_node = xmlNewNode (NULL, "or");
-
- dep_iter = dep;
- while (dep_iter) {
- RCResItemDep *dep_item = (RCResItemDep *)(dep_iter->data);
- xmlAddChild (or_node, rc_resItem_dep_to_xml_node (dep_item));
- dep_iter = dep_iter->next;
- }
-
- return or_node;
-} /* rc_resItem_dep_or_slist_to_xml_node */
-
-xmlNode *
-rc_resItem_dep_to_xml_node (RCResItemDep *dep_item)
-{
- RCResItemSpec *spec = (RCResItemSpec *) dep_item;
- xmlNode *dep_node;
-
- if (rc_resItem_dep_is_or (dep_item)) {
- RCResItemDepSList *dep_or_slist;
- dep_or_slist = rc_dep_string_to_or_dep_slist
- (rc_resItem_spec_get_name (spec));
- dep_node = rc_resItem_dep_or_slist_to_xml_node (dep_or_slist);
- rc_resItem_dep_slist_free (dep_or_slist);
- return dep_node;
- }
-
- dep_node = xmlNewNode (NULL, "dep");
-
- xmlSetProp (dep_node, "name", rc_resItem_spec_get_name (spec));
-
- if (rc_resItem_dep_get_relation (dep_item) != Relation::Any) {
- xmlSetProp (dep_node, "op",
- rc_resItem_relation_to_string (
- rc_resItem_dep_get_relation (dep_item), false));
-
- if (rc_resItem_spec_has_epoch (spec)) {
- gchar *tmp;
-
- tmp = g_strdup_printf ("%d", rc_resItem_spec_get_epoch (spec));
- xmlSetProp (dep_node, "epoch", tmp);
- g_free (tmp);
- }
-
- if (spec->version) {
- xmlSetProp (dep_node, "version", spec->version);
- }
-
- if (spec->release) {
- xmlSetProp (dep_node, "release", spec->release);
- }
- }
-
- return (dep_node);
-} /* rc_resItem_dep_to_xml_node */
-
-#endif
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(Dependency,Spec);
+
+ //---------------------------------------------------------------------------
+
+ #define RELATION_INVALID -1
+ #define RELATION_ANY 0
+ #define RELATION_EQUAL (1 << 0)
+ #define RELATION_LESS (1 << 1)
+ #define RELATION_GREATER (1 << 2)
+ #define RELATION_NONE (1 << 3)
+
+ const Relation & Relation::Invalid = Relation (RELATION_INVALID);
+ const Relation & Relation::Any = Relation (RELATION_ANY);
+ const Relation & Relation::Equal = Relation (RELATION_EQUAL);
+ const Relation & Relation::NotEqual = Relation (RELATION_LESS|RELATION_GREATER);
+ const Relation & Relation::Less = Relation (RELATION_LESS);
+ const Relation & Relation::LessEqual = Relation (RELATION_LESS|RELATION_EQUAL);
+ const Relation & Relation::Greater = Relation (RELATION_GREATER);
+ const Relation & Relation::GreaterEqual = Relation (RELATION_GREATER|RELATION_EQUAL);
+ const Relation & Relation::None = Relation (RELATION_NONE);
+
+
+ const Relation &
+ Relation::parse(const char *relation)
+ {
+ if (!strcmp (relation, "(any)"))
+ return Any;
+ else if (!strcmp (relation, "=") || !strcmp (relation, "eq"))
+ return Equal;
+ else if (!strcmp (relation, "<") || !strcmp(relation, "lt") || !strcmp(relation, "<"))
+ return Less;
+ else if (!strcmp (relation, "<=") || !strcmp(relation, "lte") || !strcmp(relation, "<="))
+ return LessEqual;
+ else if (!strcmp (relation, ">") || !strcmp(relation, "gt") || !strcmp(relation, ">"))
+ return Greater;
+ else if (!strcmp (relation, ">=") || !strcmp(relation, "gte") || !strcmp(relation, ">="))
+ return GreaterEqual;
+ else if (!strcmp (relation, "!=") || !strcmp(relation, "ne"))
+ return NotEqual;
+ else if (!strcmp (relation, "!!") || !strcmp(relation, "none"))
+ return None;
+ else
+ return Invalid;
+ }
+
+
+ bool
+ Relation::isEqual () const
+ {
+ return _op == RELATION_EQUAL;
+ }
+
+
+ string
+ Relation::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Relation::toString ( const Relation & relation )
+ {
+ string res;
+
+ switch (relation.op()) {
+ case RELATION_INVALID: res = "(invalid)";
+ break;
+ case RELATION_ANY: res = "";
+ break;
+ case RELATION_EQUAL: res = "==";
+ break;
+ case RELATION_LESS|RELATION_GREATER: res = "!=";
+ break;
+ case RELATION_LESS: res = "<";
+ break;
+ case RELATION_LESS|RELATION_EQUAL: res = "<=";
+ break;
+ case RELATION_GREATER: res = ">";
+ break;
+ case RELATION_GREATER|RELATION_EQUAL: res = ">=";
+ break;
+ case RELATION_NONE: res = "!!";
+ break;
+ default:
+ res = "??";
+ res += stringutil::numstring (relation.op());
+ res += "??";
+ break;
+ }
+ return res;
+ }
+
+
+ string
+ Relation::toWord ( const Relation & relation )
+ {
+ string res;
+
+ switch (relation.op()) {
+ case RELATION_INVALID: res = "(invalid)";
+ break;
+ case RELATION_ANY: res = "(any)";
+ break;
+ case RELATION_EQUAL: res = "equal to";
+ break;
+ case RELATION_LESS|RELATION_GREATER: res = "not equal to";
+ break;
+ case RELATION_LESS: res = "less than";
+ break;
+ case RELATION_LESS|RELATION_EQUAL: res = "less than or equal to";
+ break;
+ case RELATION_GREATER: res = "greater than";
+ break;
+ case RELATION_GREATER|RELATION_EQUAL: res = "greater than or equal to";
+ break;
+ case RELATION_NONE: res = "not installed";
+ break;
+ default:
+ res = "??";
+ res += stringutil::numstring (relation.op());
+ res += "??";
+ break;
+ }
+ return res;
+ }
+
+
+ ostream &
+ Relation::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream & os, const Relation & relation)
+ {
+ return os << relation.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ string
+ Dependency::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Dependency::toString ( const Dependency & dependency )
+ {
+ string res;
+
+ res += dependency.name();
+ if (dependency.relation() != Relation::Any) {
+ res += " ";
+ res += dependency.relation().asString();
+ res += " ";
+
+ res += dependency.edition()->asString();
+ }
+ if (dependency.orDep()) res += " [OR]";
+ if (dependency.preDep()) res += " [PRE]";
+
+ return res;
+ }
+
+
+ string
+ Dependency::toString (const CDependencyList & dl)
+ {
+ string res("[");
+ for (CDependencyList::const_iterator iter = dl.begin(); iter != dl.end(); iter++) {
+ if (iter != dl.begin()) res += ", ";
+ res += (*iter)->asString();
+ }
+ return res + "]";
+ }
+
+
+
+
+ ostream &
+ Dependency::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Dependency& dependency)
+ {
+ return os << dependency.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Dependency::Dependency (const string & name, const Relation & relation, const Kind & kind,
+ constChannelPtr channel,
+ int epoch, const string & version, const string & release, const Arch * arch,
+ bool or_dep, bool pre_dep)
+ : Spec (kind, name, epoch, version, release, arch)
+ , _relation (relation)
+ , _channel (channel)
+ , _or_dep (or_dep)
+ , _pre_dep (pre_dep)
+ {
+ }
+
+
+ Dependency::Dependency (const string & name, const Relation & relation, const Kind & kind,
+ constChannelPtr channel, constEditionPtr edition, bool or_dep, bool pre_dep)
+ : Spec (kind, name, edition)
+ , _relation (relation)
+ , _channel (channel)
+ , _or_dep (or_dep)
+ , _pre_dep (pre_dep)
+ {
+ }
+
+
+ Dependency::Dependency (OrDependencyPtr or_dep)
+ : Spec (Kind::Package, or_dep->name())
+ , _relation (Relation::Any)
+ , _channel (NULL)
+ , _or_dep (false)
+ , _pre_dep (true)
+ {
+ or_dep->addCreatedProvide (this);
+ }
+
+
+ Dependency::Dependency (constXmlNodePtr node)
+ : Spec (Kind::Package, "")
+ , _relation (Relation::Any)
+ , _channel (new Channel(CHANNEL_TYPE_ANY))
+ , _or_dep (false)
+ , _pre_dep (false)
+ {
+ const char *tmp;
+
+ if (!node->equals("dep")) {
+ fprintf (stderr, "Dependency::Dependency bad node\n");
+ abort();
+ }
+
+ setName(node->getProp ("name"));
+ tmp = node->getProp ("op", NULL);
+ if (tmp) {
+ _relation = Relation::parse(tmp);
+ setEpoch (node->getIntValueDefault ("epoch", -1));
+ setVersion (node->getProp ("version"));
+ setRelease (node->getProp ("release"));
+ }
+
+ tmp = node->getProp ("arch", NULL);
+ if (tmp) {
+ setArch (Arch::create (node->getProp ("arch")));
+ } else {
+ setArch (Arch::Unknown);
+ }
+ #if 0
+ tmp = node->getProp ("kind", NULL);
+ if (tmp) {
+ setKind (Kind (node->getProp ("kind")));
+ }
+ #endif
+ /* FIXME: should get channel from XML */
+ /* FIXME: should get arch from XML */
+ }
+
+
+ Dependency::~Dependency()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ DependencyPtr parseXml (constXmlNodePtr node)
+ {
+ if (node->equals("dep")) {
+ return new Dependency (node);
+ } else if (node->equals("or")) {
+ CDependencyList or_dep_list;
+
+ node = node->children();
+
+ while (node) {
+ if (node->isElement()) {
+ or_dep_list.push_back (new Dependency (node));
+ }
+
+ node = node->next();
+ }
+
+ OrDependencyPtr or_dep = OrDependency::fromDependencyList(or_dep_list);
+ return new Dependency (or_dep);
+ }
+
+ fprintf (stderr, "Unhandled dependency [%s]\n", node->name());
+
+ return NULL;
+ }
+
+
+ bool
+ Dependency::verifyRelation (constDependencyPtr prov) const
+ {
+ int compare_ret = 0;
+ if (getenv ("SPEW_DEP")) fprintf (stderr, "Dependency::verifyRelation(dep: %s, prov: %s)", asString().c_str(), prov->asString().c_str());
+ /* No dependency can be met by a different token name */
+ if (name() != prov->name()) {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, "-> wrong name\n");
+ return false;
+ }
+
+ /* No dependency can be met by a different type */
+ if (kind() != prov->kind()) {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, "-> wrong kind(dep: %s, prov: %s)\n", kind().asString().c_str(), prov->kind().asString().c_str());
+ return false;
+ }
+
+ /* WARNING: RC_RELATION_NONE is NOT handled */
+
+ /* No specific version in the req, so return */
+ if (_relation == Relation::Any) {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " (any) -> true\n");
+ return true;
+ }
+
+ /* No specific version in the prov. In RPM this means it will satisfy
+ * any version, but debian it will not satisfy a versioned dep */
+ if (prov->relation() == Relation::Any) {
+ if (GVersion.hasProperty (VERSION_PROP_PROVIDE_ANY)) {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " provides (any) matches GVersion -> true\n");
+ return true;
+ }
+ else {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " provides (any) does not match GVersion -> false\n");
+ return false;
+ }
+ }
+
+ if (!channel()->equals (prov->channel()))
+ {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " wrong channel -> false\n");
+ return false;
+ }
+
+ SpecPtr newdepspec;
+ SpecPtr newprovspec;
+
+ if (epoch() >= 0 && prov->epoch() >= 0) {
+ /* HACK: This sucks, but I don't know a better way to compare elements one at a time */
+ newdepspec = new Spec(kind(), "", epoch());
+ newprovspec = new Spec(prov->kind(), "", prov->epoch());
+ compare_ret = GVersion.compare (newprovspec, newdepspec);
+ } else if (prov->epoch() > 0 ) {
+ if (GVersion.hasProperty (VERSION_PROP_IGNORE_ABSENT_EPOCHS)) {
+ compare_ret = 0;
+ }
+ else {
+ compare_ret = 1;
+ }
+ } else if (epoch() > 0 ) {
+ compare_ret = -1;
+ }
+ if (getenv ("SPEW_DEP")) fprintf (stderr, "epoch(%d), prov->epoch(%d) -> compare_ret %d\n", epoch(), prov->epoch(), compare_ret);
+ if (compare_ret == 0) {
+ if (GVersion.hasProperty (VERSION_PROP_ALWAYS_VERIFY_RELEASE)
+ || (!(release().empty() || prov->release().empty()))) {
+ newdepspec = new Spec(kind(), "", -1, version(), release());
+ newprovspec = new Spec(prov->kind(), "", -1, prov->version(), prov->release());
+ } else {
+ newdepspec = new Spec(kind(), "", -1, version());
+ newprovspec = new Spec(prov->kind(), "", -1, prov->version());
+ }
+ compare_ret = GVersion.compare (newprovspec, newdepspec);
+ }
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " (compare result -> %d)", compare_ret);
+
+ if (compare_ret < 0
+ && ((prov->relation().op() & Relation::Greater.op())
+ || (_relation.op() & Relation::Less.op())))
+ {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " -> true\n");
+ return true;
+ } else if (compare_ret > 0
+ && ((prov->relation().op() & Relation::Less.op())
+ || (_relation.op() & Relation::Greater.op())))
+ {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " -> true\n");
+ return true;
+ } else if (compare_ret == 0
+ && (((prov->relation().op() & Relation::Equal.op()) && (_relation.op() & Relation::Equal.op()))
+ || ((prov->relation().op() & Relation::Less.op()) && (_relation.op() & Relation::Less.op()))
+ || ((prov->relation().op() & Relation::Greater.op()) && (_relation.op() & Relation::Greater.op()))))
+ {
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " -> true\n");
+ return true;
+ }
+
+ if (getenv ("SPEW_DEP")) fprintf (stderr, " -> false\n");
+ return false;
+ }
+
+ //---------------------------------------------------------------------------
+
+ #if 0
+ xmlNode *
+ rc_resItem_dep_or_slist_to_xml_node (RCResItemDepSList *dep)
+ {
+ xmlNode *or_node;
+ const RCResItemDepSList *dep_iter;
+
+ or_node = xmlNewNode (NULL, "or");
+
+ dep_iter = dep;
+ while (dep_iter) {
+ RCResItemDep *dep_item = (RCResItemDep *)(dep_iter->data);
+ xmlAddChild (or_node, rc_resItem_dep_to_xml_node (dep_item));
+ dep_iter = dep_iter->next;
+ }
+
+ return or_node;
+ } /* rc_resItem_dep_or_slist_to_xml_node */
+
+ xmlNode *
+ rc_resItem_dep_to_xml_node (RCResItemDep *dep_item)
+ {
+ RCResItemSpec *spec = (RCResItemSpec *) dep_item;
+ xmlNode *dep_node;
+
+ if (rc_resItem_dep_is_or (dep_item)) {
+ RCResItemDepSList *dep_or_slist;
+ dep_or_slist = rc_dep_string_to_or_dep_slist
+ (rc_resItem_spec_get_name (spec));
+ dep_node = rc_resItem_dep_or_slist_to_xml_node (dep_or_slist);
+ rc_resItem_dep_slist_free (dep_or_slist);
+ return dep_node;
+ }
+
+ dep_node = xmlNewNode (NULL, "dep");
+
+ xmlSetProp (dep_node, "name", rc_resItem_spec_get_name (spec));
+
+ if (rc_resItem_dep_get_relation (dep_item) != Relation::Any) {
+ xmlSetProp (dep_node, "op",
+ rc_resItem_relation_to_string (
+ rc_resItem_dep_get_relation (dep_item), false));
+
+ if (rc_resItem_spec_has_epoch (spec)) {
+ gchar *tmp;
+
+ tmp = g_strdup_printf ("%d", rc_resItem_spec_get_epoch (spec));
+ xmlSetProp (dep_node, "epoch", tmp);
+ g_free (tmp);
+ }
+
+ if (spec->version) {
+ xmlSetProp (dep_node, "version", spec->version);
+ }
+
+ if (spec->release) {
+ xmlSetProp (dep_node, "release", spec->release);
+ }
+ }
+
+ return (dep_node);
+ } /* rc_resItem_dep_to_xml_node */
+
+ #endif
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Spec.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Relation
-/**
- * A dependency relation
- **/
-
-class Relation {
-
- private:
-
- int _op;
-
- Relation (int op) { _op = op; }
-
- public:
-
- virtual ~Relation() {}
-
- // ---------------------------------- I/O
-
- static std::string toString ( const Relation & relation );
-
- static std::string toWord ( const Relation & relation );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream & str, const Relation & relation );
-
- std::string asString ( void ) const;
-
- // ---------------------------------- consts
-
- static const Relation & Invalid;
- static const Relation & Any;
- static const Relation & Equal;
- static const Relation & NotEqual;
- static const Relation & Less;
- static const Relation & LessEqual;
- static const Relation & Greater;
- static const Relation & GreaterEqual;
- static const Relation & None;
-
- static const Relation & parse (const char *relation);
-
- // ---------------------------------- accessors
-
- int op (void) const { return _op; }
-
- bool isEqual () const;
-
- // equality operator
- bool operator==( const Relation & rel ) const {
- return (_op == rel.op());
- }
-
- // inequality
- bool operator!=( const Relation & rel ) const {
- return !(*this == rel);
- }
-
-};
-
-///////////////////////////////////////////////////////////////////
-
-typedef std::list <DependencyPtr> DependencyList;
-typedef std::list <constDependencyPtr> CDependencyList;
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Dependency
-/**
- *
- **/
-
-class Dependency : public Spec {
- REP_BODY(Dependency);
-
- private:
- Relation _relation;
- constChannelPtr _channel;
- bool _or_dep;
- bool _pre_dep;
-
- public:
-
- Dependency (const std::string & name,
- const Relation & relation,
- const Kind & kind = Kind::Package,
- constChannelPtr channel = NULL,
- int epoch = -1,
- const std::string & version = "",
- const std::string & release = "",
- const Arch * arch = Arch::Any,
- bool or_dep = false,
- bool pre_dep = false);
-
- Dependency (const std::string & name,
- const Relation & relation,
- const Kind & kind = Kind::Package,
- constChannelPtr channel = NULL,
- constEditionPtr edition = NULL,
- bool or_dep = false,
- bool pre_dep = false);
-
- Dependency (OrDependencyPtr or_dep); //RCResItemDep *rc_dep_or_new_provide (RCDepOr *dor);
-
- Dependency (constXmlNodePtr node); //RCResItemDep *rc_xml_node_to_resItem_dep (const xmlNode *node);
-
- virtual ~Dependency();
-
- // ---------------------------------- I/O
-
- const xmlNodePtr asXmlNode (void) const; // xmlNode *rc_resItem_dep_to_xml_node (RCResItemDep *dep_item);
-
- static std::string toString ( const Dependency & dep );
-
- static std::string toString ( const CDependencyList & deplist );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream & str, const Dependency & dep);
-
- std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- const Relation & relation() const { return _relation; }
- constChannelPtr channel (void) const { return _channel; }
-
- bool orDep (void) const { return _or_dep; }
- void setOrDep (bool or_dep) { _or_dep = or_dep; }
-
- bool preDep (void) const { return _pre_dep; }
- void setPreDep (bool pre_dep) { _pre_dep = pre_dep; }
-
- // ---------------------------------- methods
-
- DependencyPtr parseXml (constXmlNodePtr node);
- bool verifyRelation (constDependencyPtr prov) const;
-};
-
-// xmlNode *rc_resItem_dep_or_slist_to_xml_node (RCResItemDepSList *dep);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Relation
+ /**
+ * A dependency relation
+ **/
+
+ class Relation {
+
+ private:
+
+ int _op;
+
+ Relation (int op) { _op = op; }
+
+ public:
+
+ virtual ~Relation() {}
+
+ // ---------------------------------- I/O
+
+ static std::string toString ( const Relation & relation );
+
+ static std::string toWord ( const Relation & relation );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream & str, const Relation & relation );
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- consts
+
+ static const Relation & Invalid;
+ static const Relation & Any;
+ static const Relation & Equal;
+ static const Relation & NotEqual;
+ static const Relation & Less;
+ static const Relation & LessEqual;
+ static const Relation & Greater;
+ static const Relation & GreaterEqual;
+ static const Relation & None;
+
+ static const Relation & parse (const char *relation);
+
+ // ---------------------------------- accessors
+
+ int op (void) const { return _op; }
+
+ bool isEqual () const;
+
+ // equality operator
+ bool operator==( const Relation & rel ) const {
+ return (_op == rel.op());
+ }
+
+ // inequality
+ bool operator!=( const Relation & rel ) const {
+ return !(*this == rel);
+ }
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+
+ typedef std::list <DependencyPtr> DependencyList;
+ typedef std::list <constDependencyPtr> CDependencyList;
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Dependency
+ /**
+ *
+ **/
+
+ class Dependency : public Spec {
+ REP_BODY(Dependency);
+
+ private:
+ Relation _relation;
+ constChannelPtr _channel;
+ bool _or_dep;
+ bool _pre_dep;
+
+ public:
+
+ Dependency (const std::string & name,
+ const Relation & relation,
+ const Kind & kind = Kind::Package,
+ constChannelPtr channel = NULL,
+ int epoch = -1,
+ const std::string & version = "",
+ const std::string & release = "",
+ const Arch * arch = Arch::Any,
+ bool or_dep = false,
+ bool pre_dep = false);
+
+ Dependency (const std::string & name,
+ const Relation & relation,
+ const Kind & kind = Kind::Package,
+ constChannelPtr channel = NULL,
+ constEditionPtr edition = NULL,
+ bool or_dep = false,
+ bool pre_dep = false);
+
+ Dependency (OrDependencyPtr or_dep); //RCResItemDep *rc_dep_or_new_provide (RCDepOr *dor);
+
+ Dependency (constXmlNodePtr node); //RCResItemDep *rc_xml_node_to_resItem_dep (const xmlNode *node);
+
+ virtual ~Dependency();
+
+ // ---------------------------------- I/O
+
+ const xmlNodePtr asXmlNode (void) const; // xmlNode *rc_resItem_dep_to_xml_node (RCResItemDep *dep_item);
+
+ static std::string toString ( const Dependency & dep );
+
+ static std::string toString ( const CDependencyList & deplist );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream & str, const Dependency & dep);
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ const Relation & relation() const { return _relation; }
+ constChannelPtr channel (void) const { return _channel; }
+
+ bool orDep (void) const { return _or_dep; }
+ void setOrDep (bool or_dep) { _or_dep = or_dep; }
+
+ bool preDep (void) const { return _pre_dep; }
+ void setPreDep (bool pre_dep) { _pre_dep = pre_dep; }
+
+ // ---------------------------------- methods
+
+ DependencyPtr parseXml (constXmlNodePtr node);
+ bool verifyRelation (constDependencyPtr prov) const;
+ };
+
+ // xmlNode *rc_resItem_dep_or_slist_to_xml_node (RCResItemDepSList *dep);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Dependency_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/SpecPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : DependencyPtr
-// CLASS NAME : constDependencyPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(Dependency,Spec);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : DependencyPtr
+ // CLASS NAME : constDependencyPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(Dependency,Spec);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _DependencyPtr_h
#include <zypp/solver/detail/Edition.h>
#include <zypp/solver/detail/Version.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(Edition);
-
-//---------------------------------------------------------------------------
-
-string
-Edition::asString ( bool full ) const
-{
- return toString (*this, full);
-}
-
-
-string
-Edition::toString ( const Edition & edition, bool full )
-{
- string res ("");
-
- if (edition._epoch >= 0) {
- res += stringutil::numstring (edition._epoch);
- res += ":";
- }
-
- res += edition._version;
- if (!edition._release.empty()) {
- res += "-";
- res += edition._release;
- }
-
- if (full) {
- res += ".";
- res += edition._arch->asString();
- }
-
- return res;
-}
-
-
-ostream &
-Edition::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Edition& edition)
-{
- return os << edition.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Edition::Edition( int epoch, const string & version, const string & release, const Arch * arch)
- : _epoch (epoch)
- , _version (version)
- , _release (release)
- , _arch (arch)
-{
-}
-
-
-Edition::~Edition()
-{
-}
-
-
-EditionPtr
-Edition::copy (void) const
-{
- return new Edition (_epoch, _version, _release, _arch);
-}
-
-
-EditionPtr
-Edition::fromString (const char *s)
-{
- return GVersion.parse (s);
-}
-
-
-bool
-Edition::match( constEditionPtr edition ) const {
-//fprintf (stderr, "<%s> match <%s>\n", asString().c_str(), edition->asString().c_str());
- if (_epoch != edition->_epoch) return false;
-//fprintf (stderr, "epoch ok\n");
- if (_version != edition->_version) return false;
-//fprintf (stderr, "version ok\n");
- if (_release != edition->_release) return false;
-//fprintf (stderr, "release ok\n");
- if (_arch != edition->_arch) return false;
-//fprintf (stderr, "arch ok\n");
- return true;
-}
-
-
-bool
-Edition::equals( constEditionPtr edition ) const {
-//fprintf (stderr, "<%s> equals <%s>\n", asString().c_str(), edition->asString().c_str());
- return match (edition);
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(Edition);
+
+ //---------------------------------------------------------------------------
+
+ string
+ Edition::asString ( bool full ) const
+ {
+ return toString (*this, full);
+ }
+
+
+ string
+ Edition::toString ( const Edition & edition, bool full )
+ {
+ string res ("");
+
+ if (edition._epoch >= 0) {
+ res += stringutil::numstring (edition._epoch);
+ res += ":";
+ }
+
+ res += edition._version;
+ if (!edition._release.empty()) {
+ res += "-";
+ res += edition._release;
+ }
+
+ if (full) {
+ res += ".";
+ res += edition._arch->asString();
+ }
+
+ return res;
+ }
+
+
+ ostream &
+ Edition::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Edition& edition)
+ {
+ return os << edition.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Edition::Edition( int epoch, const string & version, const string & release, const Arch * arch)
+ : _epoch (epoch)
+ , _version (version)
+ , _release (release)
+ , _arch (arch)
+ {
+ }
+
+
+ Edition::~Edition()
+ {
+ }
+
+
+ EditionPtr
+ Edition::copy (void) const
+ {
+ return new Edition (_epoch, _version, _release, _arch);
+ }
+
+
+ EditionPtr
+ Edition::fromString (const char *s)
+ {
+ return GVersion.parse (s);
+ }
+
+
+ bool
+ Edition::match( constEditionPtr edition ) const {
+ //fprintf (stderr, "<%s> match <%s>\n", asString().c_str(), edition->asString().c_str());
+ if (_epoch != edition->_epoch) return false;
+ //fprintf (stderr, "epoch ok\n");
+ if (_version != edition->_version) return false;
+ //fprintf (stderr, "version ok\n");
+ if (_release != edition->_release) return false;
+ //fprintf (stderr, "release ok\n");
+ if (_arch != edition->_arch) return false;
+ //fprintf (stderr, "arch ok\n");
+ return true;
+ }
+
+
+ bool
+ Edition::equals( constEditionPtr edition ) const {
+ //fprintf (stderr, "<%s> equals <%s>\n", asString().c_str(), edition->asString().c_str());
+ return match (edition);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/XmlNodePtr.h>
#include <zypp/solver/detail/Arch.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Edition
-/**
- *
- **/
-class Edition : public CountedRep {
- REP_BODY(Edition);
-
- private:
- int _epoch;
- std::string _version;
- std::string _release;
- const Arch *_arch;
-
- public:
-
- //
- // -1 resp. NULL values are treated as 'any'
- //
-
- Edition( int epoch = -1, const std::string & version = "", const std::string & release = "", const Arch * arch = Arch::Unknown);
- virtual ~Edition();
-
- // ---------------------------------- I/O
-
- const XmlNodePtr asXmlNode (void) const;
-
- static std::string toString ( const Edition & edition, bool full = false );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Edition& );
-
- std::string asString ( bool full = false ) const;
-
- // ---------------------------------- accessors
-
- void setVersion (const std::string & version) { _version = version; }
- void setRelease (const std::string & release) { _release = release; }
- void setEpoch (int epoch) { _epoch = epoch; }
- void setArch (const std::string & arch) { _arch = Arch::create(arch); }
- void setArch (const Arch * arch) { _arch = arch; }
-
- const std::string & version() const { return _version; }
- const std::string & release() const { return _release; }
- const int epoch() const { return _epoch; }
- bool hasEpoch() const { return _epoch >= 0; }
- const Arch * arch() const { return _arch; }
-
- bool match( constEditionPtr edition ) const;
- bool equals( constEditionPtr edition ) const;
-
- // ---------------------------------- accessors
-
- EditionPtr copy (void) const;
- static EditionPtr fromString (const char *s);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Edition
+ /**
+ *
+ **/
+ class Edition : public CountedRep {
+ REP_BODY(Edition);
+
+ private:
+ int _epoch;
+ std::string _version;
+ std::string _release;
+ const Arch *_arch;
+
+ public:
+
+ //
+ // -1 resp. NULL values are treated as 'any'
+ //
+
+ Edition( int epoch = -1, const std::string & version = "", const std::string & release = "", const Arch * arch = Arch::Unknown);
+ virtual ~Edition();
+
+ // ---------------------------------- I/O
+
+ const XmlNodePtr asXmlNode (void) const;
+
+ static std::string toString ( const Edition & edition, bool full = false );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Edition& );
+
+ std::string asString ( bool full = false ) const;
+
+ // ---------------------------------- accessors
+
+ void setVersion (const std::string & version) { _version = version; }
+ void setRelease (const std::string & release) { _release = release; }
+ void setEpoch (int epoch) { _epoch = epoch; }
+ void setArch (const std::string & arch) { _arch = Arch::create(arch); }
+ void setArch (const Arch * arch) { _arch = arch; }
+
+ const std::string & version() const { return _version; }
+ const std::string & release() const { return _release; }
+ const int epoch() const { return _epoch; }
+ bool hasEpoch() const { return _epoch >= 0; }
+ const Arch * arch() const { return _arch; }
+
+ bool match( constEditionPtr edition ) const;
+ bool equals( constEditionPtr edition ) const;
+
+ // ---------------------------------- accessors
+
+ EditionPtr copy (void) const;
+ static EditionPtr fromString (const char *s);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Edition_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : EditionPtr
+ // CLASS NAME : constEditionPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(Edition);
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : EditionPtr
-// CLASS NAME : constEditionPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(Edition);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _EditionPtr_h
#ifndef _Hash_h
#define _Hash_h
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef unsigned int HashValue;
-typedef unsigned int HashValue;
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Hash_h
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-const Importance & Importance::Undefined= Importance("undefined");
-
-//---------------------------------------------------------------------------
-string
-Importance::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Importance::toString ( const Importance & importance )
-{
- string res;
-
- switch (importance.importance()) {
- case IMPORTANCE_UNDEFINED: res = "undefined"; break;
- case IMPORTANCE_INVALID: res = "invalid"; break;
- case IMPORTANCE_NECESSARY: res = "necessary"; break;
- case IMPORTANCE_URGENT: res = "urgent"; break;
- case IMPORTANCE_SUGGESTED: res = "suggested"; break;
- case IMPORTANCE_FEATURE: res = "feature"; break;
- case IMPORTANCE_MINOR: res = "minor"; break;
- default:
- rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid importance %d\n", importance.importance());
- res = "invalid";
- }
- return res;
-}
-
-
-ostream &
-Importance::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Importance& importance)
-{
- return os << importance.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Importance::Importance(const char *importance_str)
-{
- _importance = IMPORTANCE_INVALID;
- if (importance_str != NULL) {
- switch (*importance_str) {
- case 'f':
- if (!strcmp (importance_str, "feature")) {
- _importance = IMPORTANCE_FEATURE;
- }
- break;
- case 'm':
- if (!strcmp (importance_str, "minor")) {
- _importance = IMPORTANCE_MINOR;
- }
- break;
- case 'n':
- if (!strcmp (importance_str, "necessary")) {
- _importance = IMPORTANCE_NECESSARY;
- }
- break;
- case 's':
- if (!strcmp (importance_str, "suggested")) {
- _importance = IMPORTANCE_SUGGESTED;
- }
- break;
- case 'u':
- if (!strcmp (importance_str, "urgent")) {
- _importance = IMPORTANCE_URGENT;
- }
- else if (!strcmp (importance_str, "undefined")) {
- _importance = IMPORTANCE_UNDEFINED;
- }
- default:
- break;
- }
- }
- if (_importance == IMPORTANCE_INVALID)
- rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid importance '%s'\n", importance_str ? importance_str : "<null>");
-
-}
-
-
-Importance::~Importance()
-{
-}
-
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ const Importance & Importance::Undefined= Importance("undefined");
+
+ //---------------------------------------------------------------------------
+ string
+ Importance::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Importance::toString ( const Importance & importance )
+ {
+ string res;
+
+ switch (importance.importance()) {
+ case IMPORTANCE_UNDEFINED: res = "undefined"; break;
+ case IMPORTANCE_INVALID: res = "invalid"; break;
+ case IMPORTANCE_NECESSARY: res = "necessary"; break;
+ case IMPORTANCE_URGENT: res = "urgent"; break;
+ case IMPORTANCE_SUGGESTED: res = "suggested"; break;
+ case IMPORTANCE_FEATURE: res = "feature"; break;
+ case IMPORTANCE_MINOR: res = "minor"; break;
+ default:
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid importance %d\n", importance.importance());
+ res = "invalid";
+ }
+ return res;
+ }
+
+
+ ostream &
+ Importance::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Importance& importance)
+ {
+ return os << importance.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Importance::Importance(const char *importance_str)
+ {
+ _importance = IMPORTANCE_INVALID;
+ if (importance_str != NULL) {
+ switch (*importance_str) {
+ case 'f':
+ if (!strcmp (importance_str, "feature")) {
+ _importance = IMPORTANCE_FEATURE;
+ }
+ break;
+ case 'm':
+ if (!strcmp (importance_str, "minor")) {
+ _importance = IMPORTANCE_MINOR;
+ }
+ break;
+ case 'n':
+ if (!strcmp (importance_str, "necessary")) {
+ _importance = IMPORTANCE_NECESSARY;
+ }
+ break;
+ case 's':
+ if (!strcmp (importance_str, "suggested")) {
+ _importance = IMPORTANCE_SUGGESTED;
+ }
+ break;
+ case 'u':
+ if (!strcmp (importance_str, "urgent")) {
+ _importance = IMPORTANCE_URGENT;
+ }
+ else if (!strcmp (importance_str, "undefined")) {
+ _importance = IMPORTANCE_UNDEFINED;
+ }
+ default:
+ break;
+ }
+ }
+ if (_importance == IMPORTANCE_INVALID)
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid importance '%s'\n", importance_str ? importance_str : "<null>");
+
+ }
+
+
+ Importance::~Importance()
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
#include <y2util/Ustring.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Importance
-/**
- *
- **/
-class Importance {
-
- private:
-
- typedef enum {
- IMPORTANCE_INVALID = -1,
-
- IMPORTANCE_NECESSARY,
- IMPORTANCE_URGENT,
- IMPORTANCE_SUGGESTED,
- IMPORTANCE_FEATURE,
- IMPORTANCE_MINOR,
- IMPORTANCE_UNDEFINED,
-
- // Not a real importance
- IMPORTANCE_LAST
- } importance_t;
-
- importance_t _importance;
-
- private:
- importance_t importance () const { return _importance; }
-
- public:
-
- Importance(const char *importance_str);
- virtual ~Importance();
-
- static const Importance & Undefined;
-
- // ---------------------------------- I/O
-
- static std::string toString ( const Importance & importance);
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Importance & importance);
-
- std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- // equality
- bool operator==( const Importance & importance) const {
- return _importance == importance.importance();
- }
-
- // inequality
- bool operator!=( const Importance & importance) const {
- return !(*this == importance);
- }
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Importance
+ /**
+ *
+ **/
+ class Importance {
+
+ private:
+
+ typedef enum {
+ IMPORTANCE_INVALID = -1,
+
+ IMPORTANCE_NECESSARY,
+ IMPORTANCE_URGENT,
+ IMPORTANCE_SUGGESTED,
+ IMPORTANCE_FEATURE,
+ IMPORTANCE_MINOR,
+ IMPORTANCE_UNDEFINED,
+
+ // Not a real importance
+ IMPORTANCE_LAST
+ } importance_t;
+
+ importance_t _importance;
+
+ private:
+ importance_t importance () const { return _importance; }
+
+ public:
+
+ Importance(const char *importance_str);
+ virtual ~Importance();
+
+ static const Importance & Undefined;
+
+ // ---------------------------------- I/O
+
+ static std::string toString ( const Importance & importance);
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Importance & importance);
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ // equality
+ bool operator==( const Importance & importance) const {
+ return _importance == importance.importance();
+ }
+
+ // inequality
+ bool operator!=( const Importance & importance) const {
+ return !(*this == importance);
+ }
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Importance_h
#include <zypp/solver/detail/Match.h>
#include <zypp/solver/detail/World.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(Match);
-
-//---------------------------------------------------------------------------
-
-string
-Match::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Match::toString ( const Match & lock )
-{
- return "<lock/>";
-}
-
-
-ostream &
-Match::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Match& edition)
-{
- return os << edition.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Match::Match()
- : _importance (Importance::Undefined)
-{
-}
-
-Match::Match (XmlNodePtr node)
- : _importance (Importance::Undefined)
-{
-}
-
-Match::~Match()
-{
-}
-
-//---------------------------------------------------------------------------
-
-XmlNodePtr
-Match::asXmlNode (void) const
-{
- return new XmlNode("match");
-}
-
-
-// equality
-bool
-Match::equals ( const Match & lock ) const {
-
- // Check the name glob
-
- if ((_name_glob.empty()) ^ (lock._name_glob.empty()))
- return false;
- if (_name_glob != lock._name_glob)
- return false;
-
- // Check the channel
-
- if ((_channel_id.empty()) ^ (lock._channel_id.empty()))
- return false;
- if (_channel_id != lock._channel_id)
- return false;
-
- // Check the importance
-
- if (_importance != lock._importance
- || _importance_gteq != lock._importance_gteq)
- {
- return false;
- }
-
- // Check the dep
- if ((_dependency == NULL) ^ (lock._dependency == NULL))
- return false;
- if (_dependency && lock._dependency) {
- if (!( ((constSpecPtr) _dependency)->equals((constSpecPtr) lock._dependency))
- || (_dependency->relation() != lock._dependency->relation())
- || (_dependency->kind() != lock._dependency->kind()))
- {
- return false;
- }
- }
-
- return true;
-}
-
-
-bool
-Match::test (constResItemPtr resItem, WorldPtr world) const
-{
- string name;
- constChannelPtr channel = resItem->channel ();
-
- if (channel != NULL && !_channel_id.empty()) {
- if (! channel->hasEqualId (_channel_id)) {
- return false;
- }
- }
-
- name = resItem->name ();
-
-// FIXME, implement regexp
-#if 0
- if (match->_pattern_spec
- && ! g_pattern_match_string (match->pattern_spec, name)) {
- return false;
- }
-#endif
-
- /* FIXME: ResItems don't have ResItemUpdate right now */
-/* if (match->importance != RC_IMPORTANCE_INVALID && */
-/* !rc_resItem_is_installed (resItem)) { */
-/* RCResItemUpdate *up = rc_resItem_get_latest_update (pkg); */
-/* if (up) { */
-/* if (match->importance_gteq ? up->importance > match->importance */
-/* : up->importance < match->importance) */
-/* return FALSE; */
-/* } */
-/* } */
-
- if (_dependency) {
- DependencyPtr dependency;
- bool check;
-
- dependency = new Dependency (resItem->name(), Relation::Equal, Kind::Package, resItem->channel(), resItem->edition());
- check = _dependency->verifyRelation (dependency);
- return check;
- }
-
- return true;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(Match);
+
+ //---------------------------------------------------------------------------
+
+ string
+ Match::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Match::toString ( const Match & lock )
+ {
+ return "<lock/>";
+ }
+
+
+ ostream &
+ Match::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Match& edition)
+ {
+ return os << edition.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Match::Match()
+ : _importance (Importance::Undefined)
+ {
+ }
+
+ Match::Match (XmlNodePtr node)
+ : _importance (Importance::Undefined)
+ {
+ }
+
+ Match::~Match()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ XmlNodePtr
+ Match::asXmlNode (void) const
+ {
+ return new XmlNode("match");
+ }
+
+
+ // equality
+ bool
+ Match::equals ( const Match & lock ) const {
+
+ // Check the name glob
+
+ if ((_name_glob.empty()) ^ (lock._name_glob.empty()))
+ return false;
+ if (_name_glob != lock._name_glob)
+ return false;
+
+ // Check the channel
+
+ if ((_channel_id.empty()) ^ (lock._channel_id.empty()))
+ return false;
+ if (_channel_id != lock._channel_id)
+ return false;
+
+ // Check the importance
+
+ if (_importance != lock._importance
+ || _importance_gteq != lock._importance_gteq)
+ {
+ return false;
+ }
+
+ // Check the dep
+ if ((_dependency == NULL) ^ (lock._dependency == NULL))
+ return false;
+ if (_dependency && lock._dependency) {
+ if (!( ((constSpecPtr) _dependency)->equals((constSpecPtr) lock._dependency))
+ || (_dependency->relation() != lock._dependency->relation())
+ || (_dependency->kind() != lock._dependency->kind()))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ bool
+ Match::test (constResItemPtr resItem, WorldPtr world) const
+ {
+ string name;
+ constChannelPtr channel = resItem->channel ();
+
+ if (channel != NULL && !_channel_id.empty()) {
+ if (! channel->hasEqualId (_channel_id)) {
+ return false;
+ }
+ }
+
+ name = resItem->name ();
+
+ // FIXME, implement regexp
+ #if 0
+ if (match->_pattern_spec
+ && ! g_pattern_match_string (match->pattern_spec, name)) {
+ return false;
+ }
+ #endif
+
+ /* FIXME: ResItems don't have ResItemUpdate right now */
+ /* if (match->importance != RC_IMPORTANCE_INVALID && */
+ /* !rc_resItem_is_installed (resItem)) { */
+ /* RCResItemUpdate *up = rc_resItem_get_latest_update (pkg); */
+ /* if (up) { */
+ /* if (match->importance_gteq ? up->importance > match->importance */
+ /* : up->importance < match->importance) */
+ /* return FALSE; */
+ /* } */
+ /* } */
+
+ if (_dependency) {
+ DependencyPtr dependency;
+ bool check;
+
+ dependency = new Dependency (resItem->name(), Relation::Equal, Kind::Package, resItem->channel(), resItem->edition());
+ check = _dependency->verifyRelation (dependency);
+ return check;
+ }
+
+ return true;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/WorldPtr.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-class Match;
-typedef std::list<constMatchPtr> MatchList;
-
-class World;
-typedef bool (*MatchFn) (constMatchPtr match, void *data);
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Match
-/**
- *
- **/
-class Match : public CountedRep {
- REP_BODY(Match);
-
- private:
- std::string _channel_id;
-
- constDependencyPtr _dependency;
-
- std::string _name_glob;
-// GPatternSpec *_pattern_spec;
-
- Importance _importance;
- bool _importance_gteq;
-
- public:
-
- Match();
- Match(XmlNodePtr node);
- virtual ~Match();
-
- // ---------------------------------- I/O
-
- static std::string toString ( const Match & lock );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Match & lock );
-
- std::string asString ( void ) const;
-
- XmlNodePtr asXmlNode (void) const;
-
- // ---------------------------------- accessors
-
- const std::string & channelId () const { return _channel_id; }
- void setChannel (constChannelPtr channel) { _channel_id = channel->id(); }
- void setChannelId (const std::string & channel_id) { _channel_id = channel_id; }
-
- constDependencyPtr dependency () const { return _dependency; }
- void setDependency (constDependencyPtr dependency) { _dependency = dependency; }
-
- const std::string & glob () const { return _name_glob; }
- void setGlob (const std::string & glob_str) { _name_glob = glob_str; }
-
- const Importance & importance (bool *match_gteq) const { *match_gteq = _importance_gteq; return _importance; }
- void setImportance (const Importance & importance, bool match_gteq) { _importance = importance; _importance_gteq = match_gteq; }
-
- // ---------------------------------- methods
-
- typedef bool (*MatchFn) (constMatchPtr, void *data);
-
- // equality
- bool equals (const Match & match) const;
-
- bool test (constResItemPtr resItem, WorldPtr world) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ class Match;
+ typedef std::list<constMatchPtr> MatchList;
+
+ class World;
+ typedef bool (*MatchFn) (constMatchPtr match, void *data);
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Match
+ /**
+ *
+ **/
+ class Match : public CountedRep {
+ REP_BODY(Match);
+
+ private:
+ std::string _channel_id;
+
+ constDependencyPtr _dependency;
+
+ std::string _name_glob;
+ // GPatternSpec *_pattern_spec;
+
+ Importance _importance;
+ bool _importance_gteq;
+
+ public:
+
+ Match();
+ Match(XmlNodePtr node);
+ virtual ~Match();
+
+ // ---------------------------------- I/O
+
+ static std::string toString ( const Match & lock );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Match & lock );
+
+ std::string asString ( void ) const;
+
+ XmlNodePtr asXmlNode (void) const;
+
+ // ---------------------------------- accessors
+
+ const std::string & channelId () const { return _channel_id; }
+ void setChannel (constChannelPtr channel) { _channel_id = channel->id(); }
+ void setChannelId (const std::string & channel_id) { _channel_id = channel_id; }
+
+ constDependencyPtr dependency () const { return _dependency; }
+ void setDependency (constDependencyPtr dependency) { _dependency = dependency; }
+
+ const std::string & glob () const { return _name_glob; }
+ void setGlob (const std::string & glob_str) { _name_glob = glob_str; }
+
+ const Importance & importance (bool *match_gteq) const { *match_gteq = _importance_gteq; return _importance; }
+ void setImportance (const Importance & importance, bool match_gteq) { _importance = importance; _importance_gteq = match_gteq; }
+
+ // ---------------------------------- methods
+
+ typedef bool (*MatchFn) (constMatchPtr, void *data);
+
+ // equality
+ bool equals (const Match & match) const;
+
+ bool test (constResItemPtr resItem, WorldPtr world) const;
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Match_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/Edition.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : MatchPtr
-// CLASS NAME : constMatchPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(Match);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : MatchPtr
+ // CLASS NAME : constMatchPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(Match);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _MatchPtr_h
#include <zypp/solver/detail/MultiWorld.h>
#include <zypp/solver/detail/ServiceWorld.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-//===========================================================================
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : SubWorldInfo
-
-class SubWorldInfo {
-
- private:
- WorldPtr _subworld;
- WorldPtr _refreshed_subworld;
-
- bool _refreshed_ready;
-
- unsigned int _changed_resItems_id;
- unsigned int _changed_channels_id;
- unsigned int _changed_subscriptions_id;
- unsigned int _changed_locks_id;
-
- public:
-
- SubWorldInfo (WorldPtr subworld, MultiWorldPtr multiworld);
- virtual ~SubWorldInfo();
-
- // ---------------------------------- I/O
-
- static std::string toString (const SubWorldInfo & subworldinfo);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const SubWorldInfo & subworldinfo);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- WorldPtr subworld () const { return _subworld; }
-
- // ---------------------------------- methods
-
-};
-
-//---------------------------------------------------------------------------
-
-string
-SubWorldInfo::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-SubWorldInfo::toString ( const SubWorldInfo & subworldinfo )
-{
- return "<subworldinfo/>";
-}
-
-
-ostream &
-SubWorldInfo::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const SubWorldInfo & subworldinfo)
-{
- return os << subworldinfo.asString();
-}
-
-//---------------------------------------------------------------------------
-
-SubWorldInfo::SubWorldInfo (WorldPtr subworld, MultiWorldPtr multiworld)
- : _subworld (subworld)
- , _changed_resItems_id (0)
- , _changed_channels_id (0)
- , _changed_subscriptions_id (0)
- , _changed_locks_id (0)
-
-{
-#if 0
- _changed_resItems_id =
- g_signal_connect (G_OBJECT (subworld),
- "changed_resItems",
- (GCallback) changed_resItems_cb,
- world);
-
- _changed_channels_id =
- g_signal_connect (G_OBJECT (subworld),
- "changed_channels",
- (GCallback) changed_channels_cb,
- world);
-
- _changed_subscriptions_id =
- g_signal_connect (G_OBJECT (subworld),
- "changed_subscriptions",
- (GCallback) changed_subscriptions_cb,
- world);
-
- _changed_locks_id =
- g_signal_connect (G_OBJECT (subworld),
- "changed_locks",
- (GCallback) changed_locks_cb,
- world);
-#endif
-}
-
-
-SubWorldInfo::~SubWorldInfo()
-{
-}
-
-
-//===========================================================================
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : NameConflictInfo
-
-class NameConflictInfo {
-
- private:
- int _depth;
- MultiWorldPtr _multiworld;
- WorldPtr _subworld;
- const char *_name;
-
- public:
- NameConflictInfo(int depth, MultiWorldPtr multiworld, WorldPtr subworld, const char *name);
- virtual ~NameConflictInfo();
-
- // ---------------------------------- I/O
-
- static std::string toString (const NameConflictInfo & nameconflictinfo);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const NameConflictInfo & nameconflictinfo);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- int depth () const { return _depth; }
- MultiWorldPtr multiworld () const { return _multiworld; }
- WorldPtr subworld () const { return _subworld; }
- const char *name () const { return _name; }
- void setName (const char *name) { free((void *)_name); _name = strdup (name); }
-
- // ---------------------------------- methods
-
- void incDepth (void) { _depth++; }
-};
-
-
-//---------------------------------------------------------------------------
-
-string
-NameConflictInfo::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-NameConflictInfo::toString ( const NameConflictInfo & subworldinfo )
-{
- return "<nameconflictinfo/>";
-}
-
-
-ostream &
-NameConflictInfo::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const NameConflictInfo & subworldinfo)
-{
- return os << subworldinfo.asString();
-}
-
-//---------------------------------------------------------------------------
-
-NameConflictInfo::NameConflictInfo (int depth, MultiWorldPtr multiworld, WorldPtr subworld, const char *name)
- : _depth (depth)
- , _multiworld (multiworld)
- , _subworld (subworld)
- , _name (strdup (name))
-{
-}
-
-
-NameConflictInfo::~NameConflictInfo()
-{
- free ((void *)_name);
-}
-
-
-//===========================================================================
-
-IMPL_DERIVED_POINTER(MultiWorld, World);
-
-string
-MultiWorld::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-MultiWorld::toString ( const MultiWorld & world )
-{
- return "<undumpworld/>";
-}
-
-
-ostream &
-MultiWorld::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const MultiWorld & world)
-{
- return os << world.asString();
-}
-
-//---------------------------------------------------------------------------
-
-MultiWorld::MultiWorld ()
- : World (MULTI_WORLD)
-{
-}
-
-
-MultiWorld::~MultiWorld()
-{
-}
-
-//---------------------------------------------------------------------------
-
-class ForeachByTypeInfo {
- public:
- WorldType type;
- WorldFn callback;
- NameConflictInfo *name_conflict_info;
-
- int count;
-};
-
-
-int
-MultiWorld::foreachSubworld (WorldFn callback, void *user_data)
-{
- if (callback == NULL) return -1;
-
- /* Make a copy of subworlds for case where user callback is
- running main loop and a refresh starts at that time. */
-
- WorldList copied_subworlds;
-
- for (SubWorldInfoList::iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- copied_subworlds.push_front ((*iter)->subworld());
- }
-
- int count = 0;
-
- for (WorldList::const_iterator iter = copied_subworlds.begin(); iter != copied_subworlds.end(); iter++) {
- if (! callback (*iter, user_data)) {
- count = -1;
- break;
- } else
- ++count;
- }
-
- return count;
-}
-
-
-static bool
-foreach_by_type_cb (constWorldPtr subworld, void *user_data)
-{
- ForeachByTypeInfo *info = (ForeachByTypeInfo *)user_data;
-
- if ((subworld->type() != info->type)
- || info->callback == NULL)
- {
- return true;
- }
-
- if (! info->callback (subworld, info->name_conflict_info)) {
- info->count = -1;
- return false;
- } else {
- ++info->count;
- return true;
- }
-}
-
-
-int
-MultiWorld::foreachSubworldByType (WorldType type, WorldFn callback, NameConflictInfo *name_conflict_info)
-{
- ForeachByTypeInfo info;
-
- info.type = type;
- info.callback = callback;
- info.name_conflict_info = name_conflict_info;
- info.count = 0;
-
- foreachSubworld (foreach_by_type_cb, (void *)(&info));
-
- return info.count;
-}
-
-//---------------------------------------------------------------------------
-// subworld
-
-static bool
-service_name_conflict_cb (constWorldPtr world, void *user_data)
-{
- constServiceWorldPtr service = world;
- if (service == NULL) {
- fprintf (stderr, "OOPS: service_name_conflict_cb: world is no service\n");
- abort();
- }
-
- NameConflictInfo *info = (NameConflictInfo *)user_data;
- if (!strcasecmp (service->name(), info->name())) {
- info->incDepth();
- ServiceWorldPtr infoservice = info->subworld();
- if (infoservice == NULL) {
- fprintf (stderr, "OOPS: service_name_conflict_cb: info->subworld is no service\n");
- abort();
- }
- info->setName (stringutil::form ("%s (%d)", infoservice->name(), info->depth()).c_str());
- info->multiworld()->foreachSubworldByType (SERVICE_WORLD, service_name_conflict_cb, info);
- return false;
- }
-
- return true;
-}
-
-
-void
-MultiWorld::addSubworld (WorldPtr subworld)
-{
- if (subworld == NULL) return;
-
- /*
- * If we're adding a service, make sure that the name of the service
- * doesn't conflict with any other.
- */
- ServiceWorldPtr service = subworld; // service will be NULL if subworld is not a ServiceWorld
-
- if (service != NULL) {
- NameConflictInfo conflict_info (0, this, subworld, service->name());
-
- foreachSubworldByType (SERVICE_WORLD, service_name_conflict_cb, &conflict_info);
-
- service->setName (conflict_info.name());
- }
-
- SubWorldInfo *subworld_info = new SubWorldInfo (subworld, this);
-
- _subworlds.push_back (subworld_info);
-
-// g_signal_emit (multi, signals[SUBWORLD_ADDED], 0, subworld);
-
- return;
-}
-
-
-void
-MultiWorld::removeSubworld (WorldPtr subworld)
-{
- if (subworld == NULL) return;
-
- for (SubWorldInfoList::iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- if ((*iter)->subworld() == subworld) {
- _subworlds.erase (iter);
-// g_signal_emit (multi, signals[SUBWORLD_REMOVED], 0, subworld);
- return;
- }
- }
- return;
-}
-
-
-//---------------------------------------------------------------------------
-// channels
-
-ChannelList
-MultiWorld::channels () const
-{
- ChannelList cl;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- cl = (*iter)->subworld()->channels();
-//FIXME cl.merge ((*iter)->subworld()->channels());
- }
- return cl;
-}
-
-
-bool
-MultiWorld::containsChannel (constChannelPtr channel) const
-{
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- if ((*iter)->subworld()->containsChannel(channel))
- return true;
- }
- return false;
-}
-
-
-ChannelPtr
-MultiWorld::getChannelByName (const char *channel_name) const
-{
- ChannelPtr channel;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- channel = (*iter)->subworld()->getChannelByName(channel_name);
- if (channel != NULL)
- return channel;
- }
- return NULL;
-}
-
-
-ChannelPtr
-MultiWorld::getChannelByAlias (const char *alias) const
-{
- ChannelPtr channel;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- channel = (*iter)->subworld()->getChannelByAlias(alias);
- if (channel != NULL)
- return channel;
- }
- return NULL;
-}
-
-
-ChannelPtr
-MultiWorld::getChannelById (const char *channel_id) const
-{
- ChannelPtr channel;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- channel = (*iter)->subworld()->getChannelById(channel_id);
- if (channel != NULL)
- return channel;
- }
- return NULL;
-}
-
-
-int
-MultiWorld::foreachChannel (ChannelFn fn, void *data) const
-{
- int count = 0;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- int this_count;
- this_count = (*iter)->subworld()->foreachChannel(fn, data);
- if (this_count < 0)
- return -1;
- count += this_count;
- }
- return count;
-}
-
-
-//---------------------------------------------------------------------------
-// Single resItem queries
-
-constResItemPtr
-MultiWorld::findInstalledResItem (constResItemPtr resItem)
-{
- constResItemPtr installed;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- installed = (*iter)->subworld()->findInstalledResItem(resItem);
- if (installed != NULL)
- return installed;
- }
- return NULL;
-}
-
-
-constResItemPtr
-MultiWorld::findResItem (constChannelPtr channel, const char *name) const
-{
- constResItemPtr resItem;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- resItem = (*iter)->subworld()->findResItem(channel, name);
- if (resItem != NULL)
- return resItem;
- }
- return NULL;
-}
-
-
-constResItemPtr
-MultiWorld::findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const
-{
- constResItemPtr resItem;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- resItem = (*iter)->subworld()->findResItemWithConstraint(channel, name, constraint, is_and);
- if (resItem != NULL)
- return resItem;
- }
- return NULL;
-}
-
-
-ChannelPtr
-MultiWorld::guessResItemChannel (constResItemPtr resItem) const
-{
- ChannelPtr channel;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- channel = (*iter)->subworld()->guessResItemChannel(resItem);
- if (channel != NULL)
- return channel;
- }
- return NULL;
-}
-
-//---------------------------------------------------------------------------
-// iterate over resItems
-
-int
-MultiWorld::foreachResItem (ChannelPtr channel, CResItemFn fn, void *data)
-{
- return foreachResItemByName ("", channel, fn, data);
-}
-
-
-int
-MultiWorld::foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data)
-{
- int count = 0;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- int this_count;
- this_count = (*iter)->subworld()->foreachResItemByName(name, channel, fn, data);
- if (this_count < 0)
- return -1;
- count += this_count;
- }
- return count;
-}
-
-
-int
-MultiWorld::foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data)
-{
- fprintf (stderr, "MultiWorld::foreachResItemByMatch not implemented\n");
- return 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// iterater over resItems with dependency
-
-int
-MultiWorld::foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data)
-{
- int count = 0;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- int this_count;
- this_count = (*iter)->subworld()->foreachProvidingResItem (dep, fn, data);
- if (this_count < 0)
- return -1;
- count += this_count;
- }
- return count;
-}
-
-int
-MultiWorld::foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
-{
- int count = 0;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- int this_count;
- this_count = (*iter)->subworld()->foreachRequiringResItem (dep, fn, data);
- if (this_count < 0)
- return -1;
- count += this_count;
- }
- return count;
-}
-
-int
-MultiWorld::foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
-{
- int count = 0;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- int this_count;
- this_count = (*iter)->subworld()->foreachConflictingResItem (dep, fn, data);
- if (this_count < 0)
- return -1;
- count += this_count;
- }
- return count;
-}
-
-
-//-----------------------------------------------------------------------------
-// iterater over resItems with locks
-
-int
-MultiWorld::foreachLock (MatchFn fn, void *data) const
-{
- int count = 0;
- for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
- int this_count;
- this_count = (*iter)->subworld()->foreachLock(fn, data);
- if (this_count < 0)
- return -1;
- count += this_count;
- }
- return count;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ //===========================================================================
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : SubWorldInfo
+
+ class SubWorldInfo {
+
+ private:
+ WorldPtr _subworld;
+ WorldPtr _refreshed_subworld;
+
+ bool _refreshed_ready;
+
+ unsigned int _changed_resItems_id;
+ unsigned int _changed_channels_id;
+ unsigned int _changed_subscriptions_id;
+ unsigned int _changed_locks_id;
+
+ public:
+
+ SubWorldInfo (WorldPtr subworld, MultiWorldPtr multiworld);
+ virtual ~SubWorldInfo();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const SubWorldInfo & subworldinfo);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const SubWorldInfo & subworldinfo);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ WorldPtr subworld () const { return _subworld; }
+
+ // ---------------------------------- methods
+
+ };
+
+ //---------------------------------------------------------------------------
+
+ string
+ SubWorldInfo::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ SubWorldInfo::toString ( const SubWorldInfo & subworldinfo )
+ {
+ return "<subworldinfo/>";
+ }
+
+
+ ostream &
+ SubWorldInfo::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const SubWorldInfo & subworldinfo)
+ {
+ return os << subworldinfo.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ SubWorldInfo::SubWorldInfo (WorldPtr subworld, MultiWorldPtr multiworld)
+ : _subworld (subworld)
+ , _changed_resItems_id (0)
+ , _changed_channels_id (0)
+ , _changed_subscriptions_id (0)
+ , _changed_locks_id (0)
+
+ {
+ #if 0
+ _changed_resItems_id =
+ g_signal_connect (G_OBJECT (subworld),
+ "changed_resItems",
+ (GCallback) changed_resItems_cb,
+ world);
+
+ _changed_channels_id =
+ g_signal_connect (G_OBJECT (subworld),
+ "changed_channels",
+ (GCallback) changed_channels_cb,
+ world);
+
+ _changed_subscriptions_id =
+ g_signal_connect (G_OBJECT (subworld),
+ "changed_subscriptions",
+ (GCallback) changed_subscriptions_cb,
+ world);
+
+ _changed_locks_id =
+ g_signal_connect (G_OBJECT (subworld),
+ "changed_locks",
+ (GCallback) changed_locks_cb,
+ world);
+ #endif
+ }
+
+
+ SubWorldInfo::~SubWorldInfo()
+ {
+ }
+
+
+ //===========================================================================
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : NameConflictInfo
+
+ class NameConflictInfo {
+
+ private:
+ int _depth;
+ MultiWorldPtr _multiworld;
+ WorldPtr _subworld;
+ const char *_name;
+
+ public:
+ NameConflictInfo(int depth, MultiWorldPtr multiworld, WorldPtr subworld, const char *name);
+ virtual ~NameConflictInfo();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const NameConflictInfo & nameconflictinfo);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const NameConflictInfo & nameconflictinfo);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ int depth () const { return _depth; }
+ MultiWorldPtr multiworld () const { return _multiworld; }
+ WorldPtr subworld () const { return _subworld; }
+ const char *name () const { return _name; }
+ void setName (const char *name) { free((void *)_name); _name = strdup (name); }
+
+ // ---------------------------------- methods
+
+ void incDepth (void) { _depth++; }
+ };
+
+
+ //---------------------------------------------------------------------------
+
+ string
+ NameConflictInfo::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ NameConflictInfo::toString ( const NameConflictInfo & subworldinfo )
+ {
+ return "<nameconflictinfo/>";
+ }
+
+
+ ostream &
+ NameConflictInfo::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const NameConflictInfo & subworldinfo)
+ {
+ return os << subworldinfo.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ NameConflictInfo::NameConflictInfo (int depth, MultiWorldPtr multiworld, WorldPtr subworld, const char *name)
+ : _depth (depth)
+ , _multiworld (multiworld)
+ , _subworld (subworld)
+ , _name (strdup (name))
+ {
+ }
+
+
+ NameConflictInfo::~NameConflictInfo()
+ {
+ free ((void *)_name);
+ }
+
+
+ //===========================================================================
+
+ IMPL_DERIVED_POINTER(MultiWorld, World);
+
+ string
+ MultiWorld::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ MultiWorld::toString ( const MultiWorld & world )
+ {
+ return "<undumpworld/>";
+ }
+
+
+ ostream &
+ MultiWorld::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const MultiWorld & world)
+ {
+ return os << world.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ MultiWorld::MultiWorld ()
+ : World (MULTI_WORLD)
+ {
+ }
+
+
+ MultiWorld::~MultiWorld()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ class ForeachByTypeInfo {
+ public:
+ WorldType type;
+ WorldFn callback;
+ NameConflictInfo *name_conflict_info;
+
+ int count;
+ };
+
+
+ int
+ MultiWorld::foreachSubworld (WorldFn callback, void *user_data)
+ {
+ if (callback == NULL) return -1;
+
+ /* Make a copy of subworlds for case where user callback is
+ running main loop and a refresh starts at that time. */
+
+ WorldList copied_subworlds;
+
+ for (SubWorldInfoList::iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ copied_subworlds.push_front ((*iter)->subworld());
+ }
+
+ int count = 0;
+
+ for (WorldList::const_iterator iter = copied_subworlds.begin(); iter != copied_subworlds.end(); iter++) {
+ if (! callback (*iter, user_data)) {
+ count = -1;
+ break;
+ } else
+ ++count;
+ }
+
+ return count;
+ }
+
+
+ static bool
+ foreach_by_type_cb (constWorldPtr subworld, void *user_data)
+ {
+ ForeachByTypeInfo *info = (ForeachByTypeInfo *)user_data;
+
+ if ((subworld->type() != info->type)
+ || info->callback == NULL)
+ {
+ return true;
+ }
+
+ if (! info->callback (subworld, info->name_conflict_info)) {
+ info->count = -1;
+ return false;
+ } else {
+ ++info->count;
+ return true;
+ }
+ }
+
+
+ int
+ MultiWorld::foreachSubworldByType (WorldType type, WorldFn callback, NameConflictInfo *name_conflict_info)
+ {
+ ForeachByTypeInfo info;
+
+ info.type = type;
+ info.callback = callback;
+ info.name_conflict_info = name_conflict_info;
+ info.count = 0;
+
+ foreachSubworld (foreach_by_type_cb, (void *)(&info));
+
+ return info.count;
+ }
+
+ //---------------------------------------------------------------------------
+ // subworld
+
+ static bool
+ service_name_conflict_cb (constWorldPtr world, void *user_data)
+ {
+ constServiceWorldPtr service = world;
+ if (service == NULL) {
+ fprintf (stderr, "OOPS: service_name_conflict_cb: world is no service\n");
+ abort();
+ }
+
+ NameConflictInfo *info = (NameConflictInfo *)user_data;
+ if (!strcasecmp (service->name(), info->name())) {
+ info->incDepth();
+ ServiceWorldPtr infoservice = info->subworld();
+ if (infoservice == NULL) {
+ fprintf (stderr, "OOPS: service_name_conflict_cb: info->subworld is no service\n");
+ abort();
+ }
+ info->setName (stringutil::form ("%s (%d)", infoservice->name(), info->depth()).c_str());
+ info->multiworld()->foreachSubworldByType (SERVICE_WORLD, service_name_conflict_cb, info);
+ return false;
+ }
+
+ return true;
+ }
+
+
+ void
+ MultiWorld::addSubworld (WorldPtr subworld)
+ {
+ if (subworld == NULL) return;
+
+ /*
+ * If we're adding a service, make sure that the name of the service
+ * doesn't conflict with any other.
+ */
+ ServiceWorldPtr service = subworld; // service will be NULL if subworld is not a ServiceWorld
+
+ if (service != NULL) {
+ NameConflictInfo conflict_info (0, this, subworld, service->name());
+
+ foreachSubworldByType (SERVICE_WORLD, service_name_conflict_cb, &conflict_info);
+
+ service->setName (conflict_info.name());
+ }
+
+ SubWorldInfo *subworld_info = new SubWorldInfo (subworld, this);
+
+ _subworlds.push_back (subworld_info);
+
+ // g_signal_emit (multi, signals[SUBWORLD_ADDED], 0, subworld);
+
+ return;
+ }
+
+
+ void
+ MultiWorld::removeSubworld (WorldPtr subworld)
+ {
+ if (subworld == NULL) return;
+
+ for (SubWorldInfoList::iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ if ((*iter)->subworld() == subworld) {
+ _subworlds.erase (iter);
+ // g_signal_emit (multi, signals[SUBWORLD_REMOVED], 0, subworld);
+ return;
+ }
+ }
+ return;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // channels
+
+ ChannelList
+ MultiWorld::channels () const
+ {
+ ChannelList cl;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ cl = (*iter)->subworld()->channels();
+ //FIXME cl.merge ((*iter)->subworld()->channels());
+ }
+ return cl;
+ }
+
+
+ bool
+ MultiWorld::containsChannel (constChannelPtr channel) const
+ {
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ if ((*iter)->subworld()->containsChannel(channel))
+ return true;
+ }
+ return false;
+ }
+
+
+ ChannelPtr
+ MultiWorld::getChannelByName (const char *channel_name) const
+ {
+ ChannelPtr channel;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ channel = (*iter)->subworld()->getChannelByName(channel_name);
+ if (channel != NULL)
+ return channel;
+ }
+ return NULL;
+ }
+
+
+ ChannelPtr
+ MultiWorld::getChannelByAlias (const char *alias) const
+ {
+ ChannelPtr channel;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ channel = (*iter)->subworld()->getChannelByAlias(alias);
+ if (channel != NULL)
+ return channel;
+ }
+ return NULL;
+ }
+
+
+ ChannelPtr
+ MultiWorld::getChannelById (const char *channel_id) const
+ {
+ ChannelPtr channel;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ channel = (*iter)->subworld()->getChannelById(channel_id);
+ if (channel != NULL)
+ return channel;
+ }
+ return NULL;
+ }
+
+
+ int
+ MultiWorld::foreachChannel (ChannelFn fn, void *data) const
+ {
+ int count = 0;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ int this_count;
+ this_count = (*iter)->subworld()->foreachChannel(fn, data);
+ if (this_count < 0)
+ return -1;
+ count += this_count;
+ }
+ return count;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // Single resItem queries
+
+ constResItemPtr
+ MultiWorld::findInstalledResItem (constResItemPtr resItem)
+ {
+ constResItemPtr installed;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ installed = (*iter)->subworld()->findInstalledResItem(resItem);
+ if (installed != NULL)
+ return installed;
+ }
+ return NULL;
+ }
+
+
+ constResItemPtr
+ MultiWorld::findResItem (constChannelPtr channel, const char *name) const
+ {
+ constResItemPtr resItem;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ resItem = (*iter)->subworld()->findResItem(channel, name);
+ if (resItem != NULL)
+ return resItem;
+ }
+ return NULL;
+ }
+
+
+ constResItemPtr
+ MultiWorld::findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const
+ {
+ constResItemPtr resItem;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ resItem = (*iter)->subworld()->findResItemWithConstraint(channel, name, constraint, is_and);
+ if (resItem != NULL)
+ return resItem;
+ }
+ return NULL;
+ }
+
+
+ ChannelPtr
+ MultiWorld::guessResItemChannel (constResItemPtr resItem) const
+ {
+ ChannelPtr channel;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ channel = (*iter)->subworld()->guessResItemChannel(resItem);
+ if (channel != NULL)
+ return channel;
+ }
+ return NULL;
+ }
+
+ //---------------------------------------------------------------------------
+ // iterate over resItems
+
+ int
+ MultiWorld::foreachResItem (ChannelPtr channel, CResItemFn fn, void *data)
+ {
+ return foreachResItemByName ("", channel, fn, data);
+ }
+
+
+ int
+ MultiWorld::foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data)
+ {
+ int count = 0;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ int this_count;
+ this_count = (*iter)->subworld()->foreachResItemByName(name, channel, fn, data);
+ if (this_count < 0)
+ return -1;
+ count += this_count;
+ }
+ return count;
+ }
+
+
+ int
+ MultiWorld::foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data)
+ {
+ fprintf (stderr, "MultiWorld::foreachResItemByMatch not implemented\n");
+ return 0;
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // iterater over resItems with dependency
+
+ int
+ MultiWorld::foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data)
+ {
+ int count = 0;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ int this_count;
+ this_count = (*iter)->subworld()->foreachProvidingResItem (dep, fn, data);
+ if (this_count < 0)
+ return -1;
+ count += this_count;
+ }
+ return count;
+ }
+
+ int
+ MultiWorld::foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
+ {
+ int count = 0;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ int this_count;
+ this_count = (*iter)->subworld()->foreachRequiringResItem (dep, fn, data);
+ if (this_count < 0)
+ return -1;
+ count += this_count;
+ }
+ return count;
+ }
+
+ int
+ MultiWorld::foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
+ {
+ int count = 0;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ int this_count;
+ this_count = (*iter)->subworld()->foreachConflictingResItem (dep, fn, data);
+ if (this_count < 0)
+ return -1;
+ count += this_count;
+ }
+ return count;
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // iterater over resItems with locks
+
+ int
+ MultiWorld::foreachLock (MatchFn fn, void *data) const
+ {
+ int count = 0;
+ for (SubWorldInfoList::const_iterator iter = _subworlds.begin(); iter != _subworlds.end(); iter++) {
+ int this_count;
+ this_count = (*iter)->subworld()->foreachLock(fn, data);
+ if (this_count < 0)
+ return -1;
+ count += this_count;
+ }
+ return count;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/World.h>
#include <zypp/solver/detail/Pending.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
class SubWorldInfo;
class NameConflictInfo;
class MultiWorld : public World {
REP_BODY(MultiWorld);
- private:
-
- SubWorldInfoList _subworlds;
-
- PendingPtr _multi_pending;
- PendingList _subworld_pendings;
-
- void (*_subworld_added) (WorldPtr subworld);
- void (*_subworld_removed) (WorldPtr subworld);
-
- public:
-
- MultiWorld ();
- MultiWorld (XmlNodePtr node);
- MultiWorld (const char *filename);
- virtual ~MultiWorld();
-
- // ---------------------------------- I/O
-
- static std::string toString (const MultiWorld & section);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const MultiWorld & section);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- void addSubworld (WorldPtr subworld);
- void removeSubworld (WorldPtr subworld);
-
- // ---------------------------------- methods
-
- virtual ChannelList channels () const;
- virtual bool containsChannel (constChannelPtr channel) const;
- virtual ChannelPtr getChannelByName (const char *channel_name) const;
- virtual ChannelPtr getChannelByAlias (const char *alias) const;
- virtual ChannelPtr getChannelById (const char *channel_id) const;
- virtual ChannelPtr guessResItemChannel (constResItemPtr resItem) const;
- virtual int foreachChannel (ChannelFn fn, void *data) const;
-
- int foreachSubworld (WorldFn callback, void *user_data);
- int foreachSubworldByType (WorldType type, WorldFn callback, NameConflictInfo *info);
- WorldList getSubworlds ();
- ServiceWorldPtr lookupService (const char *url);
- ServiceWorldPtr lookupServiceById (const char *id);
- bool mountService (const char *url, void *error); // GError **error);
-
- // Single resItem queries
-
- virtual constResItemPtr findInstalledResItem (constResItemPtr resItem);
- virtual constResItemPtr findResItem (constChannelPtr channel, const char *name) const;
- virtual constResItemPtr findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const;
-
- // Iterate over resItems
-
- virtual int foreachResItem (ChannelPtr channel, CResItemFn fn, void *data);
- virtual int foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data);
- virtual int foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data);
-
- // Iterate across provides or requirement
-
- virtual int foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data);
- virtual int foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
- virtual int foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
-
- // locks
-
- virtual int foreachLock (MatchFn fn, void *data) const;
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ private:
+
+ SubWorldInfoList _subworlds;
+
+ PendingPtr _multi_pending;
+ PendingList _subworld_pendings;
+
+ void (*_subworld_added) (WorldPtr subworld);
+ void (*_subworld_removed) (WorldPtr subworld);
+
+ public:
+
+ MultiWorld ();
+ MultiWorld (XmlNodePtr node);
+ MultiWorld (const char *filename);
+ virtual ~MultiWorld();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const MultiWorld & section);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const MultiWorld & section);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ void addSubworld (WorldPtr subworld);
+ void removeSubworld (WorldPtr subworld);
+
+ // ---------------------------------- methods
+
+ virtual ChannelList channels () const;
+ virtual bool containsChannel (constChannelPtr channel) const;
+ virtual ChannelPtr getChannelByName (const char *channel_name) const;
+ virtual ChannelPtr getChannelByAlias (const char *alias) const;
+ virtual ChannelPtr getChannelById (const char *channel_id) const;
+ virtual ChannelPtr guessResItemChannel (constResItemPtr resItem) const;
+ virtual int foreachChannel (ChannelFn fn, void *data) const;
+
+ int foreachSubworld (WorldFn callback, void *user_data);
+ int foreachSubworldByType (WorldType type, WorldFn callback, NameConflictInfo *info);
+ WorldList getSubworlds ();
+ ServiceWorldPtr lookupService (const char *url);
+ ServiceWorldPtr lookupServiceById (const char *id);
+ bool mountService (const char *url, void *error); // GError **error);
+
+ // Single resItem queries
+
+ virtual constResItemPtr findInstalledResItem (constResItemPtr resItem);
+ virtual constResItemPtr findResItem (constChannelPtr channel, const char *name) const;
+ virtual constResItemPtr findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const;
+
+ // Iterate over resItems
+
+ virtual int foreachResItem (ChannelPtr channel, CResItemFn fn, void *data);
+ virtual int foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data);
+ virtual int foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data);
+
+ // Iterate across provides or requirement
+
+ virtual int foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data);
+ virtual int foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
+ virtual int foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
+
+ // locks
+
+ virtual int foreachLock (MatchFn fn, void *data) const;
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _MultiWorld_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/WorldPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : MultiWorldPtr
-// CLASS NAME : constMultiWorldPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(MultiWorld, World);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : MultiWorldPtr
+ // CLASS NAME : constMultiWorldPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(MultiWorld, World);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _MultiWorldPtr_h
#include <zypp/solver/detail/OrDependency.h>
#include <zypp/solver/detail/Dependency.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(OrDependency);
-
-OrDependency::OrDependencyTable OrDependency::_or_dep_table;
-
-//---------------------------------------------------------------------------
-
-string
-OrDependency::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-OrDependency::toString ( const OrDependency & dependency )
-{
- string res ("<ordependency/>");
-
- return res;
-}
-
-
-ostream &
-OrDependency::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream & os, const OrDependency & dependency)
-{
- return os << dependency.asString();
-}
-
-//---------------------------------------------------------------------------
-
-OrDependency::OrDependency (string & dep, const CDependencyList & split_ors)
- : _or_dep (dep)
- , _split_ors (split_ors)
- , _ref(1)
-{
-}
-
-
-OrDependency::OrDependency (constXmlNodePtr node)
-{
-}
-
-
-OrDependency::~OrDependency()
-{
-}
-
-
-//---------------------------------------------------------------------------
-
-OrDependencyPtr
-OrDependency::fromDependencyList (const CDependencyList & deplist)
-{
- string depstr = dependencyListToString(deplist);
-
- OrDependencyTable::iterator pos = _or_dep_table.find(depstr);
- if (pos != _or_dep_table.end()) {
- (*pos).second->incRef();
- return (*pos).second;
- }
-
- OrDependencyPtr or_dep = new OrDependency (depstr, deplist);
- _or_dep_table[depstr] = or_dep;
- return or_dep;
-}
-
-
-OrDependencyPtr
-OrDependency::fromString (const char *dep)
-{
- string depstr = string (dep);
-
- OrDependencyTable::iterator pos = _or_dep_table.find(depstr);
- if (pos != _or_dep_table.end()) {
- (*pos).second->incRef();
- return (*pos).second;
- }
-
- CDependencyList deplist = stringToDependencyList (dep);
- OrDependencyPtr or_dep = new OrDependency (depstr, deplist);
- _or_dep_table[depstr] = or_dep;
- return or_dep;
-
-}
-
-
-string
-OrDependency::dependencyListToString (const CDependencyList & deplist)
-{
- string str ("(||");
-
- for (CDependencyList::const_iterator dep = deplist.begin(); dep != deplist.end(); dep++) {
- if (dep != deplist.begin())
- str += "|";
-
- str += (*dep)->name();
-
- Relation relation = (*dep)->relation();
-
- if (relation != Relation::Any) {
- str += "&";
- str += relation.asString();
- str += "&";
-
- if ((*dep)->epoch() >= 0) {
- str += stringutil::form("%d:", (*dep)->epoch());
- }
-
- str += (*dep)->version();
-
- string rel = (*dep)->release();
- if (!rel.empty()) {
- str += "-";
- str += rel;
- }
- }
-
- }
-
- str += ")";
-
- return str;
-}
-
-
-CDependencyList
-OrDependency::stringToDependencyList (const char *s)
-{
- const char *p, *zz;
- CDependencyList out_dep;
- bool have_more = true;
-
- if (strncmp (s, "(||", 3)) {
- fprintf (stderr, "'%s' is not a 'munged or' string!\n", s);
- return out_dep;
- }
-
- s += 3;
-
- zz = strchr (s, ')');
-
- if (!zz)
- return out_dep;
-
- /* s now points to the start of the first thing */
- do {
- char *z;
- SpecPtr spec;
- char *name;
- Relation relation = Relation::Any;
- EditionPtr edition = NULL;
-
- /* grab the name */
-
- z = strchr (s, '|');
- p = strchr (s, '&');
-
- if (!z) {
- have_more = false;
- }
- else {
- /* We don't want to get a p from a later element. */
- if (p > z)
- p = NULL;
- }
-
- name = strndup (s, p ? p - s : (z ? z - s : zz - s));
-
- if (p) {
- char *e;
- char op[4];
- char *vstr;
-
- /* We need to parse version things */
- p++;
- e = strchr (p, '&');
- if (!e || e-p > 3) {
- /* Bad. */
- fprintf (stderr, "Couldn't parse ver str [%s]\n", p);
- }
-
- /* text between p and e is an operator */
- strncpy (op, p, e - p);
- op[e - p] = 0;
- relation = Relation::parse (op);
-
- e++;
- if (z) {
- p = z;
- } else {
- p = zz;
- }
-
- /* e .. p is the epoch:version-release */
- vstr = strndup (e, p - e);
-
- EditionPtr edition = Edition::fromString (vstr);
-
- free ((void *)vstr);
-
- }
-
- DependencyPtr dep = new Dependency (name, relation, Kind::Package, NULL, edition);
-
- out_dep.push_back (dep);
- free ((void *)name);
-
- s = z + 1;
-
- if (p == zz)
- have_more = false;
- } while (have_more);
-
- return out_dep;
-}
-
-
-void
-OrDependency::addCreatedProvide (constDependencyPtr dep)
-{
- _created_provides.push_back (dep);
-}
-
-
-constDependencyPtr
-OrDependency::find (const char *dep)
-{
- string depstr (dep);
-
- OrDependencyTable::iterator pos = _or_dep_table.find(depstr);
- if (pos != _or_dep_table.end()) {
- return new Dependency ((*pos).second);
- }
-
- return NULL;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(OrDependency);
+
+ OrDependency::OrDependencyTable OrDependency::_or_dep_table;
+
+ //---------------------------------------------------------------------------
+
+ string
+ OrDependency::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ OrDependency::toString ( const OrDependency & dependency )
+ {
+ string res ("<ordependency/>");
+
+ return res;
+ }
+
+
+ ostream &
+ OrDependency::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream & os, const OrDependency & dependency)
+ {
+ return os << dependency.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ OrDependency::OrDependency (string & dep, const CDependencyList & split_ors)
+ : _or_dep (dep)
+ , _split_ors (split_ors)
+ , _ref(1)
+ {
+ }
+
+
+ OrDependency::OrDependency (constXmlNodePtr node)
+ {
+ }
+
+
+ OrDependency::~OrDependency()
+ {
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ OrDependencyPtr
+ OrDependency::fromDependencyList (const CDependencyList & deplist)
+ {
+ string depstr = dependencyListToString(deplist);
+
+ OrDependencyTable::iterator pos = _or_dep_table.find(depstr);
+ if (pos != _or_dep_table.end()) {
+ (*pos).second->incRef();
+ return (*pos).second;
+ }
+
+ OrDependencyPtr or_dep = new OrDependency (depstr, deplist);
+ _or_dep_table[depstr] = or_dep;
+ return or_dep;
+ }
+
+
+ OrDependencyPtr
+ OrDependency::fromString (const char *dep)
+ {
+ string depstr = string (dep);
+
+ OrDependencyTable::iterator pos = _or_dep_table.find(depstr);
+ if (pos != _or_dep_table.end()) {
+ (*pos).second->incRef();
+ return (*pos).second;
+ }
+
+ CDependencyList deplist = stringToDependencyList (dep);
+ OrDependencyPtr or_dep = new OrDependency (depstr, deplist);
+ _or_dep_table[depstr] = or_dep;
+ return or_dep;
+
+ }
+
+
+ string
+ OrDependency::dependencyListToString (const CDependencyList & deplist)
+ {
+ string str ("(||");
+
+ for (CDependencyList::const_iterator dep = deplist.begin(); dep != deplist.end(); dep++) {
+ if (dep != deplist.begin())
+ str += "|";
+
+ str += (*dep)->name();
+
+ Relation relation = (*dep)->relation();
+
+ if (relation != Relation::Any) {
+ str += "&";
+ str += relation.asString();
+ str += "&";
+
+ if ((*dep)->epoch() >= 0) {
+ str += stringutil::form("%d:", (*dep)->epoch());
+ }
+
+ str += (*dep)->version();
+
+ string rel = (*dep)->release();
+ if (!rel.empty()) {
+ str += "-";
+ str += rel;
+ }
+ }
+
+ }
+
+ str += ")";
+
+ return str;
+ }
+
+
+ CDependencyList
+ OrDependency::stringToDependencyList (const char *s)
+ {
+ const char *p, *zz;
+ CDependencyList out_dep;
+ bool have_more = true;
+
+ if (strncmp (s, "(||", 3)) {
+ fprintf (stderr, "'%s' is not a 'munged or' string!\n", s);
+ return out_dep;
+ }
+
+ s += 3;
+
+ zz = strchr (s, ')');
+
+ if (!zz)
+ return out_dep;
+
+ /* s now points to the start of the first thing */
+ do {
+ char *z;
+ SpecPtr spec;
+ char *name;
+ Relation relation = Relation::Any;
+ EditionPtr edition = NULL;
+
+ /* grab the name */
+
+ z = strchr (s, '|');
+ p = strchr (s, '&');
+
+ if (!z) {
+ have_more = false;
+ }
+ else {
+ /* We don't want to get a p from a later element. */
+ if (p > z)
+ p = NULL;
+ }
+
+ name = strndup (s, p ? p - s : (z ? z - s : zz - s));
+
+ if (p) {
+ char *e;
+ char op[4];
+ char *vstr;
+
+ /* We need to parse version things */
+ p++;
+ e = strchr (p, '&');
+ if (!e || e-p > 3) {
+ /* Bad. */
+ fprintf (stderr, "Couldn't parse ver str [%s]\n", p);
+ }
+
+ /* text between p and e is an operator */
+ strncpy (op, p, e - p);
+ op[e - p] = 0;
+ relation = Relation::parse (op);
+
+ e++;
+ if (z) {
+ p = z;
+ } else {
+ p = zz;
+ }
+
+ /* e .. p is the epoch:version-release */
+ vstr = strndup (e, p - e);
+
+ EditionPtr edition = Edition::fromString (vstr);
+
+ free ((void *)vstr);
+
+ }
+
+ DependencyPtr dep = new Dependency (name, relation, Kind::Package, NULL, edition);
+
+ out_dep.push_back (dep);
+ free ((void *)name);
+
+ s = z + 1;
+
+ if (p == zz)
+ have_more = false;
+ } while (have_more);
+
+ return out_dep;
+ }
+
+
+ void
+ OrDependency::addCreatedProvide (constDependencyPtr dep)
+ {
+ _created_provides.push_back (dep);
+ }
+
+
+ constDependencyPtr
+ OrDependency::find (const char *dep)
+ {
+ string depstr (dep);
+
+ OrDependencyTable::iterator pos = _or_dep_table.find(depstr);
+ if (pos != _or_dep_table.end()) {
+ return new Dependency ((*pos).second);
+ }
+
+ return NULL;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : OrDependency
-/**
- *
- **/
-
-class OrDependency : public CountedRep {
- REP_BODY(OrDependency);
-
- private:
- typedef std::map<std::string, OrDependencyPtr> OrDependencyTable;
-
- static OrDependencyTable _or_dep_table;
-
- std::string _or_dep;
- CDependencyList _split_ors;
- CDependencyList _created_provides;
- int _ref;
-
- OrDependency (std::string & dep, const CDependencyList & split_ors);
-
- static std::string dependencyListToString (const CDependencyList & deplist);
- static CDependencyList stringToDependencyList (const char *s);
-
- void incRef() { _ref++; }
- void decRef() { _ref--; }
-
- public:
-
- OrDependency (constXmlNodePtr node);
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
- virtual ~OrDependency();
-
- // ---------------------------------- I/O
-
- const xmlNodePtr asXmlNode (void) const;
-
- static std::string toString ( const OrDependency & ordep );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const OrDependency & ordep );
-
- std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- const char *name (void) const { return _or_dep.c_str(); }
- void addCreatedProvide (constDependencyPtr dep);
-
- // ---------------------------------- methods
-
- static OrDependencyPtr fromDependencyList (const CDependencyList & deplist);
- static OrDependencyPtr fromString (const char *dep);
- static constDependencyPtr find (const char *dep);
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
///////////////////////////////////////////////////////////////////
-
+ //
+ // CLASS NAME : OrDependency
+ /**
+ *
+ **/
+
+ class OrDependency : public CountedRep {
+ REP_BODY(OrDependency);
+
+ private:
+ typedef std::map<std::string, OrDependencyPtr> OrDependencyTable;
+
+ static OrDependencyTable _or_dep_table;
+
+ std::string _or_dep;
+ CDependencyList _split_ors;
+ CDependencyList _created_provides;
+ int _ref;
+
+ OrDependency (std::string & dep, const CDependencyList & split_ors);
+
+ static std::string dependencyListToString (const CDependencyList & deplist);
+ static CDependencyList stringToDependencyList (const char *s);
+
+ void incRef() { _ref++; }
+ void decRef() { _ref--; }
+
+ public:
+
+ OrDependency (constXmlNodePtr node);
+
+ virtual ~OrDependency();
+
+ // ---------------------------------- I/O
+
+ const xmlNodePtr asXmlNode (void) const;
+
+ static std::string toString ( const OrDependency & ordep );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const OrDependency & ordep );
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ const char *name (void) const { return _or_dep.c_str(); }
+ void addCreatedProvide (constDependencyPtr dep);
+
+ // ---------------------------------- methods
+
+ static OrDependencyPtr fromDependencyList (const CDependencyList & deplist);
+ static OrDependencyPtr fromString (const char *dep);
+ static constDependencyPtr find (const char *dep);
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _OrDependency_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : OrDependencyPtr
-// CLASS NAME : constOrDependencyPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(OrDependency);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : OrDependencyPtr
+ // CLASS NAME : constOrDependencyPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(OrDependency);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _DependencyPtr_h
#include <zypp/solver/detail/World.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(Package,Spec);
-
-struct DepTable {
- CDependencyList requires;
- CDependencyList provides;
- CDependencyList conflicts;
- CDependencyList obsoletes;
- CDependencyList children;
- CDependencyList suggests;
- CDependencyList recommends;
-};
-
-//---------------------------------------------------------------------------
-
-static void
-extract_dep_info (constXmlNodePtr iter, struct DepTable & dep_table)
-{
- if (iter->equals("requires")) {
- constXmlNodePtr iter2;
-
- iter2 = iter->children();
-
- while (iter2) {
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- dep_table.requires.push_back(new Dependency (iter2));
- iter2 = iter2->next();
- }
-
- } else if (iter->equals("recommends")) {
- constXmlNodePtr iter2;
-
- iter2 = iter->children();
-
- while (iter2) {
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- dep_table.recommends.push_back (new Dependency (iter2));
- iter2 = iter2->next();
- }
-
- } else if (iter->equals("suggests")) {
- constXmlNodePtr iter2;
-
- iter2 = iter->children();
-
- while (iter2) {
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- dep_table.suggests.push_back (new Dependency (iter2));
- iter2 = iter2->next();
- }
-
- } else if (iter->equals("conflicts")) {
- XmlNodePtr iter2;
- bool all_are_obs = false, this_is_obs = false;
- const char *obs;
-
- iter2 = iter->children();
-
- obs = iter->getProp ("obsoletes", NULL);
- if (obs) {
- all_are_obs = true;
- free ((void *)obs);
- }
-
- while (iter2) {
-
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- DependencyPtr dep = new Dependency (iter2);
-
- if (! all_are_obs) {
- this_is_obs = false;
- obs = iter2->getProp ("obsoletes", NULL);
- if (obs) {
- this_is_obs = true;
- free ((void *)obs);
- }
- }
-
- if (all_are_obs || this_is_obs) {
- dep_table.obsoletes.push_back (dep);
- } else {
- dep_table.conflicts.push_back (dep);
- }
-
- iter2 = iter2->next();
- }
-
- } else if (iter->equals("obsoletes")) {
- constXmlNodePtr iter2;
-
- iter2 = iter->children();
-
- while (iter2) {
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- dep_table.obsoletes.push_back (new Dependency (iter2));
- iter2 = iter2->next();
- }
-
- } else if (iter->equals("provides")) {
- constXmlNodePtr iter2;
-
- iter2 = iter->children();
-
- while (iter2) {
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- dep_table.provides.push_back (new Dependency (iter2));
- iter2 = iter2->next();
- }
-
- } else if (iter->equals("children")) {
- constXmlNodePtr iter2;
-
- iter2 = iter->children();
-
- while (iter2) {
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- dep_table.children.push_back (new Dependency (iter2));
- iter2 = iter2->next();
- }
- }
-}
-
-//---------------------------------------------------------------------------
-
-
-string
-Package::asString ( bool full ) const
-{
- return toString (*this, full);
-}
-
-
-string
-Package::toString ( const PackageUpdateList & l, bool full )
-{
- string ret ("[");
- for (PackageUpdateList::const_iterator i = l.begin(); i != l.end(); i++) {
- if (i != l.begin()) ret += ", ";
- ret += (*i)->asString(full);
- }
- return ret + "]";
-}
-
-string
-Package::toString ( const Package & package, bool full )
-{
- string ret;
- ret += ResItem::toString(package, full);
- if (full) {
-// if (package._section != NULL) ret += (string ("<section '") + package._section->asString() + "'/>");
-// if (!package._pretty_name.empty()) ret += (string ("<pretty_name '") + package._pretty_name + "'/>");
-// if (!package._summary.empty()) ret += (string ("<summary '") + package._summary + "'/>");
-// if (!package._description.empty()) ret += (string ("<description '") + package._description + "'/>");
- ret += (string ("<history '") + toString(package._history) + "'/>");
- }
- return ret;
-}
-
-
-ostream &
-Package::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Package& package)
-{
- return os << package.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Package::Package (constChannelPtr channel)
- : ResItem (Kind::Package, "")
- , _section (NULL)
- , _pretty_name ("")
- , _summary ("")
- , _description ("")
- , _package_filename ("")
- , _signature_filename ("")
- , _install_only (false)
- , _package_set (false)
- , _id ("")
-{
- setChannel (channel);
-}
-
-
-Package::Package (constXmlNodePtr node, constChannelPtr channel)
- : ResItem (Kind::Package, "")
- , _section (NULL)
- , _pretty_name ("")
- , _summary ("")
- , _description ("")
- , _package_filename ("")
- , _signature_filename ("")
- , _install_only (false)
- , _package_set (false)
- , _id ("")
-{
- if (!node->equals("package")) {
- fprintf (stderr, "Package::Package() not a package node\n");
- exit (1);
- }
-
- const char *epoch = NULL, *version = NULL, *release = NULL;
- struct DepTable dep_table;
-
- setChannel (channel);
-
- constXmlNodePtr iter = node->children();
-
- while (iter) {
- bool extracted_deps = false;
-
- if (iter->equals("name")) { setName (iter->getContent());
- } else if (iter->equals("epoch")) { setEpoch (atoi (iter->getContent()));
- } else if (iter->equals("version")) { setVersion (iter->getContent());
- } else if (iter->equals("release")) { setRelease (iter->getContent());
- } else if (iter->equals("summary")) { _summary = strdup (iter->getContent());
- } else if (iter->equals("description")) { _description = strdup (iter->getContent());
- } else if (iter->equals("section")) { _section = new Section (iter->getContent());
- } else if (iter->equals("arch")) { setArch (iter->getContent());
- } else if (iter->equals("filesize")) {
- const char *tmp = iter->getContent();
- setFileSize (tmp && *tmp ? atoi (tmp) : 0);
- free ((void *)tmp);
- } else if (iter->equals("installedsize")) {
- const char *tmp = iter->getContent();
- setInstalledSize (tmp && *tmp ? atoi (tmp) : 0);
- free ((void *)tmp);
- } else if (iter->equals("install_only")) { _install_only = true;
- } else if (iter->equals("package_set")) { _package_set = true;
- } else if (iter->equals("history")) {
- constXmlNodePtr iter2;
-
- iter2 = iter->children();
-
- while (iter2) {
- if (!iter2->isElement()) {
- iter2 = iter2->next();
- continue;
- }
-
- PackageUpdatePtr update = new PackageUpdate (iter2, this);
- addUpdate (update);
-
- iter2 = iter2->next();
- }
- } else if (iter->equals("deps")) {
- constXmlNodePtr iter2;
-
- for (iter2 = iter->children(); iter2; iter2 = iter2->next()) {
- if (!iter2->isElement())
- continue;
-
- extract_dep_info (iter2, dep_table);
- }
-
- extracted_deps = true;
- }
- else {
- if (!extracted_deps)
- extract_dep_info (iter, dep_table);
- else {
- /* FIXME: Bitch to the user here? */
- }
- }
-
- iter = iter->next();
- }
-
- if (!dep_table.children.empty()) {
- // children are used in package sets
- // treat them as normal requires
- //
-#warning Children are handled as requires
- CDependencyList::const_iterator iter;
- for (iter = dep_table.children.begin(); iter != dep_table.children.end(); iter++)
- {
- dep_table.requires.push_back (*iter);
- }
- }
-
-
- // check if we're already listed in the provides
- // if not, provide ourself
-
- CDependencyList::const_iterator piter;
- for (piter = dep_table.provides.begin(); piter != dep_table.provides.end(); piter++) {
- if ((*piter)->relation().isEqual()
- && ((*piter)->name() == name()))
- {
- break;
- }
- }
- if (piter == dep_table.provides.end()) { // no self provide found, construct one
- constDependencyPtr selfdep = new Dependency (name(), Relation::Equal, kind(), this->channel(), edition());
-if (getenv ("RC_SPEW")) fprintf (stderr, "Adding self-provide [%s]\n", selfdep->asString().c_str());
- dep_table.provides.push_front (selfdep);
- }
-
- setRequires (dep_table.requires);
- setProvides (dep_table.provides);
- setConflicts (dep_table.conflicts);
- setObsoletes (dep_table.obsoletes);
- setSuggests (dep_table.suggests);
- setRecommends (dep_table.recommends);
-
- if (version) {
-
- setEpoch (epoch ? atoi (epoch) : -1);
- setVersion (version);
- setRelease (release);
-
- /* We set these to NULL so that they won't get freed when we
- clean up before returning. */
- version = release = NULL;
-
- } else if (!_history.empty()) {
-
- /* If possible, we grab the version info from the most
- recent update. */
-
- PackageUpdatePtr update = _history.front();
-
- setEpoch (update->package()->epoch());
- setVersion (update->package()->version());
- setRelease (update->package()->release());
-
- } else {
-
- /* Otherwise, try to find where the package provides itself,
- and use that version info. */
-
- if (!provides().empty())
- for (CDependencyList::const_iterator iter = provides().begin(); iter != provides().end(); iter++) {
- if ((*iter)->relation() == Relation::Equal &&
- ((*iter)->name() == name()))
- {
- setEpoch ((*iter)->epoch());
- setVersion ((*iter)->version());
- setRelease ((*iter)->release());
- break;
- }
- }
- }
-
- /* clean-up */
- if (epoch) free ((void *)epoch);
- if (version) free ((void *)version);
- if (release) free ((void *)release);
-
- /* Hack for no archs in the XML yet */
- if (arch()->isUnknown())
- setArch (Arch::System);
-}
-
-Package::~Package()
-{
-}
-
-//---------------------------------------------------------------------------
-
-
-void
-Package::addUpdate (PackageUpdatePtr update)
-{
- if (update == NULL) return;
-
- assert (update->package() == NULL || update->package() == this);
-
- update->setPackage(this);
-
- if (_history.empty()) {
- _history.push_back (update);
- } else {
-#warning addUpdate incomplete
-#if 1
- for (PackageUpdateList::iterator iter = _history.begin(); iter != _history.end(); iter++) {
- int result = GVersion.compare ((SpecPtr)update, (SpecPtr)(*iter));
-
- if (result > 0 || (result == 0 && update->parent() != NULL)) {
- _history.insert (iter, update); // = g_slist_insert_before (package->history, l, update);
- break;
- } else if (iter == _history.end() || // FIXME list.last() ?
- (result == 0 && update->parent() == NULL)) {
- _history.insert (++iter, update); // = g_slist_insert_before (package->history, l->next, update);
- break;
- }
- }
-#endif
- }
-}
-
-
-PackageUpdatePtr
-Package::getLatestUpdate (void) const
-{
- WorldPtr world;
-
- if (_history.empty()) {
- return NULL;
- }
-
- PackageUpdatePtr latest = _history.back();
- /* if the absolute latest is not a patch, just return that */
- if (latest->parent() == NULL) {
- return latest;
- }
-
- world = World::globalWorld();
-
- for (PackageUpdateList::const_iterator l = _history.begin(); l != _history.end(); l++) {
- PackageUpdatePtr update = *l;
- constResItemPtr installed;
-
- if (!update->equals (latest)) {
- return NULL;
- }
-
- /* found a non-patch package equal to the latest, so use that */
- if (update->parent() == NULL) {
- return update;
- }
-
- /* see if the required parent for this patch is installed */
- installed = world->findInstalledResItem (update->parent());
-
- if (installed != NULL &&
- installed->equals(update->parent()))
- return update;
- }
-
- /* no suitable update found */
- return NULL;
-}
-
-
-#if 0
-xmlNode *
-rc_package_to_xml_node (RCPackage *package)
-{
- xmlNode *package_node;
- xmlNode *tmp_node;
- xmlNode *deps_node;
- RCResItem *r;
- RCResItemSpec *spec;
- RCPackageUpdateSList *history_iter;
- int i;
- char buffer[128];
- char *tmp_str;
-
- r = RC_RESOLVABLE (package);
- spec = rc_resItem_get_spec (r);
-
- package_node = xmlNewNode (NULL, "package");
-
- xmlNewTextChild (package_node, NULL, "name", rc_resItem_get_name (r));
-
- if (spec->has_epoch) {
- g_snprintf (buffer, 128, "%d", spec->epoch);
- xmlNewTextChild (package_node, NULL, "epoch", buffer);
- }
-
- xmlNewTextChild (package_node, NULL, "version", spec->version);
-
- if (spec->release) {
- xmlNewTextChild (package_node, NULL, "release", spec->release);
- }
-
- tmp_str = sanitize_string (package->summary);
- xmlNewTextChild (package_node, NULL, "summary", tmp_str);
- g_free (tmp_str);
-
- tmp_str = sanitize_string (package->description);
- xmlNewTextChild (package_node, NULL, "description", tmp_str);
- g_free (tmp_str);
-
- xmlNewTextChild (package_node, NULL, "arch",
- rc_arch_to_string (spec->arch));
-
- xmlNewTextChild (package_node, NULL, "section",
- rc_package_section_to_string (package->section));
-
- g_snprintf (buffer, 128, "%u", rc_resItem_get_file_size (r));
- xmlNewTextChild (package_node, NULL, "filesize", buffer);
-
- g_snprintf (buffer, 128, "%u", rc_resItem_get_installed_size (r));
- xmlNewTextChild (package_node, NULL, "installedsize", buffer);
-
- if (package->install_only) {
- xmlNewTextChild (package_node, NULL, "install_only", "1");
- }
-
- if (package->package_set) {
- xmlNewTextChild (package_node, NULL, "package_set", "1");
- }
-
- if (package->history) {
- tmp_node = xmlNewChild (package_node, NULL, "history", NULL);
- for (history_iter = package->history; history_iter;
- history_iter = history_iter->next)
- {
- RCPackageUpdate *update = (RCPackageUpdate *)(history_iter->data);
- xmlAddChild (tmp_node, rc_package_update_to_xml_node (update));
- }
- }
-
- deps_node = xmlNewChild (package_node, NULL, "deps", NULL);
-
- if (r->requires_a) {
- tmp_node = xmlNewChild (deps_node, NULL, "requires", NULL);
- for (i = 0; i < r->requires_a->len; i++) {
- RCResItemDep *dep = r->requires_a->data[i];
-
- xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
- }
- }
-
- if (r->recommends_a) {
- tmp_node = xmlNewChild (deps_node, NULL, "recommends", NULL);
- for (i = 0; i < r->recommends_a->len; i++) {
- RCResItemDep *dep = r->recommends_a->data[i];
-
- xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
- }
- }
-
- if (r->suggests_a) {
- tmp_node = xmlNewChild (deps_node, NULL, "suggests", NULL);
- for (i = 0; i < r->suggests_a->len; i++) {
- RCResItemDep *dep = r->suggests_a->data[i];
-
- xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
- }
- }
-
- if (r->conflicts_a) {
- tmp_node = xmlNewChild (deps_node, NULL, "conflicts", NULL);
- for (i = 0; i < r->conflicts_a->len; i++) {
- RCResItemDep *dep = r->conflicts_a->data[i];
-
- xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
- }
- }
-
- if (r->obsoletes_a) {
- tmp_node = xmlNewChild (deps_node, NULL, "obsoletes", NULL);
- for (i = 0; i < r->obsoletes_a->len; i++) {
- RCResItemDep *dep = r->obsoletes_a->data[i];
-
- xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
- }
- }
-
- if (r->provides_a) {
- tmp_node = xmlNewChild (deps_node, NULL, "provides", NULL);
- for (i = 0; i < r->provides_a->len; i++) {
- RCResItemDep *dep = r->provides_a->data[i];
-
- xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
- }
- }
-
- return (package_node);
-} /* rc_package_to_xml_node */
-
-#endif
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(Package,Spec);
+
+ struct DepTable {
+ CDependencyList requires;
+ CDependencyList provides;
+ CDependencyList conflicts;
+ CDependencyList obsoletes;
+ CDependencyList children;
+ CDependencyList suggests;
+ CDependencyList recommends;
+ };
+
+ //---------------------------------------------------------------------------
+
+ static void
+ extract_dep_info (constXmlNodePtr iter, struct DepTable & dep_table)
+ {
+ if (iter->equals("requires")) {
+ constXmlNodePtr iter2;
+
+ iter2 = iter->children();
+
+ while (iter2) {
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ dep_table.requires.push_back(new Dependency (iter2));
+ iter2 = iter2->next();
+ }
+
+ } else if (iter->equals("recommends")) {
+ constXmlNodePtr iter2;
+
+ iter2 = iter->children();
+
+ while (iter2) {
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ dep_table.recommends.push_back (new Dependency (iter2));
+ iter2 = iter2->next();
+ }
+
+ } else if (iter->equals("suggests")) {
+ constXmlNodePtr iter2;
+
+ iter2 = iter->children();
+
+ while (iter2) {
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ dep_table.suggests.push_back (new Dependency (iter2));
+ iter2 = iter2->next();
+ }
+
+ } else if (iter->equals("conflicts")) {
+ XmlNodePtr iter2;
+ bool all_are_obs = false, this_is_obs = false;
+ const char *obs;
+
+ iter2 = iter->children();
+
+ obs = iter->getProp ("obsoletes", NULL);
+ if (obs) {
+ all_are_obs = true;
+ free ((void *)obs);
+ }
+
+ while (iter2) {
+
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ DependencyPtr dep = new Dependency (iter2);
+
+ if (! all_are_obs) {
+ this_is_obs = false;
+ obs = iter2->getProp ("obsoletes", NULL);
+ if (obs) {
+ this_is_obs = true;
+ free ((void *)obs);
+ }
+ }
+
+ if (all_are_obs || this_is_obs) {
+ dep_table.obsoletes.push_back (dep);
+ } else {
+ dep_table.conflicts.push_back (dep);
+ }
+
+ iter2 = iter2->next();
+ }
+
+ } else if (iter->equals("obsoletes")) {
+ constXmlNodePtr iter2;
+
+ iter2 = iter->children();
+
+ while (iter2) {
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ dep_table.obsoletes.push_back (new Dependency (iter2));
+ iter2 = iter2->next();
+ }
+
+ } else if (iter->equals("provides")) {
+ constXmlNodePtr iter2;
+
+ iter2 = iter->children();
+
+ while (iter2) {
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ dep_table.provides.push_back (new Dependency (iter2));
+ iter2 = iter2->next();
+ }
+
+ } else if (iter->equals("children")) {
+ constXmlNodePtr iter2;
+
+ iter2 = iter->children();
+
+ while (iter2) {
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ dep_table.children.push_back (new Dependency (iter2));
+ iter2 = iter2->next();
+ }
+ }
+ }
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ Package::asString ( bool full ) const
+ {
+ return toString (*this, full);
+ }
+
+
+ string
+ Package::toString ( const PackageUpdateList & l, bool full )
+ {
+ string ret ("[");
+ for (PackageUpdateList::const_iterator i = l.begin(); i != l.end(); i++) {
+ if (i != l.begin()) ret += ", ";
+ ret += (*i)->asString(full);
+ }
+ return ret + "]";
+ }
+
+ string
+ Package::toString ( const Package & package, bool full )
+ {
+ string ret;
+ ret += ResItem::toString(package, full);
+ if (full) {
+ // if (package._section != NULL) ret += (string ("<section '") + package._section->asString() + "'/>");
+ // if (!package._pretty_name.empty()) ret += (string ("<pretty_name '") + package._pretty_name + "'/>");
+ // if (!package._summary.empty()) ret += (string ("<summary '") + package._summary + "'/>");
+ // if (!package._description.empty()) ret += (string ("<description '") + package._description + "'/>");
+ ret += (string ("<history '") + toString(package._history) + "'/>");
+ }
+ return ret;
+ }
+
+
+ ostream &
+ Package::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Package& package)
+ {
+ return os << package.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Package::Package (constChannelPtr channel)
+ : ResItem (Kind::Package, "")
+ , _section (NULL)
+ , _pretty_name ("")
+ , _summary ("")
+ , _description ("")
+ , _package_filename ("")
+ , _signature_filename ("")
+ , _install_only (false)
+ , _package_set (false)
+ , _id ("")
+ {
+ setChannel (channel);
+ }
+
+
+ Package::Package (constXmlNodePtr node, constChannelPtr channel)
+ : ResItem (Kind::Package, "")
+ , _section (NULL)
+ , _pretty_name ("")
+ , _summary ("")
+ , _description ("")
+ , _package_filename ("")
+ , _signature_filename ("")
+ , _install_only (false)
+ , _package_set (false)
+ , _id ("")
+ {
+ if (!node->equals("package")) {
+ fprintf (stderr, "Package::Package() not a package node\n");
+ exit (1);
+ }
+
+ const char *epoch = NULL, *version = NULL, *release = NULL;
+ struct DepTable dep_table;
+
+ setChannel (channel);
+
+ constXmlNodePtr iter = node->children();
+
+ while (iter) {
+ bool extracted_deps = false;
+
+ if (iter->equals("name")) { setName (iter->getContent());
+ } else if (iter->equals("epoch")) { setEpoch (atoi (iter->getContent()));
+ } else if (iter->equals("version")) { setVersion (iter->getContent());
+ } else if (iter->equals("release")) { setRelease (iter->getContent());
+ } else if (iter->equals("summary")) { _summary = strdup (iter->getContent());
+ } else if (iter->equals("description")) { _description = strdup (iter->getContent());
+ } else if (iter->equals("section")) { _section = new Section (iter->getContent());
+ } else if (iter->equals("arch")) { setArch (iter->getContent());
+ } else if (iter->equals("filesize")) {
+ const char *tmp = iter->getContent();
+ setFileSize (tmp && *tmp ? atoi (tmp) : 0);
+ free ((void *)tmp);
+ } else if (iter->equals("installedsize")) {
+ const char *tmp = iter->getContent();
+ setInstalledSize (tmp && *tmp ? atoi (tmp) : 0);
+ free ((void *)tmp);
+ } else if (iter->equals("install_only")) { _install_only = true;
+ } else if (iter->equals("package_set")) { _package_set = true;
+ } else if (iter->equals("history")) {
+ constXmlNodePtr iter2;
+
+ iter2 = iter->children();
+
+ while (iter2) {
+ if (!iter2->isElement()) {
+ iter2 = iter2->next();
+ continue;
+ }
+
+ PackageUpdatePtr update = new PackageUpdate (iter2, this);
+ addUpdate (update);
+
+ iter2 = iter2->next();
+ }
+ } else if (iter->equals("deps")) {
+ constXmlNodePtr iter2;
+
+ for (iter2 = iter->children(); iter2; iter2 = iter2->next()) {
+ if (!iter2->isElement())
+ continue;
+
+ extract_dep_info (iter2, dep_table);
+ }
+
+ extracted_deps = true;
+ }
+ else {
+ if (!extracted_deps)
+ extract_dep_info (iter, dep_table);
+ else {
+ /* FIXME: Bitch to the user here? */
+ }
+ }
+
+ iter = iter->next();
+ }
+
+ if (!dep_table.children.empty()) {
+ // children are used in package sets
+ // treat them as normal requires
+ //
+ #warning Children are handled as requires
+ CDependencyList::const_iterator iter;
+ for (iter = dep_table.children.begin(); iter != dep_table.children.end(); iter++)
+ {
+ dep_table.requires.push_back (*iter);
+ }
+ }
+
+
+ // check if we're already listed in the provides
+ // if not, provide ourself
+
+ CDependencyList::const_iterator piter;
+ for (piter = dep_table.provides.begin(); piter != dep_table.provides.end(); piter++) {
+ if ((*piter)->relation().isEqual()
+ && ((*piter)->name() == name()))
+ {
+ break;
+ }
+ }
+ if (piter == dep_table.provides.end()) { // no self provide found, construct one
+ constDependencyPtr selfdep = new Dependency (name(), Relation::Equal, kind(), this->channel(), edition());
+ if (getenv ("RC_SPEW")) fprintf (stderr, "Adding self-provide [%s]\n", selfdep->asString().c_str());
+ dep_table.provides.push_front (selfdep);
+ }
+
+ setRequires (dep_table.requires);
+ setProvides (dep_table.provides);
+ setConflicts (dep_table.conflicts);
+ setObsoletes (dep_table.obsoletes);
+ setSuggests (dep_table.suggests);
+ setRecommends (dep_table.recommends);
+
+ if (version) {
+
+ setEpoch (epoch ? atoi (epoch) : -1);
+ setVersion (version);
+ setRelease (release);
+
+ /* We set these to NULL so that they won't get freed when we
+ clean up before returning. */
+ version = release = NULL;
+
+ } else if (!_history.empty()) {
+
+ /* If possible, we grab the version info from the most
+ recent update. */
+
+ PackageUpdatePtr update = _history.front();
+
+ setEpoch (update->package()->epoch());
+ setVersion (update->package()->version());
+ setRelease (update->package()->release());
+
+ } else {
+
+ /* Otherwise, try to find where the package provides itself,
+ and use that version info. */
+
+ if (!provides().empty())
+ for (CDependencyList::const_iterator iter = provides().begin(); iter != provides().end(); iter++) {
+ if ((*iter)->relation() == Relation::Equal &&
+ ((*iter)->name() == name()))
+ {
+ setEpoch ((*iter)->epoch());
+ setVersion ((*iter)->version());
+ setRelease ((*iter)->release());
+ break;
+ }
+ }
+ }
+
+ /* clean-up */
+ if (epoch) free ((void *)epoch);
+ if (version) free ((void *)version);
+ if (release) free ((void *)release);
+
+ /* Hack for no archs in the XML yet */
+ if (arch()->isUnknown())
+ setArch (Arch::System);
+ }
+
+ Package::~Package()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+
+ void
+ Package::addUpdate (PackageUpdatePtr update)
+ {
+ if (update == NULL) return;
+
+ assert (update->package() == NULL || update->package() == this);
+
+ update->setPackage(this);
+
+ if (_history.empty()) {
+ _history.push_back (update);
+ } else {
+ #warning addUpdate incomplete
+ #if 1
+ for (PackageUpdateList::iterator iter = _history.begin(); iter != _history.end(); iter++) {
+ int result = GVersion.compare ((SpecPtr)update, (SpecPtr)(*iter));
+
+ if (result > 0 || (result == 0 && update->parent() != NULL)) {
+ _history.insert (iter, update); // = g_slist_insert_before (package->history, l, update);
+ break;
+ } else if (iter == _history.end() || // FIXME list.last() ?
+ (result == 0 && update->parent() == NULL)) {
+ _history.insert (++iter, update); // = g_slist_insert_before (package->history, l->next, update);
+ break;
+ }
+ }
+ #endif
+ }
+ }
+
+
+ PackageUpdatePtr
+ Package::getLatestUpdate (void) const
+ {
+ WorldPtr world;
+
+ if (_history.empty()) {
+ return NULL;
+ }
+
+ PackageUpdatePtr latest = _history.back();
+ /* if the absolute latest is not a patch, just return that */
+ if (latest->parent() == NULL) {
+ return latest;
+ }
+
+ world = World::globalWorld();
+
+ for (PackageUpdateList::const_iterator l = _history.begin(); l != _history.end(); l++) {
+ PackageUpdatePtr update = *l;
+ constResItemPtr installed;
+
+ if (!update->equals (latest)) {
+ return NULL;
+ }
+
+ /* found a non-patch package equal to the latest, so use that */
+ if (update->parent() == NULL) {
+ return update;
+ }
+
+ /* see if the required parent for this patch is installed */
+ installed = world->findInstalledResItem (update->parent());
+
+ if (installed != NULL &&
+ installed->equals(update->parent()))
+ return update;
+ }
+
+ /* no suitable update found */
+ return NULL;
+ }
+
+
+ #if 0
+ xmlNode *
+ rc_package_to_xml_node (RCPackage *package)
+ {
+ xmlNode *package_node;
+ xmlNode *tmp_node;
+ xmlNode *deps_node;
+ RCResItem *r;
+ RCResItemSpec *spec;
+ RCPackageUpdateSList *history_iter;
+ int i;
+ char buffer[128];
+ char *tmp_str;
+
+ r = RC_RESOLVABLE (package);
+ spec = rc_resItem_get_spec (r);
+
+ package_node = xmlNewNode (NULL, "package");
+
+ xmlNewTextChild (package_node, NULL, "name", rc_resItem_get_name (r));
+
+ if (spec->has_epoch) {
+ g_snprintf (buffer, 128, "%d", spec->epoch);
+ xmlNewTextChild (package_node, NULL, "epoch", buffer);
+ }
+
+ xmlNewTextChild (package_node, NULL, "version", spec->version);
+
+ if (spec->release) {
+ xmlNewTextChild (package_node, NULL, "release", spec->release);
+ }
+
+ tmp_str = sanitize_string (package->summary);
+ xmlNewTextChild (package_node, NULL, "summary", tmp_str);
+ g_free (tmp_str);
+
+ tmp_str = sanitize_string (package->description);
+ xmlNewTextChild (package_node, NULL, "description", tmp_str);
+ g_free (tmp_str);
+
+ xmlNewTextChild (package_node, NULL, "arch",
+ rc_arch_to_string (spec->arch));
+
+ xmlNewTextChild (package_node, NULL, "section",
+ rc_package_section_to_string (package->section));
+
+ g_snprintf (buffer, 128, "%u", rc_resItem_get_file_size (r));
+ xmlNewTextChild (package_node, NULL, "filesize", buffer);
+
+ g_snprintf (buffer, 128, "%u", rc_resItem_get_installed_size (r));
+ xmlNewTextChild (package_node, NULL, "installedsize", buffer);
+
+ if (package->install_only) {
+ xmlNewTextChild (package_node, NULL, "install_only", "1");
+ }
+
+ if (package->package_set) {
+ xmlNewTextChild (package_node, NULL, "package_set", "1");
+ }
+
+ if (package->history) {
+ tmp_node = xmlNewChild (package_node, NULL, "history", NULL);
+ for (history_iter = package->history; history_iter;
+ history_iter = history_iter->next)
+ {
+ RCPackageUpdate *update = (RCPackageUpdate *)(history_iter->data);
+ xmlAddChild (tmp_node, rc_package_update_to_xml_node (update));
+ }
+ }
+
+ deps_node = xmlNewChild (package_node, NULL, "deps", NULL);
+
+ if (r->requires_a) {
+ tmp_node = xmlNewChild (deps_node, NULL, "requires", NULL);
+ for (i = 0; i < r->requires_a->len; i++) {
+ RCResItemDep *dep = r->requires_a->data[i];
+
+ xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
+ }
+ }
+
+ if (r->recommends_a) {
+ tmp_node = xmlNewChild (deps_node, NULL, "recommends", NULL);
+ for (i = 0; i < r->recommends_a->len; i++) {
+ RCResItemDep *dep = r->recommends_a->data[i];
+
+ xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
+ }
+ }
+
+ if (r->suggests_a) {
+ tmp_node = xmlNewChild (deps_node, NULL, "suggests", NULL);
+ for (i = 0; i < r->suggests_a->len; i++) {
+ RCResItemDep *dep = r->suggests_a->data[i];
+
+ xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
+ }
+ }
+
+ if (r->conflicts_a) {
+ tmp_node = xmlNewChild (deps_node, NULL, "conflicts", NULL);
+ for (i = 0; i < r->conflicts_a->len; i++) {
+ RCResItemDep *dep = r->conflicts_a->data[i];
+
+ xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
+ }
+ }
+
+ if (r->obsoletes_a) {
+ tmp_node = xmlNewChild (deps_node, NULL, "obsoletes", NULL);
+ for (i = 0; i < r->obsoletes_a->len; i++) {
+ RCResItemDep *dep = r->obsoletes_a->data[i];
+
+ xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
+ }
+ }
+
+ if (r->provides_a) {
+ tmp_node = xmlNewChild (deps_node, NULL, "provides", NULL);
+ for (i = 0; i < r->provides_a->len; i++) {
+ RCResItemDep *dep = r->provides_a->data[i];
+
+ xmlAddChild (tmp_node, rc_resItem_dep_to_xml_node (dep));
+ }
+ }
+
+ return (package_node);
+ } /* rc_package_to_xml_node */
+
+ #endif
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResItem.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
typedef std::list<PackagePtr> PackageList;
typedef PackageList * PackageListPtr;
class Package : public ResItem {
REP_BODY(Package);
-
- private:
- SectionPtr _section;
-
- // Filled in by package info XML
- std::string _pretty_name;
- std::string _summary;
- std::string _description;
-
- PackageUpdateList _history;
-
- // After downloading this package, fill in the local file name,
- // and signature, if appropriate
- std::string _package_filename;
- std::string _signature_filename;
-
- bool _install_only; // Only install, don't upgrade this package
- bool _package_set;
-
- std::string _id;
-
- public:
-
- Package(constChannelPtr channel);
- Package(constXmlNodePtr node, constChannelPtr channel); //RCPackage *rc_xml_node_to_package (const xmlNode *node, const RCChannel *channel);
- virtual ~Package();
-
- // ---------------------------------- I/O
-
- const xmlNodePtr asXmlNode (void) const; // xmlNode *rc_package_to_xml_node (RCPackage *package);
-
- static std::string toString ( const Package & spec, bool full = false );
-
- static std::string toString ( const PackageUpdateList & l, bool full = false );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Package& );
-
- std::string asString ( bool full = false ) const;
-
- // ---------------------------------- accessors
-
- // accessor for _section
- const SectionPtr section() const { return _section; }
- void setSection (const SectionPtr section) { _section = section; }
-
- // accessor for _pretty_name
- const std::string prettyName() const { return _pretty_name; }
- void setPrettyName(const std::string & pretty_name) { _pretty_name = pretty_name; }
-
- // accessor for _summary
- const std::string summary() const { return _summary; }
- void setSummary (const std::string & summary) { _summary = summary; }
-
- // accessor for _description
- const std::string description() const { return _description; }
- void setDescription(const std::string & description) { _description = description; }
-
- // accessor for _package_filename
- const PackageUpdateList & history() const { return _history; }
- void setHistory(const PackageUpdateList & history) { _history = history; }
-
- // accessor for _package_filename
- const std::string packageFilename() const { return _package_filename; }
- void setPackageFilename(const std::string & package_filename) { _package_filename = package_filename; }
-
- // accessor for _signature_filename
- const std::string signatureFilename() const { return _signature_filename; }
- void setSignatureFilename(const std::string & signature_filename) { _signature_filename = signature_filename; }
-
- // accessor for _install_only
- bool installOnly() const { return _install_only; }
- void setInstallOnly(bool install_only) { _install_only = install_only; }
-
- // accessor for _package_set
- bool packageSet() const { return _package_set; }
- void setPackageSet(bool package_set) { _package_set = package_set; }
-
- // accessor for id
- const std::string id() const { return _id; }
- void setId (const std::string & id) { _id = id; }
-
- // ---------------------------------- methods
-
- void addUpdate (PackageUpdatePtr update);
-
- PackageUpdatePtr getLatestUpdate (void) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+
+ private:
+ SectionPtr _section;
+
+ // Filled in by package info XML
+ std::string _pretty_name;
+ std::string _summary;
+ std::string _description;
+
+ PackageUpdateList _history;
+
+ // After downloading this package, fill in the local file name,
+ // and signature, if appropriate
+ std::string _package_filename;
+ std::string _signature_filename;
+
+ bool _install_only; // Only install, don't upgrade this package
+ bool _package_set;
+
+ std::string _id;
+
+ public:
+
+ Package(constChannelPtr channel);
+ Package(constXmlNodePtr node, constChannelPtr channel); //RCPackage *rc_xml_node_to_package (const xmlNode *node, const RCChannel *channel);
+ virtual ~Package();
+
+ // ---------------------------------- I/O
+
+ const xmlNodePtr asXmlNode (void) const; // xmlNode *rc_package_to_xml_node (RCPackage *package);
+
+ static std::string toString ( const Package & spec, bool full = false );
+
+ static std::string toString ( const PackageUpdateList & l, bool full = false );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Package& );
+
+ std::string asString ( bool full = false ) const;
+
+ // ---------------------------------- accessors
+
+ // accessor for _section
+ const SectionPtr section() const { return _section; }
+ void setSection (const SectionPtr section) { _section = section; }
+
+ // accessor for _pretty_name
+ const std::string prettyName() const { return _pretty_name; }
+ void setPrettyName(const std::string & pretty_name) { _pretty_name = pretty_name; }
+
+ // accessor for _summary
+ const std::string summary() const { return _summary; }
+ void setSummary (const std::string & summary) { _summary = summary; }
+
+ // accessor for _description
+ const std::string description() const { return _description; }
+ void setDescription(const std::string & description) { _description = description; }
+
+ // accessor for _package_filename
+ const PackageUpdateList & history() const { return _history; }
+ void setHistory(const PackageUpdateList & history) { _history = history; }
+
+ // accessor for _package_filename
+ const std::string packageFilename() const { return _package_filename; }
+ void setPackageFilename(const std::string & package_filename) { _package_filename = package_filename; }
+
+ // accessor for _signature_filename
+ const std::string signatureFilename() const { return _signature_filename; }
+ void setSignatureFilename(const std::string & signature_filename) { _signature_filename = signature_filename; }
+
+ // accessor for _install_only
+ bool installOnly() const { return _install_only; }
+ void setInstallOnly(bool install_only) { _install_only = install_only; }
+
+ // accessor for _package_set
+ bool packageSet() const { return _package_set; }
+ void setPackageSet(bool package_set) { _package_set = package_set; }
+
+ // accessor for id
+ const std::string id() const { return _id; }
+ void setId (const std::string & id) { _id = id; }
+
+ // ---------------------------------- methods
+
+ void addUpdate (PackageUpdatePtr update);
+
+ PackageUpdatePtr getLatestUpdate (void) const;
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Package_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/SpecPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : PackagePtr
-// CLASS NAME : constPackagePtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(Package,Spec);
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : PackagePtr
+ // CLASS NAME : constPackagePtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(Package,Spec);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _PackagePtr_h
#include <zypp/solver/detail/PackageUpdate.h>
#include <zypp/solver/detail/Package.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(PackageUpdate, Spec);
-
-//---------------------------------------------------------------------------
-
-string
-PackageUpdate::asString ( bool full ) const
-{
- return toString (*this);
-}
-
-
-string
-PackageUpdate::toString ( const PackageUpdate & package_update, bool full )
-{
- string ret;
- ret += ((const Spec &)package_update).asString(full);
-
- return ret;
-}
-
-
-ostream &
-PackageUpdate::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const PackageUpdate& package_update)
-{
- return os << package_update.asString();
-}
-
-
-const XmlNodePtr
-PackageUpdate::asXmlNode (void) const
-{
- XmlNodePtr update_node = new XmlNode("update");
- string tmp;
-
- if (hasEpoch()) {
- tmp = stringutil::form("%d", epoch());
- update_node->addTextChild ("epoch", tmp.c_str());
- }
-
- update_node->addTextChild ("version", version().c_str());
-
- if (!release().empty()) {
- update_node->addTextChild ("release", release().c_str());
- }
-
- if (_package_url && *_package_url) {
- update_node->addTextChild ("filename", basename (strdup (_package_url)));
- }
-
- tmp = stringutil::form ("%ld", (unsigned long)_package_size);
- update_node->addTextChild ("filesize", tmp.c_str());
-
- tmp = stringutil::form ("%ld", (unsigned long)_installed_size);
- update_node->addTextChild ("installedsize", tmp.c_str());
-
- if (_signature_url) {
- update_node->addTextChild ("signaturename", _signature_url);
-
- tmp = stringutil::form ("%ld", (unsigned long)_signature_size);
- update_node->addTextChild ("signaturesize", tmp.c_str());
- }
-
- if (_md5sum) {
- update_node->addTextChild ("md5sum", _md5sum);
- }
-
- update_node->addTextChild ("importance", _importance->asString().c_str());
-
- update_node->addTextChild ("description", _description);
-
- if (_hid) {
- tmp = stringutil::form ("%d", _hid);
- update_node->addTextChild ("hid", tmp.c_str());
- }
-
- if (_license) {
- update_node->addTextChild ("license", _license);
- }
-
- return update_node;
-}
-
-//---------------------------------------------------------------------------
-
-PackageUpdate::PackageUpdate (const string & name)
- : Spec (Kind::Package, name)
- , _package (NULL)
- , _package_url (NULL)
- , _package_size (0)
- , _installed_size (0)
- , _signature_url (NULL)
- , _signature_size (0)
- , _md5sum (NULL)
- , _importance (NULL)
- , _hid (0)
- , _description (NULL)
- , _license (NULL)
- , _parent (NULL)
-{
-}
-
-
-PackageUpdate::PackageUpdate (constXmlNodePtr node, PackagePtr package)
- : Spec (Kind::Package, package->name())
- , _package (NULL)
- , _package_url (NULL)
- , _package_size (0)
- , _installed_size (0)
- , _signature_url (NULL)
- , _signature_size (0)
- , _md5sum (NULL)
- , _importance (NULL)
- , _hid (0)
- , _description (NULL)
- , _license (NULL)
- , _parent (NULL)
-{
- constChannelPtr channel;
- const char *url_prefix = NULL;
-
- if (node == NULL) {
- fprintf (stderr, "PackageUpdate::PackageUpdate(NULL)\n");
- exit (1);
- }
-
- /* Make sure this is an update node */
- if (strcasecmp (node->name(), "update")) {
- fprintf (stderr, "PackageUpdate::PackageUpdate() wrong node (%s)\n", node->name());
- exit (1);
- }
-
- channel = package->channel();
-
- _package = package;
-
- if (channel) {
- url_prefix = channel->filePath();
- }
-
- XmlNodePtr iter = node->children();
-
- while (iter) {
- if (iter->equals ("epoch")) { setEpoch (iter->getUnsignedIntContentDefault (0));
- } else if (iter->equals ("version")) { setVersion (iter->getContent());
- } else if (iter->equals ("release")) { setRelease (iter->getContent());
- } else if (iter->equals ("arch")) { setArch (iter->getContent());
- } else if (iter->equals ("filename")) {
- const char *tmp = iter->getContent();
- if (url_prefix) {
- _package_url = maybe_merge_paths (url_prefix, tmp);
- } else {
- _package_url = strdup (tmp);
- }
- } else if (iter->equals ("filesize")) { _package_size = iter->getUnsignedIntContentDefault (0);
- } else if (iter->equals ("installedsize")) { _installed_size = iter->getUnsignedIntContentDefault (0);
- } else if (iter->equals ("signaturename")) {
- const char *tmp = iter->getContent();
- if (url_prefix) {
- _signature_url = maybe_merge_paths (url_prefix, tmp);
- } else {
- _signature_url = strdup (tmp);
- }
- } else if (iter->equals ("signaturesize")) { _signature_size = iter->getUnsignedIntContentDefault (0);
- } else if (iter->equals ("md5sum")) { _md5sum = iter->getContent();
- } else if (iter->equals ("importance")) { _importance = new Importance (iter->getContent());
- } else if (iter->equals ("description")) { _description = iter->getContent();
- } else if (iter->equals ("hid")) { _hid = iter->getUnsignedIntContentDefault (0);
- } else if (iter->equals ("license")) { _license = iter->getContent();
- }
-
- iter = iter->next();
- }
-}
-
-
-PackageUpdate::~PackageUpdate()
-{
- if (_package != NULL) _package = NULL;
- if (_package_url != NULL) free ((void *)_package_url);
- if (_signature_url != NULL) free ((void *)_signature_url);
- if (_md5sum != NULL) free ((void *)_md5sum);
- if (_description != NULL) free ((void *)_description);
- if (_license != NULL) free ((void *)_license);
- if (_parent != NULL) _parent = NULL;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(PackageUpdate, Spec);
+
+ //---------------------------------------------------------------------------
+
+ string
+ PackageUpdate::asString ( bool full ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ PackageUpdate::toString ( const PackageUpdate & package_update, bool full )
+ {
+ string ret;
+ ret += ((const Spec &)package_update).asString(full);
+
+ return ret;
+ }
+
+
+ ostream &
+ PackageUpdate::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const PackageUpdate& package_update)
+ {
+ return os << package_update.asString();
+ }
+
+
+ const XmlNodePtr
+ PackageUpdate::asXmlNode (void) const
+ {
+ XmlNodePtr update_node = new XmlNode("update");
+ string tmp;
+
+ if (hasEpoch()) {
+ tmp = stringutil::form("%d", epoch());
+ update_node->addTextChild ("epoch", tmp.c_str());
+ }
+
+ update_node->addTextChild ("version", version().c_str());
+
+ if (!release().empty()) {
+ update_node->addTextChild ("release", release().c_str());
+ }
+
+ if (_package_url && *_package_url) {
+ update_node->addTextChild ("filename", basename (strdup (_package_url)));
+ }
+
+ tmp = stringutil::form ("%ld", (unsigned long)_package_size);
+ update_node->addTextChild ("filesize", tmp.c_str());
+
+ tmp = stringutil::form ("%ld", (unsigned long)_installed_size);
+ update_node->addTextChild ("installedsize", tmp.c_str());
+
+ if (_signature_url) {
+ update_node->addTextChild ("signaturename", _signature_url);
+
+ tmp = stringutil::form ("%ld", (unsigned long)_signature_size);
+ update_node->addTextChild ("signaturesize", tmp.c_str());
+ }
+
+ if (_md5sum) {
+ update_node->addTextChild ("md5sum", _md5sum);
+ }
+
+ update_node->addTextChild ("importance", _importance->asString().c_str());
+
+ update_node->addTextChild ("description", _description);
+
+ if (_hid) {
+ tmp = stringutil::form ("%d", _hid);
+ update_node->addTextChild ("hid", tmp.c_str());
+ }
+
+ if (_license) {
+ update_node->addTextChild ("license", _license);
+ }
+
+ return update_node;
+ }
+
+ //---------------------------------------------------------------------------
+
+ PackageUpdate::PackageUpdate (const string & name)
+ : Spec (Kind::Package, name)
+ , _package (NULL)
+ , _package_url (NULL)
+ , _package_size (0)
+ , _installed_size (0)
+ , _signature_url (NULL)
+ , _signature_size (0)
+ , _md5sum (NULL)
+ , _importance (NULL)
+ , _hid (0)
+ , _description (NULL)
+ , _license (NULL)
+ , _parent (NULL)
+ {
+ }
+
+
+ PackageUpdate::PackageUpdate (constXmlNodePtr node, PackagePtr package)
+ : Spec (Kind::Package, package->name())
+ , _package (NULL)
+ , _package_url (NULL)
+ , _package_size (0)
+ , _installed_size (0)
+ , _signature_url (NULL)
+ , _signature_size (0)
+ , _md5sum (NULL)
+ , _importance (NULL)
+ , _hid (0)
+ , _description (NULL)
+ , _license (NULL)
+ , _parent (NULL)
+ {
+ constChannelPtr channel;
+ const char *url_prefix = NULL;
+
+ if (node == NULL) {
+ fprintf (stderr, "PackageUpdate::PackageUpdate(NULL)\n");
+ exit (1);
+ }
+
+ /* Make sure this is an update node */
+ if (strcasecmp (node->name(), "update")) {
+ fprintf (stderr, "PackageUpdate::PackageUpdate() wrong node (%s)\n", node->name());
+ exit (1);
+ }
+
+ channel = package->channel();
+
+ _package = package;
+
+ if (channel) {
+ url_prefix = channel->filePath();
+ }
+
+ XmlNodePtr iter = node->children();
+
+ while (iter) {
+ if (iter->equals ("epoch")) { setEpoch (iter->getUnsignedIntContentDefault (0));
+ } else if (iter->equals ("version")) { setVersion (iter->getContent());
+ } else if (iter->equals ("release")) { setRelease (iter->getContent());
+ } else if (iter->equals ("arch")) { setArch (iter->getContent());
+ } else if (iter->equals ("filename")) {
+ const char *tmp = iter->getContent();
+ if (url_prefix) {
+ _package_url = maybe_merge_paths (url_prefix, tmp);
+ } else {
+ _package_url = strdup (tmp);
+ }
+ } else if (iter->equals ("filesize")) { _package_size = iter->getUnsignedIntContentDefault (0);
+ } else if (iter->equals ("installedsize")) { _installed_size = iter->getUnsignedIntContentDefault (0);
+ } else if (iter->equals ("signaturename")) {
+ const char *tmp = iter->getContent();
+ if (url_prefix) {
+ _signature_url = maybe_merge_paths (url_prefix, tmp);
+ } else {
+ _signature_url = strdup (tmp);
+ }
+ } else if (iter->equals ("signaturesize")) { _signature_size = iter->getUnsignedIntContentDefault (0);
+ } else if (iter->equals ("md5sum")) { _md5sum = iter->getContent();
+ } else if (iter->equals ("importance")) { _importance = new Importance (iter->getContent());
+ } else if (iter->equals ("description")) { _description = iter->getContent();
+ } else if (iter->equals ("hid")) { _hid = iter->getUnsignedIntContentDefault (0);
+ } else if (iter->equals ("license")) { _license = iter->getContent();
+ }
+
+ iter = iter->next();
+ }
+ }
+
+
+ PackageUpdate::~PackageUpdate()
+ {
+ if (_package != NULL) _package = NULL;
+ if (_package_url != NULL) free ((void *)_package_url);
+ if (_signature_url != NULL) free ((void *)_signature_url);
+ if (_md5sum != NULL) free ((void *)_md5sum);
+ if (_description != NULL) free ((void *)_description);
+ if (_license != NULL) free ((void *)_license);
+ if (_parent != NULL) _parent = NULL;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Importance.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
**/
class PackageUpdate : public Spec {
- REP_BODY(PackageUpdate);
-
- private:
- PackagePtr _package;
-
- const char *_package_url;
- size_t _package_size;
- size_t _installed_size;
-
- const char *_signature_url;
- size_t _signature_size;
-
- const char *_md5sum;
-
- const Importance *_importance;
-
- unsigned int _hid;
-
- const char *_description;
-
- const char *_license;
-
- // refers to the parent package for SuSE patch RPMs
- constPackagePtr _parent;
-
- public:
-
- PackageUpdate(const std::string & name);
- PackageUpdate(constXmlNodePtr node, PackagePtr package);
-
- virtual ~PackageUpdate();
-
- // ---------------------------------- I/O
-
- const XmlNodePtr asXmlNode (void) const;
-
- static std::string toString ( const PackageUpdate & packageupdate, bool full = false );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const PackageUpdate& );
-
- std::string asString ( bool full = false ) const;
-
- // ---------------------------------- accessors
-
- constPackagePtr package() const { return _package; }
- void setPackage (PackagePtr package) { _package = package; }
-
- const char *packageUrl() const { return _package_url; }
- void setPackageUrl (const char *package_url) { _package_url = package_url; }
-
- size_t packageSize() const { return _package_size; }
- void setPackageSize (size_t package_size) { _package_size = package_size; }
-
- size_t installedSize() const { return _installed_size; }
- void setInstalledSize (size_t installed_size ) { _installed_size = installed_size; }
-
- const char *description() const { return _description; }
- void setDescription(const char *description) { _description = strdup (description); }
-
- const char *signatureUrl() const { return _signature_url; }
- void setSignatureUrl (const char *signature_url) { _signature_url = signature_url; }
-
- size_t signatureSize() const { return _signature_size; }
- void setSignatureSize (size_t signature_size) { _signature_size = signature_size; }
-
- const char *md5sum() const { return _md5sum; }
- void setMd5sum (const char *md5sum) { _md5sum = md5sum; }
-
- const Importance *importance() const { return _importance; }
- void setImportance (const Importance *importance) { _importance = importance; }
-
- unsigned int hid() const { return _hid; }
- void setHid (unsigned int hid) { _hid = hid; }
-
- const char *license() const { return _license; }
- void setLicense (const char *license) { _license = license; }
-
- // refers to the parent package for SuSE patch RPMs
- constPackagePtr parent() const { return _parent; }
- void setParent (constPackagePtr parent) { _parent = parent; }
-
- // ---------------------------------- methods
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+ REP_BODY(PackageUpdate);
+
+ private:
+ PackagePtr _package;
+
+ const char *_package_url;
+ size_t _package_size;
+ size_t _installed_size;
+
+ const char *_signature_url;
+ size_t _signature_size;
+
+ const char *_md5sum;
+
+ const Importance *_importance;
+
+ unsigned int _hid;
+
+ const char *_description;
+
+ const char *_license;
+
+ // refers to the parent package for SuSE patch RPMs
+ constPackagePtr _parent;
+
+ public:
+
+ PackageUpdate(const std::string & name);
+ PackageUpdate(constXmlNodePtr node, PackagePtr package);
+
+ virtual ~PackageUpdate();
+
+ // ---------------------------------- I/O
+
+ const XmlNodePtr asXmlNode (void) const;
+
+ static std::string toString ( const PackageUpdate & packageupdate, bool full = false );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const PackageUpdate& );
+
+ std::string asString ( bool full = false ) const;
+
+ // ---------------------------------- accessors
+
+ constPackagePtr package() const { return _package; }
+ void setPackage (PackagePtr package) { _package = package; }
+
+ const char *packageUrl() const { return _package_url; }
+ void setPackageUrl (const char *package_url) { _package_url = package_url; }
+
+ size_t packageSize() const { return _package_size; }
+ void setPackageSize (size_t package_size) { _package_size = package_size; }
+
+ size_t installedSize() const { return _installed_size; }
+ void setInstalledSize (size_t installed_size ) { _installed_size = installed_size; }
+
+ const char *description() const { return _description; }
+ void setDescription(const char *description) { _description = strdup (description); }
+
+ const char *signatureUrl() const { return _signature_url; }
+ void setSignatureUrl (const char *signature_url) { _signature_url = signature_url; }
+
+ size_t signatureSize() const { return _signature_size; }
+ void setSignatureSize (size_t signature_size) { _signature_size = signature_size; }
+
+ const char *md5sum() const { return _md5sum; }
+ void setMd5sum (const char *md5sum) { _md5sum = md5sum; }
+
+ const Importance *importance() const { return _importance; }
+ void setImportance (const Importance *importance) { _importance = importance; }
+
+ unsigned int hid() const { return _hid; }
+ void setHid (unsigned int hid) { _hid = hid; }
+
+ const char *license() const { return _license; }
+ void setLicense (const char *license) { _license = license; }
+
+ // refers to the parent package for SuSE patch RPMs
+ constPackagePtr parent() const { return _parent; }
+ void setParent (constPackagePtr parent) { _parent = parent; }
+
+ // ---------------------------------- methods
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _PackageUpdate_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/Spec.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : PackageUpdatePtr
-// CLASS NAME : constPackageUpdatePtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(PackageUpdate,Spec);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : PackageUpdatePtr
+ // CLASS NAME : constPackageUpdatePtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(PackageUpdate,Spec);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _PackageUpdatePtr_h
#include <zypp/solver/detail/Packman.h>
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(Packman);
-
-//---------------------------------------------------------------------------
-
-string
-Packman::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Packman::toString ( const Packman & store )
-{
- string res ("<packman/>");
-
- return res;
-}
-
-
-ostream &
-Packman::dumpOn (ostream & str) const
-{
- str << asString();
- return str;
-}
-
-
-ostream &
-operator<< (ostream & os, const Packman & store)
-{
- return os << store.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Packman::Packman ()
-{
-}
-
-
-Packman::~Packman()
-{
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(Packman);
+
+ //---------------------------------------------------------------------------
+
+ string
+ Packman::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Packman::toString ( const Packman & store )
+ {
+ string res ("<packman/>");
+
+ return res;
+ }
+
+
+ ostream &
+ Packman::dumpOn (ostream & str) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream &
+ operator<< (ostream & os, const Packman & store)
+ {
+ return os << store.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Packman::Packman ()
+ {
+ }
+
+
+ Packman::~Packman()
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/PackmanPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Packman
-
-class Packman : public CountedRep {
- REP_BODY(Packman);
-
- private:
-
-
- public:
-
- Packman ();
- virtual ~Packman();
-
- // ---------------------------------- I/O
-
- static std::string toString (const Packman & section);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const Packman & section);
-
- std::string asString (void) const;
-
- // ---------------------------------- accessors
-
-
- // ---------------------------------- methods
-
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Packman
+
+ class Packman : public CountedRep {
+ REP_BODY(Packman);
+
+ private:
+
+
+ public:
+
+ Packman ();
+ virtual ~Packman();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const Packman & section);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const Packman & section);
+
+ std::string asString (void) const;
+
+ // ---------------------------------- accessors
+
+
+ // ---------------------------------- methods
+
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Packman_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : PackmanPtr
-// CLASS NAME : constPackmanPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(Packman);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : PackmanPtr
+ // CLASS NAME : constPackmanPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(Packman);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _PackmanPtr_h
#include <zypp/solver/detail/Pending.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(Pending);
-
-//---------------------------------------------------------------------------
-
-string
-Pending::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Pending::toString ( const Pending & pending )
-{
- return "<pending/>";
-}
-
-
-ostream &
-Pending::dumpOn (ostream & str) const
-{
- str << asString();
- return str;
-}
-
-
-ostream &
-operator<< (ostream & os, const Pending & pending)
-{
- return os << pending.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Pending::Pending (const char *description)
-{
-}
-
-
-Pending::~Pending()
-{
-}
-
-//---------------------------------------------------------------------------
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(Pending);
+
+ //---------------------------------------------------------------------------
+
+ string
+ Pending::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Pending::toString ( const Pending & pending )
+ {
+ return "<pending/>";
+ }
+
+
+ ostream &
+ Pending::dumpOn (ostream & str) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream &
+ operator<< (ostream & os, const Pending & pending)
+ {
+ return os << pending.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Pending::Pending (const char *description)
+ {
+ }
+
+
+ Pending::~Pending()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/PendingPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
-
-class Pending;
-typedef std::list <PendingPtr> PendingList;
-typedef PendingList * PendingListPtr;
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Pending
-
-class Pending : public CountedRep {
- REP_BODY(Pending);
-
-typedef enum {
- PENDING_STATUS_INVALID = 0,
- PENDING_STATUS_PRE_BEGIN,
- PENDING_STATUS_RUNNING,
- PENDING_STATUS_BLOCKING,
- PENDING_STATUS_ABORTED,
- PENDING_STATUS_FAILED,
- PENDING_STATUS_FINISHED
-} PendingStatus;
-
-const char *pendingStatusToString (PendingStatus status);
-
-#define INVALID_PENDING_ID 0
-
-
- private:
-
- char *_description;
- int _id;
-
- PendingStatus _status;
-
- double _percent_complete;
-
- size_t _completed_size;
- size_t _total_size;
-
- time_t _start_time;
- time_t _last_time;
- time_t _poll_time;
-
- int _retval;
- char *_error_msg;
-
- std::list<const char *> _messages;
-
- void (*_update) (PendingPtr);
- void (*_complete) (PendingPtr);
- void (*_message) (PendingPtr);
-
- public:
-
- Pending (const char *description);
- virtual ~Pending();
-
- // ---------------------------------- I/O
-
- static std::string toString (const Pending & section);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const Pending & section);
-
- std::string asString (void) const;
-
- // ---------------------------------- accessors
-
- const char *description (void) const { return _description; }
- void setDescription (const char *description) { _description = strdup (description); }
- int id (void) const { return _id; }
- PendingStatus status (void) const { return _status; }
- double percentComplete (void) const { return _percent_complete; }
- size_t completedSize (void) const { return _completed_size; }
- size_t totalSize (void) const { return _total_size; }
- time_t startTime (void) const { return _start_time; }
- time_t lastTime (void) const { return _last_time; }
- time_t pollTime (void) const { return _poll_time; }
-
- int elapsedSecs (void) const { return 0; }
- int expectedSecs (void) const { return 0; }
- int remainingSecs (void) const { return 0; }
-
- std::list<const char *> messages (void) const { return _messages; }
- const char *latestMessage (void) const { return _error_msg; }
-
- // ---------------------------------- methods
-
- PendingPtr lookupById (int id);
- std::list<PendingPtr> getAllActiveIds (void);
-
- void begin (void);
- void update (double percent_complete);
- void updateBySize (size_t size, size_t total_size);
-
- void finished (int retval);
- void abort (int retval);
- void fail (int retval, const char *error_msg);
-
- bool isActive (void);
-
- const char *errorMsg (void);
-
- void addMessage (const char *message);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ class Pending;
+ typedef std::list <PendingPtr> PendingList;
+ typedef PendingList * PendingListPtr;
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Pending
+
+ class Pending : public CountedRep {
+ REP_BODY(Pending);
+
+ typedef enum {
+ PENDING_STATUS_INVALID = 0,
+ PENDING_STATUS_PRE_BEGIN,
+ PENDING_STATUS_RUNNING,
+ PENDING_STATUS_BLOCKING,
+ PENDING_STATUS_ABORTED,
+ PENDING_STATUS_FAILED,
+ PENDING_STATUS_FINISHED
+ } PendingStatus;
+
+ const char *pendingStatusToString (PendingStatus status);
+
+ #define INVALID_PENDING_ID 0
+
+
+ private:
+
+ char *_description;
+ int _id;
+
+ PendingStatus _status;
+
+ double _percent_complete;
+
+ size_t _completed_size;
+ size_t _total_size;
+
+ time_t _start_time;
+ time_t _last_time;
+ time_t _poll_time;
+
+ int _retval;
+ char *_error_msg;
+
+ std::list<const char *> _messages;
+
+ void (*_update) (PendingPtr);
+ void (*_complete) (PendingPtr);
+ void (*_message) (PendingPtr);
+
+ public:
+
+ Pending (const char *description);
+ virtual ~Pending();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const Pending & section);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const Pending & section);
+
+ std::string asString (void) const;
+
+ // ---------------------------------- accessors
+
+ const char *description (void) const { return _description; }
+ void setDescription (const char *description) { _description = strdup (description); }
+ int id (void) const { return _id; }
+ PendingStatus status (void) const { return _status; }
+ double percentComplete (void) const { return _percent_complete; }
+ size_t completedSize (void) const { return _completed_size; }
+ size_t totalSize (void) const { return _total_size; }
+ time_t startTime (void) const { return _start_time; }
+ time_t lastTime (void) const { return _last_time; }
+ time_t pollTime (void) const { return _poll_time; }
+
+ int elapsedSecs (void) const { return 0; }
+ int expectedSecs (void) const { return 0; }
+ int remainingSecs (void) const { return 0; }
+
+ std::list<const char *> messages (void) const { return _messages; }
+ const char *latestMessage (void) const { return _error_msg; }
+
+ // ---------------------------------- methods
+
+ PendingPtr lookupById (int id);
+ std::list<PendingPtr> getAllActiveIds (void);
+
+ void begin (void);
+ void update (double percent_complete);
+ void updateBySize (size_t size, size_t total_size);
+
+ void finished (int retval);
+ void abort (int retval);
+ void fail (int retval, const char *error_msg);
+
+ bool isActive (void);
+
+ const char *errorMsg (void);
+
+ void addMessage (const char *message);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Pending_h
#define _PendingPtr_h
#include <y2util/RepDef.h>
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : PendingPtr
+ // CLASS NAME : constPendingPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(Pending);
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : PendingPtr
-// CLASS NAME : constPendingPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(Pending);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _PendingPtr_h
#include <zypp/solver/detail/QueueItem.h>
#include <zypp/solver/detail/ResolverContext.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(QueueItem);
-
-//---------------------------------------------------------------------------
-
-string
-QueueItem::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-QueueItem::toString ( const QueueItem & item )
-{
- return "<queueitem/>";
-}
-
-
-string
-QueueItem::toString ( const QueueItemList & itemlist, const string & sep )
-{
- string res = "[";
- for (QueueItemList::const_iterator iter = itemlist.begin(); iter != itemlist.end(); iter++) {
- if (iter != itemlist.begin())
- res += sep;
- res += (*iter)->asString();
- }
- return res + "]";
-}
-
-
-ostream &
-QueueItem::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const QueueItem & item )
-{
- return os << item.asString();
-}
-
-//---------------------------------------------------------------------------
-
-QueueItem::QueueItem (QueueItemType type, WorldPtr world)
- : _type (type)
- , _world (world)
- , _priority (0)
- , _size (0)
-{
-}
-
-
-QueueItem::~QueueItem()
-{
-}
-
-//---------------------------------------------------------------------------
-
-void
-QueueItem::copy (constQueueItemPtr from)
-{
- _priority = from->_priority;
- _size = from->_size;
- _pending_info = ResolverInfoList (from->_pending_info.begin(), from->_pending_info.end());
-}
-
-
-//---------------------------------------------------------------------------
-
-void
-QueueItem::addInfo (ResolverInfoPtr info)
-{
- _pending_info.push_back (info);
-}
-
-
-void
-QueueItem::logInfo (ResolverContextPtr context)
-{
- for (ResolverInfoList::const_iterator iter = _pending_info.begin(); iter != _pending_info.end(); iter++) {
- context->addInfo (*iter);
- }
- _pending_info.clear();
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(QueueItem);
+
+ //---------------------------------------------------------------------------
+
+ string
+ QueueItem::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ QueueItem::toString ( const QueueItem & item )
+ {
+ return "<queueitem/>";
+ }
+
+
+ string
+ QueueItem::toString ( const QueueItemList & itemlist, const string & sep )
+ {
+ string res = "[";
+ for (QueueItemList::const_iterator iter = itemlist.begin(); iter != itemlist.end(); iter++) {
+ if (iter != itemlist.begin())
+ res += sep;
+ res += (*iter)->asString();
+ }
+ return res + "]";
+ }
+
+
+ ostream &
+ QueueItem::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const QueueItem & item )
+ {
+ return os << item.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItem::QueueItem (QueueItemType type, WorldPtr world)
+ : _type (type)
+ , _world (world)
+ , _priority (0)
+ , _size (0)
+ {
+ }
+
+
+ QueueItem::~QueueItem()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ QueueItem::copy (constQueueItemPtr from)
+ {
+ _priority = from->_priority;
+ _size = from->_size;
+ _pending_info = ResolverInfoList (from->_pending_info.begin(), from->_pending_info.end());
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ void
+ QueueItem::addInfo (ResolverInfoPtr info)
+ {
+ _pending_info.push_back (info);
+ }
+
+
+ void
+ QueueItem::logInfo (ResolverContextPtr context)
+ {
+ for (ResolverInfoList::const_iterator iter = _pending_info.begin(); iter != _pending_info.end(); iter++) {
+ context->addInfo (*iter);
+ }
+ _pending_info.clear();
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
-typedef enum {
- QUEUE_ITEM_TYPE_UNKNOWN = 0, // ordering is important !
- QUEUE_ITEM_TYPE_INSTALL,
- QUEUE_ITEM_TYPE_REQUIRE,
- QUEUE_ITEM_TYPE_BRANCH,
- QUEUE_ITEM_TYPE_GROUP,
- QUEUE_ITEM_TYPE_CONFLICT,
- QUEUE_ITEM_TYPE_UNINSTALL,
- QUEUE_ITEM_TYPE_LAST
-} QueueItemType;
-
-
-typedef std::list<QueueItemPtr> QueueItemList;
-
-#define CMP(a,b) (((a) < (b)) - ((b) < (a)))
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : QueueItem
-
-class QueueItem : public CountedRep {
- REP_BODY(QueueItem);
-
- private:
-
- QueueItemType _type;
- WorldPtr _world;
-
- int _priority;
- size_t _size;
- ResolverInfoList _pending_info;
-
- protected:
-
- QueueItem (QueueItemType type, WorldPtr world);
-
- public:
-
- virtual ~QueueItem();
-
- // ---------------------------------- I/O
-
- static std::string toString (const QueueItem & item);
-
- static std::string toString (const QueueItemList & itemlist, const std::string & sep = ", ");
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const QueueItem & item);
-
- virtual std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- WorldPtr world (void) const { return _world; }
- int priority (void) const { return _priority; }
- void setPriority (int priority) { _priority = priority; }
- int size (void) const { return _size; }
-
- // ---------------------------------- methods
-
- void copy (constQueueItemPtr from);
-
- bool isBranch (void) const { return _type == QUEUE_ITEM_TYPE_BRANCH; }
- bool isConflict (void) const { return _type == QUEUE_ITEM_TYPE_CONFLICT; }
- bool isGroup (void) const { return _type == QUEUE_ITEM_TYPE_GROUP; }
- bool isInstall (void) const { return _type == QUEUE_ITEM_TYPE_INSTALL; }
- bool isRequire (void) const { return _type == QUEUE_ITEM_TYPE_REQUIRE; }
- bool isUninstall (void) const { return _type == QUEUE_ITEM_TYPE_UNINSTALL; }
-
- virtual bool process (ResolverContextPtr context, QueueItemList & qil) = 0;
- virtual QueueItemPtr copy (void) const = 0;
- virtual int cmp (constQueueItemPtr item) const = 0;
- int compare (constQueueItemPtr item) const { return CMP(_type, item->_type); }
-
- // isRedundant true == can be dropped from any branch
- virtual bool isRedundant (ResolverContextPtr context) const = 0;
-
- // isSatisfied true == can be dropped from any queue, and any
- // branch containing it can also be dropped
- virtual bool isSatisfied (ResolverContextPtr context) const = 0;
-
- void addInfo (ResolverInfoPtr);
- void logInfo (ResolverContextPtr);
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef enum {
+ QUEUE_ITEM_TYPE_UNKNOWN = 0, // ordering is important !
+ QUEUE_ITEM_TYPE_INSTALL,
+ QUEUE_ITEM_TYPE_REQUIRE,
+ QUEUE_ITEM_TYPE_BRANCH,
+ QUEUE_ITEM_TYPE_GROUP,
+ QUEUE_ITEM_TYPE_CONFLICT,
+ QUEUE_ITEM_TYPE_UNINSTALL,
+ QUEUE_ITEM_TYPE_LAST
+ } QueueItemType;
+
+
+ typedef std::list<QueueItemPtr> QueueItemList;
+
+ #define CMP(a,b) (((a) < (b)) - ((b) < (a)))
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : QueueItem
+
+ class QueueItem : public CountedRep {
+ REP_BODY(QueueItem);
+
+ private:
+
+ QueueItemType _type;
+ WorldPtr _world;
+
+ int _priority;
+ size_t _size;
+ ResolverInfoList _pending_info;
+
+ protected:
+
+ QueueItem (QueueItemType type, WorldPtr world);
+
+ public:
+
+ virtual ~QueueItem();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const QueueItem & item);
+
+ static std::string toString (const QueueItemList & itemlist, const std::string & sep = ", ");
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const QueueItem & item);
+
+ virtual std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ WorldPtr world (void) const { return _world; }
+ int priority (void) const { return _priority; }
+ void setPriority (int priority) { _priority = priority; }
+ int size (void) const { return _size; }
+
+ // ---------------------------------- methods
+
+ void copy (constQueueItemPtr from);
+
+ bool isBranch (void) const { return _type == QUEUE_ITEM_TYPE_BRANCH; }
+ bool isConflict (void) const { return _type == QUEUE_ITEM_TYPE_CONFLICT; }
+ bool isGroup (void) const { return _type == QUEUE_ITEM_TYPE_GROUP; }
+ bool isInstall (void) const { return _type == QUEUE_ITEM_TYPE_INSTALL; }
+ bool isRequire (void) const { return _type == QUEUE_ITEM_TYPE_REQUIRE; }
+ bool isUninstall (void) const { return _type == QUEUE_ITEM_TYPE_UNINSTALL; }
+
+ virtual bool process (ResolverContextPtr context, QueueItemList & qil) = 0;
+ virtual QueueItemPtr copy (void) const = 0;
+ virtual int cmp (constQueueItemPtr item) const = 0;
+ int compare (constQueueItemPtr item) const { return CMP(_type, item->_type); }
+
+ // isRedundant true == can be dropped from any branch
+ virtual bool isRedundant (ResolverContextPtr context) const = 0;
+
+ // isSatisfied true == can be dropped from any queue, and any
+ // branch containing it can also be dropped
+ virtual bool isSatisfied (ResolverContextPtr context) const = 0;
+
+ void addInfo (ResolverInfoPtr);
+ void logInfo (ResolverContextPtr);
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItem_h
#include <zypp/solver/detail/QueueItem.h>
#include <zypp/solver/detail/Resolver.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(QueueItemBranch,QueueItem);
-
-//---------------------------------------------------------------------------
-
-string
-QueueItemBranch::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-QueueItemBranch::toString ( const QueueItemBranch & item)
-{
- string res = "[Branch: ";
- if (!item._label.empty()) {
- res += item._label;
- }
- res += "\n\t";
- res += QueueItem::toString(item._possible_items, "\n\t");
- res += "]";
- return res;
-}
-
-
-ostream &
-QueueItemBranch::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const QueueItemBranch & item)
-{
- return os << item.asString();
-}
-
-//---------------------------------------------------------------------------
-
-QueueItemBranch::QueueItemBranch (WorldPtr world)
- : QueueItem (QUEUE_ITEM_TYPE_BRANCH, world)
-{
-}
-
-
-QueueItemBranch::~QueueItemBranch()
-{
-}
-
-//---------------------------------------------------------------------------
-
-void
-QueueItemBranch::addItem (QueueItemPtr subitem)
-{
- assert (this != subitem);
-#if 0
- // We want to keep the list of possible items sorted for easy comparison later.
- for (QueueItemList::iterator pos = _possible_items.begin(); pos != _possible_items.end(); pos++) {
-
- if ((*pos)->cmp(subitem) >= 0) { // found a larger one
- _possible_items.insert (pos, subitem); // insert before
- return;
- }
- }
-#endif
- _possible_items.push_back (subitem); // no larger found, subitem must be largest
-
- return;
-}
-
-
-bool
-QueueItemBranch::contains (QueueItemPtr possible_subbranch)
-{
- QueueItemBranchPtr branch = (QueueItemBranchPtr)possible_subbranch;
-
- if (branch == NULL
- || !branch->isBranch()) {
- return false;
- }
-
-
- if (_possible_items.size() < branch->_possible_items.size()) {
- return false;
- }
-
- QueueItemList::iterator iter = _possible_items.begin();
- QueueItemList::iterator iter_sub = branch->_possible_items.begin();
-
- /* For every item inside the possible sub-branch, look for a matching item
- in the branch. If we can't find a match, fail. (We can do this in one
- pass since the possible_items lists are sorted)
- */
- while (iter_sub != branch->_possible_items.end()) {
-
- while (iter != _possible_items.end()
- && (*iter)->cmp (*iter_sub)) {
- iter++;
- }
-
- if (iter == _possible_items.end())
- return false;
-
- iter++;
- iter_sub++;
- }
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-bool
-QueueItemBranch::process (ResolverContextPtr context, QueueItemList & qil)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemBranch::process(%s)\n", asString().c_str());
-
- QueueItemList live_branches;
- unsigned int branch_count;
- bool did_something = true;
-
- for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
-
- QueueItemPtr item = *iter;
-
- if (item->isSatisfied (context))
- goto finished;
-
- /* Drop any useless branch items */
- if (! item->isRedundant (context)) {
- live_branches.push_front (item);
- }
- }
-
- branch_count = live_branches.size();
-
- if (branch_count == 0) {
-
- /* Do nothing */
-
- } else if (branch_count == 1) {
-
- /* If we just have one possible item, process it. */
-
- QueueItemPtr item = live_branches.front();
- did_something = item->process (context, qil);
-
- /* Set the item pointer to NULL inside of our original branch
- item, since our call to rc_queue_item_process is now
- responsible for freeing it. */
-
- for (QueueItemList::iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
- if (*iter == item) {
- _possible_items.erase (iter);
- break;
- }
- }
-
- } else if (branch_count == _possible_items.size()) {
-
- /* Nothing was eliminated, so just pass the branch through (and set it to
- NULL so that it won't get freed when we exit. */
-
- qil.push_front (this);
-// FIXME: dont free item = NULL;
- did_something = false;
-
- } else {
-//fprintf (stderr, "QueueItemBranch::process rebranching\n");
- QueueItemBranchPtr new_branch = new QueueItemBranch (world());
- for (QueueItemList::const_iterator iter = live_branches.begin(); iter != live_branches.end(); iter++) {
- new_branch->addItem ((*iter)->copy());
- }
- qil.push_front (new_branch);
- }
-
- finished:
-//FIXME rc_queue_item_free (item);
-
- return did_something;
-}
-
-
-int
-QueueItemBranch::cmp (constQueueItemPtr item) const
-{
- int cmp = this->compare (item); // assures equal type
- if (cmp != 0)
- return cmp;
-
- constQueueItemBranchPtr branch = item;
-
- /* First, sort by # of possible items. */
- cmp = CMP(_possible_items.size(), branch->_possible_items.size());
- if (cmp != 0)
- return cmp;
-
- /* We can do a by-item cmp since the possible items are kept in sorted order. */
- QueueItemList::const_iterator ia = _possible_items.begin();
- QueueItemList::const_iterator ib = branch->_possible_items.begin();
-
- while (ia != _possible_items.end() && ib != branch->_possible_items.end()) {
- if (*ia && *ib) {
- cmp = (*ia)->cmp (*ib);
- if (cmp != 0) {
- return cmp;
- }
- }
- ia++;
- ib++;
- }
-
- /* Both lists should end at the same time, since we initially sorted on length. */
- assert (ia == _possible_items.end() && ib == branch->_possible_items.end());
-
- return 0;
-}
-
-
-QueueItemPtr
-QueueItemBranch::copy (void) const
-{
- QueueItemBranchPtr new_branch = new QueueItemBranch (world());
- ((QueueItemPtr)new_branch)->copy((constQueueItemPtr)this);
-
- for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
- QueueItemPtr cpy = (*iter)->copy();
- new_branch->_possible_items.push_front (cpy);
- }
-
- return new_branch;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(QueueItemBranch,QueueItem);
+
+ //---------------------------------------------------------------------------
+
+ string
+ QueueItemBranch::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ QueueItemBranch::toString ( const QueueItemBranch & item)
+ {
+ string res = "[Branch: ";
+ if (!item._label.empty()) {
+ res += item._label;
+ }
+ res += "\n\t";
+ res += QueueItem::toString(item._possible_items, "\n\t");
+ res += "]";
+ return res;
+ }
+
+
+ ostream &
+ QueueItemBranch::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const QueueItemBranch & item)
+ {
+ return os << item.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItemBranch::QueueItemBranch (WorldPtr world)
+ : QueueItem (QUEUE_ITEM_TYPE_BRANCH, world)
+ {
+ }
+
+
+ QueueItemBranch::~QueueItemBranch()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ QueueItemBranch::addItem (QueueItemPtr subitem)
+ {
+ assert (this != subitem);
+ #if 0
+ // We want to keep the list of possible items sorted for easy comparison later.
+ for (QueueItemList::iterator pos = _possible_items.begin(); pos != _possible_items.end(); pos++) {
+
+ if ((*pos)->cmp(subitem) >= 0) { // found a larger one
+ _possible_items.insert (pos, subitem); // insert before
+ return;
+ }
+ }
+ #endif
+ _possible_items.push_back (subitem); // no larger found, subitem must be largest
+
+ return;
+ }
+
+
+ bool
+ QueueItemBranch::contains (QueueItemPtr possible_subbranch)
+ {
+ QueueItemBranchPtr branch = (QueueItemBranchPtr)possible_subbranch;
+
+ if (branch == NULL
+ || !branch->isBranch()) {
+ return false;
+ }
+
+
+ if (_possible_items.size() < branch->_possible_items.size()) {
+ return false;
+ }
+
+ QueueItemList::iterator iter = _possible_items.begin();
+ QueueItemList::iterator iter_sub = branch->_possible_items.begin();
+
+ /* For every item inside the possible sub-branch, look for a matching item
+ in the branch. If we can't find a match, fail. (We can do this in one
+ pass since the possible_items lists are sorted)
+ */
+ while (iter_sub != branch->_possible_items.end()) {
+
+ while (iter != _possible_items.end()
+ && (*iter)->cmp (*iter_sub)) {
+ iter++;
+ }
+
+ if (iter == _possible_items.end())
+ return false;
+
+ iter++;
+ iter_sub++;
+ }
+
+ return true;
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ QueueItemBranch::process (ResolverContextPtr context, QueueItemList & qil)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemBranch::process(%s)\n", asString().c_str());
+
+ QueueItemList live_branches;
+ unsigned int branch_count;
+ bool did_something = true;
+
+ for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
+
+ QueueItemPtr item = *iter;
+
+ if (item->isSatisfied (context))
+ goto finished;
+
+ /* Drop any useless branch items */
+ if (! item->isRedundant (context)) {
+ live_branches.push_front (item);
+ }
+ }
+
+ branch_count = live_branches.size();
+
+ if (branch_count == 0) {
+
+ /* Do nothing */
+
+ } else if (branch_count == 1) {
+
+ /* If we just have one possible item, process it. */
+
+ QueueItemPtr item = live_branches.front();
+ did_something = item->process (context, qil);
+
+ /* Set the item pointer to NULL inside of our original branch
+ item, since our call to rc_queue_item_process is now
+ responsible for freeing it. */
+
+ for (QueueItemList::iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
+ if (*iter == item) {
+ _possible_items.erase (iter);
+ break;
+ }
+ }
+
+ } else if (branch_count == _possible_items.size()) {
+
+ /* Nothing was eliminated, so just pass the branch through (and set it to
+ NULL so that it won't get freed when we exit. */
+
+ qil.push_front (this);
+ // FIXME: dont free item = NULL;
+ did_something = false;
+
+ } else {
+ //fprintf (stderr, "QueueItemBranch::process rebranching\n");
+ QueueItemBranchPtr new_branch = new QueueItemBranch (world());
+ for (QueueItemList::const_iterator iter = live_branches.begin(); iter != live_branches.end(); iter++) {
+ new_branch->addItem ((*iter)->copy());
+ }
+ qil.push_front (new_branch);
+ }
+
+ finished:
+ //FIXME rc_queue_item_free (item);
+
+ return did_something;
+ }
+
+
+ int
+ QueueItemBranch::cmp (constQueueItemPtr item) const
+ {
+ int cmp = this->compare (item); // assures equal type
+ if (cmp != 0)
+ return cmp;
+
+ constQueueItemBranchPtr branch = item;
+
+ /* First, sort by # of possible items. */
+ cmp = CMP(_possible_items.size(), branch->_possible_items.size());
+ if (cmp != 0)
+ return cmp;
+
+ /* We can do a by-item cmp since the possible items are kept in sorted order. */
+ QueueItemList::const_iterator ia = _possible_items.begin();
+ QueueItemList::const_iterator ib = branch->_possible_items.begin();
+
+ while (ia != _possible_items.end() && ib != branch->_possible_items.end()) {
+ if (*ia && *ib) {
+ cmp = (*ia)->cmp (*ib);
+ if (cmp != 0) {
+ return cmp;
+ }
+ }
+ ia++;
+ ib++;
+ }
+
+ /* Both lists should end at the same time, since we initially sorted on length. */
+ assert (ia == _possible_items.end() && ib == branch->_possible_items.end());
+
+ return 0;
+ }
+
+
+ QueueItemPtr
+ QueueItemBranch::copy (void) const
+ {
+ QueueItemBranchPtr new_branch = new QueueItemBranch (world());
+ ((QueueItemPtr)new_branch)->copy((constQueueItemPtr)this);
+
+ for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
+ QueueItemPtr cpy = (*iter)->copy();
+ new_branch->_possible_items.push_front (cpy);
+ }
+
+ return new_branch;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : QueueItemBranch
-
-class QueueItemBranch : public QueueItem {
- REP_BODY(QueueItemBranch);
-
- private:
- std::string _label;
- QueueItemList _possible_items;
-
- public:
-
- QueueItemBranch (WorldPtr world);
- virtual ~QueueItemBranch();
-
- // ---------------------------------- I/O
-
- static std::string toString (const QueueItemBranch & item);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const QueueItemBranch & item);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- QueueItemList possibleItems (void) const { return _possible_items; }
-
- const std::string & label (void) const { return _label; }
- void setLabel (const std::string & label) { _label = label; }
-
- bool isEmpty (void) const { return _possible_items.empty(); }
-
- // ---------------------------------- methods
-
- virtual bool process (ResolverContextPtr context, QueueItemList & qil);
- virtual QueueItemPtr copy (void) const;
- virtual int cmp (constQueueItemPtr item) const;
- virtual bool isRedundant (ResolverContextPtr context) const { return false; }
- virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
-
- void addItem (QueueItemPtr subitem);
- bool contains (QueueItemPtr possible_subbranch);
-};
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : QueueItemBranch
+
+ class QueueItemBranch : public QueueItem {
+ REP_BODY(QueueItemBranch);
+
+ private:
+ std::string _label;
+ QueueItemList _possible_items;
+
+ public:
+
+ QueueItemBranch (WorldPtr world);
+ virtual ~QueueItemBranch();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const QueueItemBranch & item);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const QueueItemBranch & item);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ QueueItemList possibleItems (void) const { return _possible_items; }
+
+ const std::string & label (void) const { return _label; }
+ void setLabel (const std::string & label) { _label = label; }
+
+ bool isEmpty (void) const { return _possible_items.empty(); }
+
+ // ---------------------------------- methods
+
+ virtual bool process (ResolverContextPtr context, QueueItemList & qil);
+ virtual QueueItemPtr copy (void) const;
+ virtual int cmp (constQueueItemPtr item) const;
+ virtual bool isRedundant (ResolverContextPtr context) const { return false; }
+ virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
+
+ void addItem (QueueItemPtr subitem);
+ bool contains (QueueItemPtr possible_subbranch);
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemBranch_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/QueueItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : QueueItemBranchPtr
-// CLASS NAME : constQueueItemBranchPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(QueueItemBranch,QueueItem);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : QueueItemBranchPtr
+ // CLASS NAME : constQueueItemBranchPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(QueueItemBranch,QueueItem);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemBranchPtr_h
#include <zypp/solver/detail/ResolverInfoMisc.h>
#include <zypp/solver/detail/ResolverInfoObsoletes.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(QueueItemConflict,QueueItem);
-
-//---------------------------------------------------------------------------
-
-string
-QueueItemConflict::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-QueueItemConflict::toString ( const QueueItemConflict & item)
-{
- string res = "[Conflict: ";
- res += item._dep->asString();
- res += ", Triggered by ";
- res += item._conflicting_resItem->asString();
- if (item._actually_an_obsolete) res += ", Obsolete !";
- res += "]";
- return res;
-}
-
-
-ostream &
-QueueItemConflict::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const QueueItemConflict & item)
-{
- return os << item.asString();
-}
-
-//---------------------------------------------------------------------------
-
-QueueItemConflict::QueueItemConflict (WorldPtr world, constDependencyPtr dep, constResItemPtr resItem)
- : QueueItem (QUEUE_ITEM_TYPE_CONFLICT, world)
- , _dep (dep)
- , _conflicting_resItem (resItem)
- , _actually_an_obsolete (false)
-{
-}
-
-
-QueueItemConflict::~QueueItemConflict()
-{
-}
-
-//---------------------------------------------------------------------------
-
-#if PHI
-
-// on conflict, try to find upgrade candidates for the installed resItem triggering the conflict
-// there are cases where upgrading prevents the conflict
-// rc tends to uninstall the resItem
-// phi tends to upgrade the resItem
-// testcases: exercise-02conflict-08-test.xml, exercise-02conflict-09-test.xml
-
-typedef struct {
- ResolverContextPtr context;
- CResItemList upgrades;
-} UpgradeCandidateInfo;
-
-
-static bool
-upgrade_candidates_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
-{
-//fprintf (stderr, "upgrade_candidates_cb(%s,%s)\n", resItem->asString().c_str(), spec->asString().c_str());
- UpgradeCandidateInfo *info = (UpgradeCandidateInfo *)data;
- if (info->context->getStatus (resItem) == RESOLVABLE_STATUS_UNINSTALLED) {
- info->upgrades.push_back (resItem);
- }
- return true;
-}
-
-#endif // PHI
-
-
-typedef struct {
- WorldPtr world;
- constResItemPtr conflicting_resItem;
- constDependencyPtr dep;
- ResolverContextPtr context;
- QueueItemList & new_items;
-
- string pkg_str;
- string dep_str;
-
- bool actually_an_obsolete;
-} ConflictProcessInfo;
-
-
-static bool
-conflict_process_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
-{
- ConflictProcessInfo *info = (ConflictProcessInfo *)data;
- ResItemStatus status;
- string pkg_str, spec_str, msg;
- ResolverInfoPtr log_info;
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "conflict_process_cb (resolvable[%s], spec[%s], info [%s]\n", resItem->asString().c_str(), spec->asString().c_str(), info->conflicting_resItem->asString().c_str());
- if (getenv ("RC_SPEW")) fprintf (stderr, "conflict_process_cb (resolvable equals spec: %s, info->dep [%s]\n", resItem->equals(spec) ? "YES" : "NO", info->dep->asString().c_str());
-
- /* We conflict with ourself. For the purpose of installing ourself, we
- * just ignore it, but it's Debian's way of saying that one and only one
- * resItem with this provide may exist on the system at a time. */
-
- if (info->conflicting_resItem
- && resItem->equals (info->conflicting_resItem)) {
- return true;
- }
-
- /* FIXME: This should probably be a GVersion capability. */
- /* Obsoletes don't apply to virtual provides, only the resItems
- * themselves. A provide is "virtual" if it's not the same spec
- * as the resItem that's providing it. This, of course, only
- * applies to RPM, since it's the only one with obsoletes right
- * now. */
-
- if (info->actually_an_obsolete
- && !(resItem->equals(spec)))
- {
- return true;
- }
-
- pkg_str = resItem->asString();
- spec_str = spec->asString();
-
- status = info->context->getStatus (resItem);
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "conflict_process_cb (resolvable[%s]<%s>\n", resItem->asString().c_str(), ResolverContext::toString(status).c_str());
-
- switch (status) {
-
- case RESOLVABLE_STATUS_INSTALLED:
- case RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT: {
- QueueItemUninstallPtr uninstall;
- ResolverInfoPtr log_info;
-
-#if PHI
- // maybe an upgrade can resolve the conflict ?
- // check if other resItem is available which upgrades
-
- // find non-installed packages which provide the conflicting name
-
- UpgradeCandidateInfo upgrade_info;
- upgrade_info.context = info->context;
-
- DependencyPtr maybe_upgrade_dep = new Dependency (resItem->name(), Relation::Any, Kind::Package, new Channel (CHANNEL_TYPE_NONSYSTEM), -1);
- info->world->foreachProvidingResItem (maybe_upgrade_dep, upgrade_candidates_cb, (void *)&upgrade_info);
-
-#endif
-
- uninstall = new QueueItemUninstall (info->world, resItem, "conflict");
- uninstall->setDependency (info->dep);
-
- if (info->actually_an_obsolete) {
- uninstall->setDueToObsolete ();
- log_info = new ResolverInfoObsoletes (resItem, info->conflicting_resItem);
- } else {
- uninstall->setDueToConflict ();
- log_info = new ResolverInfoConflictsWith (resItem, info->conflicting_resItem);
- }
-
- uninstall->addInfo (log_info);
-
-#if PHI
- if (upgrade_info.upgrades.empty ()) {
-#endif
-
- info->new_items.push_back (uninstall);
-
-#if PHI
- }
- else {
- // there are upgrade candidates for the conflicting resItem
- // branch to: 1. uninstall, 2. upgrade (for each upgrading resItem)
-
- QueueItemBranchPtr branch = new QueueItemBranch (info->world);
-
- branch->addItem (uninstall); // try uninstall
-
- for (CResItemList::const_iterator iter = upgrade_info.upgrades.begin(); iter != upgrade_info.upgrades.end(); iter++) {
- QueueItemInstallPtr upgrade = new QueueItemInstall (info->world, *iter);
- upgrade->setUpgrades (resItem);
- branch->addItem (upgrade); // try upgrade
- }
- info->new_items.push_back (branch);
- }
-#endif
-
- break;
- }
-
- case RESOLVABLE_STATUS_TO_BE_INSTALLED: {
- msg = string ("A conflict over ") + info->dep_str + " (" + spec_str + ") requires the removal of the to-be-installed resolvable " + pkg_str;
-
- ResolverInfoMiscPtr misc_info = new ResolverInfoMisc (resItem,RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
- misc_info->flagAsError ();
- if (info->conflicting_resItem) {
- misc_info->addRelatedResItem (info->conflicting_resItem);
- }
- info->context->addInfo (misc_info);
-
- break;
- }
-
- case RESOLVABLE_STATUS_UNINSTALLED: {
- info->context->setStatus (resItem, RESOLVABLE_STATUS_TO_BE_UNINSTALLED);
- msg = string ("Marking ") + pkg_str + " as uninstallable due to conflicts over " + info->dep_str + " (" + spec_str + ")";
- if (!(info->pkg_str.empty())) {
- msg += " from ";
- msg += info->pkg_str;
- }
-
- ResolverInfoMiscPtr misc_info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
- misc_info->addRelatedResItem (resItem);
- if (info->conflicting_resItem) {
- misc_info->addRelatedResItem(info->conflicting_resItem);
- }
- info->context->addInfo (misc_info);
-
- break;
- }
-
- case RESOLVABLE_STATUS_TO_BE_UNINSTALLED:
- case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE:
- /* This is the easy case -- we do nothing. */
- break;
-
- default:
- abort();
- }
-
- return true;
-}
-
-
-bool
-QueueItemConflict::process (ResolverContextPtr context, QueueItemList & new_items)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemConflict::process(%s)\n", this->asString().c_str());
-
- ConflictProcessInfo info = { world(), _conflicting_resItem, _dep, context, new_items, "", "", _actually_an_obsolete };
-
- if (_conflicting_resItem) {
- info.pkg_str = _conflicting_resItem->asString();
- }
-
- info.dep_str = _dep->relation().asString() + " " + ((constSpecPtr)_dep)->asString();
-
- world()->foreachProvidingResItem (_dep, conflict_process_cb, (void *)&info);
-
-// FIXME: free self
-
- return true;
-}
-
-
-//---------------------------------------------------------------------------
-
-QueueItemPtr
-QueueItemConflict::copy (void) const
-{
- QueueItemConflictPtr new_conflict = new QueueItemConflict (world(), _dep, _conflicting_resItem);
- ((QueueItemPtr)new_conflict)->copy((constQueueItemPtr)this);
-
- // _actually_an_obsolete is not being copied !
-
- return new_conflict;
-}
-
-
-int
-QueueItemConflict::cmp (constQueueItemPtr item) const
-{
- int cmp = this->compare (item); // assures equal type
- if (cmp != 0)
- return cmp;
-
- constQueueItemConflictPtr conflict = item;
- cmp = GVersion.compare ((constSpecPtr) _dep, ((constSpecPtr)(conflict->dependency())));
- if (cmp)
- return cmp;
-
- return CMP ((int) _dep->relation().op(), (int) (conflict->dependency()->relation().op()));
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(QueueItemConflict,QueueItem);
+
+ //---------------------------------------------------------------------------
+
+ string
+ QueueItemConflict::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ QueueItemConflict::toString ( const QueueItemConflict & item)
+ {
+ string res = "[Conflict: ";
+ res += item._dep->asString();
+ res += ", Triggered by ";
+ res += item._conflicting_resItem->asString();
+ if (item._actually_an_obsolete) res += ", Obsolete !";
+ res += "]";
+ return res;
+ }
+
+
+ ostream &
+ QueueItemConflict::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const QueueItemConflict & item)
+ {
+ return os << item.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItemConflict::QueueItemConflict (WorldPtr world, constDependencyPtr dep, constResItemPtr resItem)
+ : QueueItem (QUEUE_ITEM_TYPE_CONFLICT, world)
+ , _dep (dep)
+ , _conflicting_resItem (resItem)
+ , _actually_an_obsolete (false)
+ {
+ }
+
+
+ QueueItemConflict::~QueueItemConflict()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ #if PHI
+
+ // on conflict, try to find upgrade candidates for the installed resItem triggering the conflict
+ // there are cases where upgrading prevents the conflict
+ // rc tends to uninstall the resItem
+ // phi tends to upgrade the resItem
+ // testcases: exercise-02conflict-08-test.xml, exercise-02conflict-09-test.xml
+
+ typedef struct {
+ ResolverContextPtr context;
+ CResItemList upgrades;
+ } UpgradeCandidateInfo;
+
+
+ static bool
+ upgrade_candidates_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
+ {
+ //fprintf (stderr, "upgrade_candidates_cb(%s,%s)\n", resItem->asString().c_str(), spec->asString().c_str());
+ UpgradeCandidateInfo *info = (UpgradeCandidateInfo *)data;
+ if (info->context->getStatus (resItem) == RESOLVABLE_STATUS_UNINSTALLED) {
+ info->upgrades.push_back (resItem);
+ }
+ return true;
+ }
+
+ #endif // PHI
+
+
+ typedef struct {
+ WorldPtr world;
+ constResItemPtr conflicting_resItem;
+ constDependencyPtr dep;
+ ResolverContextPtr context;
+ QueueItemList & new_items;
+
+ string pkg_str;
+ string dep_str;
+
+ bool actually_an_obsolete;
+ } ConflictProcessInfo;
+
+
+ static bool
+ conflict_process_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
+ {
+ ConflictProcessInfo *info = (ConflictProcessInfo *)data;
+ ResItemStatus status;
+ string pkg_str, spec_str, msg;
+ ResolverInfoPtr log_info;
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "conflict_process_cb (resolvable[%s], spec[%s], info [%s]\n", resItem->asString().c_str(), spec->asString().c_str(), info->conflicting_resItem->asString().c_str());
+ if (getenv ("RC_SPEW")) fprintf (stderr, "conflict_process_cb (resolvable equals spec: %s, info->dep [%s]\n", resItem->equals(spec) ? "YES" : "NO", info->dep->asString().c_str());
+
+ /* We conflict with ourself. For the purpose of installing ourself, we
+ * just ignore it, but it's Debian's way of saying that one and only one
+ * resItem with this provide may exist on the system at a time. */
+
+ if (info->conflicting_resItem
+ && resItem->equals (info->conflicting_resItem)) {
+ return true;
+ }
+
+ /* FIXME: This should probably be a GVersion capability. */
+ /* Obsoletes don't apply to virtual provides, only the resItems
+ * themselves. A provide is "virtual" if it's not the same spec
+ * as the resItem that's providing it. This, of course, only
+ * applies to RPM, since it's the only one with obsoletes right
+ * now. */
+
+ if (info->actually_an_obsolete
+ && !(resItem->equals(spec)))
+ {
+ return true;
+ }
+
+ pkg_str = resItem->asString();
+ spec_str = spec->asString();
+
+ status = info->context->getStatus (resItem);
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "conflict_process_cb (resolvable[%s]<%s>\n", resItem->asString().c_str(), ResolverContext::toString(status).c_str());
+
+ switch (status) {
+
+ case RESOLVABLE_STATUS_INSTALLED:
+ case RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT: {
+ QueueItemUninstallPtr uninstall;
+ ResolverInfoPtr log_info;
+
+ #if PHI
+ // maybe an upgrade can resolve the conflict ?
+ // check if other resItem is available which upgrades
+
+ // find non-installed packages which provide the conflicting name
+
+ UpgradeCandidateInfo upgrade_info;
+ upgrade_info.context = info->context;
+
+ DependencyPtr maybe_upgrade_dep = new Dependency (resItem->name(), Relation::Any, Kind::Package, new Channel (CHANNEL_TYPE_NONSYSTEM), -1);
+ info->world->foreachProvidingResItem (maybe_upgrade_dep, upgrade_candidates_cb, (void *)&upgrade_info);
+
+ #endif
+
+ uninstall = new QueueItemUninstall (info->world, resItem, "conflict");
+ uninstall->setDependency (info->dep);
+
+ if (info->actually_an_obsolete) {
+ uninstall->setDueToObsolete ();
+ log_info = new ResolverInfoObsoletes (resItem, info->conflicting_resItem);
+ } else {
+ uninstall->setDueToConflict ();
+ log_info = new ResolverInfoConflictsWith (resItem, info->conflicting_resItem);
+ }
+
+ uninstall->addInfo (log_info);
+
+ #if PHI
+ if (upgrade_info.upgrades.empty ()) {
+ #endif
+
+ info->new_items.push_back (uninstall);
+
+ #if PHI
+ }
+ else {
+ // there are upgrade candidates for the conflicting resItem
+ // branch to: 1. uninstall, 2. upgrade (for each upgrading resItem)
+
+ QueueItemBranchPtr branch = new QueueItemBranch (info->world);
+
+ branch->addItem (uninstall); // try uninstall
+
+ for (CResItemList::const_iterator iter = upgrade_info.upgrades.begin(); iter != upgrade_info.upgrades.end(); iter++) {
+ QueueItemInstallPtr upgrade = new QueueItemInstall (info->world, *iter);
+ upgrade->setUpgrades (resItem);
+ branch->addItem (upgrade); // try upgrade
+ }
+ info->new_items.push_back (branch);
+ }
+ #endif
+
+ break;
+ }
+
+ case RESOLVABLE_STATUS_TO_BE_INSTALLED: {
+ msg = string ("A conflict over ") + info->dep_str + " (" + spec_str + ") requires the removal of the to-be-installed resolvable " + pkg_str;
+
+ ResolverInfoMiscPtr misc_info = new ResolverInfoMisc (resItem,RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+
+ misc_info->flagAsError ();
+ if (info->conflicting_resItem) {
+ misc_info->addRelatedResItem (info->conflicting_resItem);
+ }
+ info->context->addInfo (misc_info);
+
+ break;
+ }
+
+ case RESOLVABLE_STATUS_UNINSTALLED: {
+ info->context->setStatus (resItem, RESOLVABLE_STATUS_TO_BE_UNINSTALLED);
+ msg = string ("Marking ") + pkg_str + " as uninstallable due to conflicts over " + info->dep_str + " (" + spec_str + ")";
+ if (!(info->pkg_str.empty())) {
+ msg += " from ";
+ msg += info->pkg_str;
+ }
+
+ ResolverInfoMiscPtr misc_info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+
+ misc_info->addRelatedResItem (resItem);
+ if (info->conflicting_resItem) {
+ misc_info->addRelatedResItem(info->conflicting_resItem);
+ }
+ info->context->addInfo (misc_info);
+
+ break;
+ }
+
+ case RESOLVABLE_STATUS_TO_BE_UNINSTALLED:
+ case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE:
+ /* This is the easy case -- we do nothing. */
+ break;
+
+ default:
+ abort();
+ }
+
+ return true;
+ }
+
+
+ bool
+ QueueItemConflict::process (ResolverContextPtr context, QueueItemList & new_items)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemConflict::process(%s)\n", this->asString().c_str());
+
+ ConflictProcessInfo info = { world(), _conflicting_resItem, _dep, context, new_items, "", "", _actually_an_obsolete };
+
+ if (_conflicting_resItem) {
+ info.pkg_str = _conflicting_resItem->asString();
+ }
+
+ info.dep_str = _dep->relation().asString() + " " + ((constSpecPtr)_dep)->asString();
+
+ world()->foreachProvidingResItem (_dep, conflict_process_cb, (void *)&info);
+
+ // FIXME: free self
+
+ return true;
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ QueueItemPtr
+ QueueItemConflict::copy (void) const
+ {
+ QueueItemConflictPtr new_conflict = new QueueItemConflict (world(), _dep, _conflicting_resItem);
+ ((QueueItemPtr)new_conflict)->copy((constQueueItemPtr)this);
+
+ // _actually_an_obsolete is not being copied !
+
+ return new_conflict;
+ }
+
+
+ int
+ QueueItemConflict::cmp (constQueueItemPtr item) const
+ {
+ int cmp = this->compare (item); // assures equal type
+ if (cmp != 0)
+ return cmp;
+
+ constQueueItemConflictPtr conflict = item;
+ cmp = GVersion.compare ((constSpecPtr) _dep, ((constSpecPtr)(conflict->dependency())));
+ if (cmp)
+ return cmp;
+
+ return CMP ((int) _dep->relation().op(), (int) (conflict->dependency()->relation().op()));
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : QueueItemConflict
-
-class QueueItemConflict : public QueueItem {
- REP_BODY(QueueItemConflict);
-
- private:
- constDependencyPtr _dep;
- constResItemPtr _conflicting_resItem;
-
- bool _actually_an_obsolete;
-
- public:
-
- QueueItemConflict (WorldPtr world, constDependencyPtr dep, constResItemPtr resItem);
- virtual ~QueueItemConflict();
-
- // ---------------------------------- I/O
-
- static std::string toString (const QueueItemConflict & item);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const QueueItemConflict & item);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- constDependencyPtr dependency (void) const { return _dep; }
- bool actuallyAnObsolete (void) const { return _actually_an_obsolete; }
- void setActuallyAnObsolete (void) { _actually_an_obsolete = true; }
-
- // ---------------------------------- methods
-
- virtual bool process (ResolverContextPtr context, QueueItemList & qil);
- virtual QueueItemPtr copy (void) const;
- virtual int cmp (constQueueItemPtr item) const;
- virtual bool isRedundant (ResolverContextPtr context) const { return false; }
- virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
-
-};
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : QueueItemConflict
+
+ class QueueItemConflict : public QueueItem {
+ REP_BODY(QueueItemConflict);
+
+ private:
+ constDependencyPtr _dep;
+ constResItemPtr _conflicting_resItem;
+
+ bool _actually_an_obsolete;
+
+ public:
+
+ QueueItemConflict (WorldPtr world, constDependencyPtr dep, constResItemPtr resItem);
+ virtual ~QueueItemConflict();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const QueueItemConflict & item);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const QueueItemConflict & item);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ constDependencyPtr dependency (void) const { return _dep; }
+ bool actuallyAnObsolete (void) const { return _actually_an_obsolete; }
+ void setActuallyAnObsolete (void) { _actually_an_obsolete = true; }
+
+ // ---------------------------------- methods
+
+ virtual bool process (ResolverContextPtr context, QueueItemList & qil);
+ virtual QueueItemPtr copy (void) const;
+ virtual int cmp (constQueueItemPtr item) const;
+ virtual bool isRedundant (ResolverContextPtr context) const { return false; }
+ virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemConflict_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/QueueItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : QueueItemConflictPtr
-// CLASS NAME : constQueueItemConflictPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(QueueItemConflict,QueueItem);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : QueueItemConflictPtr
+ // CLASS NAME : constQueueItemConflictPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(QueueItemConflict,QueueItem);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemConflictPtr_h
#include <zypp/solver/detail/QueueItemGroup.h>
#include <zypp/solver/detail/QueueItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(QueueItemGroup,QueueItem);
-
-//---------------------------------------------------------------------------
-
-string
-QueueItemGroup::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-QueueItemGroup::toString ( const QueueItemGroup & item)
-{
- string ret = "[Group: ";
- ret += QueueItem::toString(item._subitems);
- ret += "]";
- return ret;
-}
-
-
-ostream &
-QueueItemGroup::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const QueueItemGroup & item)
-{
- return os << item.asString();
-}
-
-//---------------------------------------------------------------------------
-
-QueueItemGroup::QueueItemGroup (WorldPtr world)
- : QueueItem (QUEUE_ITEM_TYPE_GROUP, world)
-{
-}
-
-
-QueueItemGroup::~QueueItemGroup()
-{
-}
-
-//---------------------------------------------------------------------------
-
-bool
-QueueItemGroup::process (ResolverContextPtr context, QueueItemList & new_items)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemGroup::process\n");
-
- bool did_something = false;
-
- // Just move all of the group's subitems onto the new_items list.
-
- for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
- new_items.push_front (*iter);
- did_something = true;
- }
-
- _subitems.clear();
-
-// FIXME: delete self
-
- return did_something;
-}
-
-
-QueueItemPtr
-QueueItemGroup::copy (void) const
-{
- QueueItemGroupPtr new_group = new QueueItemGroup (world());
- ((QueueItemPtr)new_group)->copy((constQueueItemPtr)this);
-
- for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
- new_group->_subitems.push_back ((*iter)->copy());
- }
- return new_group;
-}
-
-
-int
-QueueItemGroup::cmp (constQueueItemPtr item) const
-{
- int cmp = this->compare (item); // assures equal type
- if (cmp != 0)
- return cmp;
-
- constQueueItemGroupPtr group = item;
-
- // First, sort by # of subitems
-
- cmp = CMP(_subitems.size(), group->_subitems.size());
- if (cmp)
- return cmp;
-
- // We can do a by-item cmp since the possible items are kept in sorted order.
- QueueItemList::const_iterator iter2;
- for (QueueItemList::const_iterator iter = _subitems.begin(), iter2 = group->_subitems.begin();
- iter != _subitems.end() && iter2 != group->_subitems.end(); iter++, iter2++) {
- cmp = (*iter)->cmp (*iter2);
- if (cmp) {
- return cmp;
- }
- }
-
- return 0;
-}
-
-
-void
-QueueItemGroup::addItem (QueueItemPtr subitem)
-{
- // We need to keep the list sorted for comparison purposes.
- _subitems.push_back (subitem);
-// FIXME _subitems.sort(cmp)
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(QueueItemGroup,QueueItem);
+
+ //---------------------------------------------------------------------------
+
+ string
+ QueueItemGroup::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ QueueItemGroup::toString ( const QueueItemGroup & item)
+ {
+ string ret = "[Group: ";
+ ret += QueueItem::toString(item._subitems);
+ ret += "]";
+ return ret;
+ }
+
+
+ ostream &
+ QueueItemGroup::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const QueueItemGroup & item)
+ {
+ return os << item.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItemGroup::QueueItemGroup (WorldPtr world)
+ : QueueItem (QUEUE_ITEM_TYPE_GROUP, world)
+ {
+ }
+
+
+ QueueItemGroup::~QueueItemGroup()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ QueueItemGroup::process (ResolverContextPtr context, QueueItemList & new_items)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemGroup::process\n");
+
+ bool did_something = false;
+
+ // Just move all of the group's subitems onto the new_items list.
+
+ for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
+ new_items.push_front (*iter);
+ did_something = true;
+ }
+
+ _subitems.clear();
+
+ // FIXME: delete self
+
+ return did_something;
+ }
+
+
+ QueueItemPtr
+ QueueItemGroup::copy (void) const
+ {
+ QueueItemGroupPtr new_group = new QueueItemGroup (world());
+ ((QueueItemPtr)new_group)->copy((constQueueItemPtr)this);
+
+ for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
+ new_group->_subitems.push_back ((*iter)->copy());
+ }
+ return new_group;
+ }
+
+
+ int
+ QueueItemGroup::cmp (constQueueItemPtr item) const
+ {
+ int cmp = this->compare (item); // assures equal type
+ if (cmp != 0)
+ return cmp;
+
+ constQueueItemGroupPtr group = item;
+
+ // First, sort by # of subitems
+
+ cmp = CMP(_subitems.size(), group->_subitems.size());
+ if (cmp)
+ return cmp;
+
+ // We can do a by-item cmp since the possible items are kept in sorted order.
+ QueueItemList::const_iterator iter2;
+ for (QueueItemList::const_iterator iter = _subitems.begin(), iter2 = group->_subitems.begin();
+ iter != _subitems.end() && iter2 != group->_subitems.end(); iter++, iter2++) {
+ cmp = (*iter)->cmp (*iter2);
+ if (cmp) {
+ return cmp;
+ }
+ }
+
+ return 0;
+ }
+
+
+ void
+ QueueItemGroup::addItem (QueueItemPtr subitem)
+ {
+ // We need to keep the list sorted for comparison purposes.
+ _subitems.push_back (subitem);
+ // FIXME _subitems.sort(cmp)
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : QueueItemGroup
-
-class QueueItemGroup : public QueueItem {
- REP_BODY(QueueItemGroup);
-
- private:
- QueueItemList _subitems;
-
- public:
-
- QueueItemGroup (WorldPtr world);
- virtual ~QueueItemGroup();
-
- // ---------------------------------- I/O
-
- static std::string toString (const QueueItemGroup & item);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const QueueItemGroup & item);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
-
- // ---------------------------------- methods
-
- virtual bool process (ResolverContextPtr context, QueueItemList & qil);
- virtual QueueItemPtr copy (void) const;
- virtual int cmp (constQueueItemPtr item) const;
- virtual bool isRedundant (ResolverContextPtr context) const { return false; }
- virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
-
- void addItem (QueueItemPtr subitem);
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : QueueItemGroup
+
+ class QueueItemGroup : public QueueItem {
+ REP_BODY(QueueItemGroup);
+
+ private:
+ QueueItemList _subitems;
+
+ public:
+
+ QueueItemGroup (WorldPtr world);
+ virtual ~QueueItemGroup();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const QueueItemGroup & item);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const QueueItemGroup & item);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+
+ // ---------------------------------- methods
+
+ virtual bool process (ResolverContextPtr context, QueueItemList & qil);
+ virtual QueueItemPtr copy (void) const;
+ virtual int cmp (constQueueItemPtr item) const;
+ virtual bool isRedundant (ResolverContextPtr context) const { return false; }
+ virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
+
+ void addItem (QueueItemPtr subitem);
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemGroup_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/QueueItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : QueueItemGroupPtr
-// CLASS NAME : constQueueItemGroupPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(QueueItemGroup,QueueItem);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : QueueItemGroupPtr
+ // CLASS NAME : constQueueItemGroupPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(QueueItemGroup,QueueItem);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+////////////////////////////////////////////////////////////////////////
#endif // _QueueItemGroupPtr_h
#include <zypp/solver/detail/World.h>
#include <zypp/solver/detail/ResItemAndDependency.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(QueueItemInstall,QueueItem);
-
-//---------------------------------------------------------------------------
-
-string
-QueueItemInstall::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-QueueItemInstall::toString ( const QueueItemInstall & item)
-{
- string ret = "[Install: ";
- ret += item._resItem->asString();
- if (item._upgrades != NULL) {
- ret += ", Upgrades ";
- ret += item._upgrades->asString();
- }
- if (!item._deps_satisfied_by_this_install.empty()) {
- ret += ", Satisfies ";
- ret += Dependency::toString(item._deps_satisfied_by_this_install);
- }
- if (!item._needed_by.empty()) {
- ret += ", Needed by ";
- ret += ResItem::toString(item._needed_by);
- }
- if (item._explicitly_requested) ret += ", Explicit !";
- ret += "]";
- return ret;
-}
-
-
-ostream &
-QueueItemInstall::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const QueueItemInstall & item)
-{
- return os << item.asString();
-}
-
-//---------------------------------------------------------------------------
-
-QueueItemInstall::QueueItemInstall (WorldPtr world, constResItemPtr resItem)
- : QueueItem (QUEUE_ITEM_TYPE_INSTALL, world)
- , _resItem (resItem)
- , _channel_priority (0)
- , _other_penalty (0)
- , _explicitly_requested (false)
-{
- constResItemPtr upgrades = world->findInstalledResItem (resItem);
- if (getenv("RC_SPEW")) fprintf (stderr, "QueueItemInstall::QueueItemInstall(%s) upgrades %s\n", resItem->asString().c_str(), upgrades!=NULL?upgrades->asString().c_str():"nothing");
- if (upgrades
- && ! (((constSpecPtr)upgrades)->equals (resItem))) {
- setUpgrades(upgrades);
- }
-}
-
-
-QueueItemInstall::~QueueItemInstall()
-{
-}
-
-//---------------------------------------------------------------------------
-
-bool
-QueueItemInstall::isSatisfied (ResolverContextPtr context) const
-{
- return context->resItemIsPresent (_resItem);
-}
-
-
-//---------------------------------------------------------------------------
-
-// Handle system resItem's that conflict with us -> uninstall them
-
-static bool
-build_conflict_list (constResItemPtr resItem, constDependencyPtr dep, void *data)
-{
- CResItemList *rl = (CResItemList *)data;
- rl->push_front (resItem);
- return true;
-}
-
-bool
-QueueItemInstall::process (ResolverContextPtr context, QueueItemList & qil)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemInstall::process(%s)\n", this->asString().c_str());
-
- constResItemPtr resItem = _resItem;
- string pkg_name = resItem->asString();
- string msg;
- ResItemStatus status = context->getStatus (resItem);
-
- CDependencyList deps;
- CResItemList conflicts;
-
- /* If we are trying to upgrade resItem A with resItem B and they both have the
- same version number, do nothing. This shouldn't happen in general with
- red-carpet, but can come up with the installer & autopull. */
-
- if (_upgrades
- && ((constSpecPtr)_resItem)->equals (_upgrades)) {
- ResolverInfoPtr info;
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "upgrades equal resItem, skipping\n");
-
- msg = string("Skipping ") + pkg_name + (": already installed");
- info = new ResolverInfoMisc (_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
- context->addInfo (info);
- goto finished;
- }
-
- if (!_needed_by.empty()) {
- bool still_needed = false;
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "still needed ");
-
- for (CResItemList::const_iterator iter = _needed_by.begin(); iter != _needed_by.end() && !still_needed; iter++) {
- ResItemStatus status = context->getStatus (*iter);
- if (getenv ("RC_SPEW")) fprintf (stderr, "by: [status: %s] %s\n", ResolverContext::toString(status).c_str(), (*iter)->asString().c_str());
- if (! resItem_status_is_to_be_uninstalled (status)) {
- still_needed = true;
- }
- }
-
- if (! still_needed)
- goto finished;
- }
-
- /* If we are in verify mode and this install is about to fail, don't let it happen...
- instead, we try to back out of the install by removing whatever it was that
- needed this. */
-
- if (context->verifying()
- && resItem_status_is_to_be_uninstalled (context->getStatus (resItem))
- && !_needed_by.empty()) {
-
- QueueItemUninstallPtr uninstall_item;
-
- for (CResItemList::const_iterator iter = _needed_by.begin(); iter != _needed_by.end(); iter++) {
- uninstall_item = new QueueItemUninstall (world(), *iter, "uninstallable resolvable");
- qil.push_front (uninstall_item);
- }
-
- goto finished;
- }
-
- if (_upgrades == NULL) {
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "simple install of %s\n", resItem->asString(true).c_str());
-
- context->installResItem (resItem, context->verifying(), /* is_soft */ _other_penalty);
-
- } else {
-
- QueueItemUninstallPtr uninstall_item;
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "upgrade install of %s\n", resItem->asString().c_str());
-
- context->upgradeResItem (resItem, _upgrades, context->verifying(), /* is_soft */ _other_penalty);
-
- uninstall_item = new QueueItemUninstall (world(), _upgrades, "upgrade");
- uninstall_item->setUpgradedTo (resItem);
-
- if (_explicitly_requested)
- uninstall_item->setExplicitlyRequested ();
-
- qil.push_front (uninstall_item);
- }
-
- /* Log which resItem need this install */
-
- if (!_needed_by.empty()) {
- ResolverInfoNeededByPtr info;
-
- info = new ResolverInfoNeededBy (resItem);
- info->addRelatedResItemList (_needed_by);
- context->addInfo (info);
- }
-
- if (! (status == RESOLVABLE_STATUS_UNINSTALLED
- || status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK)) {
- goto finished;
- }
-
- if (_upgrades != NULL) {
- msg = string ("Upgrading ") + _upgrades->asString() + " => " + pkg_name;
- } else {
- msg = string ("Installing ") + pkg_name;
- }
-
- context->addInfoString (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
- logInfo (context);
-
- /* Construct require items for each of the resItem's requires that is still unsatisfied. */
-
- deps = resItem->requires();
- for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
- constDependencyPtr dep = *iter;
- if (!context->requirementIsMet (dep, false)) {
- if (getenv("RC_SPEW")) fprintf (stderr, "this requires %s\n", dep->asString().c_str());
- QueueItemRequirePtr req_item = new QueueItemRequire (world(), dep);
- req_item->addResItem (resItem);
- qil.push_front (req_item);
- }
- }
-
- /* Construct conflict items for each of the resItem's conflicts. */
-
- deps = resItem->conflicts();
- for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
- constDependencyPtr dep = *iter;
- if (getenv("RC_SPEW")) fprintf (stderr, "this conflicts with '%s'\n", dep->asString().c_str());
- QueueItemConflictPtr conflict_item = new QueueItemConflict (world(), dep, resItem);
- qil.push_front (conflict_item);
- }
-
- /* Construct conflict items for each of the resItem's obsoletes. */
-
- deps = resItem->obsoletes();
- for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
- constDependencyPtr dep = *iter;
- if (getenv("RC_SPEW")) fprintf (stderr, "this obsoletes %s\n", dep->asString().c_str());
- QueueItemConflictPtr conflict_item = new QueueItemConflict (world(), dep, resItem);
- conflict_item->setActuallyAnObsolete();
- qil.push_front (conflict_item);
- }
-
- /* Construct uninstall items for system resItem's that conflict with us. */
-
- deps = resItem->provides();
- for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
- constDependencyPtr dep = *iter;
- world()->foreachConflictingResItem (dep, build_conflict_list, &conflicts);
- }
-
- for (CResItemList::const_iterator iter = conflicts.begin(); iter != conflicts.end(); iter++) {
- constResItemPtr conflicting_resItem = *iter;
- ResolverInfoPtr log_info;
- QueueItemUninstallPtr uninstall_item;
-
- /* Check to see if we conflict with ourself and don't create
- * an uninstall item for it if we do. This is Debian's way of
- * saying that one and only one resItem with this provide may
- * exist on the system at a time.
- */
- if (((constSpecPtr)conflicting_resItem)->equals (resItem)) {
- continue;
- }
-
- if (getenv("RC_SPEW")) fprintf (stderr, "because: '%s'\n", conflicting_resItem->asString(true).c_str());
-
- uninstall_item = new QueueItemUninstall (world(), conflicting_resItem, "conflict");
- uninstall_item->setDueToConflict ();
- log_info = new ResolverInfoConflictsWith (conflicting_resItem, resItem);
- uninstall_item->addInfo (log_info);
- qil.push_front (uninstall_item);
- }
-
- finished:
-//FIXME rc_queue_item_free (item);
-
- return true;
-}
-
-
-QueueItemPtr
-QueueItemInstall::copy (void) const
-{
- QueueItemInstallPtr new_install = new QueueItemInstall (world(), _resItem);
- ((QueueItemPtr)new_install)->copy((constQueueItemPtr)this);
-
- new_install->_upgrades = _upgrades;
- new_install->_deps_satisfied_by_this_install = CDependencyList(_deps_satisfied_by_this_install.begin(), _deps_satisfied_by_this_install.end());
- new_install->_needed_by = CResItemList (_needed_by.begin(), _needed_by.end());
- new_install->_channel_priority = _channel_priority;
- new_install->_other_penalty = _other_penalty;
- new_install->_explicitly_requested = _explicitly_requested;
-
- return new_install;
-}
-
-
-int
-QueueItemInstall::cmp (constQueueItemPtr item) const
-{
- int cmp = this->compare (item);
- if (cmp != 0)
- return cmp;
- constQueueItemInstallPtr install = item;
- return GVersion.compare (_resItem, install->_resItem);
-}
-
-//---------------------------------------------------------------------------
-
-void
-QueueItemInstall::addDependency (constDependencyPtr dep)
-{
- _deps_satisfied_by_this_install.push_front (dep);
-}
-
-
-void
-QueueItemInstall::addNeededBy (constResItemPtr resItem)
-{
- _needed_by.push_front (resItem);
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(QueueItemInstall,QueueItem);
+
+ //---------------------------------------------------------------------------
+
+ string
+ QueueItemInstall::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ QueueItemInstall::toString ( const QueueItemInstall & item)
+ {
+ string ret = "[Install: ";
+ ret += item._resItem->asString();
+ if (item._upgrades != NULL) {
+ ret += ", Upgrades ";
+ ret += item._upgrades->asString();
+ }
+ if (!item._deps_satisfied_by_this_install.empty()) {
+ ret += ", Satisfies ";
+ ret += Dependency::toString(item._deps_satisfied_by_this_install);
+ }
+ if (!item._needed_by.empty()) {
+ ret += ", Needed by ";
+ ret += ResItem::toString(item._needed_by);
+ }
+ if (item._explicitly_requested) ret += ", Explicit !";
+ ret += "]";
+ return ret;
+ }
+
+
+ ostream &
+ QueueItemInstall::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const QueueItemInstall & item)
+ {
+ return os << item.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItemInstall::QueueItemInstall (WorldPtr world, constResItemPtr resItem)
+ : QueueItem (QUEUE_ITEM_TYPE_INSTALL, world)
+ , _resItem (resItem)
+ , _channel_priority (0)
+ , _other_penalty (0)
+ , _explicitly_requested (false)
+ {
+ constResItemPtr upgrades = world->findInstalledResItem (resItem);
+ if (getenv("RC_SPEW")) fprintf (stderr, "QueueItemInstall::QueueItemInstall(%s) upgrades %s\n", resItem->asString().c_str(), upgrades!=NULL?upgrades->asString().c_str():"nothing");
+ if (upgrades
+ && ! (((constSpecPtr)upgrades)->equals (resItem))) {
+ setUpgrades(upgrades);
+ }
+ }
+
+
+ QueueItemInstall::~QueueItemInstall()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ QueueItemInstall::isSatisfied (ResolverContextPtr context) const
+ {
+ return context->resItemIsPresent (_resItem);
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ // Handle system resItem's that conflict with us -> uninstall them
+
+ static bool
+ build_conflict_list (constResItemPtr resItem, constDependencyPtr dep, void *data)
+ {
+ CResItemList *rl = (CResItemList *)data;
+ rl->push_front (resItem);
+ return true;
+ }
+
+ bool
+ QueueItemInstall::process (ResolverContextPtr context, QueueItemList & qil)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemInstall::process(%s)\n", this->asString().c_str());
+
+ constResItemPtr resItem = _resItem;
+ string pkg_name = resItem->asString();
+ string msg;
+ ResItemStatus status = context->getStatus (resItem);
+
+ CDependencyList deps;
+ CResItemList conflicts;
+
+ /* If we are trying to upgrade resItem A with resItem B and they both have the
+ same version number, do nothing. This shouldn't happen in general with
+ red-carpet, but can come up with the installer & autopull. */
+
+ if (_upgrades
+ && ((constSpecPtr)_resItem)->equals (_upgrades)) {
+ ResolverInfoPtr info;
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "upgrades equal resItem, skipping\n");
+
+ msg = string("Skipping ") + pkg_name + (": already installed");
+ info = new ResolverInfoMisc (_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+ context->addInfo (info);
+ goto finished;
+ }
+
+ if (!_needed_by.empty()) {
+ bool still_needed = false;
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "still needed ");
+
+ for (CResItemList::const_iterator iter = _needed_by.begin(); iter != _needed_by.end() && !still_needed; iter++) {
+ ResItemStatus status = context->getStatus (*iter);
+ if (getenv ("RC_SPEW")) fprintf (stderr, "by: [status: %s] %s\n", ResolverContext::toString(status).c_str(), (*iter)->asString().c_str());
+ if (! resItem_status_is_to_be_uninstalled (status)) {
+ still_needed = true;
+ }
+ }
+
+ if (! still_needed)
+ goto finished;
+ }
+
+ /* If we are in verify mode and this install is about to fail, don't let it happen...
+ instead, we try to back out of the install by removing whatever it was that
+ needed this. */
+
+ if (context->verifying()
+ && resItem_status_is_to_be_uninstalled (context->getStatus (resItem))
+ && !_needed_by.empty()) {
+
+ QueueItemUninstallPtr uninstall_item;
+
+ for (CResItemList::const_iterator iter = _needed_by.begin(); iter != _needed_by.end(); iter++) {
+ uninstall_item = new QueueItemUninstall (world(), *iter, "uninstallable resolvable");
+ qil.push_front (uninstall_item);
+ }
+
+ goto finished;
+ }
+
+ if (_upgrades == NULL) {
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "simple install of %s\n", resItem->asString(true).c_str());
+
+ context->installResItem (resItem, context->verifying(), /* is_soft */ _other_penalty);
+
+ } else {
+
+ QueueItemUninstallPtr uninstall_item;
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "upgrade install of %s\n", resItem->asString().c_str());
+
+ context->upgradeResItem (resItem, _upgrades, context->verifying(), /* is_soft */ _other_penalty);
+
+ uninstall_item = new QueueItemUninstall (world(), _upgrades, "upgrade");
+ uninstall_item->setUpgradedTo (resItem);
+
+ if (_explicitly_requested)
+ uninstall_item->setExplicitlyRequested ();
+
+ qil.push_front (uninstall_item);
+ }
+
+ /* Log which resItem need this install */
+
+ if (!_needed_by.empty()) {
+ ResolverInfoNeededByPtr info;
+
+ info = new ResolverInfoNeededBy (resItem);
+ info->addRelatedResItemList (_needed_by);
+ context->addInfo (info);
+ }
+
+ if (! (status == RESOLVABLE_STATUS_UNINSTALLED
+ || status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK)) {
+ goto finished;
+ }
+
+ if (_upgrades != NULL) {
+ msg = string ("Upgrading ") + _upgrades->asString() + " => " + pkg_name;
+ } else {
+ msg = string ("Installing ") + pkg_name;
+ }
+
+ context->addInfoString (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+
+ logInfo (context);
+
+ /* Construct require items for each of the resItem's requires that is still unsatisfied. */
+
+ deps = resItem->requires();
+ for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
+ constDependencyPtr dep = *iter;
+ if (!context->requirementIsMet (dep, false)) {
+ if (getenv("RC_SPEW")) fprintf (stderr, "this requires %s\n", dep->asString().c_str());
+ QueueItemRequirePtr req_item = new QueueItemRequire (world(), dep);
+ req_item->addResItem (resItem);
+ qil.push_front (req_item);
+ }
+ }
+
+ /* Construct conflict items for each of the resItem's conflicts. */
+
+ deps = resItem->conflicts();
+ for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
+ constDependencyPtr dep = *iter;
+ if (getenv("RC_SPEW")) fprintf (stderr, "this conflicts with '%s'\n", dep->asString().c_str());
+ QueueItemConflictPtr conflict_item = new QueueItemConflict (world(), dep, resItem);
+ qil.push_front (conflict_item);
+ }
+
+ /* Construct conflict items for each of the resItem's obsoletes. */
+
+ deps = resItem->obsoletes();
+ for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
+ constDependencyPtr dep = *iter;
+ if (getenv("RC_SPEW")) fprintf (stderr, "this obsoletes %s\n", dep->asString().c_str());
+ QueueItemConflictPtr conflict_item = new QueueItemConflict (world(), dep, resItem);
+ conflict_item->setActuallyAnObsolete();
+ qil.push_front (conflict_item);
+ }
+
+ /* Construct uninstall items for system resItem's that conflict with us. */
+
+ deps = resItem->provides();
+ for (CDependencyList::const_iterator iter = deps.begin(); iter != deps.end(); iter++) {
+ constDependencyPtr dep = *iter;
+ world()->foreachConflictingResItem (dep, build_conflict_list, &conflicts);
+ }
+
+ for (CResItemList::const_iterator iter = conflicts.begin(); iter != conflicts.end(); iter++) {
+ constResItemPtr conflicting_resItem = *iter;
+ ResolverInfoPtr log_info;
+ QueueItemUninstallPtr uninstall_item;
+
+ /* Check to see if we conflict with ourself and don't create
+ * an uninstall item for it if we do. This is Debian's way of
+ * saying that one and only one resItem with this provide may
+ * exist on the system at a time.
+ */
+ if (((constSpecPtr)conflicting_resItem)->equals (resItem)) {
+ continue;
+ }
+
+ if (getenv("RC_SPEW")) fprintf (stderr, "because: '%s'\n", conflicting_resItem->asString(true).c_str());
+
+ uninstall_item = new QueueItemUninstall (world(), conflicting_resItem, "conflict");
+ uninstall_item->setDueToConflict ();
+ log_info = new ResolverInfoConflictsWith (conflicting_resItem, resItem);
+ uninstall_item->addInfo (log_info);
+ qil.push_front (uninstall_item);
+ }
+
+ finished:
+ //FIXME rc_queue_item_free (item);
+
+ return true;
+ }
+
+
+ QueueItemPtr
+ QueueItemInstall::copy (void) const
+ {
+ QueueItemInstallPtr new_install = new QueueItemInstall (world(), _resItem);
+ ((QueueItemPtr)new_install)->copy((constQueueItemPtr)this);
+
+ new_install->_upgrades = _upgrades;
+ new_install->_deps_satisfied_by_this_install = CDependencyList(_deps_satisfied_by_this_install.begin(), _deps_satisfied_by_this_install.end());
+ new_install->_needed_by = CResItemList (_needed_by.begin(), _needed_by.end());
+ new_install->_channel_priority = _channel_priority;
+ new_install->_other_penalty = _other_penalty;
+ new_install->_explicitly_requested = _explicitly_requested;
+
+ return new_install;
+ }
+
+
+ int
+ QueueItemInstall::cmp (constQueueItemPtr item) const
+ {
+ int cmp = this->compare (item);
+ if (cmp != 0)
+ return cmp;
+ constQueueItemInstallPtr install = item;
+ return GVersion.compare (_resItem, install->_resItem);
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ QueueItemInstall::addDependency (constDependencyPtr dep)
+ {
+ _deps_satisfied_by_this_install.push_front (dep);
+ }
+
+
+ void
+ QueueItemInstall::addNeededBy (constResItemPtr resItem)
+ {
+ _needed_by.push_front (resItem);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : QueueItemInstall
-
-class QueueItemInstall : public QueueItem {
- REP_BODY(QueueItemInstall);
-
- private:
- constResItemPtr _resItem;
- constResItemPtr _upgrades;
- CDependencyList _deps_satisfied_by_this_install;
- CResItemList _needed_by;
- int _channel_priority;
- int _other_penalty;
-
- bool _explicitly_requested;
-
- public:
-
- QueueItemInstall (WorldPtr world, constResItemPtr resItem);
- virtual ~QueueItemInstall();
-
- // ---------------------------------- I/O
-
- static std::string toString (const QueueItemInstall & item);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const QueueItemInstall & item);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- constResItemPtr resItem (void) const { return _resItem; }
-
- constResItemPtr upgrades (void) const { return _upgrades; }
- void setUpgrades (constResItemPtr upgrades) { _upgrades = upgrades; }
-
- int channelPriority (void) const { return _channel_priority; }
- void setChannelPriority (int channel_priority) { _channel_priority = channel_priority; }
-
- int otherPenalty (void) { return _other_penalty; }
- void setOtherPenalty (int other_penalty) { _other_penalty = other_penalty; }
-
- void setExplicitlyRequested (void) { _explicitly_requested = true; }
-
- // ---------------------------------- methods
-
- virtual bool process (ResolverContextPtr context, QueueItemList & qil);
- virtual QueueItemPtr copy (void) const;
- virtual int cmp (constQueueItemPtr item) const;
-
- virtual bool isRedundant (ResolverContextPtr context) const { return false; }
- virtual bool isSatisfied (ResolverContextPtr context) const;
-
- void addDependency (constDependencyPtr dep);
- void addNeededBy (constResItemPtr resItem);
-
-};
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : QueueItemInstall
+
+ class QueueItemInstall : public QueueItem {
+ REP_BODY(QueueItemInstall);
+
+ private:
+ constResItemPtr _resItem;
+ constResItemPtr _upgrades;
+ CDependencyList _deps_satisfied_by_this_install;
+ CResItemList _needed_by;
+ int _channel_priority;
+ int _other_penalty;
+
+ bool _explicitly_requested;
+
+ public:
+
+ QueueItemInstall (WorldPtr world, constResItemPtr resItem);
+ virtual ~QueueItemInstall();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const QueueItemInstall & item);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const QueueItemInstall & item);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ constResItemPtr resItem (void) const { return _resItem; }
+
+ constResItemPtr upgrades (void) const { return _upgrades; }
+ void setUpgrades (constResItemPtr upgrades) { _upgrades = upgrades; }
+
+ int channelPriority (void) const { return _channel_priority; }
+ void setChannelPriority (int channel_priority) { _channel_priority = channel_priority; }
+
+ int otherPenalty (void) { return _other_penalty; }
+ void setOtherPenalty (int other_penalty) { _other_penalty = other_penalty; }
+
+ void setExplicitlyRequested (void) { _explicitly_requested = true; }
+
+ // ---------------------------------- methods
+
+ virtual bool process (ResolverContextPtr context, QueueItemList & qil);
+ virtual QueueItemPtr copy (void) const;
+ virtual int cmp (constQueueItemPtr item) const;
+
+ virtual bool isRedundant (ResolverContextPtr context) const { return false; }
+ virtual bool isSatisfied (ResolverContextPtr context) const;
+
+ void addDependency (constDependencyPtr dep);
+ void addNeededBy (constResItemPtr resItem);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItem_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/QueueItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : QueueItemInstallPtr
-// CLASS NAME : constQueueItemInstallPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(QueueItemInstall,QueueItem);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : QueueItemInstallPtr
+ // CLASS NAME : constQueueItemInstallPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(QueueItemInstall,QueueItem);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemInstallPtr_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : QueueItemPtr
-// CLASS NAME : constQueueItemPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(QueueItem);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : QueueItemPtr
+ // CLASS NAME : constQueueItemPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(QueueItem);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemPtr_h
#include <zypp/solver/detail/Version.h>
#include <zypp/solver/detail/World.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(QueueItemRequire,QueueItem);
-
-//---------------------------------------------------------------------------
-
-string
-QueueItemRequire::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-QueueItemRequire::toString ( const QueueItemRequire & item)
-{
- string ret = "[Require: ";
- ret += item._dep->asString();
- if (item._requiring_resItem != NULL) {
- ret += ", Required by ";
- ret += item._requiring_resItem->asString();
- }
- if (item._upgraded_resItem != NULL) {
- ret += ", Upgrades ";
- ret += item._upgraded_resItem->asString();
- }
- if (item._lost_resItem != NULL) {
- ret += ", Lost ";
- ret += item._lost_resItem->asString();
- }
- if (item._remove_only) ret += ", Remove Only";
- if (item._is_child) ret += ", Child";
- ret += "]";
-
- return ret;
-}
-
-
-ostream &
-QueueItemRequire::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const QueueItemRequire & item)
-{
- return os << item.asString();
-}
-
-//---------------------------------------------------------------------------
-
-QueueItemRequire::QueueItemRequire (WorldPtr world, constDependencyPtr dep)
- : QueueItem (QUEUE_ITEM_TYPE_REQUIRE, world)
- , _dep (dep)
- , _requiring_resItem (NULL)
- , _upgraded_resItem (NULL)
- , _lost_resItem (NULL)
- , _remove_only (false)
- , _is_child (false)
-{
-}
-
-
-QueueItemRequire::~QueueItemRequire()
-{
-}
-
-//---------------------------------------------------------------------------
-
-void
-QueueItemRequire::addResItem (constResItemPtr resItem)
-{
- assert (_requiring_resItem == NULL);
- _requiring_resItem = resItem;
-}
-
-
-//---------------------------------------------------------------------------
-
-typedef std::map <constSpecPtr, bool> UniqTable;
-
-typedef struct {
- constResItemPtr resItem;
- constSpecPtr dep;
- ResolverContextPtr context;
- WorldPtr world;
- CResItemList providers;
- UniqTable *uniq;
-} RequireProcessInfo;
-
-
-static bool
-require_process_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
-{
- RequireProcessInfo *info = (RequireProcessInfo *)data;
- ResItemStatus status;
-
- status = info->context->getStatus (resItem);
-//fprintf (stderr, "require_process_cb(res: %s, spec %s, status %s)\n", resItem->asString().c_str(), spec->asString().c_str(), ResolverContext::toString(status).c_str());
-//fprintf (stderr, "require_process_cb(info->dep: %s)\n", info->dep ? info->dep->asString().c_str() : "(null)");
-//fprintf (stderr, "require_process_cb(resItemIsPossible -> %d)\n", info->context->resItemIsPossible (resItem));
- /* info->dep is set for resItem set childern only. If it is set
- allow only exactly required version */
- if (info->dep != NULL
- && !info->dep->equals(spec)) {
- return true;
- }
-
- if ((! resItem_status_is_to_be_uninstalled (status))
- && ! info->context->isParallelInstall (resItem)
- && info->uniq->find((constSpecPtr)resItem) == info->uniq->end()
- && info->context->resItemIsPossible (resItem)
- && ! info->world->resItemIsLocked (resItem)) {
-
- info->providers.push_front (resItem);
- (*(info->uniq))[resItem] = true;
- }
-
- return true;
-}
-
-
-static bool
-no_installable_providers_info_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
-{
- RequireProcessInfo *info = (RequireProcessInfo *)data;
- ResItemStatus status;
- string msg_str;
-
- status = info->context->getStatus (resItem);
-
- if (resItem_status_is_to_be_uninstalled (status)) {
- msg_str = resItem->name() + " provides " + spec->asString() + ", but is scheduled to be uninstalled.";
- } else if (info->context->isParallelInstall (resItem)) {
- msg_str = resItem->name() + " provides " + spec->asString() + ", but another version of that resItem is already installed.";
- } else if (! info->context->resItemIsPossible (resItem)) {
- msg_str = resItem->name() + " provides " + spec->asString() + ", but it is uninstallable. Try installing it on its own for more details.";
- } else if (info->world->resItemIsLocked (resItem)) {
- msg_str = resItem->name() + " provides " + spec->asString() + ", but it is locked.";
- }
-
- if (!msg_str.empty()) {
- info->context->addInfoString (info->resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg_str);
- }
-
- return true;
-}
-
-
-static bool
-look_for_upgrades_cb (constResItemPtr resItem, void *data)
-{
- CResItemList *rl = (CResItemList *)data;
- rl->push_front (resItem);
- return true;
-}
-
-
-static bool
-codependent_resItems (constResItemPtr r1, constResItemPtr r2)
-{
- string name1 = r1->name();
- string name2 = r2->name();
- int len1 = name1.size();
- int len2 = name2.size();
-
- if (len2 < len1) {
- string swap = name1;
- int swap_len = len1;
- name1 = name2;
- name2 = swap;
- len1 = len2;
- len2 = swap_len;
- }
-
- // foo and foo-bar are automatically co-dependent
- if (len1 < len2
- && strncmp (name1.c_str(), name2.c_str(), len1) == 0
- && name2[len1] == '-') {
- return true;
- }
-
- return false;
-}
-
-
-bool
-QueueItemRequire::process (ResolverContextPtr context, QueueItemList & new_items)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemRequire::process(%s)\n", this->asString().c_str());
-
- if (context->requirementIsMet (_dep, _is_child)) {
- if (getenv ("RC_SPEW")) fprintf (stderr, "requirement is already met in current context\n");
-// rc_queue_item_free (item);
- return true;
- }
-
- RequireProcessInfo info;
-
- info.resItem = _requiring_resItem;
- info.dep = _is_child ? _dep : NULL;
- info.context = context;
- info.world = world();
- info.uniq = new UniqTable(); //FIXME: op: g_hash_table_new (rc_resItem_spec_hash, rc_resItem_spec_equal);
-
- int num_providers = 0;
-
- if (! _remove_only) {
-
- world()->foreachProvidingResItem (_dep, require_process_cb, &info);
-
- num_providers = info.providers.size();
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "requirement is met by %d resolvable\n", num_providers);
- }
-
- std::string msg;
-
- if (num_providers == 0) {
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "Unfulfilled requirement, try different solution\n");
-
- QueueItemUninstallPtr uninstall_item = NULL;
- QueueItemBranchPtr branch_item = NULL;
- bool explore_uninstall_branch = true;
-
- if (_upgraded_resItem == NULL) {
- ResolverInfoPtr err_info;
-
- msg = string ("There are no ") + (_remove_only ? "alternative installed" : "installable") + " providers of " + _dep->asString();
- if (_requiring_resItem != NULL) {
- msg += " for ";
- msg += _requiring_resItem->asString();
- }
-
- err_info = new ResolverInfoMisc (_requiring_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
- context->addInfo (err_info);
-
- // Maybe we can add some extra info on why none of the providers are suitable.
- world()->foreachProvidingResItem (_dep, no_installable_providers_info_cb, (void *)&info);
- }
-
- // If this is an upgrade, we might be able to avoid removing stuff by upgrading it instead.
- if (_upgraded_resItem != NULL
- && _requiring_resItem != NULL) {
-
- CResItemList upgrade_list;
-
- world()->foreachUpgrade (_requiring_resItem, new Channel(CHANNEL_TYPE_ANY), look_for_upgrades_cb, (void *)&upgrade_list);
-
- if (!upgrade_list.empty()) {
- string label, req_str, up_str;
-
- branch_item = new QueueItemBranch (world());
-
- req_str = _requiring_resItem->asString();
- up_str = _upgraded_resItem->asString();
-
- label = string ("for requiring ") + _dep->asString() + " for " + req_str + " when upgrading " + up_str;
- branch_item->setLabel (label);
-//fprintf (stderr, "Branching: %s\n", label.c_str());
- for (CResItemList::const_iterator iter = upgrade_list.begin(); iter != upgrade_list.end(); iter++) {
- constResItemPtr upgrade_resItem = *iter;
- QueueItemInstallPtr install_item;
-
- if (context->resItemIsPossible (upgrade_resItem)) {
-
- install_item = new QueueItemInstall (world(), upgrade_resItem);
- install_item->setUpgrades (_requiring_resItem);
- branch_item->addItem (install_item);
-
- ResolverInfoNeededByPtr upgrade_info = new ResolverInfoNeededBy (upgrade_resItem);
- upgrade_info->addRelatedResItem (_upgraded_resItem);
- install_item->addInfo (upgrade_info);
-
- // If an upgrade resItem has its requirements met, don't do the uninstall branch.
- // FIXME: should we also look at conflicts here?
-
- if (explore_uninstall_branch) {
- CDependencyList requires = upgrade_resItem->requires();
- CDependencyList::const_iterator iter = requires.begin();
- for (; iter != requires.end(); iter++) {
- constDependencyPtr req = *iter;
- if (! context->requirementIsMet (req, false)) {
- break;
- }
- }
- if (iter == requires.end()) {
- explore_uninstall_branch = false;
- }
- }
-
- } /* if (context->resItemIsPossible ( ... */
- } /* for (iter = upgrade_list; ... */
- } /* if (upgrade_list) ... */
-
- if (!upgrade_list.empty()
- && branch_item->isEmpty ()) {
-
- for (CResItemList::const_iterator iter = upgrade_list.begin(); iter != upgrade_list.end(); iter++) {
- string str;
- string p1, p2;
-
- p1 = _requiring_resItem->asString();
- p2 = (*iter)->asString();
- str = string ("Upgrade to ") + p2 + " to avoid removing " + p1 + " is not possible.";
-
- ResolverInfoMiscPtr misc_info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, str);
- misc_info->addRelatedResItem (_requiring_resItem);
- misc_info->addRelatedResItem (*iter);
- context->addInfo (misc_info);
-
- explore_uninstall_branch = true;
- }
-
- //
- // The exception: we always want to consider uninstalling
- // when the requirement has resulted from a resItem losing
- // one of it's provides.
-
- } else if (!upgrade_list.empty()
- && explore_uninstall_branch
- && codependent_resItems (_requiring_resItem, _upgraded_resItem)
- && _lost_resItem == NULL) {
- explore_uninstall_branch = false;
- }
-
- } /* if (_upgrade_resItem && _requiring_resItem) ... */
-
- // We always consider uninstalling when in verification mode.
-
- if (context->verifying()) {
- explore_uninstall_branch = true;
- }
-
- if (explore_uninstall_branch && _requiring_resItem) {
- ResolverInfoPtr log_info;
- uninstall_item = new QueueItemUninstall (world(),_requiring_resItem, "unsatisfied requirements");
- uninstall_item->setDependency (_dep);
-
- if (_lost_resItem) {
- log_info = new ResolverInfoDependsOn (_requiring_resItem, _lost_resItem);
- uninstall_item->addInfo (log_info);
- }
-
- if (_remove_only)
- uninstall_item->setRemoveOnly ();
- }
-
- if (uninstall_item && branch_item) {
- branch_item->addItem (uninstall_item);
- new_items.push_front (branch_item);
- } else if (uninstall_item) {
- new_items.push_front (uninstall_item);
- } else if (branch_item) {
- new_items.push_front (branch_item);
- } else {
- // We can't do anything to resolve the missing requirement, so we fail.
- string msg = string ("Can't satisfy requirement '") + _dep->asString() + "'";
-
- context->addErrorString (NULL, msg);
- }
-
- } else if (num_providers == 1) {
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "Found exactly one resolvable, installing it.\n");
-
- QueueItemInstallPtr install_item = new QueueItemInstall (world(), info.providers.front());
- install_item->addDependency (_dep);
-
- // The requiring resItem could be NULL if the requirement was added as an extra dependency.
- if (_requiring_resItem) {
- install_item->addNeededBy (_requiring_resItem);
- }
- new_items.push_front (install_item);
-
- } else if (num_providers > 1) {
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "Found more than one resolvable, branching.\n");
-
-//fprintf (stderr, "Found more than one resItem, branching.\n");
- QueueItemBranchPtr branch_item = new QueueItemBranch (world());
-
- for (CResItemList::const_iterator iter = info.providers.begin(); iter != info.providers.end(); iter++) {
- QueueItemInstallPtr install_item = new QueueItemInstall (world(), *iter);
- install_item->addDependency (_dep);
- branch_item->addItem (install_item);
-
- // The requiring resItem could be NULL if the requirement was added as an extra dependency.
- if (_requiring_resItem) {
- install_item->addNeededBy (_requiring_resItem);
- }
- }
-
- new_items.push_front (branch_item);
-
- } else {
- abort ();
- }
-
-
-// rc_queue_item_free (item);
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-QueueItemPtr
-QueueItemRequire::copy (void) const
-{
- QueueItemRequirePtr new_require = new QueueItemRequire (world(), _dep);
- ((QueueItemPtr)new_require)->copy((constQueueItemPtr)this);
-
- new_require->_requiring_resItem = _requiring_resItem;
- new_require->_upgraded_resItem = _upgraded_resItem;
- new_require->_remove_only = _remove_only;
-
- return new_require;
-}
-
-
-int
-QueueItemRequire::cmp (constQueueItemPtr item) const
-{
- int cmp = this->compare (item); // assures equal type
- if (cmp != 0)
- return cmp;
-
- constQueueItemRequirePtr require = item;
-
- cmp = GVersion.compare ((constSpecPtr) _dep, ((constSpecPtr)(require->dependency())));
- if (cmp)
- return cmp;
-
- return CMP ((int) _dep->relation().op(), (int) (require->dependency()->relation().op()));
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(QueueItemRequire,QueueItem);
+
+ //---------------------------------------------------------------------------
+
+ string
+ QueueItemRequire::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ QueueItemRequire::toString ( const QueueItemRequire & item)
+ {
+ string ret = "[Require: ";
+ ret += item._dep->asString();
+ if (item._requiring_resItem != NULL) {
+ ret += ", Required by ";
+ ret += item._requiring_resItem->asString();
+ }
+ if (item._upgraded_resItem != NULL) {
+ ret += ", Upgrades ";
+ ret += item._upgraded_resItem->asString();
+ }
+ if (item._lost_resItem != NULL) {
+ ret += ", Lost ";
+ ret += item._lost_resItem->asString();
+ }
+ if (item._remove_only) ret += ", Remove Only";
+ if (item._is_child) ret += ", Child";
+ ret += "]";
+
+ return ret;
+ }
+
+
+ ostream &
+ QueueItemRequire::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const QueueItemRequire & item)
+ {
+ return os << item.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItemRequire::QueueItemRequire (WorldPtr world, constDependencyPtr dep)
+ : QueueItem (QUEUE_ITEM_TYPE_REQUIRE, world)
+ , _dep (dep)
+ , _requiring_resItem (NULL)
+ , _upgraded_resItem (NULL)
+ , _lost_resItem (NULL)
+ , _remove_only (false)
+ , _is_child (false)
+ {
+ }
+
+
+ QueueItemRequire::~QueueItemRequire()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ QueueItemRequire::addResItem (constResItemPtr resItem)
+ {
+ assert (_requiring_resItem == NULL);
+ _requiring_resItem = resItem;
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ typedef std::map <constSpecPtr, bool> UniqTable;
+
+ typedef struct {
+ constResItemPtr resItem;
+ constSpecPtr dep;
+ ResolverContextPtr context;
+ WorldPtr world;
+ CResItemList providers;
+ UniqTable *uniq;
+ } RequireProcessInfo;
+
+
+ static bool
+ require_process_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
+ {
+ RequireProcessInfo *info = (RequireProcessInfo *)data;
+ ResItemStatus status;
+
+ status = info->context->getStatus (resItem);
+ //fprintf (stderr, "require_process_cb(res: %s, spec %s, status %s)\n", resItem->asString().c_str(), spec->asString().c_str(), ResolverContext::toString(status).c_str());
+ //fprintf (stderr, "require_process_cb(info->dep: %s)\n", info->dep ? info->dep->asString().c_str() : "(null)");
+ //fprintf (stderr, "require_process_cb(resItemIsPossible -> %d)\n", info->context->resItemIsPossible (resItem));
+ /* info->dep is set for resItem set childern only. If it is set
+ allow only exactly required version */
+ if (info->dep != NULL
+ && !info->dep->equals(spec)) {
+ return true;
+ }
+
+ if ((! resItem_status_is_to_be_uninstalled (status))
+ && ! info->context->isParallelInstall (resItem)
+ && info->uniq->find((constSpecPtr)resItem) == info->uniq->end()
+ && info->context->resItemIsPossible (resItem)
+ && ! info->world->resItemIsLocked (resItem)) {
+
+ info->providers.push_front (resItem);
+ (*(info->uniq))[resItem] = true;
+ }
+
+ return true;
+ }
+
+
+ static bool
+ no_installable_providers_info_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
+ {
+ RequireProcessInfo *info = (RequireProcessInfo *)data;
+ ResItemStatus status;
+ string msg_str;
+
+ status = info->context->getStatus (resItem);
+
+ if (resItem_status_is_to_be_uninstalled (status)) {
+ msg_str = resItem->name() + " provides " + spec->asString() + ", but is scheduled to be uninstalled.";
+ } else if (info->context->isParallelInstall (resItem)) {
+ msg_str = resItem->name() + " provides " + spec->asString() + ", but another version of that resItem is already installed.";
+ } else if (! info->context->resItemIsPossible (resItem)) {
+ msg_str = resItem->name() + " provides " + spec->asString() + ", but it is uninstallable. Try installing it on its own for more details.";
+ } else if (info->world->resItemIsLocked (resItem)) {
+ msg_str = resItem->name() + " provides " + spec->asString() + ", but it is locked.";
+ }
+
+ if (!msg_str.empty()) {
+ info->context->addInfoString (info->resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg_str);
+ }
+
+ return true;
+ }
+
+
+ static bool
+ look_for_upgrades_cb (constResItemPtr resItem, void *data)
+ {
+ CResItemList *rl = (CResItemList *)data;
+ rl->push_front (resItem);
+ return true;
+ }
+
+
+ static bool
+ codependent_resItems (constResItemPtr r1, constResItemPtr r2)
+ {
+ string name1 = r1->name();
+ string name2 = r2->name();
+ int len1 = name1.size();
+ int len2 = name2.size();
+
+ if (len2 < len1) {
+ string swap = name1;
+ int swap_len = len1;
+ name1 = name2;
+ name2 = swap;
+ len1 = len2;
+ len2 = swap_len;
+ }
+
+ // foo and foo-bar are automatically co-dependent
+ if (len1 < len2
+ && strncmp (name1.c_str(), name2.c_str(), len1) == 0
+ && name2[len1] == '-') {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ bool
+ QueueItemRequire::process (ResolverContextPtr context, QueueItemList & new_items)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemRequire::process(%s)\n", this->asString().c_str());
+
+ if (context->requirementIsMet (_dep, _is_child)) {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "requirement is already met in current context\n");
+ // rc_queue_item_free (item);
+ return true;
+ }
+
+ RequireProcessInfo info;
+
+ info.resItem = _requiring_resItem;
+ info.dep = _is_child ? _dep : NULL;
+ info.context = context;
+ info.world = world();
+ info.uniq = new UniqTable(); //FIXME: op: g_hash_table_new (rc_resItem_spec_hash, rc_resItem_spec_equal);
+
+ int num_providers = 0;
+
+ if (! _remove_only) {
+
+ world()->foreachProvidingResItem (_dep, require_process_cb, &info);
+
+ num_providers = info.providers.size();
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "requirement is met by %d resolvable\n", num_providers);
+ }
+
+ std::string msg;
+
+ if (num_providers == 0) {
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "Unfulfilled requirement, try different solution\n");
+
+ QueueItemUninstallPtr uninstall_item = NULL;
+ QueueItemBranchPtr branch_item = NULL;
+ bool explore_uninstall_branch = true;
+
+ if (_upgraded_resItem == NULL) {
+ ResolverInfoPtr err_info;
+
+ msg = string ("There are no ") + (_remove_only ? "alternative installed" : "installable") + " providers of " + _dep->asString();
+ if (_requiring_resItem != NULL) {
+ msg += " for ";
+ msg += _requiring_resItem->asString();
+ }
+
+ err_info = new ResolverInfoMisc (_requiring_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+
+ context->addInfo (err_info);
+
+ // Maybe we can add some extra info on why none of the providers are suitable.
+ world()->foreachProvidingResItem (_dep, no_installable_providers_info_cb, (void *)&info);
+ }
+
+ // If this is an upgrade, we might be able to avoid removing stuff by upgrading it instead.
+ if (_upgraded_resItem != NULL
+ && _requiring_resItem != NULL) {
+
+ CResItemList upgrade_list;
+
+ world()->foreachUpgrade (_requiring_resItem, new Channel(CHANNEL_TYPE_ANY), look_for_upgrades_cb, (void *)&upgrade_list);
+
+ if (!upgrade_list.empty()) {
+ string label, req_str, up_str;
+
+ branch_item = new QueueItemBranch (world());
+
+ req_str = _requiring_resItem->asString();
+ up_str = _upgraded_resItem->asString();
+
+ label = string ("for requiring ") + _dep->asString() + " for " + req_str + " when upgrading " + up_str;
+ branch_item->setLabel (label);
+ //fprintf (stderr, "Branching: %s\n", label.c_str());
+ for (CResItemList::const_iterator iter = upgrade_list.begin(); iter != upgrade_list.end(); iter++) {
+ constResItemPtr upgrade_resItem = *iter;
+ QueueItemInstallPtr install_item;
+
+ if (context->resItemIsPossible (upgrade_resItem)) {
+
+ install_item = new QueueItemInstall (world(), upgrade_resItem);
+ install_item->setUpgrades (_requiring_resItem);
+ branch_item->addItem (install_item);
+
+ ResolverInfoNeededByPtr upgrade_info = new ResolverInfoNeededBy (upgrade_resItem);
+ upgrade_info->addRelatedResItem (_upgraded_resItem);
+ install_item->addInfo (upgrade_info);
+
+ // If an upgrade resItem has its requirements met, don't do the uninstall branch.
+ // FIXME: should we also look at conflicts here?
+
+ if (explore_uninstall_branch) {
+ CDependencyList requires = upgrade_resItem->requires();
+ CDependencyList::const_iterator iter = requires.begin();
+ for (; iter != requires.end(); iter++) {
+ constDependencyPtr req = *iter;
+ if (! context->requirementIsMet (req, false)) {
+ break;
+ }
+ }
+ if (iter == requires.end()) {
+ explore_uninstall_branch = false;
+ }
+ }
+
+ } /* if (context->resItemIsPossible ( ... */
+ } /* for (iter = upgrade_list; ... */
+ } /* if (upgrade_list) ... */
+
+ if (!upgrade_list.empty()
+ && branch_item->isEmpty ()) {
+
+ for (CResItemList::const_iterator iter = upgrade_list.begin(); iter != upgrade_list.end(); iter++) {
+ string str;
+ string p1, p2;
+
+ p1 = _requiring_resItem->asString();
+ p2 = (*iter)->asString();
+ str = string ("Upgrade to ") + p2 + " to avoid removing " + p1 + " is not possible.";
+
+ ResolverInfoMiscPtr misc_info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, str);
+ misc_info->addRelatedResItem (_requiring_resItem);
+ misc_info->addRelatedResItem (*iter);
+ context->addInfo (misc_info);
+
+ explore_uninstall_branch = true;
+ }
+
+ //
+ // The exception: we always want to consider uninstalling
+ // when the requirement has resulted from a resItem losing
+ // one of it's provides.
+
+ } else if (!upgrade_list.empty()
+ && explore_uninstall_branch
+ && codependent_resItems (_requiring_resItem, _upgraded_resItem)
+ && _lost_resItem == NULL) {
+ explore_uninstall_branch = false;
+ }
+
+ } /* if (_upgrade_resItem && _requiring_resItem) ... */
+
+ // We always consider uninstalling when in verification mode.
+
+ if (context->verifying()) {
+ explore_uninstall_branch = true;
+ }
+
+ if (explore_uninstall_branch && _requiring_resItem) {
+ ResolverInfoPtr log_info;
+ uninstall_item = new QueueItemUninstall (world(),_requiring_resItem, "unsatisfied requirements");
+ uninstall_item->setDependency (_dep);
+
+ if (_lost_resItem) {
+ log_info = new ResolverInfoDependsOn (_requiring_resItem, _lost_resItem);
+ uninstall_item->addInfo (log_info);
+ }
+
+ if (_remove_only)
+ uninstall_item->setRemoveOnly ();
+ }
+
+ if (uninstall_item && branch_item) {
+ branch_item->addItem (uninstall_item);
+ new_items.push_front (branch_item);
+ } else if (uninstall_item) {
+ new_items.push_front (uninstall_item);
+ } else if (branch_item) {
+ new_items.push_front (branch_item);
+ } else {
+ // We can't do anything to resolve the missing requirement, so we fail.
+ string msg = string ("Can't satisfy requirement '") + _dep->asString() + "'";
+
+ context->addErrorString (NULL, msg);
+ }
+
+ } else if (num_providers == 1) {
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "Found exactly one resolvable, installing it.\n");
+
+ QueueItemInstallPtr install_item = new QueueItemInstall (world(), info.providers.front());
+ install_item->addDependency (_dep);
+
+ // The requiring resItem could be NULL if the requirement was added as an extra dependency.
+ if (_requiring_resItem) {
+ install_item->addNeededBy (_requiring_resItem);
+ }
+ new_items.push_front (install_item);
+
+ } else if (num_providers > 1) {
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "Found more than one resolvable, branching.\n");
+
+ //fprintf (stderr, "Found more than one resItem, branching.\n");
+ QueueItemBranchPtr branch_item = new QueueItemBranch (world());
+
+ for (CResItemList::const_iterator iter = info.providers.begin(); iter != info.providers.end(); iter++) {
+ QueueItemInstallPtr install_item = new QueueItemInstall (world(), *iter);
+ install_item->addDependency (_dep);
+ branch_item->addItem (install_item);
+
+ // The requiring resItem could be NULL if the requirement was added as an extra dependency.
+ if (_requiring_resItem) {
+ install_item->addNeededBy (_requiring_resItem);
+ }
+ }
+
+ new_items.push_front (branch_item);
+
+ } else {
+ abort ();
+ }
+
+
+ // rc_queue_item_free (item);
+ return true;
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItemPtr
+ QueueItemRequire::copy (void) const
+ {
+ QueueItemRequirePtr new_require = new QueueItemRequire (world(), _dep);
+ ((QueueItemPtr)new_require)->copy((constQueueItemPtr)this);
+
+ new_require->_requiring_resItem = _requiring_resItem;
+ new_require->_upgraded_resItem = _upgraded_resItem;
+ new_require->_remove_only = _remove_only;
+
+ return new_require;
+ }
+
+
+ int
+ QueueItemRequire::cmp (constQueueItemPtr item) const
+ {
+ int cmp = this->compare (item); // assures equal type
+ if (cmp != 0)
+ return cmp;
+
+ constQueueItemRequirePtr require = item;
+
+ cmp = GVersion.compare ((constSpecPtr) _dep, ((constSpecPtr)(require->dependency())));
+ if (cmp)
+ return cmp;
+
+ return CMP ((int) _dep->relation().op(), (int) (require->dependency()->relation().op()));
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : QueueItemRequire
-
-class QueueItemRequire : public QueueItem {
- REP_BODY(QueueItemRequire);
-
- private:
- constDependencyPtr _dep;
- constResItemPtr _requiring_resItem;
- constResItemPtr _upgraded_resItem;
- constResItemPtr _lost_resItem;
- bool _remove_only;
- bool _is_child;
-
- public:
-
- QueueItemRequire (WorldPtr world, constDependencyPtr dep);
- virtual ~QueueItemRequire();
-
- // ---------------------------------- I/O
-
- static std::string toString (const QueueItemRequire & item);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const QueueItemRequire & item);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- constDependencyPtr dependency (void) const { return _dep; }
-
- void setRemoveOnly (void) { _remove_only = true; }
- void setUpgradedResItem (constResItemPtr upgraded_resItem) { _upgraded_resItem = upgraded_resItem; }
- void setLostResItem (constResItemPtr lost_resItem) { _lost_resItem = lost_resItem; }
-
- // ---------------------------------- methods
-
- virtual bool process (ResolverContextPtr context, QueueItemList & qil);
- virtual QueueItemPtr copy (void) const;
- virtual int cmp (constQueueItemPtr item) const;
- virtual bool isRedundant (ResolverContextPtr context) const { return false; }
- virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
-
- void addResItem (constResItemPtr resItem);
-
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : QueueItemRequire
+
+ class QueueItemRequire : public QueueItem {
+ REP_BODY(QueueItemRequire);
+
+ private:
+ constDependencyPtr _dep;
+ constResItemPtr _requiring_resItem;
+ constResItemPtr _upgraded_resItem;
+ constResItemPtr _lost_resItem;
+ bool _remove_only;
+ bool _is_child;
+
+ public:
+
+ QueueItemRequire (WorldPtr world, constDependencyPtr dep);
+ virtual ~QueueItemRequire();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const QueueItemRequire & item);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const QueueItemRequire & item);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ constDependencyPtr dependency (void) const { return _dep; }
+
+ void setRemoveOnly (void) { _remove_only = true; }
+ void setUpgradedResItem (constResItemPtr upgraded_resItem) { _upgraded_resItem = upgraded_resItem; }
+ void setLostResItem (constResItemPtr lost_resItem) { _lost_resItem = lost_resItem; }
+
+ // ---------------------------------- methods
+
+ virtual bool process (ResolverContextPtr context, QueueItemList & qil);
+ virtual QueueItemPtr copy (void) const;
+ virtual int cmp (constQueueItemPtr item) const;
+ virtual bool isRedundant (ResolverContextPtr context) const { return false; }
+ virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
+
+ void addResItem (constResItemPtr resItem);
+
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemRequire_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/QueueItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : QueueItemRequirePtr
-// CLASS NAME : constQueueItemRequirePtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(QueueItemRequire,QueueItem);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : QueueItemRequirePtr
+ // CLASS NAME : constQueueItemRequirePtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(QueueItemRequire,QueueItem);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemRequirePtr_h
#include <zypp/solver/detail/World.h>
#include <zypp/solver/detail/Version.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(QueueItemUninstall,QueueItem);
-
-//---------------------------------------------------------------------------
-
-string
-QueueItemUninstall::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-QueueItemUninstall::toString ( const QueueItemUninstall & item)
-{
- string ret = "[Uninstall: ";
-
- ret += item._resItem->asString();
- ret += " ("; ret += item._reason; ret += ")";
- if (item._dep_leading_to_uninstall != NULL) {
- ret += ", Triggered By ";
- ret += item._dep_leading_to_uninstall->asString();
- }
- if (item._upgraded_to != NULL) {
- ret += ", Upgraded To ";
- ret += item._upgraded_to->asString();
- }
- if (item._explicitly_requested) ret += ", Explicit";
- if (item._remove_only) ret += ", Remove Only";
- if (item._due_to_conflict) ret += ", Due To Conflict";
- if (item._due_to_obsolete) ret += ", Due To Obsolete";
- if (item._unlink) ret += ", Unlink";
- ret += "]";
-
- return ret;
-}
-
-
-ostream &
-QueueItemUninstall::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const QueueItemUninstall & item)
-{
- return os << item.asString();
-}
-
-//---------------------------------------------------------------------------
-
-QueueItemUninstall::QueueItemUninstall (WorldPtr world, constResItemPtr resItem, const std::string & reason)
- : QueueItem (QUEUE_ITEM_TYPE_UNINSTALL, world)
- , _resItem (resItem)
- , _reason (reason)
- , _dep_leading_to_uninstall (NULL)
- , _upgraded_to (NULL)
- , _explicitly_requested (false)
- , _remove_only (false)
- , _due_to_conflict (false)
- , _due_to_obsolete (false)
- , _unlink (false)
-{
-}
-
-
-QueueItemUninstall::~QueueItemUninstall()
-{
-}
-
-//---------------------------------------------------------------------------
-
-void
-QueueItemUninstall::setUnlink ()
-{
- _unlink = true;
- /* Reduce the priority so that unlink items will tend to get
- processed later. We want to process unlinks as late as possible...
- this will make our "is this item in use" check more accurate. */
- setPriority (0);
-
- return;
-}
-
-//---------------------------------------------------------------------------
-
-typedef struct {
- ResolverContextPtr context;
- bool cancel_unlink;
-} UnlinkCheckInfo;
-
-
-static bool
-unlink_check_cb (constResItemPtr resItem, constDependencyPtr dep, void *data)
-{
- UnlinkCheckInfo *info = (UnlinkCheckInfo *)data;
-
- if (info->cancel_unlink)
- return true;
-
- if (! info->context->resItemIsPresent (resItem))
- return true;
-
- if (info->context->requirementIsMet (dep, false))
- return true;
-
- info->cancel_unlink = true;
-
- return true;
-}
-
-typedef struct {
- WorldPtr world;
- ResolverContextPtr context;
- constResItemPtr uninstalled_resItem;
- constResItemPtr upgraded_resItem;
- QueueItemList *require_items;
- bool remove_only;
-} UninstallProcessInfo;
-
-
-static bool
-uninstall_process_cb (constResItemPtr resItem, constDependencyPtr dep, void *data)
-{
- UninstallProcessInfo *info = (UninstallProcessInfo *)data;
-
- if (! info->context->resItemIsPresent (resItem))
- return true;
-
- if (info->context->requirementIsMet (dep, false))
- return true;
-
- QueueItemRequirePtr require_item = new QueueItemRequire (info->world, dep);
- require_item->addResItem (resItem);
- if (info->remove_only) {
- require_item->setRemoveOnly ();
- }
- require_item->setUpgradedResItem (info->upgraded_resItem);
- require_item->setLostResItem (info->uninstalled_resItem);
-
- info->require_items->push_front (require_item);
-
- return true;
-}
-
-
-bool
-QueueItemUninstall::process (ResolverContextPtr context, QueueItemList & qil)
-{
- ResItemStatus status;
- string pkg_str;
-
- pkg_str = ((constSpecPtr)_resItem)->asString();
-
- status = context->getStatus (_resItem);
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemUninstall::process(<%s>%s)%s\n", ResolverContext::toString(status).c_str(), _resItem->asString().c_str(), _unlink ? "[unlink]" : "");
-
- /* In the case of an unlink, we only want to uninstall the resItem if it is
- being used by something else. We can't really determine this with 100%
- accuracy, since some later queue item could cause something that requires
- the resItem to be uninstalled. The alternative is to try to do something
- really clever... but I'm not clever enough to think of an algorithm that
- (1) Would do the right thing.
- (2) Is guaranteed to terminate. (!)
- so this will have to do. In practice, I don't think that this is a serious
- problem. */
-
- if (_unlink) {
- bool unlink_cancelled = false;
-
- /* If the resItem is to-be-installed, obviously it is being use! */
- if (status == RESOLVABLE_STATUS_TO_BE_INSTALLED) {
-
- unlink_cancelled = true;
-
- } else if (status == RESOLVABLE_STATUS_INSTALLED) {
- UnlinkCheckInfo info;
-
- /* Flag the resItem as to-be-uninstalled so that it won't
- satisfy any other resItem's deps during this check. */
- context->setStatus (_resItem, RESOLVABLE_STATUS_TO_BE_UNINSTALLED);
-
- info.context = context;
- info.cancel_unlink = false;
-
- CDependencyList provides = _resItem->provides();
- for (CDependencyList::const_iterator iter = provides.begin(); iter != provides.end() && ! info.cancel_unlink; iter++) {
- world()->foreachRequiringResItem (*iter, unlink_check_cb, &info);
- }
-
- /* Set the status back to normal. */
- context->setStatus (_resItem, status);
-
- if (info.cancel_unlink)
- unlink_cancelled = true;
- }
-
- if (unlink_cancelled) {
- string msg = pkg_str + " is required by other installed resolvable, so it won't be unlinked.";
- context->addInfoString (_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
- goto finished;
- }
- }
-
- context->uninstallResItem (_resItem, _upgraded_to != NULL, _due_to_obsolete, _unlink);
-
- if (status == RESOLVABLE_STATUS_INSTALLED) {
-
- if (! _explicitly_requested
- && world()->resItemIsLocked (_resItem)) {
- string msg = pkg_str + " is locked, and cannot be uninstalled.";
- context->addErrorString (_resItem, msg);
- goto finished;
- }
-
- this->logInfo (context);
-
- if (_dep_leading_to_uninstall
- && !_due_to_conflict
- && !_due_to_obsolete)
- {
- ResolverInfoPtr info = new ResolverInfoMissingReq (_resItem, _dep_leading_to_uninstall);
- context->addInfo (info);
- }
-
- CDependencyList provides = _resItem->provides();
- for (CDependencyList::const_iterator iter = provides.begin(); iter != provides.end(); iter++) {
- UninstallProcessInfo info;
-
- info.world = world();
- info.context = context;
- info.uninstalled_resItem = _resItem;
- info.upgraded_resItem = _upgraded_to;
- info.require_items = &qil;
- info.remove_only = _remove_only;
-
- world()->foreachRequiringResItem (*iter, uninstall_process_cb, &info);
- }
- }
-
- finished:
-// FIXME rc_queue_item_free (item);
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-int
-QueueItemUninstall::cmp (constQueueItemPtr item) const
-{
- int cmp = this->compare (item); // assures equal type
- if (cmp != 0)
- return cmp;
-
- constQueueItemUninstallPtr uninstall = item;
- return GVersion.compare (_resItem, uninstall->_resItem);
-}
-
-
-QueueItemPtr
-QueueItemUninstall::copy (void) const
-{
- QueueItemUninstallPtr new_uninstall = new QueueItemUninstall (world(), _resItem, _reason);
- ((QueueItemPtr)new_uninstall)->copy((constQueueItemPtr)this);
-
-
- new_uninstall->_resItem = _resItem;
- new_uninstall->_dep_leading_to_uninstall = _dep_leading_to_uninstall;
- new_uninstall->_upgraded_to = _upgraded_to;
-
- new_uninstall->_explicitly_requested = _explicitly_requested;
- new_uninstall->_remove_only = _remove_only;
- new_uninstall->_due_to_conflict = _due_to_conflict;
- new_uninstall->_due_to_obsolete = _due_to_obsolete;
- new_uninstall->_unlink = _unlink;
-
- return new_uninstall;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(QueueItemUninstall,QueueItem);
+
+ //---------------------------------------------------------------------------
+
+ string
+ QueueItemUninstall::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ QueueItemUninstall::toString ( const QueueItemUninstall & item)
+ {
+ string ret = "[Uninstall: ";
+
+ ret += item._resItem->asString();
+ ret += " ("; ret += item._reason; ret += ")";
+ if (item._dep_leading_to_uninstall != NULL) {
+ ret += ", Triggered By ";
+ ret += item._dep_leading_to_uninstall->asString();
+ }
+ if (item._upgraded_to != NULL) {
+ ret += ", Upgraded To ";
+ ret += item._upgraded_to->asString();
+ }
+ if (item._explicitly_requested) ret += ", Explicit";
+ if (item._remove_only) ret += ", Remove Only";
+ if (item._due_to_conflict) ret += ", Due To Conflict";
+ if (item._due_to_obsolete) ret += ", Due To Obsolete";
+ if (item._unlink) ret += ", Unlink";
+ ret += "]";
+
+ return ret;
+ }
+
+
+ ostream &
+ QueueItemUninstall::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const QueueItemUninstall & item)
+ {
+ return os << item.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ QueueItemUninstall::QueueItemUninstall (WorldPtr world, constResItemPtr resItem, const std::string & reason)
+ : QueueItem (QUEUE_ITEM_TYPE_UNINSTALL, world)
+ , _resItem (resItem)
+ , _reason (reason)
+ , _dep_leading_to_uninstall (NULL)
+ , _upgraded_to (NULL)
+ , _explicitly_requested (false)
+ , _remove_only (false)
+ , _due_to_conflict (false)
+ , _due_to_obsolete (false)
+ , _unlink (false)
+ {
+ }
+
+
+ QueueItemUninstall::~QueueItemUninstall()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ QueueItemUninstall::setUnlink ()
+ {
+ _unlink = true;
+ /* Reduce the priority so that unlink items will tend to get
+ processed later. We want to process unlinks as late as possible...
+ this will make our "is this item in use" check more accurate. */
+ setPriority (0);
+
+ return;
+ }
+
+ //---------------------------------------------------------------------------
+
+ typedef struct {
+ ResolverContextPtr context;
+ bool cancel_unlink;
+ } UnlinkCheckInfo;
+
+
+ static bool
+ unlink_check_cb (constResItemPtr resItem, constDependencyPtr dep, void *data)
+ {
+ UnlinkCheckInfo *info = (UnlinkCheckInfo *)data;
+
+ if (info->cancel_unlink)
+ return true;
+
+ if (! info->context->resItemIsPresent (resItem))
+ return true;
+
+ if (info->context->requirementIsMet (dep, false))
+ return true;
+
+ info->cancel_unlink = true;
+
+ return true;
+ }
+
+ typedef struct {
+ WorldPtr world;
+ ResolverContextPtr context;
+ constResItemPtr uninstalled_resItem;
+ constResItemPtr upgraded_resItem;
+ QueueItemList *require_items;
+ bool remove_only;
+ } UninstallProcessInfo;
+
+
+ static bool
+ uninstall_process_cb (constResItemPtr resItem, constDependencyPtr dep, void *data)
+ {
+ UninstallProcessInfo *info = (UninstallProcessInfo *)data;
+
+ if (! info->context->resItemIsPresent (resItem))
+ return true;
+
+ if (info->context->requirementIsMet (dep, false))
+ return true;
+
+ QueueItemRequirePtr require_item = new QueueItemRequire (info->world, dep);
+ require_item->addResItem (resItem);
+ if (info->remove_only) {
+ require_item->setRemoveOnly ();
+ }
+ require_item->setUpgradedResItem (info->upgraded_resItem);
+ require_item->setLostResItem (info->uninstalled_resItem);
+
+ info->require_items->push_front (require_item);
+
+ return true;
+ }
+
+
+ bool
+ QueueItemUninstall::process (ResolverContextPtr context, QueueItemList & qil)
+ {
+ ResItemStatus status;
+ string pkg_str;
+
+ pkg_str = ((constSpecPtr)_resItem)->asString();
+
+ status = context->getStatus (_resItem);
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "QueueItemUninstall::process(<%s>%s)%s\n", ResolverContext::toString(status).c_str(), _resItem->asString().c_str(), _unlink ? "[unlink]" : "");
+
+ /* In the case of an unlink, we only want to uninstall the resItem if it is
+ being used by something else. We can't really determine this with 100%
+ accuracy, since some later queue item could cause something that requires
+ the resItem to be uninstalled. The alternative is to try to do something
+ really clever... but I'm not clever enough to think of an algorithm that
+ (1) Would do the right thing.
+ (2) Is guaranteed to terminate. (!)
+ so this will have to do. In practice, I don't think that this is a serious
+ problem. */
+
+ if (_unlink) {
+ bool unlink_cancelled = false;
+
+ /* If the resItem is to-be-installed, obviously it is being use! */
+ if (status == RESOLVABLE_STATUS_TO_BE_INSTALLED) {
+
+ unlink_cancelled = true;
+
+ } else if (status == RESOLVABLE_STATUS_INSTALLED) {
+ UnlinkCheckInfo info;
+
+ /* Flag the resItem as to-be-uninstalled so that it won't
+ satisfy any other resItem's deps during this check. */
+ context->setStatus (_resItem, RESOLVABLE_STATUS_TO_BE_UNINSTALLED);
+
+ info.context = context;
+ info.cancel_unlink = false;
+
+ CDependencyList provides = _resItem->provides();
+ for (CDependencyList::const_iterator iter = provides.begin(); iter != provides.end() && ! info.cancel_unlink; iter++) {
+ world()->foreachRequiringResItem (*iter, unlink_check_cb, &info);
+ }
+
+ /* Set the status back to normal. */
+ context->setStatus (_resItem, status);
+
+ if (info.cancel_unlink)
+ unlink_cancelled = true;
+ }
+
+ if (unlink_cancelled) {
+ string msg = pkg_str + " is required by other installed resolvable, so it won't be unlinked.";
+ context->addInfoString (_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+ goto finished;
+ }
+ }
+
+ context->uninstallResItem (_resItem, _upgraded_to != NULL, _due_to_obsolete, _unlink);
+
+ if (status == RESOLVABLE_STATUS_INSTALLED) {
+
+ if (! _explicitly_requested
+ && world()->resItemIsLocked (_resItem)) {
+ string msg = pkg_str + " is locked, and cannot be uninstalled.";
+ context->addErrorString (_resItem, msg);
+ goto finished;
+ }
+
+ this->logInfo (context);
+
+ if (_dep_leading_to_uninstall
+ && !_due_to_conflict
+ && !_due_to_obsolete)
+ {
+ ResolverInfoPtr info = new ResolverInfoMissingReq (_resItem, _dep_leading_to_uninstall);
+ context->addInfo (info);
+ }
+
+ CDependencyList provides = _resItem->provides();
+ for (CDependencyList::const_iterator iter = provides.begin(); iter != provides.end(); iter++) {
+ UninstallProcessInfo info;
+
+ info.world = world();
+ info.context = context;
+ info.uninstalled_resItem = _resItem;
+ info.upgraded_resItem = _upgraded_to;
+ info.require_items = &qil;
+ info.remove_only = _remove_only;
+
+ world()->foreachRequiringResItem (*iter, uninstall_process_cb, &info);
+ }
+ }
+
+ finished:
+ // FIXME rc_queue_item_free (item);
+
+ return true;
+ }
+
+ //---------------------------------------------------------------------------
+
+ int
+ QueueItemUninstall::cmp (constQueueItemPtr item) const
+ {
+ int cmp = this->compare (item); // assures equal type
+ if (cmp != 0)
+ return cmp;
+
+ constQueueItemUninstallPtr uninstall = item;
+ return GVersion.compare (_resItem, uninstall->_resItem);
+ }
+
+
+ QueueItemPtr
+ QueueItemUninstall::copy (void) const
+ {
+ QueueItemUninstallPtr new_uninstall = new QueueItemUninstall (world(), _resItem, _reason);
+ ((QueueItemPtr)new_uninstall)->copy((constQueueItemPtr)this);
+
+
+ new_uninstall->_resItem = _resItem;
+ new_uninstall->_dep_leading_to_uninstall = _dep_leading_to_uninstall;
+ new_uninstall->_upgraded_to = _upgraded_to;
+
+ new_uninstall->_explicitly_requested = _explicitly_requested;
+ new_uninstall->_remove_only = _remove_only;
+ new_uninstall->_due_to_conflict = _due_to_conflict;
+ new_uninstall->_due_to_obsolete = _due_to_obsolete;
+ new_uninstall->_unlink = _unlink;
+
+ return new_uninstall;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : QueueItemUninstall
-
-class QueueItemUninstall : public QueueItem {
- REP_BODY(QueueItemUninstall);
-
- private:
- constResItemPtr _resItem;
- const std::string _reason;
- constDependencyPtr _dep_leading_to_uninstall;
- constResItemPtr _upgraded_to;
-
- bool _explicitly_requested;
- bool _remove_only;
- bool _due_to_conflict;
- bool _due_to_obsolete;
- bool _unlink;
-
- public:
-
- QueueItemUninstall (WorldPtr world, constResItemPtr resItem, const std::string & reason);
- virtual ~QueueItemUninstall();
-
- // ---------------------------------- I/O
-
- static std::string toString (const QueueItemUninstall & item);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const QueueItemUninstall & item);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- void setDependency (constDependencyPtr dep) { _dep_leading_to_uninstall = dep; }
- void setExplicitlyRequested (void) { _explicitly_requested = true; }
- void setRemoveOnly (void) { _remove_only = true; }
- void setUpgradedTo (constResItemPtr resItem) { _upgraded_to = resItem; }
- void setDueToConflict (void) { _due_to_conflict = true; }
- void setDueToObsolete (void) { _due_to_obsolete = true; }
- void setUnlink (void);
-
- // ---------------------------------- methods
-
- virtual bool process (ResolverContextPtr context, QueueItemList & qil);
- virtual QueueItemPtr copy (void) const;
- virtual int cmp (constQueueItemPtr item) const;
- virtual bool isRedundant (ResolverContextPtr context) const { return false; }
- virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
-
-};
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : QueueItemUninstall
+
+ class QueueItemUninstall : public QueueItem {
+ REP_BODY(QueueItemUninstall);
+
+ private:
+ constResItemPtr _resItem;
+ const std::string _reason;
+ constDependencyPtr _dep_leading_to_uninstall;
+ constResItemPtr _upgraded_to;
+
+ bool _explicitly_requested;
+ bool _remove_only;
+ bool _due_to_conflict;
+ bool _due_to_obsolete;
+ bool _unlink;
+
+ public:
+
+ QueueItemUninstall (WorldPtr world, constResItemPtr resItem, const std::string & reason);
+ virtual ~QueueItemUninstall();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const QueueItemUninstall & item);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const QueueItemUninstall & item);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ void setDependency (constDependencyPtr dep) { _dep_leading_to_uninstall = dep; }
+ void setExplicitlyRequested (void) { _explicitly_requested = true; }
+ void setRemoveOnly (void) { _remove_only = true; }
+ void setUpgradedTo (constResItemPtr resItem) { _upgraded_to = resItem; }
+ void setDueToConflict (void) { _due_to_conflict = true; }
+ void setDueToObsolete (void) { _due_to_obsolete = true; }
+ void setUnlink (void);
+
+ // ---------------------------------- methods
+
+ virtual bool process (ResolverContextPtr context, QueueItemList & qil);
+ virtual QueueItemPtr copy (void) const;
+ virtual int cmp (constQueueItemPtr item) const;
+ virtual bool isRedundant (ResolverContextPtr context) const { return false; }
+ virtual bool isSatisfied (ResolverContextPtr context) const { return false; }
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemUninstall_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/QueueItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : QueueItemUninstallPtr
-// CLASS NAME : constQueueItemUninstallPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(QueueItemUninstall,QueueItem);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : QueueItemUninstallPtr
+ // CLASS NAME : constQueueItemUninstallPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(QueueItemUninstall,QueueItem);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _QueueItemUninstallPtr_h
#include <zypp/solver/detail/ResItem.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-
-IMPL_DERIVED_POINTER(ResItem,Spec);
-
-//---------------------------------------------------------------------------
-
-string
-ResItem::asString ( bool full ) const
-{
- return toString (*this, full);
-}
-
-
-string
-ResItem::toString ( const ResItem & resItem, bool full )
-{
- string res;
-
- res += Spec::toString(resItem);
- if (!resItem.channel()->system()) {
- res += "[";
- res += (resItem.channel() == NULL) ? "(channel?)" : resItem.channel()->name();
- res += "]";
- }
- if (!full) return res;
-
- if (resItem.isInstalled()) res += "<installed>";
- if (resItem.local()) res += "<local>";
-
- res += "FileSize ";
- res += stringutil::numstring (resItem.fileSize());
- res += ", InstalledSize ";
- res += stringutil::numstring (resItem.installedSize());
-
- if (!resItem.requires().empty()) {
- res += ", Requires: ";
- res += Dependency::toString(resItem.requires());
- }
-
- if (!resItem.provides().empty()) {
- res += ", Provides: ";
- res += Dependency::toString(resItem.provides());
- }
- if (!resItem.conflicts().empty()) {
- res += ", Conflicts: ";
- res += Dependency::toString(resItem.conflicts());
- }
- if (!resItem.obsoletes().empty()) {
- res += ", Obsoletes: ";
- res += Dependency::toString(resItem.obsoletes());
- }
-
- if (!resItem.suggests().empty()) {
- res += ", Suggests: ";
- res += Dependency::toString(resItem.suggests());
- }
- if (!resItem.recommends().empty()) {
- res += ", Recommends: ";
- res += Dependency::toString(resItem.recommends());
- }
- if (!resItem.freshens().empty()) {
- res += ", Freshens: ";
- res += Dependency::toString(resItem.freshens());
- }
- return res;
-}
-
-
-string
-ResItem::toString ( const CResItemList & rl, bool full )
-{
- string res("[");
- for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
- if (iter != rl.begin()) res += ", ";
- res += (*iter)->asString(full);
- }
- return res + "]";
-}
-
-
-ostream &
-ResItem::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResItem& edition)
-{
- return os << edition.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResItem::ResItem (const Kind & kind, const string & name, int epoch, const string & version, const string & release, const Arch * arch)
- :Spec (kind, name, epoch, version, release, arch)
- , _channel (false)
- , _installed (false)
- , _local (false)
- , _locked (false)
- , _file_size (0)
- , _installed_size (0)
-
-{
-}
-
-
-ResItem::~ResItem()
-{
-}
-
-//---------------------------------------------------------------------------
-
-bool
-ResItem::isInstalled () const
-{
- if (_channel != NULL
- && _channel->system()) {
- return true;
- }
- return false;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+
+ IMPL_DERIVED_POINTER(ResItem,Spec);
+
+ //---------------------------------------------------------------------------
+
+ string
+ ResItem::asString ( bool full ) const
+ {
+ return toString (*this, full);
+ }
+
+
+ string
+ ResItem::toString ( const ResItem & resItem, bool full )
+ {
+ string res;
+
+ res += Spec::toString(resItem);
+ if (!resItem.channel()->system()) {
+ res += "[";
+ res += (resItem.channel() == NULL) ? "(channel?)" : resItem.channel()->name();
+ res += "]";
+ }
+ if (!full) return res;
+
+ if (resItem.isInstalled()) res += "<installed>";
+ if (resItem.local()) res += "<local>";
+
+ res += "FileSize ";
+ res += stringutil::numstring (resItem.fileSize());
+ res += ", InstalledSize ";
+ res += stringutil::numstring (resItem.installedSize());
+
+ if (!resItem.requires().empty()) {
+ res += ", Requires: ";
+ res += Dependency::toString(resItem.requires());
+ }
+
+ if (!resItem.provides().empty()) {
+ res += ", Provides: ";
+ res += Dependency::toString(resItem.provides());
+ }
+ if (!resItem.conflicts().empty()) {
+ res += ", Conflicts: ";
+ res += Dependency::toString(resItem.conflicts());
+ }
+ if (!resItem.obsoletes().empty()) {
+ res += ", Obsoletes: ";
+ res += Dependency::toString(resItem.obsoletes());
+ }
+
+ if (!resItem.suggests().empty()) {
+ res += ", Suggests: ";
+ res += Dependency::toString(resItem.suggests());
+ }
+ if (!resItem.recommends().empty()) {
+ res += ", Recommends: ";
+ res += Dependency::toString(resItem.recommends());
+ }
+ if (!resItem.freshens().empty()) {
+ res += ", Freshens: ";
+ res += Dependency::toString(resItem.freshens());
+ }
+ return res;
+ }
+
+
+ string
+ ResItem::toString ( const CResItemList & rl, bool full )
+ {
+ string res("[");
+ for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
+ if (iter != rl.begin()) res += ", ";
+ res += (*iter)->asString(full);
+ }
+ return res + "]";
+ }
+
+
+ ostream &
+ ResItem::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResItem& edition)
+ {
+ return os << edition.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResItem::ResItem (const Kind & kind, const string & name, int epoch, const string & version, const string & release, const Arch * arch)
+ :Spec (kind, name, epoch, version, release, arch)
+ , _channel (false)
+ , _installed (false)
+ , _local (false)
+ , _locked (false)
+ , _file_size (0)
+ , _installed_size (0)
+
+ {
+ }
+
+
+ ResItem::~ResItem()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ ResItem::isInstalled () const
+ {
+ if (_channel != NULL
+ && _channel->system()) {
+ return true;
+ }
+ return false;
+ }
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/StoreWorldPtr.h>
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-typedef std::list<ResItemPtr> ResItemList;
-typedef std::list<constResItemPtr> CResItemList;
-
-typedef bool (*ResItemFn) (ResItemPtr r, void *data);
-typedef bool (*CResItemFn) (constResItemPtr r, void *data);
-typedef bool (*ResItemPairFn) (constResItemPtr r1, constResItemPtr r2, void *data);
-typedef bool (*ResItemAndSpecFn) (constResItemPtr r, constSpecPtr spec, void *data);
-typedef bool (*ResItemAndDepFn) (constResItemPtr r, constDependencyPtr dep, void *data);
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResItem
-/**
- *
- **/
-
-class ResItem : public Spec {
- REP_BODY(ResItem);
-
- private:
- constChannelPtr _channel;
-
- bool _installed;
- bool _local;
- bool _locked;
-
- size_t _file_size;
- size_t _installed_size;
-
- CDependencyList _requires;
- CDependencyList _provides;
- CDependencyList _conflicts;
- CDependencyList _obsoletes;
-
- CDependencyList _suggests;
- CDependencyList _recommends;
- CDependencyList _freshens;
-
- protected:
-
- // ---------------------------------- accessors
-
- void setLocal (bool local) { _local = local; }
-
- public:
-
- ResItem(const Kind & kind, const std::string & name, int epoch = -1, const std::string & version = "", const std::string & release = "", const Arch * arch = Arch::Unknown);
-
- ResItem(const XmlNodePtr node);
-
- virtual ~ResItem();
-
- // ---------------------------------- I/O
-
- const XmlNodePtr asXmlNode (void) const;
-
- static std::string toString ( const ResItem & res, bool full = false );
-
- static std::string toString ( const CResItemList & reslist, bool full = false );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream & str, const ResItem & str);
-
- std::string asString ( bool full = false ) const;
-
- // ---------------------------------- accessors
-
- constChannelPtr channel() const { return _channel; }
- void setChannel (constChannelPtr channel) { _channel = channel; }
-
- bool locked () const { return _locked; }
- void setLocked (bool locked) { _locked = locked; }
-
- bool isInstalled() const; // does *not* reflect _installed
- void setInstalled (bool installed) { _installed = installed; }
-
- bool local() const { return _local; }
-
- size_t fileSize() const { return _file_size; }
- void setFileSize (size_t file_size) { _file_size = file_size; }
-
- size_t installedSize() const { return _installed_size; }
- void setInstalledSize (size_t installed_size) { _installed_size = installed_size; }
-
- const CDependencyList & requires() const { return _requires; }
- void setRequires (const CDependencyList & requires) { _requires = requires; }
-
- const CDependencyList & provides() const { return _provides; }
- void setProvides (const CDependencyList & provides) { _provides = provides; }
-
- const CDependencyList & conflicts() const { return _conflicts; }
- void setConflicts (const CDependencyList & conflicts) { _conflicts = conflicts; }
-
- const CDependencyList & obsoletes() const { return _obsoletes; }
- void setObsoletes (const CDependencyList & obsoletes) { _obsoletes = obsoletes; }
-
- const CDependencyList & suggests() const { return _suggests; }
- void setSuggests (const CDependencyList & suggests) { _suggests = suggests; }
-
- const CDependencyList & recommends() const { return _recommends; }
- void setRecommends (const CDependencyList & recommends) { _recommends = recommends; }
-
- const CDependencyList & freshens() const { return _freshens; }
- void setFreshens (const CDependencyList & freshens) { _freshens = freshens; }
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+#include <zypp/ResObject.h>
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef std::list<ResItemPtr> ResItemList;
+ typedef std::list<constResItemPtr> CResItemList;
+
+ typedef bool (*ResItemFn) (ResItemPtr r, void *data);
+ typedef bool (*CResItemFn) (constResItemPtr r, void *data);
+ typedef bool (*ResItemPairFn) (constResItemPtr r1, constResItemPtr r2, void *data);
+ typedef bool (*ResItemAndSpecFn) (constResItemPtr r, constSpecPtr spec, void *data);
+ typedef bool (*ResItemAndDepFn) (constResItemPtr r, constDependencyPtr dep, void *data);
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResItem
+ /**
+ *
+ **/
+
+ class ResItem : public Spec {
+ REP_BODY(ResItem);
+
+ private:
+ constChannelPtr _channel;
+
+ bool _installed;
+ bool _local;
+ bool _locked;
+
+ size_t _file_size;
+ size_t _installed_size;
+
+ CDependencyList _requires;
+ CDependencyList _provides;
+ CDependencyList _conflicts;
+ CDependencyList _obsoletes;
+
+ CDependencyList _suggests;
+ CDependencyList _recommends;
+ CDependencyList _freshens;
+
+ protected:
+
+ // ---------------------------------- accessors
+
+ void setLocal (bool local) { _local = local; }
+
+ public:
+
+ ResItem(const Kind & kind, const std::string & name, int epoch = -1, const std::string & version = "", const std::string & release = "", const Arch * arch = Arch::Unknown);
+
+ ResItem(const XmlNodePtr node);
+
+ virtual ~ResItem();
+
+ // ---------------------------------- I/O
+
+ const XmlNodePtr asXmlNode (void) const;
+
+ static std::string toString ( const ResItem & res, bool full = false );
+
+ static std::string toString ( const CResItemList & reslist, bool full = false );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream & str, const ResItem & str);
+
+ std::string asString ( bool full = false ) const;
+
+ // ---------------------------------- accessors
+
+ constChannelPtr channel() const { return _channel; }
+ void setChannel (constChannelPtr channel) { _channel = channel; }
+
+ bool locked () const { return _locked; }
+ void setLocked (bool locked) { _locked = locked; }
+
+ bool isInstalled() const; // does *not* reflect _installed
+ void setInstalled (bool installed) { _installed = installed; }
+
+ bool local() const { return _local; }
+
+ size_t fileSize() const { return _file_size; }
+ void setFileSize (size_t file_size) { _file_size = file_size; }
+
+ size_t installedSize() const { return _installed_size; }
+ void setInstalledSize (size_t installed_size) { _installed_size = installed_size; }
+
+ const CDependencyList & requires() const { return _requires; }
+ void setRequires (const CDependencyList & requires) { _requires = requires; }
+
+ const CDependencyList & provides() const { return _provides; }
+ void setProvides (const CDependencyList & provides) { _provides = provides; }
+
+ const CDependencyList & conflicts() const { return _conflicts; }
+ void setConflicts (const CDependencyList & conflicts) { _conflicts = conflicts; }
+
+ const CDependencyList & obsoletes() const { return _obsoletes; }
+ void setObsoletes (const CDependencyList & obsoletes) { _obsoletes = obsoletes; }
+
+ const CDependencyList & suggests() const { return _suggests; }
+ void setSuggests (const CDependencyList & suggests) { _suggests = suggests; }
+
+ const CDependencyList & recommends() const { return _recommends; }
+ void setRecommends (const CDependencyList & recommends) { _recommends = recommends; }
+
+ const CDependencyList & freshens() const { return _freshens; }
+ void setFreshens (const CDependencyList & freshens) { _freshens = freshens; }
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResItem_h
#include <zypp/solver/detail/ResItemAndDependency.h>
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(ResItemAndDependency);
-
-//---------------------------------------------------------------------------
-
-ResItemAndDependency::ResItemAndDependency (constResItemPtr resItem, constDependencyPtr dependency)
- : _resItem(resItem)
- , _dependency(dependency)
-{
-}
-
-//---------------------------------------------------------------------------
-
-string
-ResItemAndDependency::asString (bool full) const
-{
- return toString (*this, full);
-}
-
-
-string
-ResItemAndDependency::toString ( const ResItemAndDependency & r_and_d, bool full )
-{
- string res ("{");
- res += r_and_d._resItem->asString(full);
- res += ", ";
- res += r_and_d._dependency->asString();
- res += "}";
- return res;
-}
-
-
-ostream &
-ResItemAndDependency::dumpOn (ostream & str) const
-{
- str << asString();
- return str;
-}
-
-
-ostream &
-operator<< (ostream & os, const ResItemAndDependency & r_and_d)
-{
- return os << r_and_d.asString();
-}
-
-//---------------------------------------------------------------------------
-
-/* This function also checks channels in addition to just dep relations */
-/* FIXME: rc_resItem_dep_verify_relation already checks the channel */
-
-bool
-ResItemAndDependency::verifyRelation (constDependencyPtr dep) const
-{
-#if PHI
- // don't check the channel, thereby honoring conflicts from installed resItems to to-be-installed resItems
- return dep->verifyRelation (_dependency);
-#else
- if (!dep->verifyRelation (_dependency)) {
- return false;
- }
- if (getenv ("SPEW_DEP")) fprintf (stderr, "ResItemAndDependency::verifyRelation _resItem->channel() %s, dep->channel() %s\n", _resItem->channel()->asString().c_str(), dep->channel()->asString().c_str());
- return _resItem->channel()->equals (dep->channel());
-#endif
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(ResItemAndDependency);
+
+ //---------------------------------------------------------------------------
+
+ ResItemAndDependency::ResItemAndDependency (constResItemPtr resItem, constDependencyPtr dependency)
+ : _resItem(resItem)
+ , _dependency(dependency)
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ string
+ ResItemAndDependency::asString (bool full) const
+ {
+ return toString (*this, full);
+ }
+
+
+ string
+ ResItemAndDependency::toString ( const ResItemAndDependency & r_and_d, bool full )
+ {
+ string res ("{");
+ res += r_and_d._resItem->asString(full);
+ res += ", ";
+ res += r_and_d._dependency->asString();
+ res += "}";
+ return res;
+ }
+
+
+ ostream &
+ ResItemAndDependency::dumpOn (ostream & str) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream &
+ operator<< (ostream & os, const ResItemAndDependency & r_and_d)
+ {
+ return os << r_and_d.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ /* This function also checks channels in addition to just dep relations */
+ /* FIXME: rc_resItem_dep_verify_relation already checks the channel */
+
+ bool
+ ResItemAndDependency::verifyRelation (constDependencyPtr dep) const
+ {
+ #if PHI
+ // don't check the channel, thereby honoring conflicts from installed resItems to to-be-installed resItems
+ return dep->verifyRelation (_dependency);
+ #else
+ if (!dep->verifyRelation (_dependency)) {
+ return false;
+ }
+ if (getenv ("SPEW_DEP")) fprintf (stderr, "ResItemAndDependency::verifyRelation _resItem->channel() %s, dep->channel() %s\n", _resItem->channel()->asString().c_str(), dep->channel()->asString().c_str());
+ return _resItem->channel()->equals (dep->channel());
+ #endif
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResItem.h>
#include <zypp/solver/detail/Dependency.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
typedef std::multimap<const std::string, constResItemPtr> ResItemTable;
-typedef std::multimap<const std::string, constResItemAndDependencyPtr> ResItemAndDependencyTable;
-
-#if PHI
-typedef std::list <constResItemAndDependencyPtr> CResItemAndDependencyList;
-#endif
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResItemAndDependency
-
-class ResItemAndDependency: public CountedRep {
- REP_BODY(ResItemAndDependency);
-
- private:
- constResItemPtr _resItem;
- constDependencyPtr _dependency;
-
- public:
-
- ResItemAndDependency (constResItemPtr resItem, constDependencyPtr dependency);
- ~ResItemAndDependency () {}
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResItemAndDependency & r_and_d, bool full = false);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const ResItemAndDependency & r_and_d);
-
- std::string asString (bool full = false) const;
-
- // ---------------------------------- accessors
-
- constResItemPtr resItem() const { return _resItem; }
- constDependencyPtr dependency() const { return _dependency; }
-
- // ---------------------------------- methods
-
- bool verifyRelation (constDependencyPtr dep) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ typedef std::multimap<const std::string, constResItemAndDependencyPtr> ResItemAndDependencyTable;
+
+ #if PHI
+ typedef std::list <constResItemAndDependencyPtr> CResItemAndDependencyList;
+ #endif
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResItemAndDependency
+
+ class ResItemAndDependency: public CountedRep {
+ REP_BODY(ResItemAndDependency);
+
+ private:
+ constResItemPtr _resItem;
+ constDependencyPtr _dependency;
+
+ public:
+
+ ResItemAndDependency (constResItemPtr resItem, constDependencyPtr dependency);
+ ~ResItemAndDependency () {}
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResItemAndDependency & r_and_d, bool full = false);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const ResItemAndDependency & r_and_d);
+
+ std::string asString (bool full = false) const;
+
+ // ---------------------------------- accessors
+
+ constResItemPtr resItem() const { return _resItem; }
+ constDependencyPtr dependency() const { return _dependency; }
+
+ // ---------------------------------- methods
+
+ bool verifyRelation (constDependencyPtr dep) const;
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResItemAndDependency_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/WorldPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResItemAndDependencyPtr
-// CLASS NAME : constResItemAndDependencyPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(ResItemAndDependency);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResItemAndDependencyPtr
+ // CLASS NAME : constResItemAndDependencyPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(ResItemAndDependency);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResItemAndDependencyPtr_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/SpecPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResItemPtr
-// CLASS NAME : constResItemPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResItem,Spec);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResItemPtr
+ // CLASS NAME : constResItemPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResItem,Spec);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResItemPtr_h
#include <zypp/solver/detail/StoreWorld.h>
#include <zypp/solver/detail/MultiWorld.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(Resolver);
-
-//---------------------------------------------------------------------------
-
-string
-Resolver::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Resolver::toString ( const Resolver & resolver )
-{
- return "<resolver/>";
-}
-
-
-ostream &
-Resolver::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Resolver & resolver)
-{
- return os << resolver.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Resolver::Resolver (WorldPtr world)
- : _current_channel (NULL)
- , _world (world)
- , _timeout_seconds (0)
- , _verifying (false)
- , _valid_solution_count (0)
- , _best_context (NULL)
- , _timed_out (false)
-{
-}
-
-
-Resolver::~Resolver()
-{
-}
-
-//---------------------------------------------------------------------------
-
-WorldPtr
-Resolver::world (void) const
-{
- if (_world == NULL)
- return World::globalWorld();
-
- return _world;
-}
-
-//---------------------------------------------------------------------------
-
-void
-Resolver::addSubscribedChannel (constChannelPtr channel)
-{
- fprintf (stderr, "Resolver::addSubscribedChannel() not implemented\n");
-}
-
-void
-Resolver::addResItemToInstall (constResItemPtr resItem)
-{
- _resItems_to_install.push_front (resItem);
-}
-
-void
-Resolver::addResItemsToInstallFromList (CResItemList & rl)
-{
- for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
- addResItemToInstall (*iter);
- }
-}
-
-void
-Resolver::addResItemToRemove (constResItemPtr resItem)
-{
- _resItems_to_remove.push_front (resItem);
-}
-
-void
-Resolver::addResItemsToRemoveFromList (CResItemList & rl)
-{
- for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
- addResItemToRemove (*iter);
- }
-}
-
-void
-Resolver::addResItemToVerify (constResItemPtr resItem)
-{
- _resItems_to_verify.push_front (resItem);
- _resItems_to_verify.sort (); //(GCompareFunc) rc_resItem_compare_name);
-}
-
-void
-Resolver::addExtraDependency (constDependencyPtr dependency)
-{
- _extra_deps.push_front (dependency);
-}
-
-void
-Resolver::addExtraConflict (constDependencyPtr dependency)
-{
- _extra_conflicts.push_front (dependency);
-}
-
-
-//---------------------------------------------------------------------------
-
-static bool
-verify_system_cb (constResItemPtr resItem, void *data)
-{
- Resolver *resolver = (Resolver *)data;
-
- resolver->addResItemToVerify (resItem);
-
- return true;
-}
-
-
-void
-Resolver::verifySystem (void)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "Resolver::verifySystem()\n");
- world()->foreachResItem (new Channel(CHANNEL_TYPE_SYSTEM), verify_system_cb, this);
-
- _verifying = true;
-
-#if 0 // commented out in libredcarpet also
- /*
- Walk across the (sorted-by-name) list of installed packages and look for
- packages with the same name. If they exist, construct a branch item
- containing multiple group items. Each group item corresponds to removing
- all but one of the duplicates.
- */
-
- for (CResItemList::const_iterator i0 = _resItems_to_verify.begin(); i0 != _resItems_to_verify.end();) {
- CResItemList::const_iterator i1 = i0;
- i1++;
- CResItemList::const_iterator i2 = i1;
- for (; i1 != _resItems_to_verify.end()&& ! (*i0)->compareName (*i1); i1++) {
- //empty
- }
-
- if (i1 != i2) {
- QueueItemBranchPtr branch_item;
-
- branch_item = new QueueItemBranch(world());
-
- for (CResItemList::const_iterator i = i0; i != i1; i++) {
-
- QueueItemGroupPtr grp_item = new QueueItemGroup(world());
-
- for (CResItemList::const_iterator j = i0; j != i1; j++) {
- constPackagePtr dup_pkg = *j;
- QueueItemUninstallPtr uninstall_item;
-
- if (i != j) {
- uninstall_item = new QueueItemUninstall (world(), dup_pkg, "duplicate install");
- grp_item->addItem (uninstall_item);
- }
-
- }
-
- branch_item->adddIitem (grp_item);
- }
-
- _initial_items.push_back (branch_item);
- }
-
- i0 = i1;
- }
-#endif
-
- /* OK, that was fun. Now just resolve the dependencies. */
- resolveDependencies ();
-
- return;
-}
-
-
-//---------------------------------------------------------------------------
-
-
-void
-Resolver::resolveDependencies (void)
-{
-
- time_t t_start, t_now;
- bool extremely_noisy = getenv ("RC_SPEW") != NULL;
- bool have_local_resItems = false;
-
- if (extremely_noisy) fprintf (stderr, "Resolver::resolveDependencies()\n");
-
- /* Walk through are list of to-be-installed packages and see if any of them are local. */
-
- for (CResItemList::const_iterator iter = _resItems_to_install.begin(); iter != _resItems_to_install.end(); iter++) {
- if ((*iter)->local()) {
- have_local_resItems = true;
- break;
- }
- }
-
- WorldPtr the_world = world();
- StoreWorldPtr local_world = NULL;
- MultiWorldPtr local_multiworld = NULL;
-
- ChannelPtr local_channel = NULL;
-
- if (have_local_resItems) {
- local_multiworld = new MultiWorld();
- local_world = new StoreWorld();
-
- local_channel = new Channel ("", "Local ResItems", "@local", "");
-
- local_world->addChannel (local_channel);
-
- local_multiworld->addSubworld (local_world);
- local_multiworld->addSubworld (the_world);
-
- the_world = local_multiworld;
- }
-
- // create initial_queue
-
- ResolverQueuePtr initial_queue = new ResolverQueue();
-
- /* Stick the current/subscribed channel and world info into the context */
-
- initial_queue->context()->setWorld(the_world);
-
- initial_queue->context()->setCurrentChannel (_current_channel);
-
- /* If this is a verify, we do a "soft resolution" */
-
- initial_queue->context()->setVerifying (_verifying);
-
- /* Add extra items. */
-
- for (QueueItemList::const_iterator iter = _initial_items.begin(); iter != _initial_items.end(); iter++) {
- initial_queue->addItem (*iter);
- }
- _initial_items.clear();
-
- for (CResItemList::const_iterator iter = _resItems_to_install.begin(); iter != _resItems_to_install.end(); iter++) {
- constResItemPtr r = *iter;
-
- /* Add local packages to our dummy channel. */
- if (r->local()) {
- assert (local_channel != NULL);
- ResItemPtr r1 = ResItemPtr::cast_away_const (r);
- r1->setChannel (local_channel);
- local_world->addResItem (r);
- }
-
- initial_queue->addResItemToInstall (r);
- }
-
- for (CResItemList::const_iterator iter = _resItems_to_remove.begin(); iter != _resItems_to_remove.end(); iter++) {
- initial_queue->addResItemToRemove (*iter, true /* remove-only mode */);
- }
-
- for (CResItemList::const_iterator iter = _resItems_to_verify.begin(); iter != _resItems_to_verify.end(); iter++) {
- initial_queue->addResItemToVerify (*iter);
- }
-
- for (CDependencyList::const_iterator iter = _extra_deps.begin(); iter != _extra_deps.end(); iter++) {
- initial_queue->addExtraDependency (*iter);
- }
-
- for (CDependencyList::const_iterator iter = _extra_conflicts.begin(); iter != _extra_conflicts.end(); iter++) {
- initial_queue->addExtraConflict (*iter);
- }
-
- if (extremely_noisy) fprintf (stderr, "Initial Queue: [%s]\n", initial_queue->asString().c_str());
-
- _pending_queues.push_front (initial_queue);
-
- time (&t_start);
-
- while (!_pending_queues.empty()) {
-
- if (extremely_noisy) {
- printf ("Pend %ld / Cmpl %ld / Prun %ld / Defr %ld / Invl %ld\n\n", (long) _pending_queues.size(), (long) _complete_queues.size(), (long) _pruned_queues.size(), (long) _deferred_queues.size(), (long) _invalid_queues.size());
- }
-
- if (_timeout_seconds > 0) {
- time (&t_now);
- if (difftime (t_now, t_start) > _timeout_seconds) {
- _timed_out = true;
- break;
- }
- }
-
- ResolverQueuePtr queue = _pending_queues.front();
- _pending_queues.pop_front();
- ResolverContextPtr context = queue->context();
-
- queue->process();
-
- if (queue->isInvalid ()) {
- if (extremely_noisy) printf ("Invalid Queue\n");
- _invalid_queues.push_front (queue);
-
- } else if (queue->isEmpty ()) {
- if (extremely_noisy) printf ("Empty Queue\n");
-
- _complete_queues.push_front (queue);
-
- ++_valid_solution_count;
-
- /* Compare this solution to our previous favorite. In the case of a tie,
- the first solution wins --- yeah, I know this is lame, but it shouldn't
- be an issue too much of the time. */
-
- if (_best_context == NULL
- || _best_context->compare (context) < 0) {
-
- _best_context = context;
- }
-
- } else if (_best_context != NULL
- && _best_context->partialCompare (context) > 0) {
-
- /* If we aren't currently as good as our previous best complete solution,
- this solution gets pruned. */
-
- if (extremely_noisy) printf ("PRUNED!\n");
-
- _pruned_queues.push_front(queue);
-
- } else {
-
- /* If our queue is isn't empty and isn't invalid, that can only mean
- one thing: we are down to nothing but branches. */
-
- queue->splitFirstBranch (_pending_queues, _deferred_queues);
- }
-
- /* If we have run out of pending queues w/o finding any solutions,
- and if we have deferred queues, make the first deferred queue
- pending. */
-
- if (_pending_queues.empty()
- && _complete_queues.empty()
- && !_deferred_queues.empty()) {
- _pending_queues.push_front (_deferred_queues.front());
- }
- }
-
- if (extremely_noisy) {
- printf ("Pend %ld / Cmpl %ld / Prun %ld / Defr %ld / Invl %ld\n--------\n", (long) _pending_queues.size(), (long) _complete_queues.size(), (long) _pruned_queues.size(), (long) _deferred_queues.size(), (long) _invalid_queues.size());
- }
-
- return;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(Resolver);
+
+ //---------------------------------------------------------------------------
+
+ string
+ Resolver::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Resolver::toString ( const Resolver & resolver )
+ {
+ return "<resolver/>";
+ }
+
+
+ ostream &
+ Resolver::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Resolver & resolver)
+ {
+ return os << resolver.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Resolver::Resolver (WorldPtr world)
+ : _current_channel (NULL)
+ , _world (world)
+ , _timeout_seconds (0)
+ , _verifying (false)
+ , _valid_solution_count (0)
+ , _best_context (NULL)
+ , _timed_out (false)
+ {
+ }
+
+
+ Resolver::~Resolver()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ WorldPtr
+ Resolver::world (void) const
+ {
+ if (_world == NULL)
+ return World::globalWorld();
+
+ return _world;
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ Resolver::addSubscribedChannel (constChannelPtr channel)
+ {
+ fprintf (stderr, "Resolver::addSubscribedChannel() not implemented\n");
+ }
+
+ void
+ Resolver::addResItemToInstall (constResItemPtr resItem)
+ {
+ _resItems_to_install.push_front (resItem);
+ }
+
+ void
+ Resolver::addResItemsToInstallFromList (CResItemList & rl)
+ {
+ for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
+ addResItemToInstall (*iter);
+ }
+ }
+
+ void
+ Resolver::addResItemToRemove (constResItemPtr resItem)
+ {
+ _resItems_to_remove.push_front (resItem);
+ }
+
+ void
+ Resolver::addResItemsToRemoveFromList (CResItemList & rl)
+ {
+ for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
+ addResItemToRemove (*iter);
+ }
+ }
+
+ void
+ Resolver::addResItemToVerify (constResItemPtr resItem)
+ {
+ _resItems_to_verify.push_front (resItem);
+ _resItems_to_verify.sort (); //(GCompareFunc) rc_resItem_compare_name);
+ }
+
+ void
+ Resolver::addExtraDependency (constDependencyPtr dependency)
+ {
+ _extra_deps.push_front (dependency);
+ }
+
+ void
+ Resolver::addExtraConflict (constDependencyPtr dependency)
+ {
+ _extra_conflicts.push_front (dependency);
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ static bool
+ verify_system_cb (constResItemPtr resItem, void *data)
+ {
+ Resolver *resolver = (Resolver *)data;
+
+ resolver->addResItemToVerify (resItem);
+
+ return true;
+ }
+
+
+ void
+ Resolver::verifySystem (void)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "Resolver::verifySystem()\n");
+ world()->foreachResItem (new Channel(CHANNEL_TYPE_SYSTEM), verify_system_cb, this);
+
+ _verifying = true;
+
+ #if 0 // commented out in libredcarpet also
+ /*
+ Walk across the (sorted-by-name) list of installed packages and look for
+ packages with the same name. If they exist, construct a branch item
+ containing multiple group items. Each group item corresponds to removing
+ all but one of the duplicates.
+ */
+
+ for (CResItemList::const_iterator i0 = _resItems_to_verify.begin(); i0 != _resItems_to_verify.end();) {
+ CResItemList::const_iterator i1 = i0;
+ i1++;
+ CResItemList::const_iterator i2 = i1;
+ for (; i1 != _resItems_to_verify.end()&& ! (*i0)->compareName (*i1); i1++) {
+ //empty
+ }
+
+ if (i1 != i2) {
+ QueueItemBranchPtr branch_item;
+
+ branch_item = new QueueItemBranch(world());
+
+ for (CResItemList::const_iterator i = i0; i != i1; i++) {
+
+ QueueItemGroupPtr grp_item = new QueueItemGroup(world());
+
+ for (CResItemList::const_iterator j = i0; j != i1; j++) {
+ constPackagePtr dup_pkg = *j;
+ QueueItemUninstallPtr uninstall_item;
+
+ if (i != j) {
+ uninstall_item = new QueueItemUninstall (world(), dup_pkg, "duplicate install");
+ grp_item->addItem (uninstall_item);
+ }
+
+ }
+
+ branch_item->adddIitem (grp_item);
+ }
+
+ _initial_items.push_back (branch_item);
+ }
+
+ i0 = i1;
+ }
+ #endif
+
+ /* OK, that was fun. Now just resolve the dependencies. */
+ resolveDependencies ();
+
+ return;
+ }
+
+
+ //---------------------------------------------------------------------------
+
+
+ void
+ Resolver::resolveDependencies (void)
+ {
+
+ time_t t_start, t_now;
+ bool extremely_noisy = getenv ("RC_SPEW") != NULL;
+ bool have_local_resItems = false;
+
+ if (extremely_noisy) fprintf (stderr, "Resolver::resolveDependencies()\n");
+
+ /* Walk through are list of to-be-installed packages and see if any of them are local. */
+
+ for (CResItemList::const_iterator iter = _resItems_to_install.begin(); iter != _resItems_to_install.end(); iter++) {
+ if ((*iter)->local()) {
+ have_local_resItems = true;
+ break;
+ }
+ }
+
+ WorldPtr the_world = world();
+ StoreWorldPtr local_world = NULL;
+ MultiWorldPtr local_multiworld = NULL;
+
+ ChannelPtr local_channel = NULL;
+
+ if (have_local_resItems) {
+ local_multiworld = new MultiWorld();
+ local_world = new StoreWorld();
+
+ local_channel = new Channel ("", "Local ResItems", "@local", "");
+
+ local_world->addChannel (local_channel);
+
+ local_multiworld->addSubworld (local_world);
+ local_multiworld->addSubworld (the_world);
+
+ the_world = local_multiworld;
+ }
+
+ // create initial_queue
+
+ ResolverQueuePtr initial_queue = new ResolverQueue();
+
+ /* Stick the current/subscribed channel and world info into the context */
+
+ initial_queue->context()->setWorld(the_world);
+
+ initial_queue->context()->setCurrentChannel (_current_channel);
+
+ /* If this is a verify, we do a "soft resolution" */
+
+ initial_queue->context()->setVerifying (_verifying);
+
+ /* Add extra items. */
+
+ for (QueueItemList::const_iterator iter = _initial_items.begin(); iter != _initial_items.end(); iter++) {
+ initial_queue->addItem (*iter);
+ }
+ _initial_items.clear();
+
+ for (CResItemList::const_iterator iter = _resItems_to_install.begin(); iter != _resItems_to_install.end(); iter++) {
+ constResItemPtr r = *iter;
+
+ /* Add local packages to our dummy channel. */
+ if (r->local()) {
+ assert (local_channel != NULL);
+ ResItemPtr r1 = ResItemPtr::cast_away_const (r);
+ r1->setChannel (local_channel);
+ local_world->addResItem (r);
+ }
+
+ initial_queue->addResItemToInstall (r);
+ }
+
+ for (CResItemList::const_iterator iter = _resItems_to_remove.begin(); iter != _resItems_to_remove.end(); iter++) {
+ initial_queue->addResItemToRemove (*iter, true /* remove-only mode */);
+ }
+
+ for (CResItemList::const_iterator iter = _resItems_to_verify.begin(); iter != _resItems_to_verify.end(); iter++) {
+ initial_queue->addResItemToVerify (*iter);
+ }
+
+ for (CDependencyList::const_iterator iter = _extra_deps.begin(); iter != _extra_deps.end(); iter++) {
+ initial_queue->addExtraDependency (*iter);
+ }
+
+ for (CDependencyList::const_iterator iter = _extra_conflicts.begin(); iter != _extra_conflicts.end(); iter++) {
+ initial_queue->addExtraConflict (*iter);
+ }
+
+ if (extremely_noisy) fprintf (stderr, "Initial Queue: [%s]\n", initial_queue->asString().c_str());
+
+ _pending_queues.push_front (initial_queue);
+
+ time (&t_start);
+
+ while (!_pending_queues.empty()) {
+
+ if (extremely_noisy) {
+ printf ("Pend %ld / Cmpl %ld / Prun %ld / Defr %ld / Invl %ld\n\n", (long) _pending_queues.size(), (long) _complete_queues.size(), (long) _pruned_queues.size(), (long) _deferred_queues.size(), (long) _invalid_queues.size());
+ }
+
+ if (_timeout_seconds > 0) {
+ time (&t_now);
+ if (difftime (t_now, t_start) > _timeout_seconds) {
+ _timed_out = true;
+ break;
+ }
+ }
+
+ ResolverQueuePtr queue = _pending_queues.front();
+ _pending_queues.pop_front();
+ ResolverContextPtr context = queue->context();
+
+ queue->process();
+
+ if (queue->isInvalid ()) {
+ if (extremely_noisy) printf ("Invalid Queue\n");
+ _invalid_queues.push_front (queue);
+
+ } else if (queue->isEmpty ()) {
+ if (extremely_noisy) printf ("Empty Queue\n");
+
+ _complete_queues.push_front (queue);
+
+ ++_valid_solution_count;
+
+ /* Compare this solution to our previous favorite. In the case of a tie,
+ the first solution wins --- yeah, I know this is lame, but it shouldn't
+ be an issue too much of the time. */
+
+ if (_best_context == NULL
+ || _best_context->compare (context) < 0) {
+
+ _best_context = context;
+ }
+
+ } else if (_best_context != NULL
+ && _best_context->partialCompare (context) > 0) {
+
+ /* If we aren't currently as good as our previous best complete solution,
+ this solution gets pruned. */
+
+ if (extremely_noisy) printf ("PRUNED!\n");
+
+ _pruned_queues.push_front(queue);
+
+ } else {
+
+ /* If our queue is isn't empty and isn't invalid, that can only mean
+ one thing: we are down to nothing but branches. */
+
+ queue->splitFirstBranch (_pending_queues, _deferred_queues);
+ }
+
+ /* If we have run out of pending queues w/o finding any solutions,
+ and if we have deferred queues, make the first deferred queue
+ pending. */
+
+ if (_pending_queues.empty()
+ && _complete_queues.empty()
+ && !_deferred_queues.empty()) {
+ _pending_queues.push_front (_deferred_queues.front());
+ }
+ }
+
+ if (extremely_noisy) {
+ printf ("Pend %ld / Cmpl %ld / Prun %ld / Defr %ld / Invl %ld\n--------\n", (long) _pending_queues.size(), (long) _complete_queues.size(), (long) _pruned_queues.size(), (long) _deferred_queues.size(), (long) _invalid_queues.size());
+ }
+
+ return;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-
-//////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : Resolver
-class Resolver : public CountedRep {
- REP_BODY(Resolver);
-
- private:
- constChannelPtr _current_channel;
-
- WorldPtr _world;
-
- int _timeout_seconds;
- bool _verifying;
-
- QueueItemList _initial_items;
- CResItemList _resItems_to_install;
- CResItemList _resItems_to_remove;
- CResItemList _resItems_to_verify;
-
- CDependencyList _extra_deps;
- CDependencyList _extra_conflicts;
-
- ResolverQueueList _pending_queues;
- ResolverQueueList _pruned_queues;
- ResolverQueueList _complete_queues;
- ResolverQueueList _deferred_queues;
- ResolverQueueList _invalid_queues;
-
- int _valid_solution_count;
-
- ResolverContextPtr _best_context;
- bool _timed_out;
-
- public:
-
- Resolver (WorldPtr world = NULL);
- virtual ~Resolver();
-
- // ---------------------------------- I/O
-
- static std::string toString (const Resolver & resolver);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const Resolver & resolver);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- QueueItemList initialItems () const { return _initial_items; }
-
- ResolverQueueList pendingQueues () const { return _pending_queues; }
- ResolverQueueList prunedQueues () const { return _pruned_queues; }
- ResolverQueueList completeQueues () const { return _complete_queues; }
- ResolverQueueList deferredQueues () const { return _deferred_queues; }
- ResolverQueueList invalidQueues () const { return _invalid_queues; }
-
- ResolverContextPtr bestContext (void) const { return _best_context; }
-
- // ---------------------------------- methods
-
- void setTimeout (int seconds) { _timeout_seconds = seconds; }
-
- WorldPtr world (void) const; // returns global world if _world == NULL
- void setWorld (WorldPtr world) { _world = world; }
-
- void setCurrentChannel (constChannelPtr channel) { _current_channel = channel; }
- void addSubscribedChannel (constChannelPtr channel);
-
- void addResItemToInstall (constResItemPtr resItem);
- void addResItemsToInstallFromList (CResItemList & rl);
-
- void addResItemToRemove (constResItemPtr resItem);
- void addResItemsToRemoveFromList (CResItemList & rl);
-
- void addResItemToVerify (constResItemPtr resItem);
-
- void addExtraDependency (constDependencyPtr dependency);
- void addExtraConflict (constDependencyPtr dependency);
-
- void verifySystem (void);
- void resolveDependencies (void);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ class Resolver : public CountedRep {
+ REP_BODY(Resolver);
+
+ private:
+ constChannelPtr _current_channel;
+
+ WorldPtr _world;
+
+ int _timeout_seconds;
+ bool _verifying;
+
+ QueueItemList _initial_items;
+ CResItemList _resItems_to_install;
+ CResItemList _resItems_to_remove;
+ CResItemList _resItems_to_verify;
+
+ CDependencyList _extra_deps;
+ CDependencyList _extra_conflicts;
+
+ ResolverQueueList _pending_queues;
+ ResolverQueueList _pruned_queues;
+ ResolverQueueList _complete_queues;
+ ResolverQueueList _deferred_queues;
+ ResolverQueueList _invalid_queues;
+
+ int _valid_solution_count;
+
+ ResolverContextPtr _best_context;
+ bool _timed_out;
+
+ public:
+
+ Resolver (WorldPtr world = NULL);
+ virtual ~Resolver();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const Resolver & resolver);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const Resolver & resolver);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ QueueItemList initialItems () const { return _initial_items; }
+
+ ResolverQueueList pendingQueues () const { return _pending_queues; }
+ ResolverQueueList prunedQueues () const { return _pruned_queues; }
+ ResolverQueueList completeQueues () const { return _complete_queues; }
+ ResolverQueueList deferredQueues () const { return _deferred_queues; }
+ ResolverQueueList invalidQueues () const { return _invalid_queues; }
+
+ ResolverContextPtr bestContext (void) const { return _best_context; }
+
+ // ---------------------------------- methods
+
+ void setTimeout (int seconds) { _timeout_seconds = seconds; }
+
+ WorldPtr world (void) const; // returns global world if _world == NULL
+ void setWorld (WorldPtr world) { _world = world; }
+
+ void setCurrentChannel (constChannelPtr channel) { _current_channel = channel; }
+ void addSubscribedChannel (constChannelPtr channel);
+
+ void addResItemToInstall (constResItemPtr resItem);
+ void addResItemsToInstallFromList (CResItemList & rl);
+
+ void addResItemToRemove (constResItemPtr resItem);
+ void addResItemsToRemoveFromList (CResItemList & rl);
+
+ void addResItemToVerify (constResItemPtr resItem);
+
+ void addExtraDependency (constDependencyPtr dependency);
+ void addExtraConflict (constDependencyPtr dependency);
+
+ void verifySystem (void);
+ void resolveDependencies (void);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Resolver_h
#include <zypp/solver/detail/ResolverInfoMisc.h>
#include <zypp/solver/detail/World.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(ResolverContext);
-
-//---------------------------------------------------------------------------
-
-string
-ResolverContext::toString (const ResItemStatus & status)
-{
- string ret;
- switch (status) {
- case RESOLVABLE_STATUS_UNKNOWN: ret = "unknown"; break;
- case RESOLVABLE_STATUS_INSTALLED: ret = "installed"; break;
- case RESOLVABLE_STATUS_UNINSTALLED: ret = "uninstalled"; break;
- case RESOLVABLE_STATUS_TO_BE_INSTALLED: ret = "to be installed"; break;
- case RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT: ret = "to be installed (soft)"; break;
- case RESOLVABLE_STATUS_TO_BE_UNINSTALLED: ret = "to be uninstalled"; break;
- case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE: ret = "to be uninstalled due to obsolete"; break;
- case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK: ret = "to be uninstalled due to unlink"; break;
- default: ret = "Huh ?"; break;
- }
-
- return ret;
-}
-
-//---------------------------------------------------------------------------
-
-string
-ResolverContext::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverContext::toString ( const ResolverContext & context )
-{
- string ret;
- if (context._parent != NULL) {
- ret += "Parent: [";
- ret += stringutil::form("<@%p> ", (const void *)(context._parent));
- ret += context._parent->asString();
- ret += "],\n\t";
- }
- ret += stringutil::form ("Download Size: %lld", context._download_size);
- ret += stringutil::form (", Install Size: %lld", context._install_size);
- ret += stringutil::form (", Total Priority: %d", context._total_priority);
- ret += stringutil::form (", Min Priority: %d", context._min_priority);
- ret += stringutil::form (", Max Priority: %d", context._max_priority);
- ret += stringutil::form (", Other Penalties: %d", context._other_penalties);
- if (context._current_channel != 0) {
- ret += ", Current Channel";
- ret += context._current_channel->asString();
- }
- if (context._verifying) ret += ", Verifying";
- if (context._invalid) ret += ", Invalid";
-
- return ret;
-}
-
-
-ostream &
-ResolverContext::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverContext & ResolverContext)
-{
- return os << ResolverContext.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverContext::ResolverContext (ResolverContextPtr parent)
- : _parent (parent)
- , _refs (0)
- , _world (NULL)
- , _last_checked_resItem (NULL)
- , _last_checked_status (RESOLVABLE_STATUS_UNKNOWN)
- , _download_size (0)
- , _install_size (0)
- , _total_priority (0)
- , _min_priority (0)
- , _max_priority (0)
- , _other_penalties (0)
- , _current_channel (NULL)
- , _verifying (false)
- , _invalid (false)
-{
- if (parent != NULL) {
- _world = parent->_world;
- _download_size = parent->_download_size;
- _install_size = parent->_install_size;
- _total_priority = parent->_total_priority;
- _max_priority = parent->_max_priority;
- _min_priority = parent->_min_priority;
- _other_penalties = parent->_other_penalties;
- _verifying = parent->_verifying;
- } else {
- _min_priority = MAXINT;
- }
-}
-
-
-ResolverContext::~ResolverContext()
-{
-}
-
-//---------------------------------------------------------------------------
-
-WorldPtr
-ResolverContext::world (void) const
-{
- if (_world == NULL) {
- return World::globalWorld();
- }
- return _world;
-}
-
-
-void
-ResolverContext::setStatus (constResItemPtr resItem, ResItemStatus status)
-{
- if (_invalid) return;
-
- ResItemStatus old_status = getStatus (resItem);
-
- if (status != old_status) {
- _status[resItem] = status;
- }
-
- // Update our cache if we changed the status of the last checked resItem.
-
- if (_last_checked_resItem == resItem)
- _last_checked_status = status;
-}
-
-
-ResItemStatus
-ResolverContext::getStatus (constResItemPtr resItem)
-{
- ResItemStatus status = RESOLVABLE_STATUS_UNKNOWN;
-
- // We often end up getting the status of the same resItem several times
- // in a row. By caching the status of the last checked resItem, we can
- // in practice eliminate the need for any hash table lookups in about
- // 50% of our calls to get_status.
-
- if (resItem == _last_checked_resItem)
- {
- return _last_checked_status;
- }
-
- ResolverContextPtr context = this;
-
- while (status == RESOLVABLE_STATUS_UNKNOWN
- && context != NULL) {
- StatusTable::const_iterator pos = context->_status.find (resItem);
- if (pos != context->_status.end()) {
- status = (*pos).second;
- }
- context = context->_parent;
- }
-
- if (status == RESOLVABLE_STATUS_UNKNOWN) {
- status = resItem->isInstalled() ? RESOLVABLE_STATUS_INSTALLED : RESOLVABLE_STATUS_UNINSTALLED;
- }
-
- _last_checked_resItem = resItem;
- _last_checked_status = status;
-
- return status;
-}
-
-
-bool
-ResolverContext::installResItem (constResItemPtr resItem, bool is_soft, int other_penalty)
-{
- ResItemStatus status, new_status;
- int priority;
- std::string msg;
-
- status = getStatus (resItem);
- if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::installResItem(<%s>%s)\n", this, ResolverContext::toString(status).c_str(), resItem->asString().c_str());
-
- if (resItem_status_is_to_be_uninstalled (status)
- && status != RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
- msg = string ("Can't install ") + ((constSpecPtr)resItem)->asString() + " since it is already marked as needing to be uninstalled";
-
- addErrorString (resItem, msg);
- return false;
- }
-
- if (resItem_status_is_to_be_installed (status)) {
- return true;
- }
-
- if (isParallelInstall (resItem)) {
- msg = string ("Can't install ") + ((constSpecPtr)resItem)->asString() + ", since a resolvable of the same name is already marked as needing to be installed";
- addErrorString (resItem, msg);
- return false;
- }
-
- if (is_soft)
- new_status = RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT;
- else if (status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK)
- new_status = RESOLVABLE_STATUS_INSTALLED;
- else
- new_status = RESOLVABLE_STATUS_TO_BE_INSTALLED;
-
- setStatus (resItem, new_status);
-
- if (status == RESOLVABLE_STATUS_UNINSTALLED) {
- /* FIXME: Incomplete */
- _download_size += resItem->fileSize();
- _install_size += resItem->installedSize();
-
- if (resItem->local())
- priority = 0;
- else {
- priority = getChannelPriority (resItem->channel ());
- }
-
- if (priority < _min_priority) _min_priority = priority;
- if (priority > _max_priority) _max_priority = priority;
-
- _other_penalties += other_penalty;
-
- }
-
- return true;
-}
-
-
-bool
-ResolverContext::upgradeResItem (constResItemPtr resItem, constResItemPtr old_resItem, bool is_soft, int other_penalty)
-{
- ResItemStatus status;
- int priority;
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::upgradeResItem(%s upgrades %s)\n", this, resItem->asString().c_str(), old_resItem->asString().c_str());
-
- status = getStatus (resItem);
-
- if (resItem_status_is_to_be_uninstalled (status))
- return false;
-
- if (resItem_status_is_to_be_installed (status))
- return true;
-
- setStatus (resItem, is_soft ? RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT : RESOLVABLE_STATUS_TO_BE_INSTALLED);
-
- if (status == RESOLVABLE_STATUS_UNINSTALLED) {
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(ResolverContext);
+
+ //---------------------------------------------------------------------------
+
+ string
+ ResolverContext::toString (const ResItemStatus & status)
+ {
+ string ret;
+ switch (status) {
+ case RESOLVABLE_STATUS_UNKNOWN: ret = "unknown"; break;
+ case RESOLVABLE_STATUS_INSTALLED: ret = "installed"; break;
+ case RESOLVABLE_STATUS_UNINSTALLED: ret = "uninstalled"; break;
+ case RESOLVABLE_STATUS_TO_BE_INSTALLED: ret = "to be installed"; break;
+ case RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT: ret = "to be installed (soft)"; break;
+ case RESOLVABLE_STATUS_TO_BE_UNINSTALLED: ret = "to be uninstalled"; break;
+ case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE: ret = "to be uninstalled due to obsolete"; break;
+ case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK: ret = "to be uninstalled due to unlink"; break;
+ default: ret = "Huh ?"; break;
+ }
+
+ return ret;
+ }
+
+ //---------------------------------------------------------------------------
+
+ string
+ ResolverContext::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverContext::toString ( const ResolverContext & context )
+ {
+ string ret;
+ if (context._parent != NULL) {
+ ret += "Parent: [";
+ ret += stringutil::form("<@%p> ", (const void *)(context._parent));
+ ret += context._parent->asString();
+ ret += "],\n\t";
+ }
+ ret += stringutil::form ("Download Size: %lld", context._download_size);
+ ret += stringutil::form (", Install Size: %lld", context._install_size);
+ ret += stringutil::form (", Total Priority: %d", context._total_priority);
+ ret += stringutil::form (", Min Priority: %d", context._min_priority);
+ ret += stringutil::form (", Max Priority: %d", context._max_priority);
+ ret += stringutil::form (", Other Penalties: %d", context._other_penalties);
+ if (context._current_channel != 0) {
+ ret += ", Current Channel";
+ ret += context._current_channel->asString();
+ }
+ if (context._verifying) ret += ", Verifying";
+ if (context._invalid) ret += ", Invalid";
+
+ return ret;
+ }
+
+
+ ostream &
+ ResolverContext::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverContext & ResolverContext)
+ {
+ return os << ResolverContext.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverContext::ResolverContext (ResolverContextPtr parent)
+ : _parent (parent)
+ , _refs (0)
+ , _world (NULL)
+ , _last_checked_resItem (NULL)
+ , _last_checked_status (RESOLVABLE_STATUS_UNKNOWN)
+ , _download_size (0)
+ , _install_size (0)
+ , _total_priority (0)
+ , _min_priority (0)
+ , _max_priority (0)
+ , _other_penalties (0)
+ , _current_channel (NULL)
+ , _verifying (false)
+ , _invalid (false)
+ {
+ if (parent != NULL) {
+ _world = parent->_world;
+ _download_size = parent->_download_size;
+ _install_size = parent->_install_size;
+ _total_priority = parent->_total_priority;
+ _max_priority = parent->_max_priority;
+ _min_priority = parent->_min_priority;
+ _other_penalties = parent->_other_penalties;
+ _verifying = parent->_verifying;
+ } else {
+ _min_priority = MAXINT;
+ }
+ }
+
+
+ ResolverContext::~ResolverContext()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ WorldPtr
+ ResolverContext::world (void) const
+ {
+ if (_world == NULL) {
+ return World::globalWorld();
+ }
+ return _world;
+ }
+
+
+ void
+ ResolverContext::setStatus (constResItemPtr resItem, ResItemStatus status)
+ {
+ if (_invalid) return;
+
+ ResItemStatus old_status = getStatus (resItem);
+
+ if (status != old_status) {
+ _status[resItem] = status;
+ }
+
+ // Update our cache if we changed the status of the last checked resItem.
+
+ if (_last_checked_resItem == resItem)
+ _last_checked_status = status;
+ }
+
+
+ ResItemStatus
+ ResolverContext::getStatus (constResItemPtr resItem)
+ {
+ ResItemStatus status = RESOLVABLE_STATUS_UNKNOWN;
+
+ // We often end up getting the status of the same resItem several times
+ // in a row. By caching the status of the last checked resItem, we can
+ // in practice eliminate the need for any hash table lookups in about
+ // 50% of our calls to get_status.
+
+ if (resItem == _last_checked_resItem)
+ {
+ return _last_checked_status;
+ }
+
+ ResolverContextPtr context = this;
+
+ while (status == RESOLVABLE_STATUS_UNKNOWN
+ && context != NULL) {
+ StatusTable::const_iterator pos = context->_status.find (resItem);
+ if (pos != context->_status.end()) {
+ status = (*pos).second;
+ }
+ context = context->_parent;
+ }
+
+ if (status == RESOLVABLE_STATUS_UNKNOWN) {
+ status = resItem->isInstalled() ? RESOLVABLE_STATUS_INSTALLED : RESOLVABLE_STATUS_UNINSTALLED;
+ }
+
+ _last_checked_resItem = resItem;
+ _last_checked_status = status;
+
+ return status;
+ }
+
+
+ bool
+ ResolverContext::installResItem (constResItemPtr resItem, bool is_soft, int other_penalty)
+ {
+ ResItemStatus status, new_status;
+ int priority;
+ std::string msg;
+
+ status = getStatus (resItem);
+ if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::installResItem(<%s>%s)\n", this, ResolverContext::toString(status).c_str(), resItem->asString().c_str());
+
+ if (resItem_status_is_to_be_uninstalled (status)
+ && status != RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
+ msg = string ("Can't install ") + ((constSpecPtr)resItem)->asString() + " since it is already marked as needing to be uninstalled";
+
+ addErrorString (resItem, msg);
+ return false;
+ }
+
+ if (resItem_status_is_to_be_installed (status)) {
+ return true;
+ }
+
+ if (isParallelInstall (resItem)) {
+ msg = string ("Can't install ") + ((constSpecPtr)resItem)->asString() + ", since a resolvable of the same name is already marked as needing to be installed";
+ addErrorString (resItem, msg);
+ return false;
+ }
+
+ if (is_soft)
+ new_status = RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT;
+ else if (status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK)
+ new_status = RESOLVABLE_STATUS_INSTALLED;
+ else
+ new_status = RESOLVABLE_STATUS_TO_BE_INSTALLED;
+
+ setStatus (resItem, new_status);
+
+ if (status == RESOLVABLE_STATUS_UNINSTALLED) {
+ /* FIXME: Incomplete */
+ _download_size += resItem->fileSize();
+ _install_size += resItem->installedSize();
+
+ if (resItem->local())
+ priority = 0;
+ else {
+ priority = getChannelPriority (resItem->channel ());
+ }
+
+ if (priority < _min_priority) _min_priority = priority;
+ if (priority > _max_priority) _max_priority = priority;
+
+ _other_penalties += other_penalty;
+
+ }
+
+ return true;
+ }
+
+
+ bool
+ ResolverContext::upgradeResItem (constResItemPtr resItem, constResItemPtr old_resItem, bool is_soft, int other_penalty)
+ {
+ ResItemStatus status;
+ int priority;
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::upgradeResItem(%s upgrades %s)\n", this, resItem->asString().c_str(), old_resItem->asString().c_str());
+
+ status = getStatus (resItem);
+
+ if (resItem_status_is_to_be_uninstalled (status))
+ return false;
+
+ if (resItem_status_is_to_be_installed (status))
+ return true;
+
+ setStatus (resItem, is_soft ? RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT : RESOLVABLE_STATUS_TO_BE_INSTALLED);
+
+ if (status == RESOLVABLE_STATUS_UNINSTALLED) {
+
+ _download_size += resItem->fileSize();
+
+ // FIXME: Incomplete
+ // We should change installed_size to reflect the difference in
+ // installed size between the old and new versions.
+
+ if (resItem->local())
+ priority = 0;
+ else {
+ priority = getChannelPriority (resItem->channel());
+ }
+
+ if (priority < _min_priority) _min_priority = priority;
+ if (priority > _max_priority) _max_priority = priority;
+
+ _other_penalties += other_penalty;
+ }
+
+ return true;
+ }
+
+
+ bool
+ ResolverContext::uninstallResItem (constResItemPtr resItem, bool part_of_upgrade, bool due_to_obsolete, bool due_to_unlink)
+ {
+ ResItemStatus status, new_status;
+ std::string msg;
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::uninstallResItem(%s %s %s %s)\n", this, resItem->asString().c_str(), part_of_upgrade ? "part_of_upgrade" : "", due_to_obsolete ? "due_to_obsolete": "", due_to_unlink ? "due_to_unlink" : "");
+
+ assert (! (due_to_obsolete && due_to_unlink));
+
+ status = getStatus (resItem);
+
+ if (status == RESOLVABLE_STATUS_TO_BE_INSTALLED) {
+ msg = ((constSpecPtr)resItem)->asString() + " is scheduled to be installed, but this is not possible because of dependency problems.";
+ addErrorString (resItem, msg);
+ return false;
+ }
+
+ if (resItem_status_is_to_be_uninstalled (status)
+ && status != RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
+ return true;
+ }
+
+ if (status == RESOLVABLE_STATUS_UNINSTALLED
+ || status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
+ msg = string ("Marking resolvable ") + ((constSpecPtr)resItem)->asString() + " as uninstallable";
+ addInfoString (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+ }
+
+
+ if (due_to_obsolete) new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE;
+ else if (due_to_unlink) new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK;
+ else new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED;
+
+ setStatus (resItem, new_status);
+
+ if (status == RESOLVABLE_STATUS_INSTALLED) {
+ /* FIXME: incomplete */
+ }
+
+ return true;
+ }
+
+
+ bool
+ ResolverContext::resItemIsPresent (constResItemPtr resItem)
+ {
+ ResItemStatus status;
+
+ status = getStatus (resItem);
+ //fprintf (stderr, "ResolverContext::resItemIsPresent(<%s>%s)\n", ResolverContext::toString(status).c_str(), resItem->asString().c_str());
+ if (status == RESOLVABLE_STATUS_UNKNOWN)
+ return false;
+
+ return (status == RESOLVABLE_STATUS_INSTALLED) || resItem_status_is_to_be_installed (status);
+ }
+
+
+ bool
+ ResolverContext::resItemIsAbsent (constResItemPtr resItem)
+ {
+ ResItemStatus status;
+
+ status = getStatus (resItem);
+ if (status == RESOLVABLE_STATUS_UNKNOWN)
+ return false;
+
+ return status == RESOLVABLE_STATUS_UNINSTALLED || resItem_status_is_to_be_uninstalled (status);
+ }
+
+
+ //---------------------------------------------------------------------------
+ // marked
+
+ void
+ ResolverContext::foreachMarkedResItem (MarkedResItemFn fn, void *data) const
+ {
+ constResolverContextPtr context = this;
+ while (context) {
+ for (StatusTable::const_iterator iter = context->_status.begin(); iter != context->_status.end(); iter++) {
+ fn (iter->first, iter->second, data);
+ }
+ context = context->_parent;
+ }
+ }
+
+
+ //---------------------------------------------------------------------------
+ // collect
+
+ static void
+ marked_resItem_collector (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ CResItemList *rl = (CResItemList *)data;
+ rl->push_back (resItem);
+ }
+
+
+ CResItemList
+ ResolverContext::getMarkedResItems (void) const
+ {
+ CResItemList rl;
+
+ foreachMarkedResItem (marked_resItem_collector, &rl);
+
+ return rl;
+ }
+
+ //---------------------------------------------------------------------------
+ // install
+
+ typedef struct {
+ WorldPtr world;
+ MarkedResItemFn fn;
+ CResItemList *rl;
+ int count;
+ } InstallInfo;
+
+ static void
+ install_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ InstallInfo *info = (InstallInfo *)data;
+ if (resItem_status_is_to_be_installed (status)
+ && ! resItem->isInstalled ()
+ && info->world->findInstalledResItem (resItem) == NULL) {
+
+ if (info->fn) info->fn (resItem, status, info->rl);
+ ++info->count;
+ }
+ }
+
+
+ int
+ ResolverContext::foreachInstall (MarkedResItemFn fn, void *data) const
+ {
+ CResItemList *rl = (CResItemList *)data;
+ InstallInfo info = { world(), fn, rl, 0 };
+
+ foreachMarkedResItem (install_pkg_cb, (void *)&info);
+
+ return info.count;
+ }
+
+
+ static void
+ context_resItem_collector (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ CResItemList *rl = (CResItemList *)data;
+ if (resItem_status_is_to_be_installed (status)
+ || (resItem_status_is_to_be_uninstalled (status) && resItem->isInstalled ())) {
+ rl->push_front (resItem);
+ }
+ }
+
+
+ CResItemList
+ ResolverContext::getInstalls (void) const
+ {
+ CResItemList rl;
+
+ foreachInstall (context_resItem_collector, (void *)&rl);
+
+ return rl;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // upgrade
+
+ typedef struct {
+ WorldPtr world;
+ MarkedResItemPairFn fn;
+ void *data;
+ ResolverContextPtr context;
+ int count;
+ } UpgradeInfo;
+
+ static void
+ upgrade_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ UpgradeInfo *info = (UpgradeInfo *)data;
+
+ constResItemPtr to_be_upgraded;
+ ResItemStatus tbu_status;
+
+ if (resItem_status_is_to_be_installed (status)
+ && ! resItem->isInstalled ()) {
+
+ to_be_upgraded = info->world->findInstalledResItem (resItem);
+ if (to_be_upgraded) {
+ tbu_status = info->context->getStatus (to_be_upgraded);
+ if (info->fn) {
+ info->fn (resItem, status, to_be_upgraded, tbu_status, info->data);
+ }
+ ++info->count;
+ }
+ }
+ }
+
+
+ int
+ ResolverContext::foreachUpgrade (MarkedResItemPairFn fn, void *data)
+ {
+ UpgradeInfo info = { world(), fn, data, this, 0 };
+
+ foreachMarkedResItem (upgrade_pkg_cb, (void *)&info);
+
+ return info.count;
+ }
+
+
+ static void
+ pair_resItem_collector (constResItemPtr resItem, ResItemStatus status, constResItemPtr old, ResItemStatus old_status, void *data)
+ {
+ CResItemList *rl = (CResItemList *)data;
+ rl->push_back (resItem);
+ }
+
+
+ CResItemList
+ ResolverContext::getUpgrades (void)
+ {
+ CResItemList rl;
+
+ foreachUpgrade (pair_resItem_collector, (void *)&rl);
+
+ return rl;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // uninstall
+
+ typedef std::map<std::string,constResItemPtr> UpgradeTable;
+
+ typedef struct {
+ MarkedResItemFn fn;
+ CResItemList *rl;
+ UpgradeTable upgrade_hash;
+ int count;
+ } UninstallInfo;
+
+ static void
+ uninstall_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ UninstallInfo *info = (UninstallInfo *)data;
+
+ UpgradeTable::const_iterator pos = info->upgrade_hash.find(resItem->name());
+
+ if (resItem_status_is_to_be_uninstalled (status)
+ && pos == info->upgrade_hash.end()) {
+ if (info->fn)
+ info->fn (resItem, status, info->rl);
+ ++info->count;
+ }
+ }
+
+ static void
+ build_upgrade_hash_cb (constResItemPtr resItem_add, ResItemStatus status_add, constResItemPtr resItem_del, ResItemStatus status_del, void *data)
+ {
+ UpgradeTable *upgrade_hash = (UpgradeTable *)data;
+ (*upgrade_hash)[resItem_del->name()] = resItem_del;
+ }
+
+
+ int
+ ResolverContext::foreachUninstall (MarkedResItemFn fn, void *data)
+ {
+ UninstallInfo info; // inits upgrade_hash
+
+ info.fn = fn;
+ info.rl = (CResItemList *)data;
+ info.count = 0;
+
+ foreachUpgrade (build_upgrade_hash_cb, (void *)&(info.upgrade_hash));
+ foreachMarkedResItem (uninstall_pkg_cb, (void *)&info);
+
+ return info.count;
+ }
+
+
+ CResItemList
+ ResolverContext::getUninstalls (void)
+ {
+ CResItemList rl;
+
+ foreachUninstall (context_resItem_collector, (void *)&rl);
+
+ return rl;
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ static void
+ install_count_cb (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ int *count = (int *)data;
+ if (! resItem->isInstalled ()) {
+ ++*count;
+ }
+ }
+
+ int
+ ResolverContext::installCount (void) const
+ {
+ int count = 0;
+
+ foreachInstall (install_count_cb, (void *)&count);
+
+ return count;
+ }
+
+
+ static void
+ uninstall_count_cb (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ int *count = (int *)data;
+ if (resItem->isInstalled ()) {
+ ++*count;
+ }
+ }
+
+
+ int
+ ResolverContext::uninstallCount (void)
+ {
+ int count = 0;
+
+ foreachUninstall (uninstall_count_cb, (void *)&count);
+
+ return count;
+ }
+
+
+ int
+ ResolverContext::upgradeCount (void)
+ {
+ return foreachUpgrade ((MarkedResItemPairFn)NULL, (void *)NULL);
+ }
+
+
+ //---------------------------------------------------------------------------
+ // info
+
+ void
+ ResolverContext::addInfo (ResolverInfoPtr info)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::addInfo(%s)\n", this, info->asString().c_str());
+ _log.push_back (info);
+
+ // _propagated_importance = false;
+
+ if (info->error ()) {
+
+ if (! _invalid) {
+ ResolverInfoPtr info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, "Marking this resolution attempt as invalid.");
+ info->flagAsError ();
+ _log.push_back (info);
+ }
+
+ _invalid = true;
+ }
+ }
+
+
+ void
+ ResolverContext::addInfoString (constResItemPtr resItem, int priority, string msg)
+ {
+ // if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext::addInfoString(%s) %s\n", resItem ? resItem->asString().c_str() : "", msg.c_str());
+ ResolverInfoPtr info = new ResolverInfoMisc (resItem, priority, msg);
+ addInfo (info);
+ }
+
+
+ void
+ ResolverContext::addErrorString (constResItemPtr resItem, string msg)
+ {
+ ResolverInfoPtr info = new ResolverInfoMisc (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+ info->flagAsError ();
+ addInfo (info);
+ }
+
+
+ //---------------------------------------------------------------------------
+ // foreach info
+
+ // We call a resItem mentioned by an error info an "error-resItem".
+ // We call a resItem mentioned by an important info an "important-resItem".
+ //
+ // The rules:
+ // (1) An info item that mentions an error-resItem is important.
+ // (2) An info item is about an important-resItem is important.
+
+ static void
+ mark_important_info (InfoList & il)
+ {
+ CResItemList error_list; // FIXME, a map is faster
+
+ bool did_something;
+ int pass_num = 1;
+
+ /* First of all, store all error-resItems in a list. */
+
+ for (InfoList::iterator iter = il.begin(); iter != il.end(); iter++) {
+ if ((*iter) != NULL // list items might be set to NULL
+ && (*iter)->error ()) {
+ constResItemPtr resItem = (*iter)->resItem();
+ if (resItem != NULL) {
+ CResItemList::iterator pos;
+ for (pos = error_list.begin(); pos != error_list.end(); pos++) {
+ if (*pos == resItem)
+ break;
+ }
+ if (pos == error_list.end()) {
+ error_list.push_front (resItem);
+ }
+ }
+
+ CResItemList resItems;
+
+ constResolverInfoContainerPtr c = *iter; // check if it really is a container
+ if (c != NULL) resItems = c->resItems();
+
+ for (CResItemList::iterator res_iter = resItems.begin(); res_iter != resItems.end(); res_iter++) {
+ CResItemList::iterator pos;
+ for (pos = error_list.begin(); pos != error_list.end(); pos++) {
+ if (*pos == *iter)
+ break;
+ }
+ if (pos == error_list.end()) {
+ error_list.push_front (*res_iter);
+ }
+ }
+ }
+ }
+
+ CResItemList important_list; // FIXME, hash is faster
+
+ do {
+ ++pass_num;
+ assert (pass_num < 10000);
+
+ did_something = false;
+
+ for (InfoList::iterator iter = il.begin(); iter != il.end(); iter++) {
+ if ((*iter) != NULL // list items might be set to NULL
+ && (*iter)->important ()) {
+ bool should_be_important = false;
+
+ for (CResItemList::const_iterator res_iter = error_list.begin(); res_iter != error_list.end() && ! should_be_important; res_iter++) {
+ constResolverInfoContainerPtr c = *iter;
+ if (c != NULL // check if it really is a container
+ && c->mentions (*res_iter)) {
+ should_be_important = true;
+ }
+ }
+
+ for (CResItemList::const_iterator res_iter = important_list.begin(); res_iter != important_list.end() && ! should_be_important; res_iter++) {
+ if ((*iter)->isAbout (*res_iter)) {
+ should_be_important = true;
+ break;
+ }
+ }
+
+ if (should_be_important) {
+ did_something = true;
+ (*iter)->flagAsImportant ();
+ CResItemList resItems;
+ constResolverInfoContainerPtr c = *iter; // check if it really is a container
+ if (c != NULL) resItems = c->resItems();
+ for (CResItemList::iterator res_iter = resItems.begin(); res_iter != resItems.end(); res_iter++) {
+ CResItemList::iterator pos;
+ for (pos = important_list.begin(); pos != important_list.end(); pos++) {
+ if (*pos == *res_iter)
+ break;
+ }
+ if (pos == important_list.end()) {
+ important_list.push_front (*res_iter);
+ }
+ }
+ }
+ }
+ }
+
+ } while (did_something);
+
+ }
+
+
+ void
+ ResolverContext::foreachInfo (ResItemPtr resItem, int priority, ResolverInfoFn fn, void *data)
+ {
+ InfoList info_list;
+
+ ResolverContextPtr context = this;
+
+
+ // Assemble a list of copies of all of the info objects
+ while (context != NULL) {
+ for (InfoList::iterator iter = context->_log.begin(); iter != context->_log.end(); iter++) {
+ if ((resItem == NULL || (*iter)->resItem() == resItem)
+ && (*iter)->priority() >= priority) {
+ info_list.push_back ((*iter)->copy());
+ }
+ }
+ context = context->_parent;
+ }
+ #if 0
+ // Merge info objects
+ for (InfoList::iterator iter = info_list.begin(); iter != info_list.end(); iter++) {
+
+ ResolverInfoPtr info1 = (*iter);
+ InfoList::iterator subiter = iter;
+ if (info1 != NULL) {
+ for (subiter++; subiter != info_list.end(); subiter++) {
+ ResolverInfoPtr info2 = *subiter;
+ if (info2 && info1->merge (info2)) {
+ *subiter = NULL;
+ }
+ }
+ }
+ }
+ #endif
+ mark_important_info (info_list);
+
+ // Walk across the list of info objects and invoke our callback
+
+ for (InfoList::iterator iter = info_list.begin(); iter != info_list.end(); iter++) {
+ if (*iter != NULL) {
+ fn (*iter, data);
+ }
+ }
+ }
+
+
+
+ static void
+ get_info_foreach_cb (ResolverInfoPtr info, void *data)
+ {
+ InfoList *il = (InfoList *)data;
+
+ if (info->important ()) {
+ il->push_back (info);
+ }
+ }
+
+
+
+ InfoList
+ ResolverContext::getInfo (void)
+ {
+ InfoList il;
+ foreachInfo (NULL, -1, get_info_foreach_cb, (void *)&il);
+ return il;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // spew
+
+ static void
+ spew_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *unused)
+ {
+ printf (" %s (%s)\n", resItem->asString().c_str(), ResolverContext::toString(status).c_str());
+ }
+
+
+ void
+ spew_pkg2_cb (constResItemPtr resItem1, ResItemStatus status1, constResItemPtr resItem2, ResItemStatus status2, void *unused)
+ {
+ const char *s1, *s2;
+
+ s1 = resItem1->asString().c_str();
+ s2 = resItem2->asString().c_str();
+
+ printf (" %s (%s) => %s (%s)\n", s2, ResolverContext::toString(status2).c_str(), s1, ResolverContext::toString(status1).c_str());
+ }
+
+
+ void
+ ResolverContext::spew (void)
+ {
+ printf ("TO INSTALL:\n");
+ foreachInstall (spew_pkg_cb, NULL);
+ printf ("\n");
+
+ printf ("TO REMOVE:\n");
+ foreachUninstall (spew_pkg_cb, NULL);
+ printf ("\n");
+
+ printf ("TO UPGRADE:\n");
+ foreachUpgrade (spew_pkg2_cb, NULL);
+ printf ("\n");
+ }
+
+
+ static void
+ spew_info_cb (ResolverInfoPtr info, void *unused)
+ {
+ const char *msg = info->asString().c_str();
+ if (info->error ()) printf ("[ERROR] ");
+ else if (info->important()) printf ("[>>>>>] ");
+ printf ("%s\n", msg);
+ }
+
+
+ void
+ ResolverContext::spewInfo (void)
+ {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::spewInfo()\n", this);
+ foreachInfo (NULL, -1, spew_info_cb, NULL);
+ }
+
+ //---------------------------------------------------------------------------
+ // requirements
- _download_size += resItem->fileSize();
-
- // FIXME: Incomplete
- // We should change installed_size to reflect the difference in
- // installed size between the old and new versions.
-
- if (resItem->local())
- priority = 0;
- else {
- priority = getChannelPriority (resItem->channel());
- }
-
- if (priority < _min_priority) _min_priority = priority;
- if (priority > _max_priority) _max_priority = priority;
-
- _other_penalties += other_penalty;
- }
-
- return true;
-}
-
-
-bool
-ResolverContext::uninstallResItem (constResItemPtr resItem, bool part_of_upgrade, bool due_to_obsolete, bool due_to_unlink)
-{
- ResItemStatus status, new_status;
- std::string msg;
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::uninstallResItem(%s %s %s %s)\n", this, resItem->asString().c_str(), part_of_upgrade ? "part_of_upgrade" : "", due_to_obsolete ? "due_to_obsolete": "", due_to_unlink ? "due_to_unlink" : "");
-
- assert (! (due_to_obsolete && due_to_unlink));
-
- status = getStatus (resItem);
-
- if (status == RESOLVABLE_STATUS_TO_BE_INSTALLED) {
- msg = ((constSpecPtr)resItem)->asString() + " is scheduled to be installed, but this is not possible because of dependency problems.";
- addErrorString (resItem, msg);
- return false;
- }
-
- if (resItem_status_is_to_be_uninstalled (status)
- && status != RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
- return true;
- }
-
- if (status == RESOLVABLE_STATUS_UNINSTALLED
- || status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
- msg = string ("Marking resolvable ") + ((constSpecPtr)resItem)->asString() + " as uninstallable";
- addInfoString (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
- }
-
-
- if (due_to_obsolete) new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE;
- else if (due_to_unlink) new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK;
- else new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED;
-
- setStatus (resItem, new_status);
-
- if (status == RESOLVABLE_STATUS_INSTALLED) {
- /* FIXME: incomplete */
- }
-
- return true;
-}
-
-
-bool
-ResolverContext::resItemIsPresent (constResItemPtr resItem)
-{
- ResItemStatus status;
-
- status = getStatus (resItem);
-//fprintf (stderr, "ResolverContext::resItemIsPresent(<%s>%s)\n", ResolverContext::toString(status).c_str(), resItem->asString().c_str());
- if (status == RESOLVABLE_STATUS_UNKNOWN)
- return false;
-
- return (status == RESOLVABLE_STATUS_INSTALLED) || resItem_status_is_to_be_installed (status);
-}
-
-
-bool
-ResolverContext::resItemIsAbsent (constResItemPtr resItem)
-{
- ResItemStatus status;
-
- status = getStatus (resItem);
- if (status == RESOLVABLE_STATUS_UNKNOWN)
- return false;
-
- return status == RESOLVABLE_STATUS_UNINSTALLED || resItem_status_is_to_be_uninstalled (status);
-}
-
-
-//---------------------------------------------------------------------------
-// marked
-
-void
-ResolverContext::foreachMarkedResItem (MarkedResItemFn fn, void *data) const
-{
- constResolverContextPtr context = this;
- while (context) {
- for (StatusTable::const_iterator iter = context->_status.begin(); iter != context->_status.end(); iter++) {
- fn (iter->first, iter->second, data);
- }
- context = context->_parent;
- }
-}
-
-
-//---------------------------------------------------------------------------
-// collect
-
-static void
-marked_resItem_collector (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- CResItemList *rl = (CResItemList *)data;
- rl->push_back (resItem);
-}
-
-
-CResItemList
-ResolverContext::getMarkedResItems (void) const
-{
- CResItemList rl;
-
- foreachMarkedResItem (marked_resItem_collector, &rl);
-
- return rl;
-}
-
-//---------------------------------------------------------------------------
-// install
-
-typedef struct {
- WorldPtr world;
- MarkedResItemFn fn;
- CResItemList *rl;
- int count;
-} InstallInfo;
-
-static void
-install_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- InstallInfo *info = (InstallInfo *)data;
- if (resItem_status_is_to_be_installed (status)
- && ! resItem->isInstalled ()
- && info->world->findInstalledResItem (resItem) == NULL) {
-
- if (info->fn) info->fn (resItem, status, info->rl);
- ++info->count;
- }
-}
-
-
-int
-ResolverContext::foreachInstall (MarkedResItemFn fn, void *data) const
-{
- CResItemList *rl = (CResItemList *)data;
- InstallInfo info = { world(), fn, rl, 0 };
-
- foreachMarkedResItem (install_pkg_cb, (void *)&info);
-
- return info.count;
-}
-
-
-static void
-context_resItem_collector (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- CResItemList *rl = (CResItemList *)data;
- if (resItem_status_is_to_be_installed (status)
- || (resItem_status_is_to_be_uninstalled (status) && resItem->isInstalled ())) {
- rl->push_front (resItem);
- }
-}
-
-
-CResItemList
-ResolverContext::getInstalls (void) const
-{
- CResItemList rl;
-
- foreachInstall (context_resItem_collector, (void *)&rl);
-
- return rl;
-}
-
-
-//---------------------------------------------------------------------------
-// upgrade
-
-typedef struct {
- WorldPtr world;
- MarkedResItemPairFn fn;
- void *data;
- ResolverContextPtr context;
- int count;
-} UpgradeInfo;
-
-static void
-upgrade_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- UpgradeInfo *info = (UpgradeInfo *)data;
-
- constResItemPtr to_be_upgraded;
- ResItemStatus tbu_status;
-
- if (resItem_status_is_to_be_installed (status)
- && ! resItem->isInstalled ()) {
-
- to_be_upgraded = info->world->findInstalledResItem (resItem);
- if (to_be_upgraded) {
- tbu_status = info->context->getStatus (to_be_upgraded);
- if (info->fn) {
- info->fn (resItem, status, to_be_upgraded, tbu_status, info->data);
- }
- ++info->count;
- }
- }
-}
-
-
-int
-ResolverContext::foreachUpgrade (MarkedResItemPairFn fn, void *data)
-{
- UpgradeInfo info = { world(), fn, data, this, 0 };
-
- foreachMarkedResItem (upgrade_pkg_cb, (void *)&info);
-
- return info.count;
-}
-
-
-static void
-pair_resItem_collector (constResItemPtr resItem, ResItemStatus status, constResItemPtr old, ResItemStatus old_status, void *data)
-{
- CResItemList *rl = (CResItemList *)data;
- rl->push_back (resItem);
-}
-
-
-CResItemList
-ResolverContext::getUpgrades (void)
-{
- CResItemList rl;
-
- foreachUpgrade (pair_resItem_collector, (void *)&rl);
-
- return rl;
-}
-
-
-//---------------------------------------------------------------------------
-// uninstall
-
-typedef std::map<std::string,constResItemPtr> UpgradeTable;
-
-typedef struct {
- MarkedResItemFn fn;
- CResItemList *rl;
- UpgradeTable upgrade_hash;
- int count;
-} UninstallInfo;
-
-static void
-uninstall_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- UninstallInfo *info = (UninstallInfo *)data;
-
- UpgradeTable::const_iterator pos = info->upgrade_hash.find(resItem->name());
-
- if (resItem_status_is_to_be_uninstalled (status)
- && pos == info->upgrade_hash.end()) {
- if (info->fn)
- info->fn (resItem, status, info->rl);
- ++info->count;
- }
-}
-
-static void
-build_upgrade_hash_cb (constResItemPtr resItem_add, ResItemStatus status_add, constResItemPtr resItem_del, ResItemStatus status_del, void *data)
-{
- UpgradeTable *upgrade_hash = (UpgradeTable *)data;
- (*upgrade_hash)[resItem_del->name()] = resItem_del;
-}
-
-
-int
-ResolverContext::foreachUninstall (MarkedResItemFn fn, void *data)
-{
- UninstallInfo info; // inits upgrade_hash
-
- info.fn = fn;
- info.rl = (CResItemList *)data;
- info.count = 0;
-
- foreachUpgrade (build_upgrade_hash_cb, (void *)&(info.upgrade_hash));
- foreachMarkedResItem (uninstall_pkg_cb, (void *)&info);
-
- return info.count;
-}
-
-
-CResItemList
-ResolverContext::getUninstalls (void)
-{
- CResItemList rl;
-
- foreachUninstall (context_resItem_collector, (void *)&rl);
-
- return rl;
-}
-
-
-//---------------------------------------------------------------------------
-
-static void
-install_count_cb (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- int *count = (int *)data;
- if (! resItem->isInstalled ()) {
- ++*count;
- }
-}
-
-int
-ResolverContext::installCount (void) const
-{
- int count = 0;
-
- foreachInstall (install_count_cb, (void *)&count);
-
- return count;
-}
-
-
-static void
-uninstall_count_cb (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- int *count = (int *)data;
- if (resItem->isInstalled ()) {
- ++*count;
- }
-}
-
-
-int
-ResolverContext::uninstallCount (void)
-{
- int count = 0;
-
- foreachUninstall (uninstall_count_cb, (void *)&count);
-
- return count;
-}
-
-
-int
-ResolverContext::upgradeCount (void)
-{
- return foreachUpgrade ((MarkedResItemPairFn)NULL, (void *)NULL);
-}
-
-
-//---------------------------------------------------------------------------
-// info
-
-void
-ResolverContext::addInfo (ResolverInfoPtr info)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::addInfo(%s)\n", this, info->asString().c_str());
- _log.push_back (info);
-
- // _propagated_importance = false;
-
- if (info->error ()) {
-
- if (! _invalid) {
- ResolverInfoPtr info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, "Marking this resolution attempt as invalid.");
- info->flagAsError ();
- _log.push_back (info);
- }
-
- _invalid = true;
- }
-}
-
-
-void
-ResolverContext::addInfoString (constResItemPtr resItem, int priority, string msg)
-{
-// if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext::addInfoString(%s) %s\n", resItem ? resItem->asString().c_str() : "", msg.c_str());
- ResolverInfoPtr info = new ResolverInfoMisc (resItem, priority, msg);
- addInfo (info);
-}
-
-
-void
-ResolverContext::addErrorString (constResItemPtr resItem, string msg)
-{
- ResolverInfoPtr info = new ResolverInfoMisc (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
- info->flagAsError ();
- addInfo (info);
-}
-
-
-//---------------------------------------------------------------------------
-// foreach info
-
-// We call a resItem mentioned by an error info an "error-resItem".
-// We call a resItem mentioned by an important info an "important-resItem".
-//
-// The rules:
-// (1) An info item that mentions an error-resItem is important.
-// (2) An info item is about an important-resItem is important.
-
-static void
-mark_important_info (InfoList & il)
-{
- CResItemList error_list; // FIXME, a map is faster
-
- bool did_something;
- int pass_num = 1;
-
- /* First of all, store all error-resItems in a list. */
-
- for (InfoList::iterator iter = il.begin(); iter != il.end(); iter++) {
- if ((*iter) != NULL // list items might be set to NULL
- && (*iter)->error ()) {
- constResItemPtr resItem = (*iter)->resItem();
- if (resItem != NULL) {
- CResItemList::iterator pos;
- for (pos = error_list.begin(); pos != error_list.end(); pos++) {
- if (*pos == resItem)
- break;
- }
- if (pos == error_list.end()) {
- error_list.push_front (resItem);
- }
- }
-
- CResItemList resItems;
-
- constResolverInfoContainerPtr c = *iter; // check if it really is a container
- if (c != NULL) resItems = c->resItems();
-
- for (CResItemList::iterator res_iter = resItems.begin(); res_iter != resItems.end(); res_iter++) {
- CResItemList::iterator pos;
- for (pos = error_list.begin(); pos != error_list.end(); pos++) {
- if (*pos == *iter)
- break;
- }
- if (pos == error_list.end()) {
- error_list.push_front (*res_iter);
- }
- }
- }
- }
-
- CResItemList important_list; // FIXME, hash is faster
-
- do {
- ++pass_num;
- assert (pass_num < 10000);
-
- did_something = false;
-
- for (InfoList::iterator iter = il.begin(); iter != il.end(); iter++) {
- if ((*iter) != NULL // list items might be set to NULL
- && (*iter)->important ()) {
- bool should_be_important = false;
-
- for (CResItemList::const_iterator res_iter = error_list.begin(); res_iter != error_list.end() && ! should_be_important; res_iter++) {
- constResolverInfoContainerPtr c = *iter;
- if (c != NULL // check if it really is a container
- && c->mentions (*res_iter)) {
- should_be_important = true;
- }
- }
-
- for (CResItemList::const_iterator res_iter = important_list.begin(); res_iter != important_list.end() && ! should_be_important; res_iter++) {
- if ((*iter)->isAbout (*res_iter)) {
- should_be_important = true;
- break;
- }
- }
-
- if (should_be_important) {
- did_something = true;
- (*iter)->flagAsImportant ();
- CResItemList resItems;
- constResolverInfoContainerPtr c = *iter; // check if it really is a container
- if (c != NULL) resItems = c->resItems();
- for (CResItemList::iterator res_iter = resItems.begin(); res_iter != resItems.end(); res_iter++) {
- CResItemList::iterator pos;
- for (pos = important_list.begin(); pos != important_list.end(); pos++) {
- if (*pos == *res_iter)
- break;
- }
- if (pos == important_list.end()) {
- important_list.push_front (*res_iter);
- }
- }
- }
- }
- }
-
- } while (did_something);
-
-}
-
-
-void
-ResolverContext::foreachInfo (ResItemPtr resItem, int priority, ResolverInfoFn fn, void *data)
-{
- InfoList info_list;
-
- ResolverContextPtr context = this;
-
-
- // Assemble a list of copies of all of the info objects
- while (context != NULL) {
- for (InfoList::iterator iter = context->_log.begin(); iter != context->_log.end(); iter++) {
- if ((resItem == NULL || (*iter)->resItem() == resItem)
- && (*iter)->priority() >= priority) {
- info_list.push_back ((*iter)->copy());
- }
- }
- context = context->_parent;
- }
-#if 0
- // Merge info objects
- for (InfoList::iterator iter = info_list.begin(); iter != info_list.end(); iter++) {
-
- ResolverInfoPtr info1 = (*iter);
- InfoList::iterator subiter = iter;
- if (info1 != NULL) {
- for (subiter++; subiter != info_list.end(); subiter++) {
- ResolverInfoPtr info2 = *subiter;
- if (info2 && info1->merge (info2)) {
- *subiter = NULL;
- }
- }
- }
- }
-#endif
- mark_important_info (info_list);
-
- // Walk across the list of info objects and invoke our callback
-
- for (InfoList::iterator iter = info_list.begin(); iter != info_list.end(); iter++) {
- if (*iter != NULL) {
- fn (*iter, data);
- }
- }
-}
-
-
-
-static void
-get_info_foreach_cb (ResolverInfoPtr info, void *data)
-{
- InfoList *il = (InfoList *)data;
-
- if (info->important ()) {
- il->push_back (info);
- }
-}
-
-
-
-InfoList
-ResolverContext::getInfo (void)
-{
- InfoList il;
- foreachInfo (NULL, -1, get_info_foreach_cb, (void *)&il);
- return il;
-}
-
-
-//---------------------------------------------------------------------------
-// spew
-
-static void
-spew_pkg_cb (constResItemPtr resItem, ResItemStatus status, void *unused)
-{
- printf (" %s (%s)\n", resItem->asString().c_str(), ResolverContext::toString(status).c_str());
-}
-
-
-void
-spew_pkg2_cb (constResItemPtr resItem1, ResItemStatus status1, constResItemPtr resItem2, ResItemStatus status2, void *unused)
-{
- const char *s1, *s2;
-
- s1 = resItem1->asString().c_str();
- s2 = resItem2->asString().c_str();
-
- printf (" %s (%s) => %s (%s)\n", s2, ResolverContext::toString(status2).c_str(), s1, ResolverContext::toString(status1).c_str());
-}
-
-
-void
-ResolverContext::spew (void)
-{
- printf ("TO INSTALL:\n");
- foreachInstall (spew_pkg_cb, NULL);
- printf ("\n");
-
- printf ("TO REMOVE:\n");
- foreachUninstall (spew_pkg_cb, NULL);
- printf ("\n");
-
- printf ("TO UPGRADE:\n");
- foreachUpgrade (spew_pkg2_cb, NULL);
- printf ("\n");
-}
-
-
-static void
-spew_info_cb (ResolverInfoPtr info, void *unused)
-{
- const char *msg = info->asString().c_str();
- if (info->error ()) printf ("[ERROR] ");
- else if (info->important()) printf ("[>>>>>] ");
- printf ("%s\n", msg);
-}
-
-
-void
-ResolverContext::spewInfo (void)
-{
- if (getenv ("RC_SPEW")) fprintf (stderr, "ResolverContext[%p]::spewInfo()\n", this);
- foreachInfo (NULL, -1, spew_info_cb, NULL);
-}
-
-//---------------------------------------------------------------------------
-// requirements
-
-typedef struct {
- ResolverContextPtr context;
- constSpecPtr dep;
- bool flag;
-} RequirementMetInfo;
-
-
-static bool
-requirement_met_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
-{
- RequirementMetInfo *info = (RequirementMetInfo *)data;
-
- // info->dep is set for resItem set children. If it is set, query the
- // exact version only.
- if ((info->dep == NULL || info->dep->equals(spec))
- && info->context->resItemIsPresent (resItem))
- {
- info->flag = true;
- }
-
-//fprintf (stderr, "requirement_met_cb(%s, %s) [info->dep %s] -> %s\n", resItem->asString().c_str(), spec->asString().c_str(), info->dep != NULL ? info->dep->asString().c_str() : "(none)", info->flag ? "true" : "false");
- return ! info->flag;
-}
-
-
-bool
-ResolverContext::requirementIsMet (constDependencyPtr dependency, bool is_child)
-{
- RequirementMetInfo info;
-
- info.context = this;
- info.dep = is_child ? dependency : NULL;
- info.flag = false;
-
- world()->foreachProvidingResItem (dependency, requirement_met_cb, (void *)&info);
-
- return info.flag;
-}
-
-
-//---------------------------------------------------------------------------
-
-static bool
-requirement_possible_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
-{
- RequirementMetInfo *info = (RequirementMetInfo *)data;
-
- ResItemStatus status = info->context->getStatus (resItem);
-
- if (! resItem_status_is_to_be_uninstalled (status)
- || status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
- info->flag = true;
- }
-
- return ! info->flag;
-}
-
-
-bool
-ResolverContext::requirementIsPossible (constDependencyPtr dep)
-{
- RequirementMetInfo info;
-
- info.context = this;
- info.flag = false;
-
- world()->foreachProvidingResItem (dep, requirement_possible_cb, (void *)&info);
-
- return info.flag;
-}
-
-
-bool
-ResolverContext::resItemIsPossible (constResItemPtr resItem)
-{
- CDependencyList requires = resItem->requires();
- for (CDependencyList::iterator iter = requires.begin(); iter != requires.end(); iter++) {
- if (! requirementIsPossible (*iter)) {
- return false;
- }
- }
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-typedef struct {
- constSpecPtr spec;
- bool flag;
-} DupNameCheckInfo;
-
-static void
-dup_name_check_cb (constResItemPtr resItem, ResItemStatus status, void *data)
-{
- DupNameCheckInfo *info = (DupNameCheckInfo *)data;
- if (! info->flag
- && resItem_status_is_to_be_installed (status)
- && info->spec->name() == resItem->name()
- && !info->spec->equals(resItem)) {
- info->flag = true;
- }
-}
-
-bool
-ResolverContext::isParallelInstall (constResItemPtr resItem)
-{
- DupNameCheckInfo info;
-
- info.spec = resItem;
- info.flag = false;
- foreachMarkedResItem (dup_name_check_cb, (void *)&info);
-
- return info.flag;
-}
-
-
-int
-ResolverContext::getChannelPriority (constChannelPtr channel) const
-{
- bool is_subscribed;
- int priority;
-
- is_subscribed = channel->isSubscribed ();
- priority = channel->getPriority (is_subscribed);
-
- return priority;
-}
-
-//---------------------------------------------------------------------------
-
-static int
-num_cmp (double a, double b)
-{
- return (b < a) - (a < b);
-}
-
-static int
-rev_num_cmp (double a, double b)
-{
- return (a < b) - (b < a);
-}
-
-static double
-churn_factor (ResolverContextPtr a)
-{
- return a->upgradeCount() + (2.0 * a->installCount ()) + (4.0 * a->uninstallCount ());
-}
-
-int
-ResolverContext::partialCompare (ResolverContextPtr context)
-{
- int cmp = 0;
- if (this != context) {
-
- // High numbers are good... we don't want solutions containing low-priority channels.
- cmp = num_cmp (_min_priority, context->_min_priority);
-
- if (cmp == 0) {
-
- // High numbers are bad. Less churn is better.
- cmp = rev_num_cmp (churn_factor (this), churn_factor (context));
-
- if (cmp == 0) {
-
- // High numbers are bad. Bigger #s means more penalties.
- cmp = rev_num_cmp (_other_penalties, context->_other_penalties);
- }
- }
- }
-
- return cmp;
-}
-
-int
-ResolverContext::compare (ResolverContextPtr context)
-{
- int cmp;
-
- if (this == context)
- return 0;
-
- cmp = partialCompare (context);
- if (cmp)
- return cmp;
-
- /* High numbers are bad. Smaller downloads are best. */
- cmp = rev_num_cmp (_download_size, context->_download_size);
- if (cmp)
- return cmp;
-
- /* High numbers are bad. Less disk space consumed is good. */
- cmp = rev_num_cmp (_install_size, context->_install_size);
- if (cmp)
- return cmp;
-
- return 0;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ typedef struct {
+ ResolverContextPtr context;
+ constSpecPtr dep;
+ bool flag;
+ } RequirementMetInfo;
+
+
+ static bool
+ requirement_met_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
+ {
+ RequirementMetInfo *info = (RequirementMetInfo *)data;
+
+ // info->dep is set for resItem set children. If it is set, query the
+ // exact version only.
+ if ((info->dep == NULL || info->dep->equals(spec))
+ && info->context->resItemIsPresent (resItem))
+ {
+ info->flag = true;
+ }
+
+ //fprintf (stderr, "requirement_met_cb(%s, %s) [info->dep %s] -> %s\n", resItem->asString().c_str(), spec->asString().c_str(), info->dep != NULL ? info->dep->asString().c_str() : "(none)", info->flag ? "true" : "false");
+ return ! info->flag;
+ }
+
+
+ bool
+ ResolverContext::requirementIsMet (constDependencyPtr dependency, bool is_child)
+ {
+ RequirementMetInfo info;
+
+ info.context = this;
+ info.dep = is_child ? dependency : NULL;
+ info.flag = false;
+
+ world()->foreachProvidingResItem (dependency, requirement_met_cb, (void *)&info);
+
+ return info.flag;
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ static bool
+ requirement_possible_cb (constResItemPtr resItem, constSpecPtr spec, void *data)
+ {
+ RequirementMetInfo *info = (RequirementMetInfo *)data;
+
+ ResItemStatus status = info->context->getStatus (resItem);
+
+ if (! resItem_status_is_to_be_uninstalled (status)
+ || status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
+ info->flag = true;
+ }
+
+ return ! info->flag;
+ }
+
+
+ bool
+ ResolverContext::requirementIsPossible (constDependencyPtr dep)
+ {
+ RequirementMetInfo info;
+
+ info.context = this;
+ info.flag = false;
+
+ world()->foreachProvidingResItem (dep, requirement_possible_cb, (void *)&info);
+
+ return info.flag;
+ }
+
+
+ bool
+ ResolverContext::resItemIsPossible (constResItemPtr resItem)
+ {
+ CDependencyList requires = resItem->requires();
+ for (CDependencyList::iterator iter = requires.begin(); iter != requires.end(); iter++) {
+ if (! requirementIsPossible (*iter)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ //---------------------------------------------------------------------------
+
+ typedef struct {
+ constSpecPtr spec;
+ bool flag;
+ } DupNameCheckInfo;
+
+ static void
+ dup_name_check_cb (constResItemPtr resItem, ResItemStatus status, void *data)
+ {
+ DupNameCheckInfo *info = (DupNameCheckInfo *)data;
+ if (! info->flag
+ && resItem_status_is_to_be_installed (status)
+ && info->spec->name() == resItem->name()
+ && !info->spec->equals(resItem)) {
+ info->flag = true;
+ }
+ }
+
+ bool
+ ResolverContext::isParallelInstall (constResItemPtr resItem)
+ {
+ DupNameCheckInfo info;
+
+ info.spec = resItem;
+ info.flag = false;
+ foreachMarkedResItem (dup_name_check_cb, (void *)&info);
+
+ return info.flag;
+ }
+
+
+ int
+ ResolverContext::getChannelPriority (constChannelPtr channel) const
+ {
+ bool is_subscribed;
+ int priority;
+
+ is_subscribed = channel->isSubscribed ();
+ priority = channel->getPriority (is_subscribed);
+
+ return priority;
+ }
+
+ //---------------------------------------------------------------------------
+
+ static int
+ num_cmp (double a, double b)
+ {
+ return (b < a) - (a < b);
+ }
+
+ static int
+ rev_num_cmp (double a, double b)
+ {
+ return (a < b) - (b < a);
+ }
+
+ static double
+ churn_factor (ResolverContextPtr a)
+ {
+ return a->upgradeCount() + (2.0 * a->installCount ()) + (4.0 * a->uninstallCount ());
+ }
+
+ int
+ ResolverContext::partialCompare (ResolverContextPtr context)
+ {
+ int cmp = 0;
+ if (this != context) {
+
+ // High numbers are good... we don't want solutions containing low-priority channels.
+ cmp = num_cmp (_min_priority, context->_min_priority);
+
+ if (cmp == 0) {
+
+ // High numbers are bad. Less churn is better.
+ cmp = rev_num_cmp (churn_factor (this), churn_factor (context));
+
+ if (cmp == 0) {
+
+ // High numbers are bad. Bigger #s means more penalties.
+ cmp = rev_num_cmp (_other_penalties, context->_other_penalties);
+ }
+ }
+ }
+
+ return cmp;
+ }
+
+ int
+ ResolverContext::compare (ResolverContextPtr context)
+ {
+ int cmp;
+
+ if (this == context)
+ return 0;
+
+ cmp = partialCompare (context);
+ if (cmp)
+ return cmp;
+
+ /* High numbers are bad. Smaller downloads are best. */
+ cmp = rev_num_cmp (_download_size, context->_download_size);
+ if (cmp)
+ return cmp;
+
+ /* High numbers are bad. Less disk space consumed is good. */
+ cmp = rev_num_cmp (_install_size, context->_install_size);
+ if (cmp)
+ return cmp;
+
+ return 0;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResItem.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-typedef enum {
- RESOLVABLE_STATUS_UNKNOWN = 0,
- RESOLVABLE_STATUS_INSTALLED,
- RESOLVABLE_STATUS_UNINSTALLED,
- RESOLVABLE_STATUS_TO_BE_INSTALLED,
- RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT,
- RESOLVABLE_STATUS_TO_BE_UNINSTALLED,
- RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE,
- RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK
-} ResItemStatus;
-
-#define resItem_status_is_to_be_installed(x) (((x) == RESOLVABLE_STATUS_TO_BE_INSTALLED) || ((x) == RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT))
-#define resItem_status_is_to_be_uninstalled(x) (((x) == RESOLVABLE_STATUS_TO_BE_UNINSTALLED) || ((x) == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE) || ((x) == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK))
-
-typedef std::map<constResItemPtr, ResItemStatus> StatusTable;
-typedef std::list<ResolverInfoPtr> InfoList;
-
-
-typedef void (*ResolverContextFn) (ResolverContextPtr ctx, void * data);
-typedef void (*MarkedResItemFn) (constResItemPtr res, ResItemStatus status, void *data);
-typedef void (*MarkedResItemPairFn) (constResItemPtr res1, ResItemStatus status1, constResItemPtr res2, ResItemStatus status2, void *data);
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverContext
-class ResolverContext : public CountedRep {
- REP_BODY(ResolverContext);
-
- private:
-
- ResolverContextPtr _parent;
-
- int _refs;
-
- WorldPtr _world;
- StatusTable _status;
-
- // just a caching mechanism
- constResItemPtr _last_checked_resItem;
- ResItemStatus _last_checked_status;
-
- InfoList _log;
- unsigned long long _download_size;
- unsigned long long _install_size;
- int _total_priority;
- int _min_priority;
- int _max_priority;
- int _other_penalties;
- constChannelPtr _current_channel;
- bool _verifying;
- bool _invalid;
-
- public:
- ResolverContext (ResolverContextPtr parent = NULL);
- virtual ~ResolverContext();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverContext & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverContext & context);
- std::string asString (void ) const;
-
- static std::string toString (const ResItemStatus & status);
-
- // ---------------------------------- accessors
-
- WorldPtr world (void) const; // gets global world, if _world == NULL
- void setWorld (WorldPtr world) { _world = world; }
-
- constChannelPtr currentChannel (void) const { return _current_channel; }
- void setCurrentChannel (constChannelPtr channel) { _current_channel = channel; }
-
- unsigned long long downloadSize(void) const { return _download_size; }
- unsigned long long installSize(void) const { return _install_size; }
- int totalPriority (void) const { return _total_priority; }
- int minPriority (void) const { return _min_priority; }
- int maxPriority (void) const { return _max_priority; }
- int otherPenalties (void) const { return _other_penalties; }
-
- bool isValid (void) const { return !_invalid; }
- bool isInvalid (void) const { return _invalid; }
-
- bool verifying (void) const { return _verifying; }
- void setVerifying (bool verifying) { _verifying = verifying; }
-
- // ---------------------------------- methods
-
- ResItemStatus getStatus (constResItemPtr res); // non-const, because its caching
- void setStatus (constResItemPtr res, ResItemStatus status);
-
- bool installResItem (constResItemPtr resItem, bool is_soft, int other_penalty);
- bool upgradeResItem (constResItemPtr new_resItem, constResItemPtr old_resItem, bool is_soft, int other_penalty);
- bool uninstallResItem (constResItemPtr resItem, bool part_of_upgrade, bool due_to_obsolete, bool due_to_unlink);
-
- bool resItemIsPresent (constResItemPtr resItem);
- bool resItemIsAbsent (constResItemPtr resItem);
-
- void foreachMarkedResItem (MarkedResItemFn fn, void *data) const;
- CResItemList getMarkedResItems (void) const;
-
- int foreachInstall (MarkedResItemFn fn, void *data) const;
- CResItemList getInstalls (void) const;
- int installCount (void) const;
-
- int foreachUninstall (MarkedResItemFn fn, void *data); // non-const, calls foreachUpgrade
- CResItemList getUninstalls (void);
- int uninstallCount (void);
-
- int foreachUpgrade (MarkedResItemPairFn fn, void *data); // non-const, calls getStatus
- CResItemList getUpgrades (void);
- int upgradeCount (void);
-
- void addInfo (ResolverInfoPtr info);
- void addInfoString (constResItemPtr resItem, int priority, std::string str);
- void addErrorString (constResItemPtr resItem, std::string str);
-
- void foreachInfo (ResItemPtr resItem, int priority, ResolverInfoFn fn, void *data);
- InfoList getInfo (void);
-
- void spew (void);
- void spewInfo (void);
-
- bool requirementIsMet (constDependencyPtr dep, bool is_child);
- bool requirementIsPossible (constDependencyPtr dep);
- bool resItemIsPossible (constResItemPtr resItem);
- bool isParallelInstall (constResItemPtr resItem);
-
- int getChannelPriority (constChannelPtr channel) const;
-
- int partialCompare (ResolverContextPtr context); // non-const, calls uninstall/upgrade Count
- int compare (ResolverContextPtr context);
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef enum {
+ RESOLVABLE_STATUS_UNKNOWN = 0,
+ RESOLVABLE_STATUS_INSTALLED,
+ RESOLVABLE_STATUS_UNINSTALLED,
+ RESOLVABLE_STATUS_TO_BE_INSTALLED,
+ RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT,
+ RESOLVABLE_STATUS_TO_BE_UNINSTALLED,
+ RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE,
+ RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK
+ } ResItemStatus;
+
+ #define resItem_status_is_to_be_installed(x) (((x) == RESOLVABLE_STATUS_TO_BE_INSTALLED) || ((x) == RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT))
+ #define resItem_status_is_to_be_uninstalled(x) (((x) == RESOLVABLE_STATUS_TO_BE_UNINSTALLED) || ((x) == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE) || ((x) == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK))
+
+ typedef std::map<constResItemPtr, ResItemStatus> StatusTable;
+ typedef std::list<ResolverInfoPtr> InfoList;
+
+
+ typedef void (*ResolverContextFn) (ResolverContextPtr ctx, void * data);
+ typedef void (*MarkedResItemFn) (constResItemPtr res, ResItemStatus status, void *data);
+ typedef void (*MarkedResItemPairFn) (constResItemPtr res1, ResItemStatus status1, constResItemPtr res2, ResItemStatus status2, void *data);
+
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverContext
+ class ResolverContext : public CountedRep {
+ REP_BODY(ResolverContext);
+
+ private:
+
+ ResolverContextPtr _parent;
+
+ int _refs;
+
+ WorldPtr _world;
+ StatusTable _status;
+
+ // just a caching mechanism
+ constResItemPtr _last_checked_resItem;
+ ResItemStatus _last_checked_status;
+
+ InfoList _log;
+ unsigned long long _download_size;
+ unsigned long long _install_size;
+ int _total_priority;
+ int _min_priority;
+ int _max_priority;
+ int _other_penalties;
+ constChannelPtr _current_channel;
+ bool _verifying;
+ bool _invalid;
+
+ public:
+ ResolverContext (ResolverContextPtr parent = NULL);
+ virtual ~ResolverContext();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverContext & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverContext & context);
+ std::string asString (void ) const;
+
+ static std::string toString (const ResItemStatus & status);
+
+ // ---------------------------------- accessors
+
+ WorldPtr world (void) const; // gets global world, if _world == NULL
+ void setWorld (WorldPtr world) { _world = world; }
+
+ constChannelPtr currentChannel (void) const { return _current_channel; }
+ void setCurrentChannel (constChannelPtr channel) { _current_channel = channel; }
+
+ unsigned long long downloadSize(void) const { return _download_size; }
+ unsigned long long installSize(void) const { return _install_size; }
+ int totalPriority (void) const { return _total_priority; }
+ int minPriority (void) const { return _min_priority; }
+ int maxPriority (void) const { return _max_priority; }
+ int otherPenalties (void) const { return _other_penalties; }
+
+ bool isValid (void) const { return !_invalid; }
+ bool isInvalid (void) const { return _invalid; }
+
+ bool verifying (void) const { return _verifying; }
+ void setVerifying (bool verifying) { _verifying = verifying; }
+
+ // ---------------------------------- methods
+
+ ResItemStatus getStatus (constResItemPtr res); // non-const, because its caching
+ void setStatus (constResItemPtr res, ResItemStatus status);
+
+ bool installResItem (constResItemPtr resItem, bool is_soft, int other_penalty);
+ bool upgradeResItem (constResItemPtr new_resItem, constResItemPtr old_resItem, bool is_soft, int other_penalty);
+ bool uninstallResItem (constResItemPtr resItem, bool part_of_upgrade, bool due_to_obsolete, bool due_to_unlink);
+
+ bool resItemIsPresent (constResItemPtr resItem);
+ bool resItemIsAbsent (constResItemPtr resItem);
+
+ void foreachMarkedResItem (MarkedResItemFn fn, void *data) const;
+ CResItemList getMarkedResItems (void) const;
+
+ int foreachInstall (MarkedResItemFn fn, void *data) const;
+ CResItemList getInstalls (void) const;
+ int installCount (void) const;
+
+ int foreachUninstall (MarkedResItemFn fn, void *data); // non-const, calls foreachUpgrade
+ CResItemList getUninstalls (void);
+ int uninstallCount (void);
+
+ int foreachUpgrade (MarkedResItemPairFn fn, void *data); // non-const, calls getStatus
+ CResItemList getUpgrades (void);
+ int upgradeCount (void);
+
+ void addInfo (ResolverInfoPtr info);
+ void addInfoString (constResItemPtr resItem, int priority, std::string str);
+ void addErrorString (constResItemPtr resItem, std::string str);
+
+ void foreachInfo (ResItemPtr resItem, int priority, ResolverInfoFn fn, void *data);
+ InfoList getInfo (void);
+
+ void spew (void);
+ void spewInfo (void);
+
+ bool requirementIsMet (constDependencyPtr dep, bool is_child);
+ bool requirementIsPossible (constDependencyPtr dep);
+ bool resItemIsPossible (constResItemPtr resItem);
+ bool isParallelInstall (constResItemPtr resItem);
+
+ int getChannelPriority (constChannelPtr channel) const;
+
+ int partialCompare (ResolverContextPtr context); // non-const, calls uninstall/upgrade Count
+ int compare (ResolverContextPtr context);
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverContext_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverContextPtr
-// CLASS NAME : constResolverContextPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(ResolverContext);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverContextPtr
+ // CLASS NAME : constResolverContextPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(ResolverContext);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverContextPtr_h
#include <zypp/solver/detail/ResolverInfo.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-static struct {
- ResolverInfoType type;
- const char *str;
-} type_str_table[] = {
- { RESOLVER_INFO_TYPE_NEEDED_BY, "needed_by" },
- { RESOLVER_INFO_TYPE_CONFLICTS_WITH, "conflicts_with" },
- { RESOLVER_INFO_TYPE_OBSOLETES, "obsoletes" },
- { RESOLVER_INFO_TYPE_DEPENDS_ON, "depended_on" },
- { RESOLVER_INFO_TYPE_CHILD_OF, "child_of" },
- { RESOLVER_INFO_TYPE_MISSING_REQ, "missing_req" },
- { RESOLVER_INFO_TYPE_MISC, "misc" },
- { RESOLVER_INFO_TYPE_INVALID, "invalid" },
- { RESOLVER_INFO_TYPE_INVALID, NULL }
-};
-
-static const char *
-info_type_to_string (ResolverInfoType type)
-{
- int i;
-
- for (i = 0; type_str_table[i].str != NULL; ++i) {
- if (type == type_str_table[i].type)
- return type_str_table[i].str;
- }
-
- return NULL;
-}
-
-
-ResolverInfoType
-resolver_info_type_from_string (const char *str)
-{
- int i;
-
- if (str == NULL) return RESOLVER_INFO_TYPE_INVALID;
-
- for (i = 0; type_str_table[i].str != NULL; ++i) {
- if (strcasecmp (str, type_str_table[i].str) == 0)
- return type_str_table[i].type;
- }
-
- return RESOLVER_INFO_TYPE_INVALID;
-}
-
-//---------------------------------------------------------------------------
-
-string
-ResolverInfo::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfo::toString ( const ResolverInfo & resolverinfo, bool full )
-{
- string res;
-
- if (full) {
- res += "<";
- res += info_type_to_string (resolverinfo._type);
- res += "> ";
- }
- if (resolverinfo._resItem != NULL) {
- res += resolverinfo._resItem->asString();
- res += ": ";
- }
-
- if (resolverinfo._error) res += " Error!";
- if (resolverinfo._important) res += " Important!";
-
- return res;
-}
-
-
-ostream &
-ResolverInfo::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfo & resolver)
-{
- return os << resolver.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfo::ResolverInfo (ResolverInfoType type, constResItemPtr resItem, int priority)
- : _type (type)
- , _resItem (resItem)
- , _priority (priority)
- , _error (false)
- , _important (false)
-{
-}
-
-
-ResolverInfo::~ResolverInfo()
-{
-}
-
-//---------------------------------------------------------------------------
-
-bool
-ResolverInfo::merge (ResolverInfoPtr to_be_merged)
-{
- if (to_be_merged == NULL) return false;
-
- if (_type != to_be_merged->_type
- || _resItem != to_be_merged->_resItem) {
- return false;
- }
-
- return true;
-}
-
-void
-ResolverInfo::copy (constResolverInfoPtr from)
-{
- _error = from->_error;
- _important = from->_important;
-}
-
-
-ResolverInfoPtr
-ResolverInfo::copy (void) const
-{
- ResolverInfoPtr cpy = new ResolverInfo(_type, _resItem, _priority);
-
- cpy->copy (this);
-
- return cpy;
-}
-
-
-//---------------------------------------------------------------------------
-
-bool
-ResolverInfo::isAbout (constResItemPtr resItem) const
-{
- if (_resItem == NULL)
- return false;
-
- return _resItem->name() == resItem->name();
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+ static struct {
+ ResolverInfoType type;
+ const char *str;
+ } type_str_table[] = {
+ { RESOLVER_INFO_TYPE_NEEDED_BY, "needed_by" },
+ { RESOLVER_INFO_TYPE_CONFLICTS_WITH, "conflicts_with" },
+ { RESOLVER_INFO_TYPE_OBSOLETES, "obsoletes" },
+ { RESOLVER_INFO_TYPE_DEPENDS_ON, "depended_on" },
+ { RESOLVER_INFO_TYPE_CHILD_OF, "child_of" },
+ { RESOLVER_INFO_TYPE_MISSING_REQ, "missing_req" },
+ { RESOLVER_INFO_TYPE_MISC, "misc" },
+ { RESOLVER_INFO_TYPE_INVALID, "invalid" },
+ { RESOLVER_INFO_TYPE_INVALID, NULL }
+ };
+
+ static const char *
+ info_type_to_string (ResolverInfoType type)
+ {
+ int i;
+
+ for (i = 0; type_str_table[i].str != NULL; ++i) {
+ if (type == type_str_table[i].type)
+ return type_str_table[i].str;
+ }
+
+ return NULL;
+ }
+
+
+ ResolverInfoType
+ resolver_info_type_from_string (const char *str)
+ {
+ int i;
+
+ if (str == NULL) return RESOLVER_INFO_TYPE_INVALID;
+
+ for (i = 0; type_str_table[i].str != NULL; ++i) {
+ if (strcasecmp (str, type_str_table[i].str) == 0)
+ return type_str_table[i].type;
+ }
+
+ return RESOLVER_INFO_TYPE_INVALID;
+ }
+
+ //---------------------------------------------------------------------------
+
+ string
+ ResolverInfo::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfo::toString ( const ResolverInfo & resolverinfo, bool full )
+ {
+ string res;
+
+ if (full) {
+ res += "<";
+ res += info_type_to_string (resolverinfo._type);
+ res += "> ";
+ }
+ if (resolverinfo._resItem != NULL) {
+ res += resolverinfo._resItem->asString();
+ res += ": ";
+ }
+
+ if (resolverinfo._error) res += " Error!";
+ if (resolverinfo._important) res += " Important!";
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfo::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfo & resolver)
+ {
+ return os << resolver.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfo::ResolverInfo (ResolverInfoType type, constResItemPtr resItem, int priority)
+ : _type (type)
+ , _resItem (resItem)
+ , _priority (priority)
+ , _error (false)
+ , _important (false)
+ {
+ }
+
+
+ ResolverInfo::~ResolverInfo()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ ResolverInfo::merge (ResolverInfoPtr to_be_merged)
+ {
+ if (to_be_merged == NULL) return false;
+
+ if (_type != to_be_merged->_type
+ || _resItem != to_be_merged->_resItem) {
+ return false;
+ }
+
+ return true;
+ }
+
+ void
+ ResolverInfo::copy (constResolverInfoPtr from)
+ {
+ _error = from->_error;
+ _important = from->_important;
+ }
+
+
+ ResolverInfoPtr
+ ResolverInfo::copy (void) const
+ {
+ ResolverInfoPtr cpy = new ResolverInfo(_type, _resItem, _priority);
+
+ cpy->copy (this);
+
+ return cpy;
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ bool
+ ResolverInfo::isAbout (constResItemPtr resItem) const
+ {
+ if (_resItem == NULL)
+ return false;
+
+ return _resItem->name() == resItem->name();
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResItem.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-
-typedef enum {
- RESOLVER_INFO_TYPE_INVALID = 0,
- RESOLVER_INFO_TYPE_NEEDED_BY,
- RESOLVER_INFO_TYPE_CONFLICTS_WITH,
- RESOLVER_INFO_TYPE_OBSOLETES,
- RESOLVER_INFO_TYPE_DEPENDS_ON,
- RESOLVER_INFO_TYPE_CHILD_OF,
- RESOLVER_INFO_TYPE_MISSING_REQ,
- RESOLVER_INFO_TYPE_MISC
-} ResolverInfoType;
-
-#define RESOLVER_INFO_PRIORITY_USER 500
-#define RESOLVER_INFO_PRIORITY_VERBOSE 100
-#define RESOLVER_INFO_PRIORITY_DEBUGGING 0
-
-typedef void (*ResolverInfoFn) (ResolverInfoPtr info, void *data);
-
-typedef std::list <ResolverInfoPtr> ResolverInfoList;
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfo
-
-class ResolverInfo : public CountedRep {
-
- REP_BODY(ResolverInfo);
-
- private:
-
- ResolverInfoType _type;
- constResItemPtr _resItem;
- int _priority;
-
- bool _error;
- bool _important;
-
- protected:
-
- ResolverInfo (ResolverInfoType type, constResItemPtr resItem, int priority);
-
- public:
-
- virtual ~ResolverInfo();
-
- void copy (constResolverInfoPtr from);
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfo & context, bool full = false);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfo & context);
- virtual std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- ResolverInfoType type (void) const { return _type; }
- constResItemPtr resItem (void) const { return _resItem; }
- int priority (void) const { return _priority; }
-
- int error (void) const { return _error; }
- void flagAsError (void) { _error = true; }
- int important (void) const { return _important; }
- void flagAsImportant (void) { _important = true; }
-
- // ---------------------------------- methods
-
- bool merge (ResolverInfoPtr to_be_merged);
- virtual ResolverInfoPtr copy (void) const;
-
- bool isAbout (constResItemPtr resItem) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef enum {
+ RESOLVER_INFO_TYPE_INVALID = 0,
+ RESOLVER_INFO_TYPE_NEEDED_BY,
+ RESOLVER_INFO_TYPE_CONFLICTS_WITH,
+ RESOLVER_INFO_TYPE_OBSOLETES,
+ RESOLVER_INFO_TYPE_DEPENDS_ON,
+ RESOLVER_INFO_TYPE_CHILD_OF,
+ RESOLVER_INFO_TYPE_MISSING_REQ,
+ RESOLVER_INFO_TYPE_MISC
+ } ResolverInfoType;
+
+ #define RESOLVER_INFO_PRIORITY_USER 500
+ #define RESOLVER_INFO_PRIORITY_VERBOSE 100
+ #define RESOLVER_INFO_PRIORITY_DEBUGGING 0
+
+ typedef void (*ResolverInfoFn) (ResolverInfoPtr info, void *data);
+
+ typedef std::list <ResolverInfoPtr> ResolverInfoList;
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfo
+
+ class ResolverInfo : public CountedRep {
+
+ REP_BODY(ResolverInfo);
+
+ private:
+
+ ResolverInfoType _type;
+ constResItemPtr _resItem;
+ int _priority;
+
+ bool _error;
+ bool _important;
+
+ protected:
+
+ ResolverInfo (ResolverInfoType type, constResItemPtr resItem, int priority);
+
+ public:
+
+ virtual ~ResolverInfo();
+
+ void copy (constResolverInfoPtr from);
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfo & context, bool full = false);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfo & context);
+ virtual std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ ResolverInfoType type (void) const { return _type; }
+ constResItemPtr resItem (void) const { return _resItem; }
+ int priority (void) const { return _priority; }
+
+ int error (void) const { return _error; }
+ void flagAsError (void) { _error = true; }
+ int important (void) const { return _important; }
+ void flagAsImportant (void) { _important = true; }
+
+ // ---------------------------------- methods
+
+ bool merge (ResolverInfoPtr to_be_merged);
+ virtual ResolverInfoPtr copy (void) const;
+
+ bool isAbout (constResItemPtr resItem) const;
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfo_h
#include <zypp/solver/detail/ResolverInfoChildOf.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoChildOf, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoChildOf::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoChildOf::toString ( const ResolverInfoChildOf & child)
-{
- string res = "<resolverinfochildof '";
-
- res += ResolverInfo::toString (child);
- res += string ("part of ") + child.resItemsToString(false);
- res += "'>";
-
- return res;
-}
-
-
-ostream &
-ResolverInfoChildOf::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoChildOf & child)
-{
- return os << child.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoChildOf::ResolverInfoChildOf (constResItemPtr resItem, constResItemPtr dependency)
- : ResolverInfoContainer (RESOLVER_INFO_TYPE_CHILD_OF, resItem, RESOLVER_INFO_PRIORITY_USER, dependency)
-{
-}
-
-
-ResolverInfoChildOf::~ResolverInfoChildOf ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-
-ResolverInfoPtr
-ResolverInfoChildOf::copy (void) const
-{
- ResolverInfoChildOfPtr cpy = new ResolverInfoChildOf(resItem(), NULL);
-
- ((ResolverInfoContainerPtr)cpy)->copy (this);
-
- return cpy;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoChildOf, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoChildOf::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoChildOf::toString ( const ResolverInfoChildOf & child)
+ {
+ string res = "<resolverinfochildof '";
+
+ res += ResolverInfo::toString (child);
+ res += string ("part of ") + child.resItemsToString(false);
+ res += "'>";
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoChildOf::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoChildOf & child)
+ {
+ return os << child.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoChildOf::ResolverInfoChildOf (constResItemPtr resItem, constResItemPtr dependency)
+ : ResolverInfoContainer (RESOLVER_INFO_TYPE_CHILD_OF, resItem, RESOLVER_INFO_PRIORITY_USER, dependency)
+ {
+ }
+
+
+ ResolverInfoChildOf::~ResolverInfoChildOf ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+
+ ResolverInfoPtr
+ ResolverInfoChildOf::copy (void) const
+ {
+ ResolverInfoChildOfPtr cpy = new ResolverInfoChildOf(resItem(), NULL);
+
+ ((ResolverInfoContainerPtr)cpy)->copy (this);
+
+ return cpy;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoChildOfPtr.h>
#include <zypp/solver/detail/ResolverInfoContainer.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-
-//////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoChildOf
-
-class ResolverInfoChildOf : public ResolverInfoContainer {
-
- REP_BODY(ResolverInfoChildOf);
-
- private:
-
- public:
-
- ResolverInfoChildOf (constResItemPtr resItem, constResItemPtr dependency);
- virtual ~ResolverInfoChildOf();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoChildOf & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoChildOf & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- virtual ResolverInfoPtr copy (void) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoChildOf
+
+ class ResolverInfoChildOf : public ResolverInfoContainer {
+
+ REP_BODY(ResolverInfoChildOf);
+
+ private:
+
+ public:
+
+ ResolverInfoChildOf (constResItemPtr resItem, constResItemPtr dependency);
+ virtual ~ResolverInfoChildOf();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoChildOf & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoChildOf & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ virtual ResolverInfoPtr copy (void) const;
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoChildOf_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfoPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoChildOfPtr
-// CLASS NAME : constResolverInfoChildOfPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoChildOf, ResolverInfo);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoChildOfPtr
+ // CLASS NAME : constResolverInfoChildOfPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoChildOf, ResolverInfo);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoChildOfPtr_h
#include <zypp/solver/detail/ResolverInfo.h>
#include <zypp/solver/detail/ResolverInfoConflictsWith.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoConflictsWith, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoConflictsWith::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoConflictsWith::toString ( const ResolverInfoConflictsWith & with)
-{
- string res;
-
- res += ResolverInfo::toString (with);
- res += string ("conflicts with ") + with.resItemsToString(false);
-
- return res;
-}
-
-
-ostream &
-ResolverInfoConflictsWith::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoConflictsWith & with)
-{
- return os << with.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoConflictsWith::ResolverInfoConflictsWith (constResItemPtr resItem, constResItemPtr with)
- : ResolverInfoContainer (RESOLVER_INFO_TYPE_CONFLICTS_WITH, resItem, RESOLVER_INFO_PRIORITY_USER, with)
-{
-}
-
-
-ResolverInfoConflictsWith::~ResolverInfoConflictsWith ()
-{
-}
-
-
-//---------------------------------------------------------------------------
-
-ResolverInfoPtr
-ResolverInfoConflictsWith::copy (void) const
-{
- ResolverInfoConflictsWithPtr cpy = new ResolverInfoConflictsWith(resItem(), NULL);
-
- ((ResolverInfoContainerPtr)cpy)->copy (this);
-
- return cpy;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoConflictsWith, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoConflictsWith::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoConflictsWith::toString ( const ResolverInfoConflictsWith & with)
+ {
+ string res;
+
+ res += ResolverInfo::toString (with);
+ res += string ("conflicts with ") + with.resItemsToString(false);
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoConflictsWith::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoConflictsWith & with)
+ {
+ return os << with.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoConflictsWith::ResolverInfoConflictsWith (constResItemPtr resItem, constResItemPtr with)
+ : ResolverInfoContainer (RESOLVER_INFO_TYPE_CONFLICTS_WITH, resItem, RESOLVER_INFO_PRIORITY_USER, with)
+ {
+ }
+
+
+ ResolverInfoConflictsWith::~ResolverInfoConflictsWith ()
+ {
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoPtr
+ ResolverInfoConflictsWith::copy (void) const
+ {
+ ResolverInfoConflictsWithPtr cpy = new ResolverInfoConflictsWith(resItem(), NULL);
+
+ ((ResolverInfoContainerPtr)cpy)->copy (this);
+
+ return cpy;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoConflictsWithPtr.h>
#include <zypp/solver/detail/ResolverInfoContainer.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoConflictsWith
+
+ class ResolverInfoConflictsWith : public ResolverInfoContainer {
+
+ REP_BODY(ResolverInfoConflictsWith);
+
+ private:
+
+ public:
+
+ ResolverInfoConflictsWith (constResItemPtr resItem, constResItemPtr with);
+ virtual ~ResolverInfoConflictsWith();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoConflictsWith & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoConflictsWith & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+
+ // ---------------------------------- methods
+
+ virtual ResolverInfoPtr copy (void) const;
+ };
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoConflictsWith
-
-class ResolverInfoConflictsWith : public ResolverInfoContainer {
-
- REP_BODY(ResolverInfoConflictsWith);
-
- private:
-
- public:
-
- ResolverInfoConflictsWith (constResItemPtr resItem, constResItemPtr with);
- virtual ~ResolverInfoConflictsWith();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoConflictsWith & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoConflictsWith & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
-
- // ---------------------------------- methods
-
- virtual ResolverInfoPtr copy (void) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoConflictsWith_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfoPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoConflictsWithPtr
-// CLASS NAME : constResolverInfoConflictsWithPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoConflictsWith, ResolverInfo);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoConflictsWithPtr
+ // CLASS NAME : constResolverInfoConflictsWithPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoConflictsWith, ResolverInfo);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoConflictsWithPtr_h
#include <zypp/solver/detail/ResolverInfoContainer.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoContainer, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoContainer::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoContainer::toString ( const ResolverInfoContainer & container )
-{
- string res = "<resolverinfocontainer '";
-
- res += ResolverInfo::toString (container);
- for (CResItemList::const_iterator iter = container._resItem_list.begin(); iter != container._resItem_list.end(); iter++) {
- if (iter != container._resItem_list.begin()) res += ", ";
- res += ((constSpecPtr)(*iter))->asString();
- }
- res += "'>";
-
- return res;
-}
-
-
-ostream &
-ResolverInfoContainer::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoContainer & container)
-{
- return os << container.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoContainer::ResolverInfoContainer (ResolverInfoType type, constResItemPtr resItem, int priority, constResItemPtr child)
- : ResolverInfo (type, resItem, priority)
-{
- if (child != NULL)
- _resItem_list.push_back (child);
-}
-
-
-ResolverInfoContainer::~ResolverInfoContainer ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-bool
-ResolverInfoContainer::merge (ResolverInfoContainerPtr to_be_merged)
-{
- bool res;
-
- res = ((ResolverInfoPtr)this)->merge ((ResolverInfoPtr)to_be_merged);
- if (!res) return res;
-
- typedef std::map<constResItemPtr, bool> SeenTable;
- SeenTable seen_packages;
-
- for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
- seen_packages[*iter] = true;
- }
-
- CResItemList rl = to_be_merged->resItems();
- for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
- SeenTable::const_iterator pos = seen_packages.find(*iter);
- if (pos == seen_packages.end()) {
- _resItem_list.push_front (*iter);
- seen_packages[*iter] = true;
- }
- }
-
- return true;
-}
-
-
-void
-ResolverInfoContainer::copy (constResolverInfoContainerPtr from)
-{
- ((ResolverInfoPtr)this)->copy(from);
-
- for (CResItemList::const_iterator iter = from->_resItem_list.begin(); iter != from->_resItem_list.end(); iter++) {
- _resItem_list.push_back (*iter);
- }
-}
-
-
-ResolverInfoPtr
-ResolverInfoContainer::copy (void) const
-{
- ResolverInfoContainerPtr cpy = new ResolverInfoContainer(type(), resItem(), priority());
-
- cpy->copy (this);
-
- return cpy;
-}
-
-//---------------------------------------------------------------------------
-
-string
-ResolverInfoContainer::resItemsToString (bool names_only) const
-{
- string res;
-
- if (_resItem_list.empty())
- return res;
-
- res += " [";
- for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
- if (iter != _resItem_list.begin())
- res += ", ";
-
- res += (names_only ? (*iter)->name() : ((constSpecPtr)(*iter))->asString());
- }
- res += "]";
-
- return res;
-}
-
-
-bool
-ResolverInfoContainer::mentions (constResItemPtr resItem) const
-{
- if (isAbout(resItem))
- return true;
-
- // Search resItem_list for any mention of the resItem.
-
- for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
- if ((*iter)->name() == resItem->name()) {
- return true;
- }
- }
-
- return false;
-}
-
-
-void
-ResolverInfoContainer::addRelatedResItem (constResItemPtr resItem)
-{
- if (!mentions(resItem)) {
- _resItem_list.push_front (resItem);
- }
-}
-
-
-void
-ResolverInfoContainer::addRelatedResItemList (const CResItemList & resItems)
-{
- for (CResItemList::const_iterator iter = resItems.begin(); iter != resItems.end(); iter++) {
- _resItem_list.push_front (*iter);
- }
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoContainer, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoContainer::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoContainer::toString ( const ResolverInfoContainer & container )
+ {
+ string res = "<resolverinfocontainer '";
+
+ res += ResolverInfo::toString (container);
+ for (CResItemList::const_iterator iter = container._resItem_list.begin(); iter != container._resItem_list.end(); iter++) {
+ if (iter != container._resItem_list.begin()) res += ", ";
+ res += ((constSpecPtr)(*iter))->asString();
+ }
+ res += "'>";
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoContainer::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoContainer & container)
+ {
+ return os << container.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoContainer::ResolverInfoContainer (ResolverInfoType type, constResItemPtr resItem, int priority, constResItemPtr child)
+ : ResolverInfo (type, resItem, priority)
+ {
+ if (child != NULL)
+ _resItem_list.push_back (child);
+ }
+
+
+ ResolverInfoContainer::~ResolverInfoContainer ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ ResolverInfoContainer::merge (ResolverInfoContainerPtr to_be_merged)
+ {
+ bool res;
+
+ res = ((ResolverInfoPtr)this)->merge ((ResolverInfoPtr)to_be_merged);
+ if (!res) return res;
+
+ typedef std::map<constResItemPtr, bool> SeenTable;
+ SeenTable seen_packages;
+
+ for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
+ seen_packages[*iter] = true;
+ }
+
+ CResItemList rl = to_be_merged->resItems();
+ for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
+ SeenTable::const_iterator pos = seen_packages.find(*iter);
+ if (pos == seen_packages.end()) {
+ _resItem_list.push_front (*iter);
+ seen_packages[*iter] = true;
+ }
+ }
+
+ return true;
+ }
+
+
+ void
+ ResolverInfoContainer::copy (constResolverInfoContainerPtr from)
+ {
+ ((ResolverInfoPtr)this)->copy(from);
+
+ for (CResItemList::const_iterator iter = from->_resItem_list.begin(); iter != from->_resItem_list.end(); iter++) {
+ _resItem_list.push_back (*iter);
+ }
+ }
+
+
+ ResolverInfoPtr
+ ResolverInfoContainer::copy (void) const
+ {
+ ResolverInfoContainerPtr cpy = new ResolverInfoContainer(type(), resItem(), priority());
+
+ cpy->copy (this);
+
+ return cpy;
+ }
+
+ //---------------------------------------------------------------------------
+
+ string
+ ResolverInfoContainer::resItemsToString (bool names_only) const
+ {
+ string res;
+
+ if (_resItem_list.empty())
+ return res;
+
+ res += " [";
+ for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
+ if (iter != _resItem_list.begin())
+ res += ", ";
+
+ res += (names_only ? (*iter)->name() : ((constSpecPtr)(*iter))->asString());
+ }
+ res += "]";
+
+ return res;
+ }
+
+
+ bool
+ ResolverInfoContainer::mentions (constResItemPtr resItem) const
+ {
+ if (isAbout(resItem))
+ return true;
+
+ // Search resItem_list for any mention of the resItem.
+
+ for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
+ if ((*iter)->name() == resItem->name()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ void
+ ResolverInfoContainer::addRelatedResItem (constResItemPtr resItem)
+ {
+ if (!mentions(resItem)) {
+ _resItem_list.push_front (resItem);
+ }
+ }
+
+
+ void
+ ResolverInfoContainer::addRelatedResItemList (const CResItemList & resItems)
+ {
+ for (CResItemList::const_iterator iter = resItems.begin(); iter != resItems.end(); iter++) {
+ _resItem_list.push_front (*iter);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoContainerPtr.h>
#include <zypp/solver/detail/ResolverInfo.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-
-//////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoContainer
-
-class ResolverInfoContainer : public ResolverInfo {
-
- REP_BODY(ResolverInfoContainer);
-
- private:
-
- CResItemList _resItem_list;
-
- protected:
-
- ResolverInfoContainer (ResolverInfoType type, constResItemPtr resItem, int priority, constResItemPtr child = NULL);
-
- public:
- virtual ~ResolverInfoContainer();
-
- void copy (constResolverInfoContainerPtr from);
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoContainer & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoContainer & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- CResItemList resItems (void) const { return _resItem_list; }
-
- // ---------------------------------- methods
-
- virtual bool merge (ResolverInfoContainerPtr to_be_merged);
- virtual ResolverInfoPtr copy (void) const;
-
- std::string resItemsToString (bool names_only) const;
-
- bool mentions (constResItemPtr resItem) const;
- void addRelatedResItem (constResItemPtr resItem);
- void addRelatedResItemList (const CResItemList & resItems);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ //////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoContainer
+
+ class ResolverInfoContainer : public ResolverInfo {
+
+ REP_BODY(ResolverInfoContainer);
+
+ private:
+
+ CResItemList _resItem_list;
+
+ protected:
+
+ ResolverInfoContainer (ResolverInfoType type, constResItemPtr resItem, int priority, constResItemPtr child = NULL);
+
+ public:
+ virtual ~ResolverInfoContainer();
+
+ void copy (constResolverInfoContainerPtr from);
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoContainer & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoContainer & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ CResItemList resItems (void) const { return _resItem_list; }
+
+ // ---------------------------------- methods
+
+ virtual bool merge (ResolverInfoContainerPtr to_be_merged);
+ virtual ResolverInfoPtr copy (void) const;
+
+ std::string resItemsToString (bool names_only) const;
+
+ bool mentions (constResItemPtr resItem) const;
+ void addRelatedResItem (constResItemPtr resItem);
+ void addRelatedResItemList (const CResItemList & resItems);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoContainer_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfo.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoContainerPtr
-// CLASS NAME : constResolverInfoContainerPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoContainer,ResolverInfo);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoContainerPtr
+ // CLASS NAME : constResolverInfoContainerPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoContainer,ResolverInfo);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoContainerPtr_h
#include <zypp/solver/detail/ResolverInfo.h>
#include <zypp/solver/detail/ResolverInfoDependsOn.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoDependsOn, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoDependsOn::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoDependsOn::toString ( const ResolverInfoDependsOn & on)
-{
- string res;
-
- res += ResolverInfo::toString (on);
- res += string ("depended on ") + on.resItemsToString(false);
-
- return res;
-}
-
-
-ostream &
-ResolverInfoDependsOn::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoDependsOn & on)
-{
- return os << on.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoDependsOn::ResolverInfoDependsOn (constResItemPtr resItem, constResItemPtr on)
- : ResolverInfoContainer (RESOLVER_INFO_TYPE_DEPENDS_ON, resItem, RESOLVER_INFO_PRIORITY_USER, on)
-{
-}
-
-
-ResolverInfoDependsOn::~ResolverInfoDependsOn ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoPtr
-ResolverInfoDependsOn::copy (void) const
-{
- ResolverInfoDependsOnPtr cpy = new ResolverInfoDependsOn(resItem(), NULL);
-
- ((ResolverInfoContainerPtr)cpy)->copy (this);
-
- return cpy;
-}
-
-//---------------------------------------------------------------------------
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoDependsOn, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoDependsOn::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoDependsOn::toString ( const ResolverInfoDependsOn & on)
+ {
+ string res;
+
+ res += ResolverInfo::toString (on);
+ res += string ("depended on ") + on.resItemsToString(false);
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoDependsOn::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoDependsOn & on)
+ {
+ return os << on.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoDependsOn::ResolverInfoDependsOn (constResItemPtr resItem, constResItemPtr on)
+ : ResolverInfoContainer (RESOLVER_INFO_TYPE_DEPENDS_ON, resItem, RESOLVER_INFO_PRIORITY_USER, on)
+ {
+ }
+
+
+ ResolverInfoDependsOn::~ResolverInfoDependsOn ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoPtr
+ ResolverInfoDependsOn::copy (void) const
+ {
+ ResolverInfoDependsOnPtr cpy = new ResolverInfoDependsOn(resItem(), NULL);
+
+ ((ResolverInfoContainerPtr)cpy)->copy (this);
+
+ return cpy;
+ }
+
+ //---------------------------------------------------------------------------
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoDependsOnPtr.h>
#include <zypp/solver/detail/ResolverInfoContainer.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoDependsOn
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoDependsOn
+
+ class ResolverInfoDependsOn : public ResolverInfoContainer {
+
+ REP_BODY(ResolverInfoDependsOn);
+
+ private:
+
+ public:
+
+ ResolverInfoDependsOn (constResItemPtr resItem, constResItemPtr on);
+ virtual ~ResolverInfoDependsOn();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoDependsOn & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoDependsOn & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ virtual ResolverInfoPtr copy (void) const;
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-class ResolverInfoDependsOn : public ResolverInfoContainer {
-
- REP_BODY(ResolverInfoDependsOn);
-
- private:
-
- public:
-
- ResolverInfoDependsOn (constResItemPtr resItem, constResItemPtr on);
- virtual ~ResolverInfoDependsOn();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoDependsOn & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoDependsOn & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- virtual ResolverInfoPtr copy (void) const;
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ResolverInfoDependsOn_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfoPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoDependsOnPtr
-// CLASS NAME : constResolverInfoDependsOnPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoDependsOn, ResolverInfo);
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoDependsOnPtr
+ // CLASS NAME : constResolverInfoDependsOnPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoDependsOn, ResolverInfo);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ResolverInfoDependsOnPtr_h
#include <zypp/solver/detail/ResolverInfo.h>
#include <zypp/solver/detail/ResolverInfoMisc.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoMisc, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoMisc::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoMisc::toString ( const ResolverInfoMisc & misc)
-{
- string res;
- res += misc._msg;
-#if 0
- res += " [";
- res += ResolverInfo::toString (misc, false);
- res += "]";
-#endif
- res += misc.resItemsToString(false);
- if (!misc._action.empty()) {
- res += string (", Action: ") + misc._action + "\n";
- }
- if (!misc._trigger.empty()) {
- res += string (", Trigger: ") + misc._trigger + "\n";
- }
-
- return res;
-}
-
-
-ostream &
-ResolverInfoMisc::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoMisc & misc)
-{
- return os << misc.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoMisc::ResolverInfoMisc (constResItemPtr resItem, int priority, const string & msg)
- : ResolverInfoContainer (RESOLVER_INFO_TYPE_MISC, resItem, priority)
- , _msg (msg)
-{
-}
-
-
-ResolverInfoMisc::~ResolverInfoMisc ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-bool
-ResolverInfoMisc::merge (ResolverInfoPtr info)
-{
- bool res;
- ResolverInfoMiscPtr to_be_merged = info;
-
- res = ((ResolverInfoPtr)this)->merge ((ResolverInfoPtr)to_be_merged);
- if (!res) return res;
-
- if (!_msg.empty()
- && !to_be_merged->_msg.empty()
- && _msg == to_be_merged->_msg) {
- return true;
- }
-
- return false;
-}
-
-
-ResolverInfoPtr
-ResolverInfoMisc::copy (void) const
-{
- ResolverInfoMiscPtr cpy = new ResolverInfoMisc(resItem(), priority(), _msg);
-
- ((ResolverInfoContainerPtr)cpy)->copy (this);
-
- return cpy;
-}
-
-//---------------------------------------------------------------------------
-
-void
-ResolverInfoMisc::addAction (const std::string & action_msg)
-{
- _action = action_msg;
-}
-
-
-void
-ResolverInfoMisc::addTrigger (const std::string & trigger_msg)
-{
- _trigger = trigger_msg;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoMisc, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoMisc::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoMisc::toString ( const ResolverInfoMisc & misc)
+ {
+ string res;
+ res += misc._msg;
+ #if 0
+ res += " [";
+ res += ResolverInfo::toString (misc, false);
+ res += "]";
+ #endif
+ res += misc.resItemsToString(false);
+ if (!misc._action.empty()) {
+ res += string (", Action: ") + misc._action + "\n";
+ }
+ if (!misc._trigger.empty()) {
+ res += string (", Trigger: ") + misc._trigger + "\n";
+ }
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoMisc::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoMisc & misc)
+ {
+ return os << misc.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoMisc::ResolverInfoMisc (constResItemPtr resItem, int priority, const string & msg)
+ : ResolverInfoContainer (RESOLVER_INFO_TYPE_MISC, resItem, priority)
+ , _msg (msg)
+ {
+ }
+
+
+ ResolverInfoMisc::~ResolverInfoMisc ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ ResolverInfoMisc::merge (ResolverInfoPtr info)
+ {
+ bool res;
+ ResolverInfoMiscPtr to_be_merged = info;
+
+ res = ((ResolverInfoPtr)this)->merge ((ResolverInfoPtr)to_be_merged);
+ if (!res) return res;
+
+ if (!_msg.empty()
+ && !to_be_merged->_msg.empty()
+ && _msg == to_be_merged->_msg) {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ ResolverInfoPtr
+ ResolverInfoMisc::copy (void) const
+ {
+ ResolverInfoMiscPtr cpy = new ResolverInfoMisc(resItem(), priority(), _msg);
+
+ ((ResolverInfoContainerPtr)cpy)->copy (this);
+
+ return cpy;
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ ResolverInfoMisc::addAction (const std::string & action_msg)
+ {
+ _action = action_msg;
+ }
+
+
+ void
+ ResolverInfoMisc::addTrigger (const std::string & trigger_msg)
+ {
+ _trigger = trigger_msg;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoMiscPtr.h>
#include <zypp/solver/detail/ResolverInfoContainer.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoMisc
-
-class ResolverInfoMisc : public ResolverInfoContainer {
-
- REP_BODY(ResolverInfoMisc);
-
- private:
-
- std::string _msg;
- std::string _action;
- std::string _trigger;
-
- public:
-
- ResolverInfoMisc (constResItemPtr resItem, int priority, const std::string & msg);
- virtual ~ResolverInfoMisc();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoMisc & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoMisc & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- virtual bool merge (ResolverInfoPtr to_be_merged);
- virtual ResolverInfoPtr copy (void) const;
-
- void addAction (const std::string & action_msg);
- void addTrigger (const std::string & trigger_msg);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoMisc
+
+ class ResolverInfoMisc : public ResolverInfoContainer {
+
+ REP_BODY(ResolverInfoMisc);
+
+ private:
+
+ std::string _msg;
+ std::string _action;
+ std::string _trigger;
+
+ public:
+
+ ResolverInfoMisc (constResItemPtr resItem, int priority, const std::string & msg);
+ virtual ~ResolverInfoMisc();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoMisc & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoMisc & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ virtual bool merge (ResolverInfoPtr to_be_merged);
+ virtual ResolverInfoPtr copy (void) const;
+
+ void addAction (const std::string & action_msg);
+ void addTrigger (const std::string & trigger_msg);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoMisc_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfoPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoMiscPtr
+ // CLASS NAME : constResolverInfoMiscPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoMisc, ResolverInfo);
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoMiscPtr
-// CLASS NAME : constResolverInfoMiscPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoMisc, ResolverInfo);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoMiscPtr_h
#include <zypp/solver/detail/ResolverInfo.h>
#include <zypp/solver/detail/ResolverInfoMissingReq.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoMissingReq, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoMissingReq::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoMissingReq::toString ( const ResolverInfoMissingReq & missing)
+ {
+ string res;
+
+ res += ResolverInfo::toString (missing);
+ res += string ("missing requirement ") + missing._missing_req->asString();
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoMissingReq::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoMissingReq & missing)
+ {
+ return os << missing.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoMissingReq::ResolverInfoMissingReq (constResItemPtr resItem, constDependencyPtr missing_req)
+ : ResolverInfo (RESOLVER_INFO_TYPE_MISSING_REQ, resItem, RESOLVER_INFO_PRIORITY_USER)
+ , _missing_req (missing_req)
+ {
+ }
+
+
+ ResolverInfoMissingReq::~ResolverInfoMissingReq ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoPtr
+ ResolverInfoMissingReq::copy (void) const
+ {
+ ResolverInfoMissingReqPtr cpy = new ResolverInfoMissingReq(resItem(), _missing_req);
+
+ ((ResolverInfoPtr)cpy)->copy (this);
+
+ return cpy;
+ }
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoMissingReq, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoMissingReq::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoMissingReq::toString ( const ResolverInfoMissingReq & missing)
-{
- string res;
-
- res += ResolverInfo::toString (missing);
- res += string ("missing requirement ") + missing._missing_req->asString();
-
- return res;
-}
-
-
-ostream &
-ResolverInfoMissingReq::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoMissingReq & missing)
-{
- return os << missing.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoMissingReq::ResolverInfoMissingReq (constResItemPtr resItem, constDependencyPtr missing_req)
- : ResolverInfo (RESOLVER_INFO_TYPE_MISSING_REQ, resItem, RESOLVER_INFO_PRIORITY_USER)
- , _missing_req (missing_req)
-{
-}
-
-
-ResolverInfoMissingReq::~ResolverInfoMissingReq ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoPtr
-ResolverInfoMissingReq::copy (void) const
-{
- ResolverInfoMissingReqPtr cpy = new ResolverInfoMissingReq(resItem(), _missing_req);
-
- ((ResolverInfoPtr)cpy)->copy (this);
-
- return cpy;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoMissingReqPtr.h>
#include <zypp/solver/detail/ResolverInfo.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoMissingReq
-
-class ResolverInfoMissingReq : public ResolverInfo {
-
- REP_BODY(ResolverInfoMissingReq);
-
- private:
-
- constDependencyPtr _missing_req;
-
- public:
-
- ResolverInfoMissingReq (constResItemPtr resItem, constDependencyPtr missing_req);
- virtual ~ResolverInfoMissingReq();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoMissingReq & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoMissingReq & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- virtual ResolverInfoPtr copy (void) const;
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoMissingReq
+
+ class ResolverInfoMissingReq : public ResolverInfo {
+
+ REP_BODY(ResolverInfoMissingReq);
+
+ private:
+
+ constDependencyPtr _missing_req;
+
+ public:
+
+ ResolverInfoMissingReq (constResItemPtr resItem, constDependencyPtr missing_req);
+ virtual ~ResolverInfoMissingReq();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoMissingReq & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoMissingReq & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ virtual ResolverInfoPtr copy (void) const;
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoMissingReq_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfoPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoMissingReqPtr
-// CLASS NAME : constResolverInfoMissingReqPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoMissingReq, ResolverInfo);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoMissingReqPtr
+ // CLASS NAME : constResolverInfoMissingReqPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoMissingReq, ResolverInfo);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoMissingReqPtr_h
#include <zypp/solver/detail/ResolverInfo.h>
#include <zypp/solver/detail/ResolverInfoNeededBy.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoNeededBy, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoNeededBy::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoNeededBy::toString ( const ResolverInfoNeededBy & by)
-{
- string res;
-
- res += ResolverInfo::toString (by, false);
- res += string (" needed by ") + by.resItemsToString(false);
-
- return res;
-}
-
-
-ostream &
-ResolverInfoNeededBy::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoNeededBy & by)
-{
- return os << by.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoNeededBy::ResolverInfoNeededBy (constResItemPtr resItem)
- : ResolverInfoContainer (RESOLVER_INFO_TYPE_NEEDED_BY, resItem, RESOLVER_INFO_PRIORITY_USER, NULL)
-{
-}
-
-
-ResolverInfoNeededBy::~ResolverInfoNeededBy ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoPtr
-ResolverInfoNeededBy::copy (void) const
-{
- ResolverInfoNeededByPtr cpy = new ResolverInfoNeededBy(resItem());
-
- ((ResolverInfoContainerPtr)cpy)->copy (this);
-
- return cpy;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoNeededBy, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoNeededBy::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoNeededBy::toString ( const ResolverInfoNeededBy & by)
+ {
+ string res;
+
+ res += ResolverInfo::toString (by, false);
+ res += string (" needed by ") + by.resItemsToString(false);
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoNeededBy::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoNeededBy & by)
+ {
+ return os << by.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoNeededBy::ResolverInfoNeededBy (constResItemPtr resItem)
+ : ResolverInfoContainer (RESOLVER_INFO_TYPE_NEEDED_BY, resItem, RESOLVER_INFO_PRIORITY_USER, NULL)
+ {
+ }
+
+
+ ResolverInfoNeededBy::~ResolverInfoNeededBy ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoPtr
+ ResolverInfoNeededBy::copy (void) const
+ {
+ ResolverInfoNeededByPtr cpy = new ResolverInfoNeededBy(resItem());
+
+ ((ResolverInfoContainerPtr)cpy)->copy (this);
+
+ return cpy;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoNeededByPtr.h>
#include <zypp/solver/detail/ResolverInfoContainer.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoNeededBy
+
+ class ResolverInfoNeededBy : public ResolverInfoContainer {
+
+ REP_BODY(ResolverInfoNeededBy);
+
+ private:
+
+ public:
+
+ ResolverInfoNeededBy (constResItemPtr resItem);
+ virtual ~ResolverInfoNeededBy();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoNeededBy & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoNeededBy & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ virtual ResolverInfoPtr copy (void) const;
+ };
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoNeededBy
-
-class ResolverInfoNeededBy : public ResolverInfoContainer {
-
- REP_BODY(ResolverInfoNeededBy);
-
- private:
-
- public:
-
- ResolverInfoNeededBy (constResItemPtr resItem);
- virtual ~ResolverInfoNeededBy();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoNeededBy & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoNeededBy & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- virtual ResolverInfoPtr copy (void) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoNeededBy_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfoPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoNeededByPtr
-// CLASS NAME : constResolverInfoNeededByPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoNeededBy, ResolverInfo);
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoNeededByPtr
+ // CLASS NAME : constResolverInfoNeededByPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoNeededBy, ResolverInfo);
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoNeededByPtr_h
#include <zypp/solver/detail/ResolverInfo.h>
#include <zypp/solver/detail/ResolverInfoObsoletes.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ResolverInfoObsoletes, ResolverInfo);
-
-//---------------------------------------------------------------------------
-
-
-string
-ResolverInfoObsoletes::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverInfoObsoletes::toString ( const ResolverInfoObsoletes & obsoletes)
-{
- string res;
-
- res += ResolverInfo::toString (obsoletes);
- res += string ("replaced by ") + obsoletes.resItemsToString(false);
-
- return res;
-}
-
-
-ostream &
-ResolverInfoObsoletes::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverInfoObsoletes & obsoletes)
-{
- return os << obsoletes.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoObsoletes::ResolverInfoObsoletes (constResItemPtr resItem, constResItemPtr obsoletes)
- : ResolverInfoContainer (RESOLVER_INFO_TYPE_OBSOLETES, resItem, RESOLVER_INFO_PRIORITY_USER, obsoletes)
-{
-}
-
-
-ResolverInfoObsoletes::~ResolverInfoObsoletes ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-ResolverInfoPtr
-ResolverInfoObsoletes::copy (void) const
-{
- ResolverInfoObsoletesPtr cpy = new ResolverInfoObsoletes(resItem(), NULL);
-
- ((ResolverInfoContainerPtr)cpy)->copy (this);
-
- return cpy;
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ResolverInfoObsoletes, ResolverInfo);
+
+ //---------------------------------------------------------------------------
+
+
+ string
+ ResolverInfoObsoletes::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverInfoObsoletes::toString ( const ResolverInfoObsoletes & obsoletes)
+ {
+ string res;
+
+ res += ResolverInfo::toString (obsoletes);
+ res += string ("replaced by ") + obsoletes.resItemsToString(false);
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverInfoObsoletes::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverInfoObsoletes & obsoletes)
+ {
+ return os << obsoletes.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoObsoletes::ResolverInfoObsoletes (constResItemPtr resItem, constResItemPtr obsoletes)
+ : ResolverInfoContainer (RESOLVER_INFO_TYPE_OBSOLETES, resItem, RESOLVER_INFO_PRIORITY_USER, obsoletes)
+ {
+ }
+
+
+ ResolverInfoObsoletes::~ResolverInfoObsoletes ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverInfoPtr
+ ResolverInfoObsoletes::copy (void) const
+ {
+ ResolverInfoObsoletesPtr cpy = new ResolverInfoObsoletes(resItem(), NULL);
+
+ ((ResolverInfoContainerPtr)cpy)->copy (this);
+
+ return cpy;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResolverInfoObsoletesPtr.h>
#include <zypp/solver/detail/ResolverInfoContainer.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverInfoObsoletes
-
-class ResolverInfoObsoletes : public ResolverInfoContainer {
-
- REP_BODY(ResolverInfoObsoletes);
-
- private:
-
- public:
-
- ResolverInfoObsoletes (constResItemPtr resItem, constResItemPtr obsoletes);
- virtual ~ResolverInfoObsoletes();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverInfoObsoletes & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoObsoletes & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- virtual ResolverInfoPtr copy (void) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverInfoObsoletes
+
+ class ResolverInfoObsoletes : public ResolverInfoContainer {
+
+ REP_BODY(ResolverInfoObsoletes);
+
+ private:
+
+ public:
+
+ ResolverInfoObsoletes (constResItemPtr resItem, constResItemPtr obsoletes);
+ virtual ~ResolverInfoObsoletes();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverInfoObsoletes & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoObsoletes & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ virtual ResolverInfoPtr copy (void) const;
+ };
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoObsoletes_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/ResolverInfoPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoObsoletesPtr
+ // CLASS NAME : constResolverInfoObsoletesPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ResolverInfoObsoletes, ResolverInfo);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoObsoletesPtr
-// CLASS NAME : constResolverInfoObsoletesPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ResolverInfoObsoletes, ResolverInfo);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ResolverInfoObsoletesPtr_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverInfoPtr
-// CLASS NAME : constResolverInfoPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(ResolverInfo);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverInfoPtr
+ // CLASS NAME : constResolverInfoPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(ResolverInfo);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _ResolverInfoPtr_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverPtr
+ // CLASS NAME : constResolverPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(Resolver);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverPtr
-// CLASS NAME : constResolverPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(Resolver);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ResolverPtr_h
#include <y2util/stringutil.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(ResolverQueue);
-
-//---------------------------------------------------------------------------
-
-
-//---------------------------------------------------------------------------
-
-string
-ResolverQueue::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ResolverQueue::toString ( const ResolverQueue & resolverqueue )
-{
- string res;
-
- res += stringutil::form ("Context [%p]", (const void *)resolverqueue._context);
- res += ", Items:\n\t";
- res += QueueItem::toString (resolverqueue._items, ",\n\t");
-
- return res;
-}
-
-
-ostream &
-ResolverQueue::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ResolverQueue & resolverqueue)
-{
- return os << resolverqueue.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ResolverQueue::ResolverQueue (ResolverContextPtr context)
- : _context (context)
-{
- if (context == NULL)
- _context = new ResolverContext();
-}
-
-
-ResolverQueue::~ResolverQueue()
-{
-}
-
-//---------------------------------------------------------------------------
-
-void
-ResolverQueue::addResItemToInstall (constResItemPtr resItem)
-{
- QueueItemInstallPtr item;
-
- if (_context->resItemIsPresent (resItem)) {
- printf ("%s is already installed", ((constSpecPtr)resItem)->asString().c_str());
- return;
- }
-
- item = new QueueItemInstall (_context->world(), resItem);
- item->setExplicitlyRequested ();
-
- addItem (item);
-}
-
-
-void
-ResolverQueue::addResItemToRemove (constResItemPtr resItem, bool remove_only_mode)
-{
- QueueItemUninstallPtr item;
-
- if (_context->resItemIsAbsent (resItem))
- return;
-
- item = new QueueItemUninstall (_context->world(), resItem, "user request");
- if (remove_only_mode)
- item->setRemoveOnly ();
-
- item->setExplicitlyRequested ();
-
- addItem (item);
-}
-
-
-void
-ResolverQueue::addResItemToVerify (constResItemPtr resItem)
-{
- WorldPtr world;
-
- world = _context->world ();
-
- CDependencyList requires = resItem->requires();
- for (CDependencyList::const_iterator iter = requires.begin(); iter != requires.end(); iter++) {
- QueueItemRequirePtr item = new QueueItemRequire (world, *iter);
- item->addResItem (resItem);
- addItem (item);
- }
-
- CDependencyList conflicts = resItem->conflicts();
- for (CDependencyList::const_iterator iter = conflicts.begin(); iter != conflicts.end(); iter++) {
- QueueItemConflictPtr item = new QueueItemConflict (world, *iter, resItem);
- addItem (item);
- }
-}
-
-
-void
-ResolverQueue::addExtraDependency (constDependencyPtr dep)
-{
- QueueItemRequirePtr item = new QueueItemRequire (_context->world(), dep);
- addItem (item);
-}
-
-
-void
-ResolverQueue::addExtraConflict (constDependencyPtr dep)
-{
- QueueItemConflictPtr item = new QueueItemConflict (_context->world(), dep, NULL);
- addItem (item);
-}
-
-
-void
-ResolverQueue::addItem (QueueItemPtr item)
-{
- _items.push_front (item);
-}
-
-
-bool
-ResolverQueue::isInvalid ()
-{
- return _context->isInvalid();
-}
-
-
-bool
-ResolverQueue::containsOnlyBranches ()
-{
- for (QueueItemList::const_iterator iter = _items.begin(); iter != _items.end(); iter++) {
- if (!(*iter)->isBranch())
- return false;
- }
-
- return true;
-}
-
-//---------------------------------------------------------------------------
-
-static int
-itemlist_max_priority (const QueueItemList & qil)
-{
- int max_priority = -1;
- for (QueueItemList::const_iterator iter = qil.begin(); iter != qil.end(); iter++) {
- if ((*iter)->priority() > max_priority) {
- max_priority = (*iter)->priority();
- }
- }
-
- return max_priority;
-}
-
-
-
-bool
-ResolverQueue::processOnce ()
-{
- QueueItemList new_items;
- int max_priority;
- bool did_something = false;
-
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce(%s), %d items\n", asString().c_str(), (int) _items.size());
- while ( (max_priority = itemlist_max_priority (_items)) >= 0
- && _context->isValid () ) {
-
- bool did_something_recently = false;
-
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce() inside loop\n");
- for (QueueItemList::iterator iter = _items.begin(); iter != _items.end() && _context->isValid();) {
- QueueItemPtr item = *iter;
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "=====> 1st pass: [%s]\n", item->asString().c_str());
- QueueItemList::iterator next = iter; next++;
- if (item && item->priority() == max_priority) {
- if (item->process (_context, new_items)) {
- did_something_recently = true;
- }
- _items.erase (iter);
- }
- iter = next;
- }
-
- if (did_something_recently) {
- did_something = true;
- }
- }
-
- _items = new_items;
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "%d items after first pass\n", (int) _items.size());
-
- /*
- Now make a second pass over the queue, removing any super-branches.
- (If one branch contains all of the possible items of another branch,
- the larger branch can be dropped.
- */
-
-// if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce() second pass\n");
- for (QueueItemList::iterator iter = _items.begin(); iter != _items.end();) {
- QueueItemList::iterator next = iter; next++;
- QueueItemPtr item = *iter;
-
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "=====> 2nd pass: [%s]\n", item->asString().c_str());
- if (item->isBranch()) {
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce() is branch\n");
- QueueItemBranchPtr branch = (QueueItemBranchPtr)item;
- for (QueueItemList::const_iterator iter2 = _items.begin(); iter2 != _items.end(); iter2++) {
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "Compare branch with [%s]\n", (*iter2)->asString().c_str());
- if (iter != iter2
- && branch->contains (*iter2)) {
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "Contained within, removing\n");
- _items.erase (iter);
- break;
- }
- }
- }
- iter = next;
- }
- if (getenv ("QUEUE_SPEW")) fprintf (stderr, "did %sthing: %d items\n", did_something ? "some" : "no", (int)_items.size());
-
- return did_something;
-}
-
-
-void
-ResolverQueue::process ()
-{
- bool very_noisy;
-
- very_noisy = getenv ("RC_SPEW") != NULL;
-
- if (very_noisy) {
- printf ("----- Processing -----\n");
- spew ();
- }
-
- while (_context->isValid ()
- && ! isEmpty ()
- && processOnce ()) {
- /* all of the work is in the conditional! */
- if (very_noisy) {
- spew ();
- }
- }
-}
-
-
-//---------------------------------------------------------------------------
-
-static ResolverQueuePtr
-copy_queue_except_for_branch (ResolverQueuePtr queue, QueueItemPtr branch_item, QueueItemPtr subitem)
-{
- ResolverContextPtr new_context;
- ResolverQueuePtr new_queue;
-
- new_context = new ResolverContext (queue->context());
- new_queue = new ResolverQueue (new_context);
-
- QueueItemList qil = queue->items();
- for (QueueItemList::const_iterator iter = qil.begin(); iter != qil.end(); iter++) {
- QueueItemPtr item = *iter;
- QueueItemPtr new_item;
-
- if (item == branch_item) {
- new_item = subitem->copy ();
-
- if (new_item->isInstall()) {
- QueueItemInstallPtr install_item = (QueueItemInstallPtr)new_item;
-
- /* Penalties are negative priorities */
- int penalty;
- penalty = - queue->context()->getChannelPriority (install_item->resItem()->channel());
-
- install_item->setOtherPenalty (penalty);
- }
-
- } else {
-
- new_item = item->copy ();
-
- }
-
- new_queue->addItem (new_item);
- }
-
- return new_queue;
-}
-
-
-void
-ResolverQueue::splitFirstBranch (ResolverQueueList & new_queues, ResolverQueueList & deferred_queues)
-{
- QueueItemBranchPtr first_branch = NULL;
- typedef std::map <QueueItemPtr, QueueItemPtr> DeferTable;
- DeferTable to_defer;
-
- for (QueueItemList::const_iterator iter = _items.begin(); iter != _items.end() && first_branch == NULL; iter++) {
- QueueItemPtr item = *iter;
- if (item->isBranch()) {
- first_branch = (QueueItemBranchPtr)item;
- }
- }
-
- if (first_branch == NULL)
- return;
-
- /*
- Check for deferrable items: if we have two install items where the to-be-installed
- resItems have the same name, then we will defer the lower-priority install if
- one of the following is true:
- (1) Both resItems have the same version
- (2) The lower-priority channel is a previous version.
- */
-
- QueueItemList possible_items = first_branch->possibleItems();
- for (QueueItemList::const_iterator iter = possible_items.begin(); iter != possible_items.end(); iter++) {
- QueueItemList::const_iterator iter2 = iter;
- for (iter2++; iter2 != possible_items.end(); iter2++) {
- QueueItemPtr item = *iter;
- QueueItemPtr item2 = *iter2;
-
- if (item->isInstall() && item2->isInstall()) {
- constResItemPtr r = ((QueueItemInstallPtr) item)->resItem();
- constResItemPtr r2 = ((QueueItemInstallPtr) item2)->resItem();
- constChannelPtr channel = r->channel();
- constChannelPtr channel2 = r2->channel();
- int priority, priority2;
-
- priority = channel->getPriority (channel->isSubscribed());
- priority2 = channel2->getPriority (channel2->isSubscribed());
-
- if (priority != priority2 && r->name() == r2->name()) {
- if (r->version() == r2->version()
- || (priority < priority2 && GVersion.compare (r, r2) < 0)
- || (priority > priority2 && GVersion.compare (r, r2) > 0)) {
-
- if (priority < priority2)
- to_defer[item] = item;
- else /* if (priority > priority2) */
- to_defer[item2] = item2;
- }
- }
- }
- }
- }
-
-
- for (QueueItemList::const_iterator iter = possible_items.begin(); iter != possible_items.end(); iter++) {
- ResolverQueuePtr new_queue;
- QueueItemPtr new_item = *iter;
-
- new_queue = copy_queue_except_for_branch (this, (QueueItemPtr) first_branch, new_item);
-
- DeferTable::const_iterator pos = to_defer.find (new_item);
- if (pos != to_defer.end()) {
- deferred_queues.push_back (new_queue);
- } else {
- new_queues.push_back (new_queue);
- }
- }
-
-}
-
-
-void
-ResolverQueue::spew ()
-{
- printf ("Resolver Queue: %s\n", _context->isInvalid() ? "INVALID" : "");
-
- if (_items.empty()) {
-
- printf (" (empty)\n");
-
- } else {
-
- for (QueueItemList::const_iterator iter = _items.begin(); iter != _items.end(); iter++) {
- printf (" %s\n", (*iter)->asString().c_str());
- }
-
- }
-
- printf ("\n");
- fflush (stdout);
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(ResolverQueue);
+
+ //---------------------------------------------------------------------------
+
+
+ //---------------------------------------------------------------------------
+
+ string
+ ResolverQueue::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ResolverQueue::toString ( const ResolverQueue & resolverqueue )
+ {
+ string res;
+
+ res += stringutil::form ("Context [%p]", (const void *)resolverqueue._context);
+ res += ", Items:\n\t";
+ res += QueueItem::toString (resolverqueue._items, ",\n\t");
+
+ return res;
+ }
+
+
+ ostream &
+ ResolverQueue::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ResolverQueue & resolverqueue)
+ {
+ return os << resolverqueue.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ResolverQueue::ResolverQueue (ResolverContextPtr context)
+ : _context (context)
+ {
+ if (context == NULL)
+ _context = new ResolverContext();
+ }
+
+
+ ResolverQueue::~ResolverQueue()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ ResolverQueue::addResItemToInstall (constResItemPtr resItem)
+ {
+ QueueItemInstallPtr item;
+
+ if (_context->resItemIsPresent (resItem)) {
+ printf ("%s is already installed", ((constSpecPtr)resItem)->asString().c_str());
+ return;
+ }
+
+ item = new QueueItemInstall (_context->world(), resItem);
+ item->setExplicitlyRequested ();
+
+ addItem (item);
+ }
+
+
+ void
+ ResolverQueue::addResItemToRemove (constResItemPtr resItem, bool remove_only_mode)
+ {
+ QueueItemUninstallPtr item;
+
+ if (_context->resItemIsAbsent (resItem))
+ return;
+
+ item = new QueueItemUninstall (_context->world(), resItem, "user request");
+ if (remove_only_mode)
+ item->setRemoveOnly ();
+
+ item->setExplicitlyRequested ();
+
+ addItem (item);
+ }
+
+
+ void
+ ResolverQueue::addResItemToVerify (constResItemPtr resItem)
+ {
+ WorldPtr world;
+
+ world = _context->world ();
+
+ CDependencyList requires = resItem->requires();
+ for (CDependencyList::const_iterator iter = requires.begin(); iter != requires.end(); iter++) {
+ QueueItemRequirePtr item = new QueueItemRequire (world, *iter);
+ item->addResItem (resItem);
+ addItem (item);
+ }
+
+ CDependencyList conflicts = resItem->conflicts();
+ for (CDependencyList::const_iterator iter = conflicts.begin(); iter != conflicts.end(); iter++) {
+ QueueItemConflictPtr item = new QueueItemConflict (world, *iter, resItem);
+ addItem (item);
+ }
+ }
+
+
+ void
+ ResolverQueue::addExtraDependency (constDependencyPtr dep)
+ {
+ QueueItemRequirePtr item = new QueueItemRequire (_context->world(), dep);
+ addItem (item);
+ }
+
+
+ void
+ ResolverQueue::addExtraConflict (constDependencyPtr dep)
+ {
+ QueueItemConflictPtr item = new QueueItemConflict (_context->world(), dep, NULL);
+ addItem (item);
+ }
+
+
+ void
+ ResolverQueue::addItem (QueueItemPtr item)
+ {
+ _items.push_front (item);
+ }
+
+
+ bool
+ ResolverQueue::isInvalid ()
+ {
+ return _context->isInvalid();
+ }
+
+
+ bool
+ ResolverQueue::containsOnlyBranches ()
+ {
+ for (QueueItemList::const_iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ if (!(*iter)->isBranch())
+ return false;
+ }
+
+ return true;
+ }
+
+ //---------------------------------------------------------------------------
+
+ static int
+ itemlist_max_priority (const QueueItemList & qil)
+ {
+ int max_priority = -1;
+ for (QueueItemList::const_iterator iter = qil.begin(); iter != qil.end(); iter++) {
+ if ((*iter)->priority() > max_priority) {
+ max_priority = (*iter)->priority();
+ }
+ }
+
+ return max_priority;
+ }
+
+
+
+ bool
+ ResolverQueue::processOnce ()
+ {
+ QueueItemList new_items;
+ int max_priority;
+ bool did_something = false;
+
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce(%s), %d items\n", asString().c_str(), (int) _items.size());
+ while ( (max_priority = itemlist_max_priority (_items)) >= 0
+ && _context->isValid () ) {
+
+ bool did_something_recently = false;
+
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce() inside loop\n");
+ for (QueueItemList::iterator iter = _items.begin(); iter != _items.end() && _context->isValid();) {
+ QueueItemPtr item = *iter;
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "=====> 1st pass: [%s]\n", item->asString().c_str());
+ QueueItemList::iterator next = iter; next++;
+ if (item && item->priority() == max_priority) {
+ if (item->process (_context, new_items)) {
+ did_something_recently = true;
+ }
+ _items.erase (iter);
+ }
+ iter = next;
+ }
+
+ if (did_something_recently) {
+ did_something = true;
+ }
+ }
+
+ _items = new_items;
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "%d items after first pass\n", (int) _items.size());
+
+ /*
+ Now make a second pass over the queue, removing any super-branches.
+ (If one branch contains all of the possible items of another branch,
+ the larger branch can be dropped.
+ */
+
+ // if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce() second pass\n");
+ for (QueueItemList::iterator iter = _items.begin(); iter != _items.end();) {
+ QueueItemList::iterator next = iter; next++;
+ QueueItemPtr item = *iter;
+
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "=====> 2nd pass: [%s]\n", item->asString().c_str());
+ if (item->isBranch()) {
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "ResolverQueue::processOnce() is branch\n");
+ QueueItemBranchPtr branch = (QueueItemBranchPtr)item;
+ for (QueueItemList::const_iterator iter2 = _items.begin(); iter2 != _items.end(); iter2++) {
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "Compare branch with [%s]\n", (*iter2)->asString().c_str());
+ if (iter != iter2
+ && branch->contains (*iter2)) {
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "Contained within, removing\n");
+ _items.erase (iter);
+ break;
+ }
+ }
+ }
+ iter = next;
+ }
+ if (getenv ("QUEUE_SPEW")) fprintf (stderr, "did %sthing: %d items\n", did_something ? "some" : "no", (int)_items.size());
+
+ return did_something;
+ }
+
+
+ void
+ ResolverQueue::process ()
+ {
+ bool very_noisy;
+
+ very_noisy = getenv ("RC_SPEW") != NULL;
+
+ if (very_noisy) {
+ printf ("----- Processing -----\n");
+ spew ();
+ }
+
+ while (_context->isValid ()
+ && ! isEmpty ()
+ && processOnce ()) {
+ /* all of the work is in the conditional! */
+ if (very_noisy) {
+ spew ();
+ }
+ }
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ static ResolverQueuePtr
+ copy_queue_except_for_branch (ResolverQueuePtr queue, QueueItemPtr branch_item, QueueItemPtr subitem)
+ {
+ ResolverContextPtr new_context;
+ ResolverQueuePtr new_queue;
+
+ new_context = new ResolverContext (queue->context());
+ new_queue = new ResolverQueue (new_context);
+
+ QueueItemList qil = queue->items();
+ for (QueueItemList::const_iterator iter = qil.begin(); iter != qil.end(); iter++) {
+ QueueItemPtr item = *iter;
+ QueueItemPtr new_item;
+
+ if (item == branch_item) {
+ new_item = subitem->copy ();
+
+ if (new_item->isInstall()) {
+ QueueItemInstallPtr install_item = (QueueItemInstallPtr)new_item;
+
+ /* Penalties are negative priorities */
+ int penalty;
+ penalty = - queue->context()->getChannelPriority (install_item->resItem()->channel());
+
+ install_item->setOtherPenalty (penalty);
+ }
+
+ } else {
+
+ new_item = item->copy ();
+
+ }
+
+ new_queue->addItem (new_item);
+ }
+
+ return new_queue;
+ }
+
+
+ void
+ ResolverQueue::splitFirstBranch (ResolverQueueList & new_queues, ResolverQueueList & deferred_queues)
+ {
+ QueueItemBranchPtr first_branch = NULL;
+ typedef std::map <QueueItemPtr, QueueItemPtr> DeferTable;
+ DeferTable to_defer;
+
+ for (QueueItemList::const_iterator iter = _items.begin(); iter != _items.end() && first_branch == NULL; iter++) {
+ QueueItemPtr item = *iter;
+ if (item->isBranch()) {
+ first_branch = (QueueItemBranchPtr)item;
+ }
+ }
+
+ if (first_branch == NULL)
+ return;
+
+ /*
+ Check for deferrable items: if we have two install items where the to-be-installed
+ resItems have the same name, then we will defer the lower-priority install if
+ one of the following is true:
+ (1) Both resItems have the same version
+ (2) The lower-priority channel is a previous version.
+ */
+
+ QueueItemList possible_items = first_branch->possibleItems();
+ for (QueueItemList::const_iterator iter = possible_items.begin(); iter != possible_items.end(); iter++) {
+ QueueItemList::const_iterator iter2 = iter;
+ for (iter2++; iter2 != possible_items.end(); iter2++) {
+ QueueItemPtr item = *iter;
+ QueueItemPtr item2 = *iter2;
+
+ if (item->isInstall() && item2->isInstall()) {
+ constResItemPtr r = ((QueueItemInstallPtr) item)->resItem();
+ constResItemPtr r2 = ((QueueItemInstallPtr) item2)->resItem();
+ constChannelPtr channel = r->channel();
+ constChannelPtr channel2 = r2->channel();
+ int priority, priority2;
+
+ priority = channel->getPriority (channel->isSubscribed());
+ priority2 = channel2->getPriority (channel2->isSubscribed());
+
+ if (priority != priority2 && r->name() == r2->name()) {
+ if (r->version() == r2->version()
+ || (priority < priority2 && GVersion.compare (r, r2) < 0)
+ || (priority > priority2 && GVersion.compare (r, r2) > 0)) {
+
+ if (priority < priority2)
+ to_defer[item] = item;
+ else /* if (priority > priority2) */
+ to_defer[item2] = item2;
+ }
+ }
+ }
+ }
+ }
+
+
+ for (QueueItemList::const_iterator iter = possible_items.begin(); iter != possible_items.end(); iter++) {
+ ResolverQueuePtr new_queue;
+ QueueItemPtr new_item = *iter;
+
+ new_queue = copy_queue_except_for_branch (this, (QueueItemPtr) first_branch, new_item);
+
+ DeferTable::const_iterator pos = to_defer.find (new_item);
+ if (pos != to_defer.end()) {
+ deferred_queues.push_back (new_queue);
+ } else {
+ new_queues.push_back (new_queue);
+ }
+ }
+
+ }
+
+
+ void
+ ResolverQueue::spew ()
+ {
+ printf ("Resolver Queue: %s\n", _context->isInvalid() ? "INVALID" : "");
+
+ if (_items.empty()) {
+
+ printf (" (empty)\n");
+
+ } else {
+
+ for (QueueItemList::const_iterator iter = _items.begin(); iter != _items.end(); iter++) {
+ printf (" %s\n", (*iter)->asString().c_str());
+ }
+
+ }
+
+ printf ("\n");
+ fflush (stdout);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResItemPtr.h>
#include <zypp/solver/detail/DependencyPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef std::list <ResolverQueuePtr> ResolverQueueList;
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ResolverQueue
+
+ class ResolverQueue : public CountedRep {
+
+ REP_BODY(ResolverQueue);
+
+ private:
+
+ ResolverContextPtr _context;
+ QueueItemList _items;
+
+ public:
+ ResolverQueue (ResolverContextPtr context = NULL);
+ virtual ~ResolverQueue();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverQueue & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverQueue & context);
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ ResolverContextPtr context (void) const { return _context; }
+ QueueItemList items(void) const { return _items; }
+
+ // ---------------------------------- methods
+
+
+ void addResItemToInstall (constResItemPtr resItem);
+ void addResItemToRemove (constResItemPtr resItem, bool remove_only_mode);
+ void addResItemToVerify (constResItemPtr resItem);
+ void addExtraDependency (constDependencyPtr dep);
+ void addExtraConflict (constDependencyPtr dep);
+ void addItem (QueueItemPtr item);
+
+ bool isEmpty () const { return _items.empty(); }
+ bool isInvalid ();
+ bool containsOnlyBranches ();
+
+ bool processOnce ();
+ void process ();
+
+ void splitFirstBranch (ResolverQueueList & new_queues, ResolverQueueList & deferred_queues);
+
+ void spew ();
+
+ };
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-typedef std::list <ResolverQueuePtr> ResolverQueueList;
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ResolverQueue
-
-class ResolverQueue : public CountedRep {
-
- REP_BODY(ResolverQueue);
-
- private:
-
- ResolverContextPtr _context;
- QueueItemList _items;
-
- public:
- ResolverQueue (ResolverContextPtr context = NULL);
- virtual ~ResolverQueue();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ResolverQueue & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverQueue & context);
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- ResolverContextPtr context (void) const { return _context; }
- QueueItemList items(void) const { return _items; }
-
- // ---------------------------------- methods
-
-
- void addResItemToInstall (constResItemPtr resItem);
- void addResItemToRemove (constResItemPtr resItem, bool remove_only_mode);
- void addResItemToVerify (constResItemPtr resItem);
- void addExtraDependency (constDependencyPtr dep);
- void addExtraConflict (constDependencyPtr dep);
- void addItem (QueueItemPtr item);
-
- bool isEmpty () const { return _items.empty(); }
- bool isInvalid ();
- bool containsOnlyBranches ();
-
- bool processOnce ();
- void process ();
-
- void splitFirstBranch (ResolverQueueList & new_queues, ResolverQueueList & deferred_queues);
-
- void spew ();
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ResolverQueue_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverQueuePtr
+ // CLASS NAME : constResolverQueuePtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(ResolverQueue);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ResolverQueuePtr
-// CLASS NAME : constResolverQueuePtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(ResolverQueue);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ResolverQueuePtr_h
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-string
-Section::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Section::asUserString ( void ) const
-{
- return toUserString (*this);
-}
-
-
-string
-Section::toString ( const Section & section )
-{
- switch (section.section()) {
- case SECTION_OFFICE: return ("office");
- case SECTION_IMAGING: return ("imaging");
- case SECTION_PIM: return ("pim");
- case SECTION_GAME: return ("game");
- case SECTION_MISC: return ("misc");
- case SECTION_MULTIMEDIA: return ("multimedia");
- case SECTION_INTERNET: return ("internet");
- case SECTION_UTIL: return ("util");
- case SECTION_SYSTEM: return ("system");
- case SECTION_DOC: return ("doc");
- case SECTION_DEVEL: return ("devel");
- case SECTION_DEVELUTIL: return ("develutil");
- case SECTION_LIBRARY: return ("library");
- case SECTION_XAPP: return ("xapp");
- default:
- rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid section number %d\n", section.section());
- }
- return ("misc");
-}
-
-string
-Section::toUserString ( const Section & section )
-{
- switch (section.section()) {
- case SECTION_OFFICE: return ("Productivity Applications");
- case SECTION_IMAGING: return ("Imaging");
- case SECTION_PIM: return ("Personal Information Management");
- case SECTION_GAME: return ("Games");
- case SECTION_MISC: return ("Miscellaneous");
- case SECTION_MULTIMEDIA: return ("Multimedia");
- case SECTION_INTERNET: return ("Internet Applications");
- case SECTION_UTIL: return ("Utilities");
- case SECTION_SYSTEM: return ("System Packages");
- case SECTION_DOC: return ("Documentation");
- case SECTION_DEVEL: return ("Development Packages");
- case SECTION_DEVELUTIL: return ("Development Utilities");
- case SECTION_LIBRARY: return ("Libraries");
- case SECTION_XAPP: return ("X Applications");
- default:
- rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid section number %d\n", section.section());
- }
-
- return ("Miscellaneous");
-}
-
-ostream &
-Section::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Section& section)
-{
- return os << section.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Section::Section(const char *section_str)
-{
- _section = SECTION_MISC;
-
- if (section_str != NULL) {
- switch (*section_str) {
- case 'd':
- if (!strcmp (section_str, "develutil")) {
- _section = SECTION_DEVELUTIL;
- }
- else if (!strcmp (section_str, "devel")) {
- _section = SECTION_DEVEL;
- }
- else if (!strcmp (section_str, "doc")) {
- _section = SECTION_DOC;
- }
- break;
- case 'g':
- if (!strcmp (section_str, "game")) {
- _section = SECTION_GAME;
- }
- break;
- case 'i':
- if (!strcmp (section_str, "imaging")) {
- _section = SECTION_IMAGING;
- }
- else if (!strcmp (section_str, "internet")) {
- _section = SECTION_INTERNET;
- }
- break;
- case 'l':
- if (!strcmp (section_str, "library")) {
- _section = SECTION_LIBRARY;
- }
- break;
- case 'm':
- if (!strcmp (section_str, "misc")) {
- _section = SECTION_MISC;
- }
- else if (!strcmp (section_str, "multimedia")) {
- _section = SECTION_MULTIMEDIA;
- }
- break;
- case 'o':
- if (!strcmp (section_str, "office")) {
- _section = SECTION_OFFICE;
- }
- break;
- case 'p':
- if (!strcmp (section_str, "pim")) {
- _section = SECTION_PIM;
- }
- break;
- case 's':
- if (!strcmp (section_str, "system")) {
- _section = SECTION_SYSTEM;
- }
- break;
- case 'u':
- if (!strcmp (section_str, "util")) {
- _section = SECTION_UTIL;
- }
- break;
- case 'x':
- if (!strcmp (section_str, "xapp")) {
- _section = SECTION_XAPP;
- }
- break;
- default:
- rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid section name %s\n", section_str);
- break;
- }
- } // if != NULL
-
-}
-
-
-Section::~Section()
-{
-}
-
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ string
+ Section::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Section::asUserString ( void ) const
+ {
+ return toUserString (*this);
+ }
+
+
+ string
+ Section::toString ( const Section & section )
+ {
+ switch (section.section()) {
+ case SECTION_OFFICE: return ("office");
+ case SECTION_IMAGING: return ("imaging");
+ case SECTION_PIM: return ("pim");
+ case SECTION_GAME: return ("game");
+ case SECTION_MISC: return ("misc");
+ case SECTION_MULTIMEDIA: return ("multimedia");
+ case SECTION_INTERNET: return ("internet");
+ case SECTION_UTIL: return ("util");
+ case SECTION_SYSTEM: return ("system");
+ case SECTION_DOC: return ("doc");
+ case SECTION_DEVEL: return ("devel");
+ case SECTION_DEVELUTIL: return ("develutil");
+ case SECTION_LIBRARY: return ("library");
+ case SECTION_XAPP: return ("xapp");
+ default:
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid section number %d\n", section.section());
+ }
+ return ("misc");
+ }
+
+ string
+ Section::toUserString ( const Section & section )
+ {
+ switch (section.section()) {
+ case SECTION_OFFICE: return ("Productivity Applications");
+ case SECTION_IMAGING: return ("Imaging");
+ case SECTION_PIM: return ("Personal Information Management");
+ case SECTION_GAME: return ("Games");
+ case SECTION_MISC: return ("Miscellaneous");
+ case SECTION_MULTIMEDIA: return ("Multimedia");
+ case SECTION_INTERNET: return ("Internet Applications");
+ case SECTION_UTIL: return ("Utilities");
+ case SECTION_SYSTEM: return ("System Packages");
+ case SECTION_DOC: return ("Documentation");
+ case SECTION_DEVEL: return ("Development Packages");
+ case SECTION_DEVELUTIL: return ("Development Utilities");
+ case SECTION_LIBRARY: return ("Libraries");
+ case SECTION_XAPP: return ("X Applications");
+ default:
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid section number %d\n", section.section());
+ }
+
+ return ("Miscellaneous");
+ }
+
+ ostream &
+ Section::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Section& section)
+ {
+ return os << section.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Section::Section(const char *section_str)
+ {
+ _section = SECTION_MISC;
+
+ if (section_str != NULL) {
+ switch (*section_str) {
+ case 'd':
+ if (!strcmp (section_str, "develutil")) {
+ _section = SECTION_DEVELUTIL;
+ }
+ else if (!strcmp (section_str, "devel")) {
+ _section = SECTION_DEVEL;
+ }
+ else if (!strcmp (section_str, "doc")) {
+ _section = SECTION_DOC;
+ }
+ break;
+ case 'g':
+ if (!strcmp (section_str, "game")) {
+ _section = SECTION_GAME;
+ }
+ break;
+ case 'i':
+ if (!strcmp (section_str, "imaging")) {
+ _section = SECTION_IMAGING;
+ }
+ else if (!strcmp (section_str, "internet")) {
+ _section = SECTION_INTERNET;
+ }
+ break;
+ case 'l':
+ if (!strcmp (section_str, "library")) {
+ _section = SECTION_LIBRARY;
+ }
+ break;
+ case 'm':
+ if (!strcmp (section_str, "misc")) {
+ _section = SECTION_MISC;
+ }
+ else if (!strcmp (section_str, "multimedia")) {
+ _section = SECTION_MULTIMEDIA;
+ }
+ break;
+ case 'o':
+ if (!strcmp (section_str, "office")) {
+ _section = SECTION_OFFICE;
+ }
+ break;
+ case 'p':
+ if (!strcmp (section_str, "pim")) {
+ _section = SECTION_PIM;
+ }
+ break;
+ case 's':
+ if (!strcmp (section_str, "system")) {
+ _section = SECTION_SYSTEM;
+ }
+ break;
+ case 'u':
+ if (!strcmp (section_str, "util")) {
+ _section = SECTION_UTIL;
+ }
+ break;
+ case 'x':
+ if (!strcmp (section_str, "xapp")) {
+ _section = SECTION_XAPP;
+ }
+ break;
+ default:
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "invalid section name %s\n", section_str);
+ break;
+ }
+ } // if != NULL
+
+ }
+
+
+ Section::~Section()
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <y2util/Ustring.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Section
-/**
- *
- **/
-class Section {
-
- private:
-
- typedef enum {
- SECTION_OFFICE = 0,
- SECTION_IMAGING,
- SECTION_PIM,
- SECTION_XAPP,
- SECTION_GAME,
- SECTION_MULTIMEDIA,
- SECTION_INTERNET,
- SECTION_UTIL,
- SECTION_SYSTEM,
- SECTION_DOC,
- SECTION_LIBRARY,
- SECTION_DEVEL,
- SECTION_DEVELUTIL,
- SECTION_MISC,
- SECTION_LAST
- } section_t;
-
- section_t _section;
-
- private:
- section_t section () const { return _section; }
-
- public:
-
- Section(const char *section_str);
- virtual ~Section();
-
- // ---------------------------------- I/O
-
- static std::string toString ( const Section & section);
- static std::string toUserString ( const Section & section);
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Section & section);
-
- std::string asString ( void ) const;
- std::string asUserString ( void ) const;
-
- // ---------------------------------- accessors
-
- // equality
- bool operator==( const Section & section) const {
- return _section == section.section();
- }
-
- // inequality
- bool operator!=( const Section & section) const {
- return !(*this == section);
- }
-
-};
-
-typedef Section * SectionPtr;
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Section
+ /**
+ *
+ **/
+ class Section {
+
+ private:
+
+ typedef enum {
+ SECTION_OFFICE = 0,
+ SECTION_IMAGING,
+ SECTION_PIM,
+ SECTION_XAPP,
+ SECTION_GAME,
+ SECTION_MULTIMEDIA,
+ SECTION_INTERNET,
+ SECTION_UTIL,
+ SECTION_SYSTEM,
+ SECTION_DOC,
+ SECTION_LIBRARY,
+ SECTION_DEVEL,
+ SECTION_DEVELUTIL,
+ SECTION_MISC,
+ SECTION_LAST
+ } section_t;
+
+ section_t _section;
+
+ private:
+ section_t section () const { return _section; }
+
+ public:
+
+ Section(const char *section_str);
+ virtual ~Section();
+
+ // ---------------------------------- I/O
+
+ static std::string toString ( const Section & section);
+ static std::string toUserString ( const Section & section);
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Section & section);
+
+ std::string asString ( void ) const;
+ std::string asUserString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ // equality
+ bool operator==( const Section & section) const {
+ return _section == section.section();
+ }
+
+ // inequality
+ bool operator!=( const Section & section) const {
+ return !(*this == section);
+ }
+
+ };
+
+ typedef Section * SectionPtr;
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Section_h
#include <zypp/solver/detail/ServiceWorld.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(ServiceWorld, World);
-
-//---------------------------------------------------------------------------
-
-string
-ServiceWorld::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-ServiceWorld::toString ( const ServiceWorld & service )
-{
- return "<serviceworld/>";
-}
-
-
-ostream &
-ServiceWorld::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const ServiceWorld & service)
-{
- return os << service.asString();
-}
-
-//---------------------------------------------------------------------------
-
-ServiceWorld::ServiceWorld ()
- : StoreWorld (SERVICE_WORLD)
-{
-}
-
-
-ServiceWorld::~ServiceWorld()
-{
- fprintf (stderr, "*** deleting service world[%p]: %s\n", this, World::toString(type()).c_str());
-}
-
-//---------------------------------------------------------------------------
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(ServiceWorld, World);
+
+ //---------------------------------------------------------------------------
+
+ string
+ ServiceWorld::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ ServiceWorld::toString ( const ServiceWorld & service )
+ {
+ return "<serviceworld/>";
+ }
+
+
+ ostream &
+ ServiceWorld::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const ServiceWorld & service)
+ {
+ return os << service.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ ServiceWorld::ServiceWorld ()
+ : StoreWorld (SERVICE_WORLD)
+ {
+ }
+
+
+ ServiceWorld::~ServiceWorld()
+ {
+ fprintf (stderr, "*** deleting service world[%p]: %s\n", this, World::toString(type()).c_str());
+ }
+
+ //---------------------------------------------------------------------------
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/StoreWorld.h>
#include <zypp/solver/detail/Channel.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-typedef bool (*ServiceWorldAssembleFn) (ServiceWorldPtr service, void *error); // GError **error
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef bool (*ServiceWorldAssembleFn) (ServiceWorldPtr service, void *error); // GError **error
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : ServiceWorld
+
+ class ServiceWorld : public StoreWorld {
+ REP_BODY(ServiceWorld);
+
+ private:
+
+ char *_url;
+ char *_name;
+ char *_unique_id;
+
+ bool _is_sticky; // if true, can't be unmounted
+ bool _is_invisible; // ... to users
+ bool _is_unsaved; // Never save into the services.xml file
+ bool _is_singleton; // only one such service at a time. FIXME: broken
+
+ ServiceWorldAssembleFn _assemble_fn;
+
+ public:
+
+ ServiceWorld ();
+ virtual ~ServiceWorld();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ServiceWorld & section);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const ServiceWorld & section);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ char *url () const { return _url; }
+ char *name () const { return _name; }
+ void setName (const char *name) { _name = strdup (name); }
+ char *unique_id () const { return _unique_id; }
+
+ // ---------------------------------- methods
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : ServiceWorld
-
-class ServiceWorld : public StoreWorld {
- REP_BODY(ServiceWorld);
-
- private:
-
- char *_url;
- char *_name;
- char *_unique_id;
-
- bool _is_sticky; // if true, can't be unmounted
- bool _is_invisible; // ... to users
- bool _is_unsaved; // Never save into the services.xml file
- bool _is_singleton; // only one such service at a time. FIXME: broken
-
- ServiceWorldAssembleFn _assemble_fn;
-
- public:
-
- ServiceWorld ();
- virtual ~ServiceWorld();
-
- // ---------------------------------- I/O
-
- static std::string toString (const ServiceWorld & section);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const ServiceWorld & section);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- char *url () const { return _url; }
- char *name () const { return _name; }
- void setName (const char *name) { _name = strdup (name); }
- char *unique_id () const { return _unique_id; }
-
- // ---------------------------------- methods
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ServiceWorld_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/WorldPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ServiceWorldPtr
+ // CLASS NAME : constServiceWorldPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(ServiceWorld, World);
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : ServiceWorldPtr
-// CLASS NAME : constServiceWorldPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(ServiceWorld, World);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _ServiceWorldPtr_h
#include <zypp/solver/detail/Spec.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(Spec);
-
-//---------------------------------------------------------------------------
-
-UstringHash Name::_nameHash;
-UstringHash Kind::_kindHash;
-const Kind & Kind::Unknown = Kind("");
-const Kind & Kind::Package = Kind("package");
-const Kind & Kind::Patch = Kind("patch");
-const Kind & Kind::Script = Kind("script");
-const Kind & Kind::Message = Kind("message");
-const Kind & Kind::Selection = Kind("selection");
-const Kind & Kind::Product = Kind("product");
-
-//---------------------------------------------------------------------------
-
-string
-Spec::asString ( bool full ) const
-{
- return toString (*this, full);
-}
-
-
-string
-Spec::toString ( const Spec & spec, bool full )
-{
- string res;
-
- if (full
- || (spec.kind() != Kind::Package
- && spec.kind() != Kind::Unknown)) {
- res += spec.kind().asString();
- res += ":";
- }
-
- res += spec.name();
-
- string ed = spec.edition()->asString (full);
- if (!ed.empty()) {
- res += "-";
- res += ed;
- }
-
- return res;
-}
-
-
-ostream &
-Spec::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Spec& spec)
-{
- return os << spec.asString();
-}
-
-//---------------------------------------------------------------------------
-
-Spec::Spec (const Kind & kind, const string & name, constEditionPtr edition)
- : _kind (kind)
- , _name (Name (name))
- , _edition (edition == NULL ? new Edition() : edition->copy())
-{
-}
-
-
-Spec::Spec ( const Kind & kind, const string & name, int epoch, const string & version, const string & release, const Arch * arch)
- : _kind (kind)
- , _name (Name (name))
- , _edition (new Edition (epoch, version, release, arch))
-{
-}
-
-
-Spec::Spec (constXmlNodePtr node)
- : _kind (Kind::Unknown)
-{
- fprintf (stderr, "Spec::Spec (constXmlNodePtr node)\nNot implemented\n");
- abort();
-}
-
-
-Spec::~Spec()
-{
-}
-
-
-// needed during xml parsing (-> XmlParser)
-
-constSpecPtr
-Spec::copy (void) const
-{
- return new Spec (_kind, _name, _edition);
-}
-
-
-#if 0
-xmlNode *
-rc_resItem_spec_to_xml_node (RCResItemSpec *spec)
-{
- xmlNode *spec_node;
- char buffer[128];
-
- spec_node = xmlNewNode (NULL, "spec");
-
- xmlNewTextChild (spec_node, NULL, "name",
- g_quark_to_string (spec->nameq));
-
- if (spec->has_epoch) {
- g_snprintf (buffer, 128, "%d", spec->epoch);
- xmlNewTextChild (spec_node, NULL, "epoch", buffer);
- }
-
- xmlNewTextChild (spec_node, NULL, "version", spec->version);
-
- if (spec->release)
- xmlNewTextChild (spec_node, NULL, "release", spec->release);
-
- xmlNewTextChild (spec_node, NULL, "arch",
- rc_arch_to_string (spec->arch));
-
- return spec_node;
-}
-
-#endif
-
-//---------------------------------------------------------------------------
-
-
-HashValue
-Spec::hash (void) const
-{
- HashValue ret = _edition->epoch() + 1;
- const char *spec_strs[3], *p;
- int i;
-
- spec_strs[0] = _name.asString().c_str();
- spec_strs[1] = _edition->version().c_str();
- spec_strs[2] = _edition->release().c_str();
-
- for (i = 0; i < 3; ++i) {
- p = spec_strs[i];
- if (p) {
- for (p += 1; *p != '\0'; ++p) {
- ret = (ret << 5) - ret + *p;
- }
- } else {
- ret = ret * 17;
- }
- }
-
- return ret;
-}
-
-
-const Spec *
-Spec::findByName (const SpecList &speclist, const Name & name) const
-{
- const Spec *spec = NULL;
- for (SpecList::const_iterator iter = speclist.begin(); iter != speclist.end(); iter++) {
- if ((*iter).name() == name) {
- spec = &(*iter);
- break;
- }
- }
- return spec;
-}
-
-
-bool
-Spec::match(constSpecPtr spec) const {
- return ((_kind == spec->kind())
- && (_name == spec->name())
- && _edition->match (spec->edition()));
-}
-
-
-bool
-Spec::equals(constSpecPtr spec) const {
-//fprintf (stderr, "<%s> equals <%s>\n", asString(true).c_str(), spec->asString(true).c_str());
- return ((_kind == spec->kind())
- && (_name == spec->name())
- && _edition->equals(spec->edition()));
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(Spec);
+
+ //---------------------------------------------------------------------------
+
+ UstringHash Name::_nameHash;
+ UstringHash Kind::_kindHash;
+ const Kind & Kind::Unknown = Kind("");
+ const Kind & Kind::Package = Kind("package");
+ const Kind & Kind::Patch = Kind("patch");
+ const Kind & Kind::Script = Kind("script");
+ const Kind & Kind::Message = Kind("message");
+ const Kind & Kind::Selection = Kind("selection");
+ const Kind & Kind::Product = Kind("product");
+
+ //---------------------------------------------------------------------------
+
+ string
+ Spec::asString ( bool full ) const
+ {
+ return toString (*this, full);
+ }
+
+
+ string
+ Spec::toString ( const Spec & spec, bool full )
+ {
+ string res;
+
+ if (full
+ || (spec.kind() != Kind::Package
+ && spec.kind() != Kind::Unknown)) {
+ res += spec.kind().asString();
+ res += ":";
+ }
+
+ res += spec.name();
+
+ string ed = spec.edition()->asString (full);
+ if (!ed.empty()) {
+ res += "-";
+ res += ed;
+ }
+
+ return res;
+ }
+
+
+ ostream &
+ Spec::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Spec& spec)
+ {
+ return os << spec.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Spec::Spec (const Kind & kind, const string & name, constEditionPtr edition)
+ : _kind (kind)
+ , _name (Name (name))
+ , _edition (edition == NULL ? new Edition() : edition->copy())
+ {
+ }
+
+
+ Spec::Spec ( const Kind & kind, const string & name, int epoch, const string & version, const string & release, const Arch * arch)
+ : _kind (kind)
+ , _name (Name (name))
+ , _edition (new Edition (epoch, version, release, arch))
+ {
+ }
+
+
+ Spec::Spec (constXmlNodePtr node)
+ : _kind (Kind::Unknown)
+ {
+ fprintf (stderr, "Spec::Spec (constXmlNodePtr node)\nNot implemented\n");
+ abort();
+ }
+
+
+ Spec::~Spec()
+ {
+ }
+
+
+ // needed during xml parsing (-> XmlParser)
+
+ constSpecPtr
+ Spec::copy (void) const
+ {
+ return new Spec (_kind, _name, _edition);
+ }
+
+
+ #if 0
+ xmlNode *
+ rc_resItem_spec_to_xml_node (RCResItemSpec *spec)
+ {
+ xmlNode *spec_node;
+ char buffer[128];
+
+ spec_node = xmlNewNode (NULL, "spec");
+
+ xmlNewTextChild (spec_node, NULL, "name",
+ g_quark_to_string (spec->nameq));
+
+ if (spec->has_epoch) {
+ g_snprintf (buffer, 128, "%d", spec->epoch);
+ xmlNewTextChild (spec_node, NULL, "epoch", buffer);
+ }
+
+ xmlNewTextChild (spec_node, NULL, "version", spec->version);
+
+ if (spec->release)
+ xmlNewTextChild (spec_node, NULL, "release", spec->release);
+
+ xmlNewTextChild (spec_node, NULL, "arch",
+ rc_arch_to_string (spec->arch));
+
+ return spec_node;
+ }
+
+ #endif
+
+ //---------------------------------------------------------------------------
+
+
+ HashValue
+ Spec::hash (void) const
+ {
+ HashValue ret = _edition->epoch() + 1;
+ const char *spec_strs[3], *p;
+ int i;
+
+ spec_strs[0] = _name.asString().c_str();
+ spec_strs[1] = _edition->version().c_str();
+ spec_strs[2] = _edition->release().c_str();
+
+ for (i = 0; i < 3; ++i) {
+ p = spec_strs[i];
+ if (p) {
+ for (p += 1; *p != '\0'; ++p) {
+ ret = (ret << 5) - ret + *p;
+ }
+ } else {
+ ret = ret * 17;
+ }
+ }
+
+ return ret;
+ }
+
+
+ const Spec *
+ Spec::findByName (const SpecList &speclist, const Name & name) const
+ {
+ const Spec *spec = NULL;
+ for (SpecList::const_iterator iter = speclist.begin(); iter != speclist.end(); iter++) {
+ if ((*iter).name() == name) {
+ spec = &(*iter);
+ break;
+ }
+ }
+ return spec;
+ }
+
+
+ bool
+ Spec::match(constSpecPtr spec) const {
+ return ((_kind == spec->kind())
+ && (_name == spec->name())
+ && _edition->match (spec->edition()));
+ }
+
+
+ bool
+ Spec::equals(constSpecPtr spec) const {
+ //fprintf (stderr, "<%s> equals <%s>\n", asString(true).c_str(), spec->asString(true).c_str());
+ return ((_kind == spec->kind())
+ && (_name == spec->name())
+ && _edition->equals(spec->edition()));
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/XmlNode.h>
#include <zypp/solver/detail/Edition.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////////
//
-// CLASS NAME : Spec
-/**
- *
- **/
-
-class Spec : public CountedRep {
- REP_BODY(Spec);
-
- private:
- Kind _kind;
- Name _name;
- EditionPtr _edition;
-
- public:
- typedef std::list<Spec> SpecList;
-
- Spec( const Kind & kind,
- const std::string & name,
- int epoch = -1,
- const std::string & version = "",
- const std::string & release = "",
- const Arch * arch = Arch::Unknown);
-
- Spec (const Kind & kind, const std::string & name, constEditionPtr edition);
-
- Spec (constXmlNodePtr node);
-
- virtual ~Spec();
-
- // ---------------------------------- I/O
-
- const xmlNodePtr asXmlNode (const char *name) const;
-
- static std::string toString ( const Spec & spec, bool full = false );
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Spec& );
-
- std::string asString ( bool full = false ) const;
-
- // ---------------------------------- accessors
-
- const std::string & version() const { return _edition->version(); }
- void setVersion (const std::string & version) { _edition->setVersion (version); }
-
- const std::string & release() const { return _edition->release(); }
- void setRelease (const std::string & release) { _edition->setRelease (release); }
-
- const int epoch() const { return _edition->epoch(); }
- void setEpoch (int epoch) { _edition->setEpoch (epoch); }
- bool hasEpoch() const { return _edition->hasEpoch(); }
-
- const Arch * arch() const { return _edition->arch(); }
- void setArch (const Arch * arch) { _edition->setArch (arch); }
- void setArch (const std::string & arch) { _edition->setArch (arch); }
-
- const Kind & kind() const { return _kind; }
- void setKind (const Kind & kind) { _kind = kind; }
-
- const std::string name() const { return _name; }
- void setName (const std::string & name) { _name = Name(name.c_str()); }
-
- constEditionPtr edition() const { return _edition; }
- void setEdition (constEditionPtr edition) { _edition = edition->copy(); }
-
- // calculate hash
- HashValue hash (void) const;
-
- // match operator
- bool match(constSpecPtr spec) const;
- bool equals (constSpecPtr spec) const;
-
- // find spec in SpecList by name
- const Spec * findByName (const SpecList &speclist, const Name & name) const;
-
- // copy
-
- constSpecPtr copy (void) const;
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ // CLASS NAME : Spec
+ /**
+ *
+ **/
+
+ class Spec : public CountedRep {
+ REP_BODY(Spec);
+
+ private:
+ Kind _kind;
+ Name _name;
+ EditionPtr _edition;
+
+ public:
+ typedef std::list<Spec> SpecList;
+
+ Spec( const Kind & kind,
+ const std::string & name,
+ int epoch = -1,
+ const std::string & version = "",
+ const std::string & release = "",
+ const Arch * arch = Arch::Unknown);
+
+ Spec (const Kind & kind, const std::string & name, constEditionPtr edition);
+
+ Spec (constXmlNodePtr node);
+
+ virtual ~Spec();
+
+ // ---------------------------------- I/O
+
+ const xmlNodePtr asXmlNode (const char *name) const;
+
+ static std::string toString ( const Spec & spec, bool full = false );
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Spec& );
+
+ std::string asString ( bool full = false ) const;
+
+ // ---------------------------------- accessors
+
+ const std::string & version() const { return _edition->version(); }
+ void setVersion (const std::string & version) { _edition->setVersion (version); }
+
+ const std::string & release() const { return _edition->release(); }
+ void setRelease (const std::string & release) { _edition->setRelease (release); }
+
+ const int epoch() const { return _edition->epoch(); }
+ void setEpoch (int epoch) { _edition->setEpoch (epoch); }
+ bool hasEpoch() const { return _edition->hasEpoch(); }
+
+ const Arch * arch() const { return _edition->arch(); }
+ void setArch (const Arch * arch) { _edition->setArch (arch); }
+ void setArch (const std::string & arch) { _edition->setArch (arch); }
+
+ const Kind & kind() const { return _kind; }
+ void setKind (const Kind & kind) { _kind = kind; }
+
+ const std::string name() const { return _name; }
+ void setName (const std::string & name) { _name = Name(name.c_str()); }
+
+ constEditionPtr edition() const { return _edition; }
+ void setEdition (constEditionPtr edition) { _edition = edition->copy(); }
+
+ // calculate hash
+ HashValue hash (void) const;
+
+ // match operator
+ bool match(constSpecPtr spec) const;
+ bool equals (constSpecPtr spec) const;
+
+ // find spec in SpecList by name
+ const Spec * findByName (const SpecList &speclist, const Name & name) const;
+
+ // copy
+
+ constSpecPtr copy (void) const;
+ };
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Spec_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : SpecPtr
-// CLASS NAME : constSpecPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(Spec);
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : SpecPtr
+ // CLASS NAME : constSpecPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(Spec);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
#endif // _SpecPtr_h
#include <zypp/solver/detail/ResItemAndDependency.h>
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(StoreWorld, World);
-
-//---------------------------------------------------------------------------
-
-string
-StoreWorld::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-StoreWorld::toString ( const StoreWorld & storeworld )
-{
- string res ("<storeworld/>");
-
- return res;
-}
-
-
-ostream &
-StoreWorld::dumpOn (ostream & str) const
-{
- str << asString();
- return str;
-}
-
-
-ostream &
-operator<< (ostream & os, const StoreWorld & storeworld)
-{
- return os << storeworld.asString();
-}
-
-//---------------------------------------------------------------------------
-
-StoreWorld::StoreWorld (WorldType type)
- : World (type)
- , _resItem_kind(Kind::Unknown)
-{
-}
-
-
-StoreWorld::~StoreWorld()
-{
- fprintf (stderr, "*** deleting store world[%p]: %s\n", this, World::toString(type()).c_str());
-}
-
-
-//---------------------------------------------------------------------------
-
-// Add/remove resItems
-
-bool
-StoreWorld::addResItem (constResItemPtr resItem)
-{
- ArchList compat_arch_list;
- ResItemAndDependencyPtr r_and_d;
- const char *package_name;
- constChannelPtr channel;
- int arch_score;
- bool actually_added_package = false;
-
- if (resItem == NULL) return false;
-
- compat_arch_list = Arch::System->getCompatList();
-//fprintf (stderr, "Arch::System '%s' -> %d compats\n", Arch::System->asString().c_str(), (int) compat_arch_list.size());
- channel = resItem->channel ();
-
-// fprintf (stderr, "StoreWorld[%p]::addResItem(%s) [%s]\n", this, ((constSpecPtr)resItem)->asString().c_str(), channel?channel->name():"?");
-
- arch_score = resItem->arch()->getCompatScore(compat_arch_list);
-
- /* Before we do anything, check to make sure that a resItem of the
- same name isn't already in that channel. If there is a
- duplicate, we keep the one with the most recent version number
- and drop the other.
-
- This check only applies to resItems in a channel. We have
- to allow for multiple installs. Grrrr...
- */
-
- if (!resItem->isInstalled ()) { // its not a system package
-
- constResItemPtr dup_res;
- int dup_arch_score;
-
- /* Filter out resItems with totally incompatible arches */
- if (arch_score < 0) {
- rc_debug (RC_DEBUG_LEVEL_DEBUG, "Ignoring resItem with incompatible arch: Arch '%s', %s", resItem->arch()->asString().c_str(), resItem->asString(true).c_str());
- goto finished;
- }
-
- package_name = resItem->name().c_str();
- dup_res = findResItem (channel, package_name);
-
- /* This shouldn't happen (and would be caught by the check
- below, because cmp will equal 0), but it never hurts to
- check and produce a more explicit warning message. */
-
- if (resItem == dup_res) {
- rc_debug (RC_DEBUG_LEVEL_WARNING, "Ignoring re-add of resItem '%s'", package_name);
- goto finished;
- }
-
- if (dup_res != NULL) {
- int cmp;
-
- cmp = GVersion.compare (resItem, dup_res);
-//fprintf (stderr, "res: %s, dup_res %s, cmp %d\n", resItem->asString().c_str(), dup_res->asString().c_str(), cmp);
- dup_arch_score = dup_res->arch()->getCompatScore(compat_arch_list);
-
-
- /* If the resItem we are trying to add has a lower
- version number, just ignore it. */
-
- if (cmp < 0) {
- rc_debug (RC_DEBUG_LEVEL_INFO, "Not adding resItem '%s'.\n\tA newer version is already in the channel.", resItem->asString().c_str());
- rc_debug (RC_DEBUG_LEVEL_INFO, "\t%s", dup_res->asString().c_str());
- goto finished;
- }
-
-
- /* If the version numbers are equal, we ignore the resItem to
- add if it has a less-preferable arch. If both
- resItems have the same version # and arch, we favor the
- first resItem and just return. */
-
- if (cmp == 0 && arch_score > dup_arch_score) {
- rc_debug (RC_DEBUG_LEVEL_INFO, "Not adding resItem '%s'.\n\tAnother resItem with the same version but with a preferred arch is already in the channel.", resItem->asString().c_str());
- rc_debug (RC_DEBUG_LEVEL_INFO, "\t%s", dup_res->asString().c_str());
- goto finished;
- }
-
-
- /* Otherwise we throw out the old resItem and proceed with
- adding the newer one. */
-
- rc_debug (RC_DEBUG_LEVEL_INFO, "Replacing resItem '%s'.\n\tAnother resItem in the channel has the same name and a superior %s.", dup_res->asString().c_str(), cmp ? "version" : "arch");
- rc_debug (RC_DEBUG_LEVEL_INFO, "\t%s", resItem->asString().c_str());
-
- removeResItem (dup_res);
- }
- }
-
- actually_added_package = true;
-
- if (channel && !channel->hidden()) {
- touchResItemSequenceNumber ();
- }
-
- /* StoreWorld all of our resItems in a hash by name. */
- _resItems_by_name.insert (ResItemTable::value_type (resItem->name(), resItem));
-
- /* StoreWorld all of the resItem's provides in a hash by name. */
- for (CDependencyList::const_iterator i = resItem->provides().begin(); i != resItem->provides().end(); i++) {
- r_and_d = new ResItemAndDependency (resItem, *i);
-
- _provides_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
- }
-
- /* StoreWorld all of the resItem's requires in a hash by name. */
-
- for (CDependencyList::const_iterator i = resItem->requires().begin(); i != resItem->requires().end(); i++) {
- r_and_d = new ResItemAndDependency (resItem, *i);
-
- _requires_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
- }
-
- /* "Recommends" are treated as requirements. */
-#warning Recommends are treated as requirements
-
- for (CDependencyList::const_iterator i = resItem->recommends().begin(); i != resItem->recommends().end(); i++) {
- r_and_d = new ResItemAndDependency (resItem, *i);
-
- _requires_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
- }
-
- /* StoreWorld all of the resItem's conflicts in a hash by name. */
-
- for (CDependencyList::const_iterator i = resItem->conflicts().begin(); i != resItem->conflicts().end(); i++) {
- r_and_d = new ResItemAndDependency (resItem, *i);
- _conflicts_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
- }
-
- finished:
-
- return actually_added_package;
-}
-
-
-void
-StoreWorld::addResItemsFromList (const CResItemList & slist)
-{
- for (CResItemList::const_iterator i = slist.begin(); i != slist.end(); i++) {
- if (!addResItem (*i)) {
- fprintf (stderr, "addResItem failed\n");
- break;
- }
- }
- return;
-}
-
-//---------------------------------------------------------------------------
-
-static void
-resItem_table_remove (ResItemTable & table, constResItemPtr resItem)
-{
- const string name = resItem->name();
- for (ResItemTable::iterator pos = table.lower_bound(name); pos != table.upper_bound(name); pos++) {
- constResItemPtr res = pos->second;
- if (res == resItem) {
- table.erase (pos);
- break;
- }
- }
- return;
-}
-
-
-static void
-resItem_and_dependency_table_remove (ResItemAndDependencyTable & table, constResItemPtr resItem)
-{
- const string name = resItem->name();
-// FIXME: this is inefficient but lower_bound can't to strcasecmp :-(
-// for (ResItemAndDependencyTable::iterator pos = table.lower_bound(name); pos != table.upper_bound(name); pos++) {
- for (ResItemAndDependencyTable::iterator pos = table.begin(); pos != table.end(); pos++) {
- constResItemAndDependencyPtr r_and_d = pos->second;
- if (r_and_d->resItem() == resItem) {
- table.erase (pos);
- break;
- }
- }
- return;
-}
-
-void
-StoreWorld::removeResItem (constResItemPtr resItem)
-{
- if (getenv("RC_SPEW")) fprintf (stderr, "StoreWorld::removeResItem (%s)\n", resItem->asString().c_str());
-
- constChannelPtr channel = resItem->channel ();
-
- if (! (channel && channel->hidden ()))
- touchResItemSequenceNumber ();
-
- resItem_and_dependency_table_remove (_provides_by_name, resItem);
- resItem_and_dependency_table_remove (_requires_by_name, resItem);
- resItem_and_dependency_table_remove (_conflicts_by_name, resItem);
-
- resItem_table_remove (_resItems_by_name, resItem);
-
- return;
-}
-
-
-void
-StoreWorld::removeResItems (constChannelPtr channel)
-{
- fprintf (stderr, "StoreWorld::removeResItems(%s) not implemented\n", channel->asString().c_str());
-}
-
-
-void
-StoreWorld::clear ()
-{
- fprintf (stderr, "StoreWorld::clear() not implemented\n");
-}
-
-//---------------------------------------------------------------------------
-// Single resItem queries
-
-static bool
-installed_version_cb (constResItemPtr resItem, void *data)
-{
- constResItemPtr *installed = (constResItemPtr *)data;
-
- if (resItem->isInstalled ()) {
- *installed = resItem;
- return false;
- }
- return true;
-}
-
-
-constResItemPtr
-StoreWorld::findInstalledResItem (constResItemPtr resItem)
-{
- constResItemPtr installed;
- sync ();
-
- foreachResItemByName (resItem->name(), new Channel(CHANNEL_TYPE_ANY) /* is this right? */, installed_version_cb, &installed);
-
- return installed;
-}
-
-
-//
-// findResItem
-// @channel: A non-wildcard #Channel.
-// @name: The name of a resItem.
-//
-// Searches the world for a resItem in the specified channel
-// with the specified name. @channel must be an actual
-// channel, not a wildcard.
-//
-// Return value: The matching resItem, or %NULL if no such
-// resItem exists.
-//
-
-constResItemPtr
-StoreWorld::findResItem (constChannelPtr channel, const char *name) const
-{
- syncConditional (channel);
- for (ResItemTable::const_iterator pos = _resItems_by_name.lower_bound(name); pos != _resItems_by_name.upper_bound(name); pos++) {
- constResItemPtr res = pos->second;
- if (res->channel() == channel) {
- return res;
- }
- }
- return NULL;
-}
-
-
-constResItemPtr
-StoreWorld::findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const
-{
- fprintf (stderr, "StoreWorld::findResItemWithConstraint() not implemented\n");
- return 0;
-}
-
-
-ChannelPtr
-StoreWorld::guessResItemChannel (constResItemPtr resItem) const
-{
- fprintf (stderr, "StoreWorld::guessResItemChannel(%s) not implemented\n", ((constSpecPtr)resItem)->asString().c_str());
- return 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// foreach resItem
-
-typedef struct {
- ChannelPtr channel;
- CResItemFn callback;
- void *data;
- int count;
- bool short_circuit;
-} ForeachResItemInfo;
-
-
-static void
-foreach_resItem_cb (const string &name, constResItemPtr resItem, void *data)
-{
- ForeachResItemInfo *info = (ForeachResItemInfo *)data;
-
- if (info->short_circuit)
- return;
-
- /* FIXME: we should filter out dup uninstalled resItems. */
-
- if (resItem && info->channel->equals(resItem->channel ())) {
- if (info->callback) {
- if (! info->callback (resItem, info->data))
- info->short_circuit = true;
- }
- ++info->count;
- }
-}
-
-
-int
-StoreWorld::foreachResItem (ChannelPtr channel, CResItemFn fn, void *data)
-{
- return foreachResItemByName ("", channel, fn, data);
-}
-
-
-int
-StoreWorld::foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data)
-{
- if (name.empty()) {
-
- ForeachResItemInfo info;
-
- info.channel = channel;
- info.callback = fn;
- info.data = data;
- info.count = 0;
- info.short_circuit = false;
-
- for (ResItemTable::const_iterator iter = _resItems_by_name.begin(); iter != _resItems_by_name.end(); iter++) {
- foreach_resItem_cb (iter->first, iter->second, (void *)&info);
- }
-
- return info.short_circuit ? -1 : info.count;
- }
-
-
- ResItemTable installed; // FIXME: <Spec, resItem> rc_resItem_spec_equal
- int count = 0;
-
- for (ResItemTable::const_iterator iter = _resItems_by_name.lower_bound(name); iter != _resItems_by_name.upper_bound(name); iter++) {
- constResItemPtr resItem = iter->second;
- if (resItem->isInstalled()) {
- const string str = ((constSpecPtr)resItem)->asString();
- installed.insert (ResItemTable::value_type(str,resItem));
- }
- }
-
- for (ResItemTable::const_iterator iter = _resItems_by_name.lower_bound(name); iter != _resItems_by_name.upper_bound(name); iter++) {
- constResItemPtr resItem = iter->second;
- if (channel->equals (resItem->channel())) {
- if (resItem->isInstalled()
- || installed.find(((constSpecPtr)resItem)->asString()) == installed.end()) {
- if (fn) {
- if (! fn(resItem, data)) {
- count = -1;
- goto finished;
- }
- }
- ++count;
- }
- }
- }
-
-finished:
-
- return count;
-}
-
-
-int
-StoreWorld::foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data)
-{
- fprintf (stderr, "StoreWorld::foreachResItemByMatch () not implemented\n");
- return 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// iterater over resItems with dependency
-
-typedef std::map<constSpecPtr, constResItemAndDependencyPtr> InstalledTable;
-
-int
-StoreWorld::foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data)
-{
- int count = 0;
- InstalledTable installed;
-//fprintf (stderr, "StoreWorld::foreachProvidingResItem(%s)\n", dep->asString().c_str());
- for (ResItemAndDependencyTable::const_iterator iter = _provides_by_name.lower_bound(dep->name()); iter != _provides_by_name.upper_bound(dep->name()); iter++) {
- constResItemAndDependencyPtr r_and_d = iter->second;
- constResItemPtr res = r_and_d->resItem();
-//fprintf (stderr, "StoreWorld::foreachProvidingResItem(): %s\n", res->asString(true).c_str());
- if (res != NULL && res->isInstalled ()) {
- installed[res] = r_and_d;
- }
- }
-
- for (ResItemAndDependencyTable::const_iterator iter = _provides_by_name.lower_bound(dep->name()); iter != _provides_by_name.upper_bound(dep->name()); iter++) {
- constResItemAndDependencyPtr r_and_d = iter->second;
-
- if (r_and_d && r_and_d->verifyRelation (dep)) {
-//fprintf (stderr, "found: %s\n", r_and_d->resItem()->asString(true).c_str());
- /* If we have multiple identical resItems in RCWorld,
- we want to only include the resItem that is installed and
- skip the rest. */
- if (r_and_d->resItem()->isInstalled()
- || installed.find(r_and_d->resItem()) == installed.end()) {
-
- if (fn) {
- if (! fn(r_and_d->resItem(), r_and_d->dependency(), data)) {
- count = -1;
- goto finished;
- }
- }
- ++count;
- }
- }
- }
-
- finished:
-
- return count;
-}
-
-int
-StoreWorld::foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
-{
- int count = 0;
- InstalledTable installed;
-
-
- for (ResItemAndDependencyTable::const_iterator iter = _requires_by_name.lower_bound(dep->name()); iter != _requires_by_name.upper_bound(dep->name()); iter++) {
- constResItemAndDependencyPtr r_and_d = iter->second;
- constResItemPtr res = r_and_d->resItem();
- if (res != NULL && res->isInstalled ()) {
-//fprintf (stderr, "is installed: %s\n", res->asString(true).c_str());
- installed[res] = r_and_d;
- }
- }
-
- for (ResItemAndDependencyTable::const_iterator iter = _requires_by_name.lower_bound(dep->name()); iter != _requires_by_name.upper_bound(dep->name()); iter++) {
- constResItemAndDependencyPtr r_and_d = iter->second;
-
- if (r_and_d && r_and_d->dependency()->verifyRelation (dep)) {
-
- /* Skip dups if one of them in installed. */
- if (r_and_d->resItem()->isInstalled()
- || installed.find(r_and_d->resItem()) == installed.end()) {
-
- if (fn) {
- if (! fn(r_and_d->resItem(), r_and_d->dependency(), data)) {
- count = -1;
- goto finished;
- }
- }
- ++count;
- }
- }
- }
-
- finished:
-
- return count;
-}
-
-
-int
-StoreWorld::foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
-{
- int count = 0;
- InstalledTable installed;
-//fprintf (stderr, "StoreWorld::foreachConflictingResItem (%s)\n", dep->name().c_str());
- for (ResItemAndDependencyTable::const_iterator iter = _conflicts_by_name.lower_bound(dep->name()); iter != _conflicts_by_name.upper_bound(dep->name()); iter++) {
- constResItemAndDependencyPtr r_and_d = iter->second;
- constResItemPtr res = r_and_d->resItem();
-//fprintf (stderr, "==> %s\n", res->asString().c_str());
- if (res != NULL && res->isInstalled ()) {
- installed[res] = r_and_d;
- }
- }
-
- for (ResItemAndDependencyTable::const_iterator iter = _conflicts_by_name.lower_bound(dep->name()); iter != _conflicts_by_name.upper_bound(dep->name()); iter++) {
- constResItemAndDependencyPtr r_and_d = iter->second;
-
- if (r_and_d)
-//fprintf (stderr, "==> %s verify %s ? %s\n", r_and_d->asString().c_str(), dep->asString().c_str(), r_and_d->verifyRelation (dep) ? "Y" : "N");
- if (r_and_d && r_and_d->verifyRelation (dep)) {
-
- /* Skip dups if one of them in installed. */
- if (r_and_d->resItem()->isInstalled()
- || installed.find(r_and_d->resItem()) == installed.end()) {
-
- if (fn) {
- if (! fn(r_and_d->resItem(), r_and_d->dependency(), data)) {
- count = -1;
- goto finished;
- }
- }
- ++count;
- }
- }
- }
-
- finished:
-
- return count;
-}
-
-//-----------------------------------------------------------------------------
-// channel functions
-
-void
-StoreWorld::addChannel (ChannelPtr channel)
-{
- if (channel == NULL) return;
-
- channel->setWorld (this);
- channel->setImmutable (true);
-
- _channels.push_back (channel);
-
- touchChannelSequenceNumber ();
-}
-
-
-void
-StoreWorld::removeChannel (constChannelPtr channel)
-{
- if (channel == NULL
- || ! containsChannel (channel))
- return;
-
- removeResItems (channel);
-
- for (ChannelList::iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
- if ((*iter)->equals (channel)) {
- _channels.erase (iter);
- touchChannelSequenceNumber ();
- break;
- }
- }
-}
-
-
-bool
-StoreWorld::containsChannel (constChannelPtr channel) const
-{
- for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
- if ((*iter)->equals (channel)) {
- return true;
- }
- }
- return false;
-}
-
-
-ChannelPtr
-StoreWorld::getChannelByName (const char *channel_name) const
-{
- if (channel_name == NULL
- || *channel_name == 0) {
- return NULL;
- }
-
- for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
- if (strcasecmp ((*iter)->name(), channel_name) == 0) {
- return *iter;
- }
- }
- return NULL;
-}
-
-
-ChannelPtr
-StoreWorld::getChannelByAlias (const char *alias) const
-{
- if (alias == NULL
- || *alias == 0) {
- return NULL;
- }
-
- for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
- if (strcasecmp ((*iter)->alias(), alias) == 0) {
- return *iter;
- }
- }
- return NULL;
-}
-
-
-ChannelPtr
-StoreWorld::getChannelById (const char *channel_id) const
-{
- if (channel_id == NULL
- || *channel_id == 0) {
- return NULL;
- }
-
- for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
- if (strcasecmp ((*iter)->id(), channel_id) == 0) {
- return *iter;
- }
- }
- return NULL;
-}
-
-
-int
-StoreWorld::foreachChannel (ChannelFn fn, void *data) const
-{
- int count = 0;
- for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
- if (!(*fn) (*iter, data))
- return -1;
- count++;
- }
- return count;
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(StoreWorld, World);
+
+ //---------------------------------------------------------------------------
+
+ string
+ StoreWorld::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ StoreWorld::toString ( const StoreWorld & storeworld )
+ {
+ string res ("<storeworld/>");
+
+ return res;
+ }
+
+
+ ostream &
+ StoreWorld::dumpOn (ostream & str) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream &
+ operator<< (ostream & os, const StoreWorld & storeworld)
+ {
+ return os << storeworld.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ StoreWorld::StoreWorld (WorldType type)
+ : World (type)
+ , _resItem_kind(Kind::Unknown)
+ {
+ }
+
+
+ StoreWorld::~StoreWorld()
+ {
+ fprintf (stderr, "*** deleting store world[%p]: %s\n", this, World::toString(type()).c_str());
+ }
+
+
+ //---------------------------------------------------------------------------
+
+ // Add/remove resItems
+
+ bool
+ StoreWorld::addResItem (constResItemPtr resItem)
+ {
+ ArchList compat_arch_list;
+ ResItemAndDependencyPtr r_and_d;
+ const char *package_name;
+ constChannelPtr channel;
+ int arch_score;
+ bool actually_added_package = false;
+
+ if (resItem == NULL) return false;
+
+ compat_arch_list = Arch::System->getCompatList();
+ //fprintf (stderr, "Arch::System '%s' -> %d compats\n", Arch::System->asString().c_str(), (int) compat_arch_list.size());
+ channel = resItem->channel ();
+
+ // fprintf (stderr, "StoreWorld[%p]::addResItem(%s) [%s]\n", this, ((constSpecPtr)resItem)->asString().c_str(), channel?channel->name():"?");
+
+ arch_score = resItem->arch()->getCompatScore(compat_arch_list);
+
+ /* Before we do anything, check to make sure that a resItem of the
+ same name isn't already in that channel. If there is a
+ duplicate, we keep the one with the most recent version number
+ and drop the other.
+
+ This check only applies to resItems in a channel. We have
+ to allow for multiple installs. Grrrr...
+ */
+
+ if (!resItem->isInstalled ()) { // its not a system package
+
+ constResItemPtr dup_res;
+ int dup_arch_score;
+
+ /* Filter out resItems with totally incompatible arches */
+ if (arch_score < 0) {
+ rc_debug (RC_DEBUG_LEVEL_DEBUG, "Ignoring resItem with incompatible arch: Arch '%s', %s", resItem->arch()->asString().c_str(), resItem->asString(true).c_str());
+ goto finished;
+ }
+
+ package_name = resItem->name().c_str();
+ dup_res = findResItem (channel, package_name);
+
+ /* This shouldn't happen (and would be caught by the check
+ below, because cmp will equal 0), but it never hurts to
+ check and produce a more explicit warning message. */
+
+ if (resItem == dup_res) {
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "Ignoring re-add of resItem '%s'", package_name);
+ goto finished;
+ }
+
+ if (dup_res != NULL) {
+ int cmp;
+
+ cmp = GVersion.compare (resItem, dup_res);
+ //fprintf (stderr, "res: %s, dup_res %s, cmp %d\n", resItem->asString().c_str(), dup_res->asString().c_str(), cmp);
+ dup_arch_score = dup_res->arch()->getCompatScore(compat_arch_list);
+
+
+ /* If the resItem we are trying to add has a lower
+ version number, just ignore it. */
+
+ if (cmp < 0) {
+ rc_debug (RC_DEBUG_LEVEL_INFO, "Not adding resItem '%s'.\n\tA newer version is already in the channel.", resItem->asString().c_str());
+ rc_debug (RC_DEBUG_LEVEL_INFO, "\t%s", dup_res->asString().c_str());
+ goto finished;
+ }
+
+
+ /* If the version numbers are equal, we ignore the resItem to
+ add if it has a less-preferable arch. If both
+ resItems have the same version # and arch, we favor the
+ first resItem and just return. */
+
+ if (cmp == 0 && arch_score > dup_arch_score) {
+ rc_debug (RC_DEBUG_LEVEL_INFO, "Not adding resItem '%s'.\n\tAnother resItem with the same version but with a preferred arch is already in the channel.", resItem->asString().c_str());
+ rc_debug (RC_DEBUG_LEVEL_INFO, "\t%s", dup_res->asString().c_str());
+ goto finished;
+ }
+
+
+ /* Otherwise we throw out the old resItem and proceed with
+ adding the newer one. */
+
+ rc_debug (RC_DEBUG_LEVEL_INFO, "Replacing resItem '%s'.\n\tAnother resItem in the channel has the same name and a superior %s.", dup_res->asString().c_str(), cmp ? "version" : "arch");
+ rc_debug (RC_DEBUG_LEVEL_INFO, "\t%s", resItem->asString().c_str());
+
+ removeResItem (dup_res);
+ }
+ }
+
+ actually_added_package = true;
+
+ if (channel && !channel->hidden()) {
+ touchResItemSequenceNumber ();
+ }
+
+ /* StoreWorld all of our resItems in a hash by name. */
+ _resItems_by_name.insert (ResItemTable::value_type (resItem->name(), resItem));
+
+ /* StoreWorld all of the resItem's provides in a hash by name. */
+ for (CDependencyList::const_iterator i = resItem->provides().begin(); i != resItem->provides().end(); i++) {
+ r_and_d = new ResItemAndDependency (resItem, *i);
+
+ _provides_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
+ }
+
+ /* StoreWorld all of the resItem's requires in a hash by name. */
+
+ for (CDependencyList::const_iterator i = resItem->requires().begin(); i != resItem->requires().end(); i++) {
+ r_and_d = new ResItemAndDependency (resItem, *i);
+
+ _requires_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
+ }
+
+ /* "Recommends" are treated as requirements. */
+ #warning Recommends are treated as requirements
+
+ for (CDependencyList::const_iterator i = resItem->recommends().begin(); i != resItem->recommends().end(); i++) {
+ r_and_d = new ResItemAndDependency (resItem, *i);
+
+ _requires_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
+ }
+
+ /* StoreWorld all of the resItem's conflicts in a hash by name. */
+
+ for (CDependencyList::const_iterator i = resItem->conflicts().begin(); i != resItem->conflicts().end(); i++) {
+ r_and_d = new ResItemAndDependency (resItem, *i);
+ _conflicts_by_name.insert (ResItemAndDependencyTable::value_type (r_and_d->dependency()->name(), r_and_d));
+ }
+
+ finished:
+
+ return actually_added_package;
+ }
+
+
+ void
+ StoreWorld::addResItemsFromList (const CResItemList & slist)
+ {
+ for (CResItemList::const_iterator i = slist.begin(); i != slist.end(); i++) {
+ if (!addResItem (*i)) {
+ fprintf (stderr, "addResItem failed\n");
+ break;
+ }
+ }
+ return;
+ }
+
+ //---------------------------------------------------------------------------
+
+ static void
+ resItem_table_remove (ResItemTable & table, constResItemPtr resItem)
+ {
+ const string name = resItem->name();
+ for (ResItemTable::iterator pos = table.lower_bound(name); pos != table.upper_bound(name); pos++) {
+ constResItemPtr res = pos->second;
+ if (res == resItem) {
+ table.erase (pos);
+ break;
+ }
+ }
+ return;
+ }
+
+
+ static void
+ resItem_and_dependency_table_remove (ResItemAndDependencyTable & table, constResItemPtr resItem)
+ {
+ const string name = resItem->name();
+ // FIXME: this is inefficient but lower_bound can't to strcasecmp :-(
+ // for (ResItemAndDependencyTable::iterator pos = table.lower_bound(name); pos != table.upper_bound(name); pos++) {
+ for (ResItemAndDependencyTable::iterator pos = table.begin(); pos != table.end(); pos++) {
+ constResItemAndDependencyPtr r_and_d = pos->second;
+ if (r_and_d->resItem() == resItem) {
+ table.erase (pos);
+ break;
+ }
+ }
+ return;
+ }
+
+ void
+ StoreWorld::removeResItem (constResItemPtr resItem)
+ {
+ if (getenv("RC_SPEW")) fprintf (stderr, "StoreWorld::removeResItem (%s)\n", resItem->asString().c_str());
+
+ constChannelPtr channel = resItem->channel ();
+
+ if (! (channel && channel->hidden ()))
+ touchResItemSequenceNumber ();
+
+ resItem_and_dependency_table_remove (_provides_by_name, resItem);
+ resItem_and_dependency_table_remove (_requires_by_name, resItem);
+ resItem_and_dependency_table_remove (_conflicts_by_name, resItem);
+
+ resItem_table_remove (_resItems_by_name, resItem);
+
+ return;
+ }
+
+
+ void
+ StoreWorld::removeResItems (constChannelPtr channel)
+ {
+ fprintf (stderr, "StoreWorld::removeResItems(%s) not implemented\n", channel->asString().c_str());
+ }
+
+
+ void
+ StoreWorld::clear ()
+ {
+ fprintf (stderr, "StoreWorld::clear() not implemented\n");
+ }
+
+ //---------------------------------------------------------------------------
+ // Single resItem queries
+
+ static bool
+ installed_version_cb (constResItemPtr resItem, void *data)
+ {
+ constResItemPtr *installed = (constResItemPtr *)data;
+
+ if (resItem->isInstalled ()) {
+ *installed = resItem;
+ return false;
+ }
+ return true;
+ }
+
+
+ constResItemPtr
+ StoreWorld::findInstalledResItem (constResItemPtr resItem)
+ {
+ constResItemPtr installed;
+ sync ();
+
+ foreachResItemByName (resItem->name(), new Channel(CHANNEL_TYPE_ANY) /* is this right? */, installed_version_cb, &installed);
+
+ return installed;
+ }
+
+
+ //
+ // findResItem
+ // @channel: A non-wildcard #Channel.
+ // @name: The name of a resItem.
+ //
+ // Searches the world for a resItem in the specified channel
+ // with the specified name. @channel must be an actual
+ // channel, not a wildcard.
+ //
+ // Return value: The matching resItem, or %NULL if no such
+ // resItem exists.
+ //
+
+ constResItemPtr
+ StoreWorld::findResItem (constChannelPtr channel, const char *name) const
+ {
+ syncConditional (channel);
+ for (ResItemTable::const_iterator pos = _resItems_by_name.lower_bound(name); pos != _resItems_by_name.upper_bound(name); pos++) {
+ constResItemPtr res = pos->second;
+ if (res->channel() == channel) {
+ return res;
+ }
+ }
+ return NULL;
+ }
+
+
+ constResItemPtr
+ StoreWorld::findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const
+ {
+ fprintf (stderr, "StoreWorld::findResItemWithConstraint() not implemented\n");
+ return 0;
+ }
+
+
+ ChannelPtr
+ StoreWorld::guessResItemChannel (constResItemPtr resItem) const
+ {
+ fprintf (stderr, "StoreWorld::guessResItemChannel(%s) not implemented\n", ((constSpecPtr)resItem)->asString().c_str());
+ return 0;
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // foreach resItem
+
+ typedef struct {
+ ChannelPtr channel;
+ CResItemFn callback;
+ void *data;
+ int count;
+ bool short_circuit;
+ } ForeachResItemInfo;
+
+
+ static void
+ foreach_resItem_cb (const string &name, constResItemPtr resItem, void *data)
+ {
+ ForeachResItemInfo *info = (ForeachResItemInfo *)data;
+
+ if (info->short_circuit)
+ return;
+
+ /* FIXME: we should filter out dup uninstalled resItems. */
+
+ if (resItem && info->channel->equals(resItem->channel ())) {
+ if (info->callback) {
+ if (! info->callback (resItem, info->data))
+ info->short_circuit = true;
+ }
+ ++info->count;
+ }
+ }
+
+
+ int
+ StoreWorld::foreachResItem (ChannelPtr channel, CResItemFn fn, void *data)
+ {
+ return foreachResItemByName ("", channel, fn, data);
+ }
+
+
+ int
+ StoreWorld::foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data)
+ {
+ if (name.empty()) {
+
+ ForeachResItemInfo info;
+
+ info.channel = channel;
+ info.callback = fn;
+ info.data = data;
+ info.count = 0;
+ info.short_circuit = false;
+
+ for (ResItemTable::const_iterator iter = _resItems_by_name.begin(); iter != _resItems_by_name.end(); iter++) {
+ foreach_resItem_cb (iter->first, iter->second, (void *)&info);
+ }
+
+ return info.short_circuit ? -1 : info.count;
+ }
+
+
+ ResItemTable installed; // FIXME: <Spec, resItem> rc_resItem_spec_equal
+ int count = 0;
+
+ for (ResItemTable::const_iterator iter = _resItems_by_name.lower_bound(name); iter != _resItems_by_name.upper_bound(name); iter++) {
+ constResItemPtr resItem = iter->second;
+ if (resItem->isInstalled()) {
+ const string str = ((constSpecPtr)resItem)->asString();
+ installed.insert (ResItemTable::value_type(str,resItem));
+ }
+ }
+
+ for (ResItemTable::const_iterator iter = _resItems_by_name.lower_bound(name); iter != _resItems_by_name.upper_bound(name); iter++) {
+ constResItemPtr resItem = iter->second;
+ if (channel->equals (resItem->channel())) {
+ if (resItem->isInstalled()
+ || installed.find(((constSpecPtr)resItem)->asString()) == installed.end()) {
+ if (fn) {
+ if (! fn(resItem, data)) {
+ count = -1;
+ goto finished;
+ }
+ }
+ ++count;
+ }
+ }
+ }
+
+ finished:
+
+ return count;
+ }
+
+
+ int
+ StoreWorld::foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data)
+ {
+ fprintf (stderr, "StoreWorld::foreachResItemByMatch () not implemented\n");
+ return 0;
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // iterater over resItems with dependency
+
+ typedef std::map<constSpecPtr, constResItemAndDependencyPtr> InstalledTable;
+
+ int
+ StoreWorld::foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data)
+ {
+ int count = 0;
+ InstalledTable installed;
+ //fprintf (stderr, "StoreWorld::foreachProvidingResItem(%s)\n", dep->asString().c_str());
+ for (ResItemAndDependencyTable::const_iterator iter = _provides_by_name.lower_bound(dep->name()); iter != _provides_by_name.upper_bound(dep->name()); iter++) {
+ constResItemAndDependencyPtr r_and_d = iter->second;
+ constResItemPtr res = r_and_d->resItem();
+ //fprintf (stderr, "StoreWorld::foreachProvidingResItem(): %s\n", res->asString(true).c_str());
+ if (res != NULL && res->isInstalled ()) {
+ installed[res] = r_and_d;
+ }
+ }
+
+ for (ResItemAndDependencyTable::const_iterator iter = _provides_by_name.lower_bound(dep->name()); iter != _provides_by_name.upper_bound(dep->name()); iter++) {
+ constResItemAndDependencyPtr r_and_d = iter->second;
+
+ if (r_and_d && r_and_d->verifyRelation (dep)) {
+ //fprintf (stderr, "found: %s\n", r_and_d->resItem()->asString(true).c_str());
+ /* If we have multiple identical resItems in RCWorld,
+ we want to only include the resItem that is installed and
+ skip the rest. */
+ if (r_and_d->resItem()->isInstalled()
+ || installed.find(r_and_d->resItem()) == installed.end()) {
+
+ if (fn) {
+ if (! fn(r_and_d->resItem(), r_and_d->dependency(), data)) {
+ count = -1;
+ goto finished;
+ }
+ }
+ ++count;
+ }
+ }
+ }
+
+ finished:
+
+ return count;
+ }
+
+ int
+ StoreWorld::foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
+ {
+ int count = 0;
+ InstalledTable installed;
+
+
+ for (ResItemAndDependencyTable::const_iterator iter = _requires_by_name.lower_bound(dep->name()); iter != _requires_by_name.upper_bound(dep->name()); iter++) {
+ constResItemAndDependencyPtr r_and_d = iter->second;
+ constResItemPtr res = r_and_d->resItem();
+ if (res != NULL && res->isInstalled ()) {
+ //fprintf (stderr, "is installed: %s\n", res->asString(true).c_str());
+ installed[res] = r_and_d;
+ }
+ }
+
+ for (ResItemAndDependencyTable::const_iterator iter = _requires_by_name.lower_bound(dep->name()); iter != _requires_by_name.upper_bound(dep->name()); iter++) {
+ constResItemAndDependencyPtr r_and_d = iter->second;
+
+ if (r_and_d && r_and_d->dependency()->verifyRelation (dep)) {
+
+ /* Skip dups if one of them in installed. */
+ if (r_and_d->resItem()->isInstalled()
+ || installed.find(r_and_d->resItem()) == installed.end()) {
+
+ if (fn) {
+ if (! fn(r_and_d->resItem(), r_and_d->dependency(), data)) {
+ count = -1;
+ goto finished;
+ }
+ }
+ ++count;
+ }
+ }
+ }
+
+ finished:
+
+ return count;
+ }
+
+
+ int
+ StoreWorld::foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data)
+ {
+ int count = 0;
+ InstalledTable installed;
+ //fprintf (stderr, "StoreWorld::foreachConflictingResItem (%s)\n", dep->name().c_str());
+ for (ResItemAndDependencyTable::const_iterator iter = _conflicts_by_name.lower_bound(dep->name()); iter != _conflicts_by_name.upper_bound(dep->name()); iter++) {
+ constResItemAndDependencyPtr r_and_d = iter->second;
+ constResItemPtr res = r_and_d->resItem();
+ //fprintf (stderr, "==> %s\n", res->asString().c_str());
+ if (res != NULL && res->isInstalled ()) {
+ installed[res] = r_and_d;
+ }
+ }
+
+ for (ResItemAndDependencyTable::const_iterator iter = _conflicts_by_name.lower_bound(dep->name()); iter != _conflicts_by_name.upper_bound(dep->name()); iter++) {
+ constResItemAndDependencyPtr r_and_d = iter->second;
+
+ if (r_and_d)
+ //fprintf (stderr, "==> %s verify %s ? %s\n", r_and_d->asString().c_str(), dep->asString().c_str(), r_and_d->verifyRelation (dep) ? "Y" : "N");
+ if (r_and_d && r_and_d->verifyRelation (dep)) {
+
+ /* Skip dups if one of them in installed. */
+ if (r_and_d->resItem()->isInstalled()
+ || installed.find(r_and_d->resItem()) == installed.end()) {
+
+ if (fn) {
+ if (! fn(r_and_d->resItem(), r_and_d->dependency(), data)) {
+ count = -1;
+ goto finished;
+ }
+ }
+ ++count;
+ }
+ }
+ }
+
+ finished:
+
+ return count;
+ }
+
+ //-----------------------------------------------------------------------------
+ // channel functions
+
+ void
+ StoreWorld::addChannel (ChannelPtr channel)
+ {
+ if (channel == NULL) return;
+
+ channel->setWorld (this);
+ channel->setImmutable (true);
+
+ _channels.push_back (channel);
+
+ touchChannelSequenceNumber ();
+ }
+
+
+ void
+ StoreWorld::removeChannel (constChannelPtr channel)
+ {
+ if (channel == NULL
+ || ! containsChannel (channel))
+ return;
+
+ removeResItems (channel);
+
+ for (ChannelList::iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
+ if ((*iter)->equals (channel)) {
+ _channels.erase (iter);
+ touchChannelSequenceNumber ();
+ break;
+ }
+ }
+ }
+
+
+ bool
+ StoreWorld::containsChannel (constChannelPtr channel) const
+ {
+ for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
+ if ((*iter)->equals (channel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ ChannelPtr
+ StoreWorld::getChannelByName (const char *channel_name) const
+ {
+ if (channel_name == NULL
+ || *channel_name == 0) {
+ return NULL;
+ }
+
+ for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
+ if (strcasecmp ((*iter)->name(), channel_name) == 0) {
+ return *iter;
+ }
+ }
+ return NULL;
+ }
+
+
+ ChannelPtr
+ StoreWorld::getChannelByAlias (const char *alias) const
+ {
+ if (alias == NULL
+ || *alias == 0) {
+ return NULL;
+ }
+
+ for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
+ if (strcasecmp ((*iter)->alias(), alias) == 0) {
+ return *iter;
+ }
+ }
+ return NULL;
+ }
+
+
+ ChannelPtr
+ StoreWorld::getChannelById (const char *channel_id) const
+ {
+ if (channel_id == NULL
+ || *channel_id == 0) {
+ return NULL;
+ }
+
+ for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
+ if (strcasecmp ((*iter)->id(), channel_id) == 0) {
+ return *iter;
+ }
+ }
+ return NULL;
+ }
+
+
+ int
+ StoreWorld::foreachChannel (ChannelFn fn, void *data) const
+ {
+ int count = 0;
+ for (ChannelList::const_iterator iter = _channels.begin(); iter != _channels.end(); iter++) {
+ if (!(*fn) (*iter, data))
+ return -1;
+ count++;
+ }
+ return count;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/ResItem.h>
#include <zypp/solver/detail/Match.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : StoreWorld
-
-class StoreWorld : public World {
- REP_BODY(StoreWorld);
-
- private:
-
- int _freeze_count;
-
- ResItemTable _resItems_by_name;
- ResItemAndDependencyTable _provides_by_name;
- ResItemAndDependencyTable _requires_by_name;
- ResItemAndDependencyTable _conflicts_by_name;
-
- PackmanPtr _packman;
- Kind _resItem_kind;
-
- ChannelList _channels;
-
- public:
-
- StoreWorld (WorldType type = STORE_WORLD);
- virtual ~StoreWorld();
-
- // ---------------------------------- I/O
-
- static std::string toString (const StoreWorld & storeworld);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const StoreWorld & storeworld);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- virtual ChannelList channels () const { return _channels; }
-
- // ---------------------------------- methods
-
- // Add/remove resItems
-
- bool addResItem (constResItemPtr resItem);
- void addResItemsFromList (const CResItemList & slist);
- void removeResItem (constResItemPtr resItem);
- void removeResItems (constChannelPtr channel);
- void clear ();
-
- // Iterate over resItems
-
- virtual int foreachResItem (ChannelPtr channel, CResItemFn fn, void *data);
- virtual int foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data);
- virtual int foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data);
-
- // Iterate across provides or requirement
-
- virtual int foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data);
- virtual int foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
- virtual int foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
-
- // Channels
-
- void addChannel (ChannelPtr channel);
- void removeChannel (constChannelPtr channel);
-
- virtual bool containsChannel (constChannelPtr channel) const;
-
- virtual ChannelPtr getChannelByName (const char *channel_name) const;
- virtual ChannelPtr getChannelByAlias (const char *alias) const;
- virtual ChannelPtr getChannelById (const char *channel_id) const;
-
- virtual int foreachChannel (ChannelFn fn, void *data) const;
-
- // Single resItem queries
-
- virtual constResItemPtr findInstalledResItem (constResItemPtr resItem);
- virtual constResItemPtr findResItem (constChannelPtr channel, const char *name) const;
- virtual constResItemPtr findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const;
- virtual ChannelPtr guessResItemChannel (constResItemPtr resItem) const;
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : StoreWorld
+
+ class StoreWorld : public World {
+ REP_BODY(StoreWorld);
+
+ private:
+
+ int _freeze_count;
+
+ ResItemTable _resItems_by_name;
+ ResItemAndDependencyTable _provides_by_name;
+ ResItemAndDependencyTable _requires_by_name;
+ ResItemAndDependencyTable _conflicts_by_name;
+
+ PackmanPtr _packman;
+ Kind _resItem_kind;
+
+ ChannelList _channels;
+
+ public:
+
+ StoreWorld (WorldType type = STORE_WORLD);
+ virtual ~StoreWorld();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const StoreWorld & storeworld);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const StoreWorld & storeworld);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ virtual ChannelList channels () const { return _channels; }
+
+ // ---------------------------------- methods
+
+ // Add/remove resItems
+
+ bool addResItem (constResItemPtr resItem);
+ void addResItemsFromList (const CResItemList & slist);
+ void removeResItem (constResItemPtr resItem);
+ void removeResItems (constChannelPtr channel);
+ void clear ();
+
+ // Iterate over resItems
+
+ virtual int foreachResItem (ChannelPtr channel, CResItemFn fn, void *data);
+ virtual int foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *data);
+ virtual int foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *data);
+
+ // Iterate across provides or requirement
+
+ virtual int foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *data);
+ virtual int foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
+ virtual int foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *data);
+
+ // Channels
+
+ void addChannel (ChannelPtr channel);
+ void removeChannel (constChannelPtr channel);
+
+ virtual bool containsChannel (constChannelPtr channel) const;
+
+ virtual ChannelPtr getChannelByName (const char *channel_name) const;
+ virtual ChannelPtr getChannelByAlias (const char *alias) const;
+ virtual ChannelPtr getChannelById (const char *channel_id) const;
+
+ virtual int foreachChannel (ChannelFn fn, void *data) const;
+
+ // Single resItem queries
+
+ virtual constResItemPtr findInstalledResItem (constResItemPtr resItem);
+ virtual constResItemPtr findResItem (constChannelPtr channel, const char *name) const;
+ virtual constResItemPtr findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const;
+ virtual ChannelPtr guessResItemChannel (constResItemPtr resItem) const;
+
+ };
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _StoreWorld_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/WorldPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : StoreWorldPtr
-// CLASS NAME : constStoreWorldPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(StoreWorld, World);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : StoreWorldPtr
+ // CLASS NAME : constStoreWorldPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(StoreWorld, World);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _StoreWorldPtr_h
#include <unistd.h>
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-#define SUBSCRIPTION_PATH "/var/adm/zypp"
-#define OLD_SUBSCRIPTION_PATH "/var/lib/rcd"
-#define SUBSCRIPTION_NAME "/subscriptions.xml"
-
-#define DEFAULT_SUBSCRIPTION_FILE SUBSCRIPTION_PATH SUBSCRIPTION_NAME
-#define OLD_SUBSCRIPTION_FILE OLD_SUBSCRIPTION_PATH SUBSCRIPTION_NAME
-
-/* Old subscriptions expire in 60 days */
-#define OLD_SUBSCRIPTION_EXPIRATION 60*24*60*60
-
-SubscriptionList Subscription::subscriptions;
-bool Subscription::subscriptions_changed = false;
-const char *Subscription::subscription_file = DEFAULT_SUBSCRIPTION_FILE;
-
-//---------------------------------------------------------------------------
-
-string
-Subscription::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Subscription::toString ( const Subscription & s)
-{
- return "<subscription/>";
-}
-
-ostream &
-Subscription::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Subscription & s)
-{
- return os << s.asString();
-}
-
-//---------------------------------------------------------------------------
-
-
-void
-Subscription::save (void)
-{
- xmlDoc *doc;
- xmlNode *root;
- char buf[64];
- time_t now;
- int save_retval;
-
- if (! subscriptions_changed)
- return;
-
- time (&now);
-
- root = xmlNewNode (NULL, (const xmlChar*)"subscriptions");
- xmlNewProp (root, (const xmlChar*)"version", (const xmlChar*)"2.0");
-
- doc = xmlNewDoc ((const xmlChar*)"1.0");
- xmlDocSetRootElement (doc, root);
-
- for (SubscriptionList::iterator iter = subscriptions.begin(); iter != subscriptions.end(); iter++) {
- xmlNode *sub_node;
-
- Subscription *sub = *iter;
-
- /* Drop "old" (i.e. imported from 1.x) subscriptions that
- we haven't seen for a while. */
- if (sub->_old) {
- double elapsed = difftime (now, sub->_last_seen);
- if (elapsed > OLD_SUBSCRIPTION_EXPIRATION)
- continue;
- }
-
- sub_node = xmlNewChild (root, NULL, (const xmlChar*)"channel", NULL);
-
- xmlNewProp (sub_node, (const xmlChar*)"id", (const xmlChar*)(sub->_channel_id.c_str()));
-
- snprintf (buf, sizeof (buf), "%ld", (long) sub->_last_seen);
- xmlNewProp (sub_node, (const xmlChar*)"last_seen", (const xmlChar*)buf);
-
- if (sub->_old)
- xmlNewProp (sub_node, (const xmlChar*)"old", (const xmlChar*)"1");
- }
-
- save_retval = xmlSaveFile (subscription_file, doc);
- xmlFreeDoc (doc);
-
- if (save_retval > 0) {
- /* Writing out the subscription file succeeded. */
- subscriptions_changed = false;
- } else {
- rc_debug (RC_DEBUG_LEVEL_WARNING, "Unable to save subscription data to '%s'", subscription_file);
- rc_debug (RC_DEBUG_LEVEL_WARNING, "Subscription will not be saved!");
- }
-}
-
-
-void
-Subscription::load_old_subscriptions (void)
-{
- static bool tried_to_do_this_already = false;
- xmlDoc *doc;
- XmlNodePtr node;
-
- if (tried_to_do_this_already)
- return;
- tried_to_do_this_already = true;
-
- if (access (OLD_SUBSCRIPTION_FILE, R_OK) != 0) {
- rc_debug (RC_DEBUG_LEVEL_WARNING, "Can't find rcd 1.x subscription file '%s'", OLD_SUBSCRIPTION_FILE);
- return;
- }
-
- doc = xmlParseFile (OLD_SUBSCRIPTION_FILE);
- if (doc == NULL) {
- rc_debug (RC_DEBUG_LEVEL_ERROR, "Can't parse rcd 1.x subscription file '%s'", OLD_SUBSCRIPTION_FILE);
- return;
- }
-
- node = new XmlNode (xmlDocGetRootElement (doc));
-
- if (!node->equals("subscriptions")) {
- rc_debug (RC_DEBUG_LEVEL_ERROR, "rcd 1.x subscription file '%s' is malformed", OLD_SUBSCRIPTION_FILE);
- return;
- }
-
- rc_debug (RC_DEBUG_LEVEL_INFO, "Importing rcd 1.x subscriptions.");
-
- node = node->children();
-
- while (node != NULL) {
-
- if (node->equals ("channel")) {
- const char *id_str;
-
- id_str = node->getProp ("channel_id");
- if (id_str && *id_str) {
-
- Subscription *sub = new Subscription (id_str);
- sub->_old = true;
-
- subscriptions.push_back (sub);
- }
- }
-
- node = node->next();
- }
-
- /* If we've imported old subscriptions, we need to write them
- out immediately into the new subscriptions file. */
-
- subscriptions_changed = true;
- save ();
-}
-
-
-void
-Subscription::load (void)
-{
- xmlDoc *doc;
- XmlNodePtr node;
-
- if (access (subscription_file, R_OK) != 0) {
- load_old_subscriptions ();
- return;
- }
-
- doc = xmlParseFile (subscription_file);
- if (doc == NULL) {
- rc_debug (RC_DEBUG_LEVEL_ERROR, "Can't parse subscription file '%s'", subscription_file);
- return;
- }
-
- node = new XmlNode (xmlDocGetRootElement (doc));
-
- if (! node->equals ("subscriptions")) {
- rc_debug (RC_DEBUG_LEVEL_ERROR, "Subscription file '%s' is malformed", subscription_file);
- return;
- }
-
- node = node->children();
-
- while (node != NULL) {
-
- if (node->equals ("channel")) {
- const char *id_str, *last_seen_str;
-
- id_str = node->getProp ("id");
- last_seen_str = node->getProp ("last_seen");
-
- if (id_str && *id_str) {
- Subscription *sub = new Subscription (id_str);
-
- if (last_seen_str)
- sub->_last_seen = (time_t) atol (last_seen_str);
- else
- sub->_last_seen = time (NULL);
-
- sub->_old = node->getUnsignedIntValueDefault("old", 0);
-
- subscriptions.push_back (sub);
- }
-
- free ((void *)id_str);
- free ((void *)last_seen_str);
-
- }
-
- node = node->next();
- }
-
- xmlFreeDoc (doc);
-}
-
-//---------------------------------------------------------------------------
-
-bool
-Subscription::match (constChannelPtr channel)
-{
- bool match;
-
- /* Paranoia is the programmer's friend. */
- if (channel == NULL) return false;
- if (channel->id() == NULL) return false;
-
- /* If this is an old (i.e. imported from 1.x) subscription, we
- compare it against the channel id's tail. */
-
- if (_old) {
- const char *id = channel->legacyId ();
- int len1, len2;
-
- if (!id)
- return false;
-
- len1 = strlen (_channel_id.c_str());
- len2 = strlen (id);
-
- if (len1 > len2)
- return false;
-
- /* If the tails match, mutate the Subscription into a
- new-style subscription for that channel. */
- if (! strcmp (id + (len2 - len1), _channel_id.c_str())) {
- _channel_id = channel->id ();
- _old = false;
- subscriptions_changed = true;
-
- return true;
- }
-
- return false;
- }
-
- match = (_channel_id == channel->id ());
-
- if (match) {
- time (&_last_seen);
- }
-
- return match;
-}
-
-//-----------------------------------------------------------------------------
-
-void
-Subscription::setFile (const char *path)
-{
- subscription_file = path;
-}
-
-
-bool
-Subscription::status (constChannelPtr channel)
-{
- if (subscriptions.empty())
- load ();
-
- if (channel == NULL)
- return false;
-
- for (SubscriptionList::iterator iter = subscriptions.begin(); iter != subscriptions.end(); iter++) {
- Subscription *sub = *iter;
- if (sub->match (channel))
- return true;
- }
-
- save ();
-
- return false;
-}
-
-
-void
-Subscription::setStatus (constChannelPtr channel, bool subscribe_to_channel)
-{
- bool currently_subscribed;
-
- if (channel == NULL) return;
-
- currently_subscribed = status (channel);
-
- if (currently_subscribed && !subscribe_to_channel) {
-
- /* Unsubscribe to the channel */
- for (SubscriptionList::iterator iter = subscriptions.begin(); iter != subscriptions.end(); iter++) {
- Subscription *sub = *iter;
- if (sub->match (channel)) {
- subscriptions.erase (iter);
- subscriptions_changed = true;
- break;
- }
- }
-
- } else if (!currently_subscribed && subscribe_to_channel) {
-
- /* Subscribe to the channel */
- Subscription *sub;
- sub = new Subscription (channel->id ());
- subscriptions.push_back(sub);
- subscriptions_changed = true;
- }
-
- save ();
-}
-
-//---------------------------------------------------------------------------
-
-Subscription::Subscription(const char *id)
-{
- _channel_id = string (id);
- _last_seen = time (NULL);
- _old = false;
-}
-
-
-Subscription::~Subscription()
-{
-}
-
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ #define SUBSCRIPTION_PATH "/var/adm/zypp"
+ #define OLD_SUBSCRIPTION_PATH "/var/lib/rcd"
+ #define SUBSCRIPTION_NAME "/subscriptions.xml"
+
+ #define DEFAULT_SUBSCRIPTION_FILE SUBSCRIPTION_PATH SUBSCRIPTION_NAME
+ #define OLD_SUBSCRIPTION_FILE OLD_SUBSCRIPTION_PATH SUBSCRIPTION_NAME
+
+ /* Old subscriptions expire in 60 days */
+ #define OLD_SUBSCRIPTION_EXPIRATION 60*24*60*60
+
+ SubscriptionList Subscription::subscriptions;
+ bool Subscription::subscriptions_changed = false;
+ const char *Subscription::subscription_file = DEFAULT_SUBSCRIPTION_FILE;
+
+ //---------------------------------------------------------------------------
+
+ string
+ Subscription::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Subscription::toString ( const Subscription & s)
+ {
+ return "<subscription/>";
+ }
+
+ ostream &
+ Subscription::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Subscription & s)
+ {
+ return os << s.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+
+ void
+ Subscription::save (void)
+ {
+ xmlDoc *doc;
+ xmlNode *root;
+ char buf[64];
+ time_t now;
+ int save_retval;
+
+ if (! subscriptions_changed)
+ return;
+
+ time (&now);
+
+ root = xmlNewNode (NULL, (const xmlChar*)"subscriptions");
+ xmlNewProp (root, (const xmlChar*)"version", (const xmlChar*)"2.0");
+
+ doc = xmlNewDoc ((const xmlChar*)"1.0");
+ xmlDocSetRootElement (doc, root);
+
+ for (SubscriptionList::iterator iter = subscriptions.begin(); iter != subscriptions.end(); iter++) {
+ xmlNode *sub_node;
+
+ Subscription *sub = *iter;
+
+ /* Drop "old" (i.e. imported from 1.x) subscriptions that
+ we haven't seen for a while. */
+ if (sub->_old) {
+ double elapsed = difftime (now, sub->_last_seen);
+ if (elapsed > OLD_SUBSCRIPTION_EXPIRATION)
+ continue;
+ }
+
+ sub_node = xmlNewChild (root, NULL, (const xmlChar*)"channel", NULL);
+
+ xmlNewProp (sub_node, (const xmlChar*)"id", (const xmlChar*)(sub->_channel_id.c_str()));
+
+ snprintf (buf, sizeof (buf), "%ld", (long) sub->_last_seen);
+ xmlNewProp (sub_node, (const xmlChar*)"last_seen", (const xmlChar*)buf);
+
+ if (sub->_old)
+ xmlNewProp (sub_node, (const xmlChar*)"old", (const xmlChar*)"1");
+ }
+
+ save_retval = xmlSaveFile (subscription_file, doc);
+ xmlFreeDoc (doc);
+
+ if (save_retval > 0) {
+ /* Writing out the subscription file succeeded. */
+ subscriptions_changed = false;
+ } else {
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "Unable to save subscription data to '%s'", subscription_file);
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "Subscription will not be saved!");
+ }
+ }
+
+
+ void
+ Subscription::load_old_subscriptions (void)
+ {
+ static bool tried_to_do_this_already = false;
+ xmlDoc *doc;
+ XmlNodePtr node;
+
+ if (tried_to_do_this_already)
+ return;
+ tried_to_do_this_already = true;
+
+ if (access (OLD_SUBSCRIPTION_FILE, R_OK) != 0) {
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "Can't find rcd 1.x subscription file '%s'", OLD_SUBSCRIPTION_FILE);
+ return;
+ }
+
+ doc = xmlParseFile (OLD_SUBSCRIPTION_FILE);
+ if (doc == NULL) {
+ rc_debug (RC_DEBUG_LEVEL_ERROR, "Can't parse rcd 1.x subscription file '%s'", OLD_SUBSCRIPTION_FILE);
+ return;
+ }
+
+ node = new XmlNode (xmlDocGetRootElement (doc));
+
+ if (!node->equals("subscriptions")) {
+ rc_debug (RC_DEBUG_LEVEL_ERROR, "rcd 1.x subscription file '%s' is malformed", OLD_SUBSCRIPTION_FILE);
+ return;
+ }
+
+ rc_debug (RC_DEBUG_LEVEL_INFO, "Importing rcd 1.x subscriptions.");
+
+ node = node->children();
+
+ while (node != NULL) {
+
+ if (node->equals ("channel")) {
+ const char *id_str;
+
+ id_str = node->getProp ("channel_id");
+ if (id_str && *id_str) {
+
+ Subscription *sub = new Subscription (id_str);
+ sub->_old = true;
+
+ subscriptions.push_back (sub);
+ }
+ }
+
+ node = node->next();
+ }
+
+ /* If we've imported old subscriptions, we need to write them
+ out immediately into the new subscriptions file. */
+
+ subscriptions_changed = true;
+ save ();
+ }
+
+
+ void
+ Subscription::load (void)
+ {
+ xmlDoc *doc;
+ XmlNodePtr node;
+
+ if (access (subscription_file, R_OK) != 0) {
+ load_old_subscriptions ();
+ return;
+ }
+
+ doc = xmlParseFile (subscription_file);
+ if (doc == NULL) {
+ rc_debug (RC_DEBUG_LEVEL_ERROR, "Can't parse subscription file '%s'", subscription_file);
+ return;
+ }
+
+ node = new XmlNode (xmlDocGetRootElement (doc));
+
+ if (! node->equals ("subscriptions")) {
+ rc_debug (RC_DEBUG_LEVEL_ERROR, "Subscription file '%s' is malformed", subscription_file);
+ return;
+ }
+
+ node = node->children();
+
+ while (node != NULL) {
+
+ if (node->equals ("channel")) {
+ const char *id_str, *last_seen_str;
+
+ id_str = node->getProp ("id");
+ last_seen_str = node->getProp ("last_seen");
+
+ if (id_str && *id_str) {
+ Subscription *sub = new Subscription (id_str);
+
+ if (last_seen_str)
+ sub->_last_seen = (time_t) atol (last_seen_str);
+ else
+ sub->_last_seen = time (NULL);
+
+ sub->_old = node->getUnsignedIntValueDefault("old", 0);
+
+ subscriptions.push_back (sub);
+ }
+
+ free ((void *)id_str);
+ free ((void *)last_seen_str);
+
+ }
+
+ node = node->next();
+ }
+
+ xmlFreeDoc (doc);
+ }
+
+ //---------------------------------------------------------------------------
+
+ bool
+ Subscription::match (constChannelPtr channel)
+ {
+ bool match;
+
+ /* Paranoia is the programmer's friend. */
+ if (channel == NULL) return false;
+ if (channel->id() == NULL) return false;
+
+ /* If this is an old (i.e. imported from 1.x) subscription, we
+ compare it against the channel id's tail. */
+
+ if (_old) {
+ const char *id = channel->legacyId ();
+ int len1, len2;
+
+ if (!id)
+ return false;
+
+ len1 = strlen (_channel_id.c_str());
+ len2 = strlen (id);
+
+ if (len1 > len2)
+ return false;
+
+ /* If the tails match, mutate the Subscription into a
+ new-style subscription for that channel. */
+ if (! strcmp (id + (len2 - len1), _channel_id.c_str())) {
+ _channel_id = channel->id ();
+ _old = false;
+ subscriptions_changed = true;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ match = (_channel_id == channel->id ());
+
+ if (match) {
+ time (&_last_seen);
+ }
+
+ return match;
+ }
+
+ //-----------------------------------------------------------------------------
+
+ void
+ Subscription::setFile (const char *path)
+ {
+ subscription_file = path;
+ }
+
+
+ bool
+ Subscription::status (constChannelPtr channel)
+ {
+ if (subscriptions.empty())
+ load ();
+
+ if (channel == NULL)
+ return false;
+
+ for (SubscriptionList::iterator iter = subscriptions.begin(); iter != subscriptions.end(); iter++) {
+ Subscription *sub = *iter;
+ if (sub->match (channel))
+ return true;
+ }
+
+ save ();
+
+ return false;
+ }
+
+
+ void
+ Subscription::setStatus (constChannelPtr channel, bool subscribe_to_channel)
+ {
+ bool currently_subscribed;
+
+ if (channel == NULL) return;
+
+ currently_subscribed = status (channel);
+
+ if (currently_subscribed && !subscribe_to_channel) {
+
+ /* Unsubscribe to the channel */
+ for (SubscriptionList::iterator iter = subscriptions.begin(); iter != subscriptions.end(); iter++) {
+ Subscription *sub = *iter;
+ if (sub->match (channel)) {
+ subscriptions.erase (iter);
+ subscriptions_changed = true;
+ break;
+ }
+ }
+
+ } else if (!currently_subscribed && subscribe_to_channel) {
+
+ /* Subscribe to the channel */
+ Subscription *sub;
+ sub = new Subscription (channel->id ());
+ subscriptions.push_back(sub);
+ subscriptions_changed = true;
+ }
+
+ save ();
+ }
+
+ //---------------------------------------------------------------------------
+
+ Subscription::Subscription(const char *id)
+ {
+ _channel_id = string (id);
+ _last_seen = time (NULL);
+ _old = false;
+ }
+
+
+ Subscription::~Subscription()
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <y2util/Ustring.h>
#include <zypp/solver/detail/ChannelPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Subscription
-
-
-class Subscription;
-typedef std::list<Subscription *> SubscriptionList;
-
-class Subscription {
-
- private:
-
- static SubscriptionList subscriptions;
- static bool subscriptions_changed;
- static const char *subscription_file;
-
- std::string _channel_id;
- time_t _last_seen;
- bool _old; // subscription imported from an old-style subs file
-
- bool match (constChannelPtr channel);
- static void save (void);
- static void load (void);
- static void load_old_subscriptions (void);
-
- public:
-
- Subscription (const char *id);
- virtual ~Subscription();
-
- // ---------------------------------- I/O
-
- static std::string toString ( const Subscription & section);
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Subscription & section);
-
- std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- void setFile (const char *file);
- static bool status (constChannelPtr channel);
- static void setStatus (constChannelPtr channel, bool channel_is_subscribed);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Subscription
+
+
+ class Subscription;
+ typedef std::list<Subscription *> SubscriptionList;
+
+ class Subscription {
+
+ private:
+
+ static SubscriptionList subscriptions;
+ static bool subscriptions_changed;
+ static const char *subscription_file;
+
+ std::string _channel_id;
+ time_t _last_seen;
+ bool _old; // subscription imported from an old-style subs file
+
+ bool match (constChannelPtr channel);
+ static void save (void);
+ static void load (void);
+ static void load_old_subscriptions (void);
+
+ public:
+
+ Subscription (const char *id);
+ virtual ~Subscription();
+
+ // ---------------------------------- I/O
+
+ static std::string toString ( const Subscription & section);
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Subscription & section);
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ void setFile (const char *file);
+ static bool status (constChannelPtr channel);
+ static void setStatus (constChannelPtr channel, bool channel_is_subscribed);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Subscription_h
#include <zypp/solver/detail/UndumpWorld.h>
#include <zypp/solver/detail/extract.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_DERIVED_POINTER(UndumpWorld, World);
-
-//---------------------------------------------------------------------------
-
-string
-UndumpWorld::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-UndumpWorld::toString ( const UndumpWorld & world )
-{
- return "<undumpworld/>";
-}
-
-
-ostream &
-UndumpWorld::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const UndumpWorld & world)
-{
- return os << world.asString();
-}
-
-//---------------------------------------------------------------------------
-
-UndumpWorld::UndumpWorld (const char *filename)
- : StoreWorld (UNDUMP_WORLD)
-{
- load (filename);
-}
-
-
-UndumpWorld::~UndumpWorld()
-{
- fprintf (stderr, "*** deleting undump world[%p]: %s\n", this, World::toString(type()).c_str());
-}
-
-//---------------------------------------------------------------------------
-
-
-static bool
-add_channel_cb (ChannelPtr channel, bool subscribed, void *data)
-{
- UndumpWorld *undump = (UndumpWorld *)data;
-
- undump->addChannel (channel);
-
- if (!channel->system ()) {
- undump->setSubscription (channel, subscribed);
- }
-
- return true;
-}
-
-
-static bool
-add_resItem_cb (constResItemPtr res, void *data)
-{
- UndumpWorld *undump = (UndumpWorld *)data;
-
- undump->addResItem (res);
-
- return true;
-}
-
-
-static bool
-add_lock_cb (constMatchPtr lock, void *data)
-{
- UndumpWorld *undump = (UndumpWorld *)data;
-
- undump->addLock (lock);
-
- return true;
-}
-
-
-void
-UndumpWorld::load (const char *filename)
-{
- if (filename) {
- extract_packages_from_undump_file (filename, add_channel_cb, add_resItem_cb, add_lock_cb, (void *)this);
- }
-}
-
-
-void
-UndumpWorld::setSubscription (constChannelPtr channel, bool subscribe)
-{
-// if (getenv("RC_SPEW")) fprintf (stderr, "UndumpWorld::setSubscription (%s, %s)\n", channel->asString().c_str(), subscribe?"subscribe":"unsubscribe");
- for (ChannelSubscriptions::iterator i = _subscriptions.begin(); i != _subscriptions.end(); i++) {
- if (*i == channel) {
- if (!subscribe) {
- _subscriptions.erase (i);
- }
- return;
- }
- }
-
- if (subscribe) {
- _subscriptions.push_back (channel);
- }
-
- return;
-}
-
-
-bool
-UndumpWorld::isSubscribed (constChannelPtr channel) const
-{
- for (ChannelSubscriptions::const_iterator i = _subscriptions.begin(); i != _subscriptions.end(); i++) {
- if (*i == channel) {
- if (getenv("RC_SPEW")) fprintf (stderr, "UndumpWorld::isSubscribed (%s) YES\n", channel->asString().c_str());
- return true;
- }
- }
-
- if (getenv("RC_SPEW")) fprintf (stderr, "UndumpWorld::isSubscribed (%s) NO\n", channel->asString().c_str());
- return false;
-}
-
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_DERIVED_POINTER(UndumpWorld, World);
+
+ //---------------------------------------------------------------------------
+
+ string
+ UndumpWorld::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ UndumpWorld::toString ( const UndumpWorld & world )
+ {
+ return "<undumpworld/>";
+ }
+
+
+ ostream &
+ UndumpWorld::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const UndumpWorld & world)
+ {
+ return os << world.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ UndumpWorld::UndumpWorld (const char *filename)
+ : StoreWorld (UNDUMP_WORLD)
+ {
+ load (filename);
+ }
+
+
+ UndumpWorld::~UndumpWorld()
+ {
+ fprintf (stderr, "*** deleting undump world[%p]: %s\n", this, World::toString(type()).c_str());
+ }
+
+ //---------------------------------------------------------------------------
+
+
+ static bool
+ add_channel_cb (ChannelPtr channel, bool subscribed, void *data)
+ {
+ UndumpWorld *undump = (UndumpWorld *)data;
+
+ undump->addChannel (channel);
+
+ if (!channel->system ()) {
+ undump->setSubscription (channel, subscribed);
+ }
+
+ return true;
+ }
+
+
+ static bool
+ add_resItem_cb (constResItemPtr res, void *data)
+ {
+ UndumpWorld *undump = (UndumpWorld *)data;
+
+ undump->addResItem (res);
+
+ return true;
+ }
+
+
+ static bool
+ add_lock_cb (constMatchPtr lock, void *data)
+ {
+ UndumpWorld *undump = (UndumpWorld *)data;
+
+ undump->addLock (lock);
+
+ return true;
+ }
+
+
+ void
+ UndumpWorld::load (const char *filename)
+ {
+ if (filename) {
+ extract_packages_from_undump_file (filename, add_channel_cb, add_resItem_cb, add_lock_cb, (void *)this);
+ }
+ }
+
+
+ void
+ UndumpWorld::setSubscription (constChannelPtr channel, bool subscribe)
+ {
+ // if (getenv("RC_SPEW")) fprintf (stderr, "UndumpWorld::setSubscription (%s, %s)\n", channel->asString().c_str(), subscribe?"subscribe":"unsubscribe");
+ for (ChannelSubscriptions::iterator i = _subscriptions.begin(); i != _subscriptions.end(); i++) {
+ if (*i == channel) {
+ if (!subscribe) {
+ _subscriptions.erase (i);
+ }
+ return;
+ }
+ }
+
+ if (subscribe) {
+ _subscriptions.push_back (channel);
+ }
+
+ return;
+ }
+
+
+ bool
+ UndumpWorld::isSubscribed (constChannelPtr channel) const
+ {
+ for (ChannelSubscriptions::const_iterator i = _subscriptions.begin(); i != _subscriptions.end(); i++) {
+ if (*i == channel) {
+ if (getenv("RC_SPEW")) fprintf (stderr, "UndumpWorld::isSubscribed (%s) YES\n", channel->asString().c_str());
+ return true;
+ }
+ }
+
+ if (getenv("RC_SPEW")) fprintf (stderr, "UndumpWorld::isSubscribed (%s) NO\n", channel->asString().c_str());
+ return false;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Channel.h>
#include <zypp/solver/detail/World.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : UndumpWorld
-
-class UndumpWorld : public StoreWorld {
- REP_BODY(UndumpWorld);
-
- private:
-
- typedef std::list<constChannelPtr> ChannelSubscriptions;
- ChannelSubscriptions _subscriptions;
-
- public:
-
- UndumpWorld (const char *filename);
- virtual ~UndumpWorld();
-
- // ---------------------------------- I/O
-
- static std::string toString (const UndumpWorld & section);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const UndumpWorld & section);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- void load (const char *filename);
- virtual bool isSubscribed (constChannelPtr channel) const;
- virtual void setSubscription (constChannelPtr channel, bool is_subscribed);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : UndumpWorld
+
+ class UndumpWorld : public StoreWorld {
+ REP_BODY(UndumpWorld);
+
+ private:
+
+ typedef std::list<constChannelPtr> ChannelSubscriptions;
+ ChannelSubscriptions _subscriptions;
+
+ public:
+
+ UndumpWorld (const char *filename);
+ virtual ~UndumpWorld();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const UndumpWorld & section);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const UndumpWorld & section);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ void load (const char *filename);
+ virtual bool isSubscribed (constChannelPtr channel) const;
+ virtual void setSubscription (constChannelPtr channel, bool is_subscribed);
+
+ };
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _UndumpWorld_h
#include <y2util/RepDef.h>
#include <zypp/solver/detail/WorldPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : UndumpWorldPtr
-// CLASS NAME : constUndumpWorldPtr
-///////////////////////////////////////////////////////////////////
-DEFINE_DERIVED_POINTER(UndumpWorld, World);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : UndumpWorldPtr
+ // CLASS NAME : constUndumpWorldPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_DERIVED_POINTER(UndumpWorld, World);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _UndumpWorldPtr_h
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-
-Version GVersion;
-
-using namespace std;
-
-string
-Version::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-Version::toString ( const Version & section )
-{
- return "<version/>";
-}
-
-ostream &
-Version::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const Version& section)
-{
- return os << section.asString();
-}
-
-//---------------------------------------------------------------------------
-
-static EditionPtr
-rpm_parse (const char *input)
-{
- const char *vptr = NULL, *rptr = NULL;
-
- if (input == NULL || *input == 0)
- return NULL;
-
- int epoch = -1;
- const char *version;
- const char *release;
- const char *arch = "";
-
- if ((vptr = strchr (input, ':'))) {
- /* We -might- have an epoch here */
- char *endptr;
-
- epoch = strtoul (input, &endptr, 10);
-
- if (endptr != vptr) {
- /* No epoch here, just a : in the version string */
- epoch = -1;
- vptr = input;
- } else {
- vptr++;
- }
- } else {
- vptr = input;
- }
-
- if ((rptr = strchr (vptr, '-'))) {
- char *v = strndup (vptr, rptr - vptr);
- version = v;
- release = rptr + 1;
- } else {
- version = vptr;
- release = NULL;
- }
-
- EditionPtr edition = new Edition(epoch, version, release, Arch::create(arch));
-
- return edition;
-}
-
-
-/* This was stolen from RPM */
-/* And then slightly hacked on by me */
-/* And then hacked on more by me */
-
-/* compare alpha and numeric segments of two versions */
-/* return 1: a is newer than b */
-/* 0: a and b are the same version */
-/* -1: b is newer than a */
-static int
-vercmp (const char *a, const char *b)
-{
- char oldch1, oldch2;
- char * str1, * str2;
- char * one, * two;
- int rc;
- int isnum;
- unsigned int alen, blen;
-
- /* easy comparison to see if versions are identical */
- if (!strcmp(a, b)) return 0;
-
- alen = strlen (a);
- blen = strlen (b);
-
- str1 = (char *)alloca(alen + 1);
- str2 = (char *)alloca(blen + 1);
-
- strcpy(str1, a);
- strcpy(str2, b);
-
- one = str1;
- two = str2;
-
- /* loop through each version segment of str1 and str2 and compare them */
- while (*one && *two) {
- while (*one && !isalnum(*one)) one++;
- while (*two && !isalnum(*two)) two++;
-
- str1 = one;
- str2 = two;
-
- /* grab first completely alpha or completely numeric segment */
- /* leave one and two pointing to the start of the alpha or numeric */
- /* segment and walk str1 and str2 to end of segment */
- if (isdigit(*str1)) {
- while (*str1 && isdigit(*str1)) str1++;
- while (*str2 && isdigit(*str2)) str2++;
- isnum = 1;
- } else {
- while (*str1 && isalpha(*str1)) str1++;
- while (*str2 && isalpha(*str2)) str2++;
- isnum = 0;
- }
-
- /* save character at the end of the alpha or numeric segment */
- /* so that they can be restored after the comparison */
- oldch1 = *str1;
- *str1 = '\0';
- oldch2 = *str2;
- *str2 = '\0';
-
- /* This should only happen if someone is changing the string */
- /* behind our back. It should be a _very_ rare race condition */
- if (one == str1) return -1; /* arbitrary */
-
- /* take care of the case where the two version segments are */
- /* different types: one numeric and one alpha */
-
- /* Here's how we handle comparing numeric and non-numeric
- * segments -- non-numeric (ximian.1) always sorts lower than
- * numeric (0.ximian.6.1). */
- if (two == str2)
- return (isnum ? 1 : -1);
-
- if (isnum) {
- /* this used to be done by converting the digit segments */
- /* to ints using atoi() - it's changed because long */
- /* digit segments can overflow an int - this should fix that. */
-
- /* throw away any leading zeros - it's a number, right? */
- while (*one == '0') one++;
- while (*two == '0') two++;
-
- /* whichever number has more digits wins */
- if (strlen(one) > strlen(two)) return 1;
- if (strlen(two) > strlen(one)) return -1;
- }
-
- /* strcmp will return which one is greater - even if the two */
- /* segments are alpha or if they are numeric. don't return */
- /* if they are equal because there might be more segments to */
- /* compare */
- rc = strcmp(one, two);
- if (rc) return rc;
-
- /* restore character that was replaced by null above */
- *str1 = oldch1;
- one = str1;
- *str2 = oldch2;
- two = str2;
- }
-
- /* this catches the case where all numeric and alpha segments have */
- /* compared identically but the segment sepparating characters were */
- /* different */
- if ((!*one) && (!*two)) return 0;
-
- /* whichever version still has characters left over wins */
- if (!*one) return -1; else return 1;
-}
-
-
-static int
-rpm_compare (constSpecPtr spec1, constSpecPtr spec2)
-{
- int rc = 0;
-
- assert (spec1 != NULL);
- assert (spec2 != NULL);
-
- const string name1 = spec1->name();
- const string name2 = spec2->name();
- if (! (name1.empty() && name2.empty()))
- {
- rc = name1.compare (name2);
- }
- if (rc) return rc;
-
- if (spec1->epoch() >= 0 && spec2->epoch() >= 0) {
- rc = spec1->epoch() - spec2->epoch();
- } else if (spec1->epoch() > 0) {
- rc = 1;
- } else if (spec2->epoch() > 0) {
- rc = -1;
- }
- if (rc) return rc;
-
- rc = vercmp (spec1->version().c_str(), spec2->version().c_str());
- if (rc) return rc;
-
- const string rel1 = spec1->release();
- const string rel2 = spec2->release();
- if (!rel1.empty() && !rel2.empty()) {
- rc = vercmp (rel1.c_str(), rel2.c_str());
- }
- return rc;
-}
-
-//---------------------------------------------------------------------------
-
-Version::Version()
- : _properties (VERSION_PROP_PROVIDE_ANY | VERSION_PROP_IGNORE_ABSENT_EPOCHS)
- , _parse (rpm_parse)
- , _compare (rpm_compare)
-{
-}
-
-
-Version::~Version()
-{
-}
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ Version GVersion;
+
+ using namespace std;
+
+ string
+ Version::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ Version::toString ( const Version & section )
+ {
+ return "<version/>";
+ }
+
+ ostream &
+ Version::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const Version& section)
+ {
+ return os << section.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ static EditionPtr
+ rpm_parse (const char *input)
+ {
+ const char *vptr = NULL, *rptr = NULL;
+
+ if (input == NULL || *input == 0)
+ return NULL;
+
+ int epoch = -1;
+ const char *version;
+ const char *release;
+ const char *arch = "";
+
+ if ((vptr = strchr (input, ':'))) {
+ /* We -might- have an epoch here */
+ char *endptr;
+
+ epoch = strtoul (input, &endptr, 10);
+
+ if (endptr != vptr) {
+ /* No epoch here, just a : in the version string */
+ epoch = -1;
+ vptr = input;
+ } else {
+ vptr++;
+ }
+ } else {
+ vptr = input;
+ }
+
+ if ((rptr = strchr (vptr, '-'))) {
+ char *v = strndup (vptr, rptr - vptr);
+ version = v;
+ release = rptr + 1;
+ } else {
+ version = vptr;
+ release = NULL;
+ }
+
+ EditionPtr edition = new Edition(epoch, version, release, Arch::create(arch));
+
+ return edition;
+ }
+
+
+ /* This was stolen from RPM */
+ /* And then slightly hacked on by me */
+ /* And then hacked on more by me */
+
+ /* compare alpha and numeric segments of two versions */
+ /* return 1: a is newer than b */
+ /* 0: a and b are the same version */
+ /* -1: b is newer than a */
+ static int
+ vercmp (const char *a, const char *b)
+ {
+ char oldch1, oldch2;
+ char * str1, * str2;
+ char * one, * two;
+ int rc;
+ int isnum;
+ unsigned int alen, blen;
+
+ /* easy comparison to see if versions are identical */
+ if (!strcmp(a, b)) return 0;
+
+ alen = strlen (a);
+ blen = strlen (b);
+
+ str1 = (char *)alloca(alen + 1);
+ str2 = (char *)alloca(blen + 1);
+
+ strcpy(str1, a);
+ strcpy(str2, b);
+
+ one = str1;
+ two = str2;
+
+ /* loop through each version segment of str1 and str2 and compare them */
+ while (*one && *two) {
+ while (*one && !isalnum(*one)) one++;
+ while (*two && !isalnum(*two)) two++;
+
+ str1 = one;
+ str2 = two;
+
+ /* grab first completely alpha or completely numeric segment */
+ /* leave one and two pointing to the start of the alpha or numeric */
+ /* segment and walk str1 and str2 to end of segment */
+ if (isdigit(*str1)) {
+ while (*str1 && isdigit(*str1)) str1++;
+ while (*str2 && isdigit(*str2)) str2++;
+ isnum = 1;
+ } else {
+ while (*str1 && isalpha(*str1)) str1++;
+ while (*str2 && isalpha(*str2)) str2++;
+ isnum = 0;
+ }
+
+ /* save character at the end of the alpha or numeric segment */
+ /* so that they can be restored after the comparison */
+ oldch1 = *str1;
+ *str1 = '\0';
+ oldch2 = *str2;
+ *str2 = '\0';
+
+ /* This should only happen if someone is changing the string */
+ /* behind our back. It should be a _very_ rare race condition */
+ if (one == str1) return -1; /* arbitrary */
+
+ /* take care of the case where the two version segments are */
+ /* different types: one numeric and one alpha */
+
+ /* Here's how we handle comparing numeric and non-numeric
+ * segments -- non-numeric (ximian.1) always sorts lower than
+ * numeric (0.ximian.6.1). */
+ if (two == str2)
+ return (isnum ? 1 : -1);
+
+ if (isnum) {
+ /* this used to be done by converting the digit segments */
+ /* to ints using atoi() - it's changed because long */
+ /* digit segments can overflow an int - this should fix that. */
+
+ /* throw away any leading zeros - it's a number, right? */
+ while (*one == '0') one++;
+ while (*two == '0') two++;
+
+ /* whichever number has more digits wins */
+ if (strlen(one) > strlen(two)) return 1;
+ if (strlen(two) > strlen(one)) return -1;
+ }
+
+ /* strcmp will return which one is greater - even if the two */
+ /* segments are alpha or if they are numeric. don't return */
+ /* if they are equal because there might be more segments to */
+ /* compare */
+ rc = strcmp(one, two);
+ if (rc) return rc;
+
+ /* restore character that was replaced by null above */
+ *str1 = oldch1;
+ one = str1;
+ *str2 = oldch2;
+ two = str2;
+ }
+
+ /* this catches the case where all numeric and alpha segments have */
+ /* compared identically but the segment sepparating characters were */
+ /* different */
+ if ((!*one) && (!*two)) return 0;
+
+ /* whichever version still has characters left over wins */
+ if (!*one) return -1; else return 1;
+ }
+
+
+ static int
+ rpm_compare (constSpecPtr spec1, constSpecPtr spec2)
+ {
+ int rc = 0;
+
+ assert (spec1 != NULL);
+ assert (spec2 != NULL);
+
+ const string name1 = spec1->name();
+ const string name2 = spec2->name();
+ if (! (name1.empty() && name2.empty()))
+ {
+ rc = name1.compare (name2);
+ }
+ if (rc) return rc;
+
+ if (spec1->epoch() >= 0 && spec2->epoch() >= 0) {
+ rc = spec1->epoch() - spec2->epoch();
+ } else if (spec1->epoch() > 0) {
+ rc = 1;
+ } else if (spec2->epoch() > 0) {
+ rc = -1;
+ }
+ if (rc) return rc;
+
+ rc = vercmp (spec1->version().c_str(), spec2->version().c_str());
+ if (rc) return rc;
+
+ const string rel1 = spec1->release();
+ const string rel2 = spec2->release();
+ if (!rel1.empty() && !rel2.empty()) {
+ rc = vercmp (rel1.c_str(), rel2.c_str());
+ }
+ return rc;
+ }
+
+ //---------------------------------------------------------------------------
+
+ Version::Version()
+ : _properties (VERSION_PROP_PROVIDE_ANY | VERSION_PROP_IGNORE_ABSENT_EPOCHS)
+ , _parse (rpm_parse)
+ , _compare (rpm_compare)
+ {
+ }
+
+
+ Version::~Version()
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <y2util/Ustring.h>
#include <zypp/solver/detail/Spec.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : Version
-/*
- * Version properties: These exist to signal various parts of the
- * world, packman, and dependency code of certain (mis)features of a
- * packaging system.
- *
- * PROVIDE_ANY - An unversioned provide matches all versions. An
- * unversioned provide translates into an RC_RELATION_ANY relation, which
- * will meet any requirement for any version. (RPM)
- *
- * IGNORE_ABSENT_EPOCHS - If an epoch isn't specified in a requirement,
- * it's ignored when verifying the provide. For example, if package "foo"
- * requires "bar >= 2.0" then both "bar 21" and "bar 1:2.0" meet the
- * requirement. (RPM)
- *
- * ALWAYS_VERIFY_RELEASE - When verifying relations, the release field is
- * usually only compared when both the requirement specifies it. For
- * example, a requirement of "foo > 2.0" would not be met by a package
- * providing "foo 2.0-10", because the release field ("10") would be
- * ignored and "2.0" is not greater than "2.0". When this property is
- * set, however, the release field will always be compared, and the
- * requirement in the previous example would be met, because "2.0-10" is
- * greater than "2.0". (Debian)
- *
- */
-
-#define VERSION_PROP_NONE (0)
-#define VERSION_PROP_PROVIDE_ANY (1 << 0)
-#define VERSION_PROP_IGNORE_ABSENT_EPOCHS (1 << 2)
-#define VERSION_PROP_ALWAYS_VERIFY_RELEASE (1 << 4)
-
-class Version {
-
- private:
-
- unsigned int _properties;
-
- EditionPtr (*_parse)(const char *input);
-
- // compare uses SpecPtr and takes name into account
- int (*_compare)(constSpecPtr a, constSpecPtr b);
-
- public:
-
- Version ();
- virtual ~Version();
-
- // ---------------------------------- I/O
-
- static std::string toString ( const Version & section);
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream&, const Version & section);
-
- std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- // ---------------------------------- methods
-
- // compare uses SpecPtr and takes name into account
- int compare (constSpecPtr a, constSpecPtr b) const { return (*_compare) (a, b); }
-
- EditionPtr parse (const char *input) const { return (*_parse)(input); }
-
- bool hasProperty (unsigned int property) const { return (_properties & property) != 0; }
-
-};
-
-extern Version GVersion;
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : Version
+ /*
+ * Version properties: These exist to signal various parts of the
+ * world, packman, and dependency code of certain (mis)features of a
+ * packaging system.
+ *
+ * PROVIDE_ANY - An unversioned provide matches all versions. An
+ * unversioned provide translates into an RC_RELATION_ANY relation, which
+ * will meet any requirement for any version. (RPM)
+ *
+ * IGNORE_ABSENT_EPOCHS - If an epoch isn't specified in a requirement,
+ * it's ignored when verifying the provide. For example, if package "foo"
+ * requires "bar >= 2.0" then both "bar 21" and "bar 1:2.0" meet the
+ * requirement. (RPM)
+ *
+ * ALWAYS_VERIFY_RELEASE - When verifying relations, the release field is
+ * usually only compared when both the requirement specifies it. For
+ * example, a requirement of "foo > 2.0" would not be met by a package
+ * providing "foo 2.0-10", because the release field ("10") would be
+ * ignored and "2.0" is not greater than "2.0". When this property is
+ * set, however, the release field will always be compared, and the
+ * requirement in the previous example would be met, because "2.0-10" is
+ * greater than "2.0". (Debian)
+ *
+ */
+
+ #define VERSION_PROP_NONE (0)
+ #define VERSION_PROP_PROVIDE_ANY (1 << 0)
+ #define VERSION_PROP_IGNORE_ABSENT_EPOCHS (1 << 2)
+ #define VERSION_PROP_ALWAYS_VERIFY_RELEASE (1 << 4)
+
+ class Version {
+
+ private:
+
+ unsigned int _properties;
+
+ EditionPtr (*_parse)(const char *input);
+
+ // compare uses SpecPtr and takes name into account
+ int (*_compare)(constSpecPtr a, constSpecPtr b);
+
+ public:
+
+ Version ();
+ virtual ~Version();
+
+ // ---------------------------------- I/O
+
+ static std::string toString ( const Version & section);
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream&, const Version & section);
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ // ---------------------------------- methods
+
+ // compare uses SpecPtr and takes name into account
+ int compare (constSpecPtr a, constSpecPtr b) const { return (*_compare) (a, b); }
+
+ EditionPtr parse (const char *input) const { return (*_parse)(input); }
+
+ bool hasProperty (unsigned int property) const { return (_properties & property) != 0; }
+
+ };
+
+ extern Version GVersion;
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _Version_h
#include <zypp/solver/detail/Subscription.h>
#include <zypp/solver/detail/Version.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(World);
-
-WorldPtr World::GlobalWorld = NULL;
-
-//---------------------------------------------------------------------------
-
-string
-World::toString (WorldType type)
-{
- switch (type) {
- case PLAIN_WORLD: return "plain";
- case STORE_WORLD: return "store";
- case MULTI_WORLD: return "multi";
- case SERVICE_WORLD: return "service";
- case UNDUMP_WORLD: return "undump";
- case LOCALDIR_WORLD: return "localdir";
- case SYSTEM_WORLD: return "system";
- default:
- break;
- }
- return "???";
-}
-
-
-string
-World::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-World::toString ( const World & world )
-{
- return "<world/>";
-}
-
-
-ostream &
-World::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const World & world)
-{
- return os << world.asString();
-}
-
-//---------------------------------------------------------------------------
-
-World::World (WorldType type)
- : _type (type)
-{
-// fprintf (stderr, "*** creating world[%p]: %s\n", this, toString(_type).c_str());
-}
-
-
-World::~World()
-{
-// fprintf (stderr, "*** deleting world[%p]: %s\n", this, toString(_type).c_str());
-}
-
-//---------------------------------------------------------------------------
-// sync/refresh functions
-
-bool
-World::sync (void) const
-{
- if (getenv("FIXME")) fprintf (stderr, "World::sync() not implemented\n");
- return false;
-}
-
-bool
-World::syncConditional (constChannelPtr channel) const
-{
- if (getenv("FIXME")) fprintf (stderr, "World::syncConditional() not implemented\n");
- return false;
-}
-
-
-PendingPtr
-World::refresh (void)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::refresh() not implemented\n");
- return 0;
-}
-
-bool
-World::hasRefresh (void)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::hasRefresh() not implemented\n");
- return false;
-}
-
-
-bool
-World::isRefreshing (void)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::isRefreshing() not implemented\n");
- return false;
-}
-
-
- /* These functions are for World-implementers only! Don't call them! */
-void
-World::refreshBegin (void)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::refreshBegin() not implemented\n");
- return;
-}
-
-void
-World::refreshComplete (void)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::refreshComplete() not implemented\n");
- return;
-}
-
-//---------------------------------------------------------------------------
-// channels, subscriptions
-
-void
-World::setSubscription (ChannelPtr channel, bool is_subscribed)
-{
- bool curr_subs_status;
-
- if (channel == NULL) return;
-
-// if (getenv("RC_SPEW")) fprintf (stderr, "World::setSubscription (%s, %s)\n", channel->asString().c_str(), is_subscribed?"subscribe":"unsubscribe");
-
- if (channel->system ()) {
- fprintf (stderr, "Can't subscribe to system channel '%s'\n", channel->name ());
- return;
- }
-
- curr_subs_status = isSubscribed (channel);
-
- Subscription::setStatus (channel, is_subscribed);
-
- if (curr_subs_status != isSubscribed (channel))
- touchSubscriptionSequenceNumber ();
-
- return;
-}
-
-
-bool
-World::isSubscribed (constChannelPtr channel) const
-{
- if (channel == NULL) return false;
-// if (getenv("RC_SPEW")) fprintf (stderr, "World::isSubscribed (%s)\n", channel->asString().c_str());
-
- if (channel->system ())
- return false;
-
- return Subscription::status (channel) ? true : false;
-}
-
-
-
-//---------------------------------------------------------------------------
-// ResItem Locks
-
-typedef struct {
- constResItemPtr resItem;
- WorldPtr world;
- bool is_locked;
-} IsLockedInfo;
-
-
-static bool
-is_locked_cb (constMatchPtr match, void *data)
-{
- IsLockedInfo *info = (IsLockedInfo *)data;
-
- if (match->test (info->resItem, info->world)) {
- info->is_locked = true;
- return false;
- }
-
- return true;
-}
-
-
-bool
-World::resItemIsLocked (constResItemPtr resItem)
-{
- IsLockedInfo info;
-
- info.resItem = resItem;
- info.world = this;
- info.is_locked = false;
-
- foreachLock (is_locked_cb, &info);
-
- return info.is_locked;
-}
-
-
-//---------------------------------------------------------------------------
-// Transacting
-
-bool
-World::canTransactResItem (constResItemPtr resItem)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::canTransactResItem() not implemented\n");
- return false;
-}
-
-bool
-World::transact (const ResItemList & installResItems, const ResItemList & remove_resItems, int flags)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::transact() not implemented\n");
- return false;
-}
-
-
-//---------------------------------------------------------------------------
-// XML serialization
-
-void
-World::serialize (XmlNodePtr parent)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::serialize() not implemented\n");
- return;
-}
-
-void
-World::toFile (const char *filename)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::toFile() not implemented\n");
- return;
-}
-
-
-//---------------------------------------------------------------------------
-// Duplicating (primarily for atomic refreshes)
-
-WorldPtr
-World::dup (void)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::dup() not implemented\n");
- return 0;
-}
-
-
-//---------------------------------------------------------------------------
-// only used for bindings
-
-void
-World::setRefreshFunction (WorldRefreshFn refresh_fn)
-{
- if (getenv("FIXME")) fprintf (stderr, "World::setRefreshFunction() not implemented\n");
- return;
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Upgrades
-
-typedef struct {
- constResItemPtr original_resItem;
- CResItemFn fn;
- void *data;
- int count;
- WorldPtr world;
-} ForeachUpgradeInfo;
-
-static bool
-foreach_upgrade_cb (constResItemPtr resItem, void *data)
-{
- ForeachUpgradeInfo *info = (ForeachUpgradeInfo *)data;
- int cmp;
-
- cmp = GVersion.compare (info->original_resItem, resItem);
-
- if (cmp >= 0) // original is already better
- return true;
-
- if (info->world->resItemIsLocked (resItem))
- return true;
-
- if (info->fn)
- info->fn (resItem, info->data);
- ++info->count;
-
- return true;
-}
-
-
-// rc_world_foreach_upgrade:
-// @world: An #RCWorld.
-// @resItem: An #RCResItem.
-// @channel: An #RCChannel or channel wildcard.
-// @fn: A callback function.
-// @user_data: Pointer passed to the callback function.
-//
-// Searchs @world for all resItems whose channel matches
-// @channel and that are an upgrade for @resItem.
-// (To be precise, an upgrade is a resItem with the same
-// name as @resItem but with a greater version number.)
-//
-// Return value: The number of matching resItems
-// that the callback functions was invoked on, or
-// -1 in the case of an error.
-
-int
-World::foreachUpgrade (constResItemPtr resItem, ChannelPtr channel, CResItemFn fn, void *data)
-{
- ForeachUpgradeInfo info;
-
- syncConditional (channel);
-
- info.original_resItem = resItem;
- info.fn = fn;
- info.data = data;
- info.count = 0;
- info.world = this;
-
- foreachResItemByName (resItem->name(), channel, foreach_upgrade_cb, (void *)&info);
-
- return info.count;
-}
-
-
-
-typedef struct {
- WorldPtr world;
- constResItemPtr system_resItem;
- CResItemList best_upgrades;
- bool subscribed_only;
- ResItemPairFn fn;
- void *data;
- int count;
-} SystemUpgradeInfo;
-
-
-static bool
-foreach_system_upgrade_cb (constResItemPtr upgrade, void *data)
-{
- SystemUpgradeInfo *info = (SystemUpgradeInfo *)data;
- constChannelPtr channel = upgrade->channel();
- int cmp;
-
- if (info->subscribed_only) {
- if (!(channel && channel->isSubscribed ()))
- return true;
- }
-
- if (info->world->resItemIsLocked (upgrade))
- return true;
-
- if (info->best_upgrades.empty()) {
- info->best_upgrades.push_back (upgrade);
- }
- else {
- /* All the versions are equal, so picking the first is fine */
- constResItemPtr best_up = info->best_upgrades.front();
-
- cmp = GVersion.compare (best_up, upgrade);
-
- if (cmp <= 0) {
- /* We have a new best resItem... */
- info->best_upgrades.pop_front();
- info->best_upgrades.push_back (upgrade);
- }
- }
-
- return true;
-}
-
-
-static void
-foreach_system_resItem_cb (const string & name, constResItemPtr resItem, SystemUpgradeInfo *info)
-{
- info->system_resItem = resItem;
- info->best_upgrades.clear();
-
- /* If the resItem is excluded, skip it. */
- if (info->world->resItemIsLocked (info->system_resItem))
- return;
-
- info->world->foreachUpgrade (info->system_resItem, new Channel (CHANNEL_TYPE_NONSYSTEM), foreach_system_upgrade_cb, info);
-
- for (CResItemList::const_iterator iter = info->best_upgrades.begin(); iter != info->best_upgrades.end(); iter++) {
- constResItemPtr upgrade = *iter;
-
- if (info->fn)
- info->fn (info->system_resItem, upgrade, info->data);
-
- ++info->count;
- }
-
- info->best_upgrades.clear();
-}
-
-typedef map<const string,constResItemPtr> UniqueTable;
-
-static bool
-build_unique_table_cb (constResItemPtr resItem, void *data)
-{
- UniqueTable *unique_table = (UniqueTable *)data;
-
- UniqueTable::const_iterator pos = unique_table->find (resItem->name());
-
- if (pos != unique_table->end()) {
- if (GVersion.compare (resItem, pos->second) <= 0)
- return true;
- }
-
- (*unique_table)[resItem->name()] = resItem;
-
- return true;
-}
-
-
-/**
- * foreachSystemUpgrade:
- * @world: An #RCWorld.
- * @subscribed_only: if TRUE, only subscribed channels are used.
- * @fn: A callback function.
- * @user_data: Pointer to be passed to the callback function.
- *
- * Iterates across all system resItems in @world for which there
- * exists an upgrade, and passes both the original resItem and
- * the upgrade resItem to the callback function.
- *
- * Return value: The number of matching resItems that the callback
- * function was invoked on, or -1 in case of an error.
- **/
-
-int
-World::foreachSystemUpgrade (bool subscribed_only, ResItemPairFn fn, void *data)
-{
- SystemUpgradeInfo info;
- UniqueTable unique_table;
-
- /* rc_world_foreach_resItem calls rc_world_sync */
-
- foreachResItem (new Channel (CHANNEL_TYPE_SYSTEM), build_unique_table_cb, &unique_table);
-
- info.world = this;
- info.subscribed_only = subscribed_only;
- info.fn = fn;
- info.data = data;
- info.count = 0;
-
- for (UniqueTable::const_iterator iter = unique_table.begin(); iter != unique_table.end(); iter++) {
- foreach_system_resItem_cb (iter->first, iter->second, &info);
- }
-
- return info.count;
-}
-
-
-PackageUpdateList
-World::getUpgrades (constResItemPtr resItem, constChannelPtr channel)
-{
- fprintf (stderr, "World::getUpgrades not implemented\n");
- return PackageUpdateList();
-}
-
-constResItemPtr
-World::getBestUpgrade (constResItemPtr resItem, bool subscribed_only)
-{
- fprintf (stderr, "World::getBestUpgrade not implemented\n");
- return 0;
-}
-
-
-//-----------------------------------------------------------------------------
-// Locks
-
-int
-World::foreachLock (MatchFn fn, void *data) const
-{
- int count = 0;
-
- for (MatchList::const_iterator iter = _locks.begin(); iter != _locks.end(); iter++) {
- if (! fn (*iter, data))
- return -1;
- ++count;
- }
-
- return count;
-}
-
-
-void
-World::addLock (constMatchPtr lock)
-{
- _locks.push_back (lock);
-}
-
-
-void
-World::removeLock (constMatchPtr lock)
-{
- for (MatchList::iterator iter = _locks.begin(); iter != _locks.end(); iter++) {
- if (*iter == lock) {
- _locks.erase (iter);
- break;
- }
- }
-}
-
-
-void
-World::clearLocks (void)
-{
- _locks.clear();
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(World);
+
+ WorldPtr World::GlobalWorld = NULL;
+
+ //---------------------------------------------------------------------------
+
+ string
+ World::toString (WorldType type)
+ {
+ switch (type) {
+ case PLAIN_WORLD: return "plain";
+ case STORE_WORLD: return "store";
+ case MULTI_WORLD: return "multi";
+ case SERVICE_WORLD: return "service";
+ case UNDUMP_WORLD: return "undump";
+ case LOCALDIR_WORLD: return "localdir";
+ case SYSTEM_WORLD: return "system";
+ default:
+ break;
+ }
+ return "???";
+ }
+
+
+ string
+ World::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ World::toString ( const World & world )
+ {
+ return "<world/>";
+ }
+
+
+ ostream &
+ World::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const World & world)
+ {
+ return os << world.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ World::World (WorldType type)
+ : _type (type)
+ {
+ // fprintf (stderr, "*** creating world[%p]: %s\n", this, toString(_type).c_str());
+ }
+
+
+ World::~World()
+ {
+ // fprintf (stderr, "*** deleting world[%p]: %s\n", this, toString(_type).c_str());
+ }
+
+ //---------------------------------------------------------------------------
+ // sync/refresh functions
+
+ bool
+ World::sync (void) const
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::sync() not implemented\n");
+ return false;
+ }
+
+ bool
+ World::syncConditional (constChannelPtr channel) const
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::syncConditional() not implemented\n");
+ return false;
+ }
+
+
+ PendingPtr
+ World::refresh (void)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::refresh() not implemented\n");
+ return 0;
+ }
+
+ bool
+ World::hasRefresh (void)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::hasRefresh() not implemented\n");
+ return false;
+ }
+
+
+ bool
+ World::isRefreshing (void)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::isRefreshing() not implemented\n");
+ return false;
+ }
+
+
+ /* These functions are for World-implementers only! Don't call them! */
+ void
+ World::refreshBegin (void)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::refreshBegin() not implemented\n");
+ return;
+ }
+
+ void
+ World::refreshComplete (void)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::refreshComplete() not implemented\n");
+ return;
+ }
+
+ //---------------------------------------------------------------------------
+ // channels, subscriptions
+
+ void
+ World::setSubscription (ChannelPtr channel, bool is_subscribed)
+ {
+ bool curr_subs_status;
+
+ if (channel == NULL) return;
+
+ // if (getenv("RC_SPEW")) fprintf (stderr, "World::setSubscription (%s, %s)\n", channel->asString().c_str(), is_subscribed?"subscribe":"unsubscribe");
+
+ if (channel->system ()) {
+ fprintf (stderr, "Can't subscribe to system channel '%s'\n", channel->name ());
+ return;
+ }
+
+ curr_subs_status = isSubscribed (channel);
+
+ Subscription::setStatus (channel, is_subscribed);
+
+ if (curr_subs_status != isSubscribed (channel))
+ touchSubscriptionSequenceNumber ();
+
+ return;
+ }
+
+
+ bool
+ World::isSubscribed (constChannelPtr channel) const
+ {
+ if (channel == NULL) return false;
+ // if (getenv("RC_SPEW")) fprintf (stderr, "World::isSubscribed (%s)\n", channel->asString().c_str());
+
+ if (channel->system ())
+ return false;
+
+ return Subscription::status (channel) ? true : false;
+ }
+
+
+
+ //---------------------------------------------------------------------------
+ // ResItem Locks
+
+ typedef struct {
+ constResItemPtr resItem;
+ WorldPtr world;
+ bool is_locked;
+ } IsLockedInfo;
+
+
+ static bool
+ is_locked_cb (constMatchPtr match, void *data)
+ {
+ IsLockedInfo *info = (IsLockedInfo *)data;
+
+ if (match->test (info->resItem, info->world)) {
+ info->is_locked = true;
+ return false;
+ }
+
+ return true;
+ }
+
+
+ bool
+ World::resItemIsLocked (constResItemPtr resItem)
+ {
+ IsLockedInfo info;
+
+ info.resItem = resItem;
+ info.world = this;
+ info.is_locked = false;
+
+ foreachLock (is_locked_cb, &info);
+
+ return info.is_locked;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // Transacting
+
+ bool
+ World::canTransactResItem (constResItemPtr resItem)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::canTransactResItem() not implemented\n");
+ return false;
+ }
+
+ bool
+ World::transact (const ResItemList & installResItems, const ResItemList & remove_resItems, int flags)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::transact() not implemented\n");
+ return false;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // XML serialization
+
+ void
+ World::serialize (XmlNodePtr parent)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::serialize() not implemented\n");
+ return;
+ }
+
+ void
+ World::toFile (const char *filename)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::toFile() not implemented\n");
+ return;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // Duplicating (primarily for atomic refreshes)
+
+ WorldPtr
+ World::dup (void)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::dup() not implemented\n");
+ return 0;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // only used for bindings
+
+ void
+ World::setRefreshFunction (WorldRefreshFn refresh_fn)
+ {
+ if (getenv("FIXME")) fprintf (stderr, "World::setRefreshFunction() not implemented\n");
+ return;
+ }
+
+
+
+ //-----------------------------------------------------------------------------
+ // Upgrades
+
+ typedef struct {
+ constResItemPtr original_resItem;
+ CResItemFn fn;
+ void *data;
+ int count;
+ WorldPtr world;
+ } ForeachUpgradeInfo;
+
+ static bool
+ foreach_upgrade_cb (constResItemPtr resItem, void *data)
+ {
+ ForeachUpgradeInfo *info = (ForeachUpgradeInfo *)data;
+ int cmp;
+
+ cmp = GVersion.compare (info->original_resItem, resItem);
+
+ if (cmp >= 0) // original is already better
+ return true;
+
+ if (info->world->resItemIsLocked (resItem))
+ return true;
+
+ if (info->fn)
+ info->fn (resItem, info->data);
+ ++info->count;
+
+ return true;
+ }
+
+
+ // rc_world_foreach_upgrade:
+ // @world: An #RCWorld.
+ // @resItem: An #RCResItem.
+ // @channel: An #RCChannel or channel wildcard.
+ // @fn: A callback function.
+ // @user_data: Pointer passed to the callback function.
+ //
+ // Searchs @world for all resItems whose channel matches
+ // @channel and that are an upgrade for @resItem.
+ // (To be precise, an upgrade is a resItem with the same
+ // name as @resItem but with a greater version number.)
+ //
+ // Return value: The number of matching resItems
+ // that the callback functions was invoked on, or
+ // -1 in the case of an error.
+
+ int
+ World::foreachUpgrade (constResItemPtr resItem, ChannelPtr channel, CResItemFn fn, void *data)
+ {
+ ForeachUpgradeInfo info;
+
+ syncConditional (channel);
+
+ info.original_resItem = resItem;
+ info.fn = fn;
+ info.data = data;
+ info.count = 0;
+ info.world = this;
+
+ foreachResItemByName (resItem->name(), channel, foreach_upgrade_cb, (void *)&info);
+
+ return info.count;
+ }
+
+
+
+ typedef struct {
+ WorldPtr world;
+ constResItemPtr system_resItem;
+ CResItemList best_upgrades;
+ bool subscribed_only;
+ ResItemPairFn fn;
+ void *data;
+ int count;
+ } SystemUpgradeInfo;
+
+
+ static bool
+ foreach_system_upgrade_cb (constResItemPtr upgrade, void *data)
+ {
+ SystemUpgradeInfo *info = (SystemUpgradeInfo *)data;
+ constChannelPtr channel = upgrade->channel();
+ int cmp;
+
+ if (info->subscribed_only) {
+ if (!(channel && channel->isSubscribed ()))
+ return true;
+ }
+
+ if (info->world->resItemIsLocked (upgrade))
+ return true;
+
+ if (info->best_upgrades.empty()) {
+ info->best_upgrades.push_back (upgrade);
+ }
+ else {
+ /* All the versions are equal, so picking the first is fine */
+ constResItemPtr best_up = info->best_upgrades.front();
+
+ cmp = GVersion.compare (best_up, upgrade);
+
+ if (cmp <= 0) {
+ /* We have a new best resItem... */
+ info->best_upgrades.pop_front();
+ info->best_upgrades.push_back (upgrade);
+ }
+ }
+
+ return true;
+ }
+
+
+ static void
+ foreach_system_resItem_cb (const string & name, constResItemPtr resItem, SystemUpgradeInfo *info)
+ {
+ info->system_resItem = resItem;
+ info->best_upgrades.clear();
+
+ /* If the resItem is excluded, skip it. */
+ if (info->world->resItemIsLocked (info->system_resItem))
+ return;
+
+ info->world->foreachUpgrade (info->system_resItem, new Channel (CHANNEL_TYPE_NONSYSTEM), foreach_system_upgrade_cb, info);
+
+ for (CResItemList::const_iterator iter = info->best_upgrades.begin(); iter != info->best_upgrades.end(); iter++) {
+ constResItemPtr upgrade = *iter;
+
+ if (info->fn)
+ info->fn (info->system_resItem, upgrade, info->data);
+
+ ++info->count;
+ }
+
+ info->best_upgrades.clear();
+ }
+
+ typedef map<const string,constResItemPtr> UniqueTable;
+
+ static bool
+ build_unique_table_cb (constResItemPtr resItem, void *data)
+ {
+ UniqueTable *unique_table = (UniqueTable *)data;
+
+ UniqueTable::const_iterator pos = unique_table->find (resItem->name());
+
+ if (pos != unique_table->end()) {
+ if (GVersion.compare (resItem, pos->second) <= 0)
+ return true;
+ }
+
+ (*unique_table)[resItem->name()] = resItem;
+
+ return true;
+ }
+
+
+ /**
+ * foreachSystemUpgrade:
+ * @world: An #RCWorld.
+ * @subscribed_only: if TRUE, only subscribed channels are used.
+ * @fn: A callback function.
+ * @user_data: Pointer to be passed to the callback function.
+ *
+ * Iterates across all system resItems in @world for which there
+ * exists an upgrade, and passes both the original resItem and
+ * the upgrade resItem to the callback function.
+ *
+ * Return value: The number of matching resItems that the callback
+ * function was invoked on, or -1 in case of an error.
+ **/
+
+ int
+ World::foreachSystemUpgrade (bool subscribed_only, ResItemPairFn fn, void *data)
+ {
+ SystemUpgradeInfo info;
+ UniqueTable unique_table;
+
+ /* rc_world_foreach_resItem calls rc_world_sync */
+
+ foreachResItem (new Channel (CHANNEL_TYPE_SYSTEM), build_unique_table_cb, &unique_table);
+
+ info.world = this;
+ info.subscribed_only = subscribed_only;
+ info.fn = fn;
+ info.data = data;
+ info.count = 0;
+
+ for (UniqueTable::const_iterator iter = unique_table.begin(); iter != unique_table.end(); iter++) {
+ foreach_system_resItem_cb (iter->first, iter->second, &info);
+ }
+
+ return info.count;
+ }
+
+
+ PackageUpdateList
+ World::getUpgrades (constResItemPtr resItem, constChannelPtr channel)
+ {
+ fprintf (stderr, "World::getUpgrades not implemented\n");
+ return PackageUpdateList();
+ }
+
+ constResItemPtr
+ World::getBestUpgrade (constResItemPtr resItem, bool subscribed_only)
+ {
+ fprintf (stderr, "World::getBestUpgrade not implemented\n");
+ return 0;
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // Locks
+
+ int
+ World::foreachLock (MatchFn fn, void *data) const
+ {
+ int count = 0;
+
+ for (MatchList::const_iterator iter = _locks.begin(); iter != _locks.end(); iter++) {
+ if (! fn (*iter, data))
+ return -1;
+ ++count;
+ }
+
+ return count;
+ }
+
+
+ void
+ World::addLock (constMatchPtr lock)
+ {
+ _locks.push_back (lock);
+ }
+
+
+ void
+ World::removeLock (constMatchPtr lock)
+ {
+ for (MatchList::iterator iter = _locks.begin(); iter != _locks.end(); iter++) {
+ if (*iter == lock) {
+ _locks.erase (iter);
+ break;
+ }
+ }
+ }
+
+
+ void
+ World::clearLocks (void)
+ {
+ _locks.clear();
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Package.h>
#include <zypp/solver/detail/PackageUpdate.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-
-typedef std::list <constWorldPtr> WorldList;
-
-class NameConflictInfo;
-
-//////////////////////////////////////////////////////////////////
-
-typedef enum {
- PLAIN_WORLD = 0,
- STORE_WORLD,
- MULTI_WORLD,
- SERVICE_WORLD,
- UNDUMP_WORLD,
- LOCALDIR_WORLD,
- SYSTEM_WORLD
-} WorldType;
-
-typedef bool (*WorldFn) (constWorldPtr world, void *user_data);
-typedef PendingPtr (*WorldRefreshFn) (constWorldPtr world);
-
-#if 0
-typedef bool (*WorldSyncFn) (constWorldPtr world, constChannelPtr channel);
-typedef PackmanPtr (*WorldPackmanFn) (constWorldPtr world, const Kind & kind);
-typedef void (*WorldSpewFn) (constWorldPtr world, FILE *out);
-typedef constWorldPtr (*WorldDupFn) (constWorldPtr world);
-
-typedef bool (*WorldCanTransactResItemFn) (constWorldPtr world, constResItemPtr resItem);
-typedef bool (*WorldTransactFn) (constWorldPtr world, const ResItemList & install_resItems, const ResItemList & remove_resItems, int flags);
-
-typedef bool (*WorldGetSubscribedFn) (const World *world, constChannelPtr channel);
-typedef void (*WorldSetSubscribedFn) (World *world, ChannelPtr channel, bool subs_status);
-
-typedef int (*WorldForeachChannelFn) (const World *world, ChannelFn callback, void *user_data);
-typedef int (*WorldForeachLockFn) (constWorldPtr world, MatchFn callback, void *user_data);
-
-typedef void (*WorldAddLockFn) (constWorldPtr world, constMatchPtr lock);
-typedef void (*WorldRemoveLockFn) (constWorldPtr world, constMatchPtr lock);
-typedef void (*WorldClearLockFn) (constWorldPtr world);
-
-typedef int (*WorldForeachResItemFn) (constWorldPtr world, const char *name, constChannelPtr channel, ResItemFn callback, void *user_data);
-typedef int (*WorldForeachPackageSpecFn) (constWorldPtr world, constDependencyPtr dep, ResItemAndSpecFn callback, void *user_data);
-typedef int (*WorldForeachPackageDepFn) (constWorldPtr world, constDependencyPtr dep, ResItemAndDepFn callback, void *user_data);
-
-typedef void (*WorldSerializeFn) (constWorldPtr world, constXmlNodePtr root);
-typedef void (*WorldUnserializeFn) (constWorldPtr world, constXmlNodePtr node);
-
-#endif
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : World
-
-class World : public CountedRep {
- REP_BODY(World);
-
- private:
- static WorldPtr GlobalWorld;
-
- WorldType _type;
-
- /* The sequence numbers gets incremented every
- time the RCWorld is changed. */
-
- unsigned int _seq_no_resItems;
- unsigned int _seq_no_channels;
- unsigned int _seq_no_subscriptions;
- unsigned int _seq_no_locks;
-
- /* Every world needs to be able to store locks, so we provide a
- place for that. Of course, derived classes are allowed to
- provide their own exotic lock semantics by providing their
- own *_lock_fn methods. */
- MatchList _lock_store;
-
- bool _refresh_pending;
-
- /* a bad hack to keep us from emitting signals while finalizing */
- bool _no_changed_signals;
-
- /* For unserialized worlds currently. If a world is read only,
- you can not refresh or transact on it. */
- bool _read_only;
-
- MatchList _locks;
-
- public:
-
- World (WorldType type = PLAIN_WORLD);
- virtual ~World();
-
- // ---------------------------------- I/O
-
- static std::string toString (const World & section);
-
- static std::string toString (WorldType type);
-
- virtual std::ostream & dumpOn(std::ostream & str ) const;
-
- friend std::ostream& operator<<(std::ostream&, const World & section);
-
- std::string asString (void ) const;
-
- // ---------------------------------- accessors
-
- WorldType type() const { return _type; }
- bool isPlainWorld () const { return _type == PLAIN_WORLD; }
- bool isUndumpWorld () const { return _type == UNDUMP_WORLD; }
- bool isMultiWorld () const { return _type == MULTI_WORLD; }
- bool isServiceWorld () const { return _type == SERVICE_WORLD; }
-
- unsigned int resItemSequenceNumber (void) const { return _seq_no_resItems; }
- unsigned int channelSequenceNumber (void) const { return _seq_no_channels; }
- unsigned int subscriptionSequenceNumber (void) const { return _seq_no_subscriptions; }
- unsigned int lockSequenceNumber (void) const { return _seq_no_locks; }
-
- void touchResItemSequenceNumber (void) { _seq_no_resItems++; }
- void touchChannelSequenceNumber (void) { _seq_no_channels++; }
- void touchSubscriptionSequenceNumber (void) { _seq_no_subscriptions++; }
- void touchLockSequenceNumber (void) { _seq_no_locks++; }
-
- MatchList locks (void) const { return _lock_store; }
-
- // ---------------------------------- methods
-
- static void setGlobalWorld (MultiWorldPtr world) { GlobalWorld = world; }
- static MultiWorldPtr globalWorld (void) { return GlobalWorld; }
-
- //RCPackman *get_packman (GType);
-
- bool sync (void) const;
- virtual bool syncConditional (constChannelPtr channel) const;
- PendingPtr refresh (void);
- bool hasRefresh (void);
- bool isRefreshing (void);
-
- /* These functions are for World-implementers only! Don't call them! */
- void refreshBegin (void);
- void refreshComplete (void);
-
- virtual int foreachChannel (ChannelFn fn, void *user_data) const = 0;
-
- virtual void setSubscription (ChannelPtr channel, bool is_subscribed);
- virtual bool isSubscribed (constChannelPtr channel) const;
-
- virtual ChannelList channels () const = 0;
- virtual bool containsChannel (constChannelPtr channel) const = 0;
-
- virtual ChannelPtr getChannelByName (const char *channel_name) const = 0;
- virtual ChannelPtr getChannelByAlias (const char *alias) const = 0;
- virtual ChannelPtr getChannelById (const char *channel_id) const = 0;
-
- // ResItem Locks
-
- virtual int foreachLock (MatchFn fn, void *data) const;
-
- void addLock (constMatchPtr lock);
- void removeLock (constMatchPtr lock);
- void clearLocks ();
-
- bool resItemIsLocked (constResItemPtr resItem);
-
- // Single resItem queries
-
- virtual constResItemPtr findInstalledResItem (constResItemPtr resItem) = 0;
- virtual constResItemPtr findResItem (constChannelPtr channel, const char *name) const = 0;
- virtual constResItemPtr findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const = 0;
- virtual ChannelPtr guessResItemChannel (constResItemPtr resItem) const = 0;
-
- // Iterate across resItems
-
- virtual int foreachResItem (ChannelPtr channel, CResItemFn fn, void *data) = 0;
- virtual int foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *user_data) = 0;
- virtual int foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *user_data) = 0;
-
- // Iterate across provides or requirement
-
- virtual int foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *user_data) = 0;
- virtual int foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *user_data) = 0;
- virtual int foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *user_data) = 0;
-
- // upgrades
-
- int foreachUpgrade (constResItemPtr resItem, ChannelPtr channel, CResItemFn fn, void *data);
- PackageUpdateList getUpgrades (constResItemPtr resItem, constChannelPtr channel);
- constResItemPtr getBestUpgrade (constResItemPtr resItem, bool subscribed_only);
- int foreachSystemUpgrade (bool subscribed_only, ResItemPairFn fn, void *data);
-
- // provider
-
- bool getSingleProvider (constDependencyPtr dep, constChannelPtr channel, constResItemPtr *resItem);
-
- // Transacting
-
- bool canTransactResItem (constResItemPtr resItem);
- bool transact (const ResItemList & installResItems, const ResItemList & remove_resItems, int flags);
-
- // XML serialization
-
- void serialize (XmlNodePtr parent);
- void toFile (const char *filename);
-
- // Duplicating (primarily for atomic refreshes)
- WorldPtr dup (void);
-
- // only used for bindings
- void setRefreshFunction (WorldRefreshFn refresh_fn);
-
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef std::list <constWorldPtr> WorldList;
+
+ class NameConflictInfo;
+
+ //////////////////////////////////////////////////////////////////
+
+ typedef enum {
+ PLAIN_WORLD = 0,
+ STORE_WORLD,
+ MULTI_WORLD,
+ SERVICE_WORLD,
+ UNDUMP_WORLD,
+ LOCALDIR_WORLD,
+ SYSTEM_WORLD
+ } WorldType;
+
+ typedef bool (*WorldFn) (constWorldPtr world, void *user_data);
+ typedef PendingPtr (*WorldRefreshFn) (constWorldPtr world);
+
+ #if 0
+ typedef bool (*WorldSyncFn) (constWorldPtr world, constChannelPtr channel);
+ typedef PackmanPtr (*WorldPackmanFn) (constWorldPtr world, const Kind & kind);
+ typedef void (*WorldSpewFn) (constWorldPtr world, FILE *out);
+ typedef constWorldPtr (*WorldDupFn) (constWorldPtr world);
+
+ typedef bool (*WorldCanTransactResItemFn) (constWorldPtr world, constResItemPtr resItem);
+ typedef bool (*WorldTransactFn) (constWorldPtr world, const ResItemList & install_resItems, const ResItemList & remove_resItems, int flags);
+
+ typedef bool (*WorldGetSubscribedFn) (const World *world, constChannelPtr channel);
+ typedef void (*WorldSetSubscribedFn) (World *world, ChannelPtr channel, bool subs_status);
+
+ typedef int (*WorldForeachChannelFn) (const World *world, ChannelFn callback, void *user_data);
+ typedef int (*WorldForeachLockFn) (constWorldPtr world, MatchFn callback, void *user_data);
+
+ typedef void (*WorldAddLockFn) (constWorldPtr world, constMatchPtr lock);
+ typedef void (*WorldRemoveLockFn) (constWorldPtr world, constMatchPtr lock);
+ typedef void (*WorldClearLockFn) (constWorldPtr world);
+
+ typedef int (*WorldForeachResItemFn) (constWorldPtr world, const char *name, constChannelPtr channel, ResItemFn callback, void *user_data);
+ typedef int (*WorldForeachPackageSpecFn) (constWorldPtr world, constDependencyPtr dep, ResItemAndSpecFn callback, void *user_data);
+ typedef int (*WorldForeachPackageDepFn) (constWorldPtr world, constDependencyPtr dep, ResItemAndDepFn callback, void *user_data);
+
+ typedef void (*WorldSerializeFn) (constWorldPtr world, constXmlNodePtr root);
+ typedef void (*WorldUnserializeFn) (constWorldPtr world, constXmlNodePtr node);
+
+ #endif
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : World
+
+ class World : public CountedRep {
+ REP_BODY(World);
+
+ private:
+ static WorldPtr GlobalWorld;
+
+ WorldType _type;
+
+ /* The sequence numbers gets incremented every
+ time the RCWorld is changed. */
+
+ unsigned int _seq_no_resItems;
+ unsigned int _seq_no_channels;
+ unsigned int _seq_no_subscriptions;
+ unsigned int _seq_no_locks;
+
+ /* Every world needs to be able to store locks, so we provide a
+ place for that. Of course, derived classes are allowed to
+ provide their own exotic lock semantics by providing their
+ own *_lock_fn methods. */
+ MatchList _lock_store;
+
+ bool _refresh_pending;
+
+ /* a bad hack to keep us from emitting signals while finalizing */
+ bool _no_changed_signals;
+
+ /* For unserialized worlds currently. If a world is read only,
+ you can not refresh or transact on it. */
+ bool _read_only;
+
+ MatchList _locks;
+
+ public:
+
+ World (WorldType type = PLAIN_WORLD);
+ virtual ~World();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const World & section);
+
+ static std::string toString (WorldType type);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const World & section);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ WorldType type() const { return _type; }
+ bool isPlainWorld () const { return _type == PLAIN_WORLD; }
+ bool isUndumpWorld () const { return _type == UNDUMP_WORLD; }
+ bool isMultiWorld () const { return _type == MULTI_WORLD; }
+ bool isServiceWorld () const { return _type == SERVICE_WORLD; }
+
+ unsigned int resItemSequenceNumber (void) const { return _seq_no_resItems; }
+ unsigned int channelSequenceNumber (void) const { return _seq_no_channels; }
+ unsigned int subscriptionSequenceNumber (void) const { return _seq_no_subscriptions; }
+ unsigned int lockSequenceNumber (void) const { return _seq_no_locks; }
+
+ void touchResItemSequenceNumber (void) { _seq_no_resItems++; }
+ void touchChannelSequenceNumber (void) { _seq_no_channels++; }
+ void touchSubscriptionSequenceNumber (void) { _seq_no_subscriptions++; }
+ void touchLockSequenceNumber (void) { _seq_no_locks++; }
+
+ MatchList locks (void) const { return _lock_store; }
+
+ // ---------------------------------- methods
+
+ static void setGlobalWorld (MultiWorldPtr world) { GlobalWorld = world; }
+ static MultiWorldPtr globalWorld (void) { return GlobalWorld; }
+
+ //RCPackman *get_packman (GType);
+
+ bool sync (void) const;
+ virtual bool syncConditional (constChannelPtr channel) const;
+ PendingPtr refresh (void);
+ bool hasRefresh (void);
+ bool isRefreshing (void);
+
+ /* These functions are for World-implementers only! Don't call them! */
+ void refreshBegin (void);
+ void refreshComplete (void);
+
+ virtual int foreachChannel (ChannelFn fn, void *user_data) const = 0;
+
+ virtual void setSubscription (ChannelPtr channel, bool is_subscribed);
+ virtual bool isSubscribed (constChannelPtr channel) const;
+
+ virtual ChannelList channels () const = 0;
+ virtual bool containsChannel (constChannelPtr channel) const = 0;
+
+ virtual ChannelPtr getChannelByName (const char *channel_name) const = 0;
+ virtual ChannelPtr getChannelByAlias (const char *alias) const = 0;
+ virtual ChannelPtr getChannelById (const char *channel_id) const = 0;
+
+ // ResItem Locks
+
+ virtual int foreachLock (MatchFn fn, void *data) const;
+
+ void addLock (constMatchPtr lock);
+ void removeLock (constMatchPtr lock);
+ void clearLocks ();
+
+ bool resItemIsLocked (constResItemPtr resItem);
+
+ // Single resItem queries
+
+ virtual constResItemPtr findInstalledResItem (constResItemPtr resItem) = 0;
+ virtual constResItemPtr findResItem (constChannelPtr channel, const char *name) const = 0;
+ virtual constResItemPtr findResItemWithConstraint (constChannelPtr channel, const char *name, constDependencyPtr constraint, bool is_and) const = 0;
+ virtual ChannelPtr guessResItemChannel (constResItemPtr resItem) const = 0;
+
+ // Iterate across resItems
+
+ virtual int foreachResItem (ChannelPtr channel, CResItemFn fn, void *data) = 0;
+ virtual int foreachResItemByName (const std::string & name, ChannelPtr channel, CResItemFn fn, void *user_data) = 0;
+ virtual int foreachResItemByMatch (constMatchPtr match, CResItemFn fn, void *user_data) = 0;
+
+ // Iterate across provides or requirement
+
+ virtual int foreachProvidingResItem (constDependencyPtr dep, ResItemAndSpecFn fn, void *user_data) = 0;
+ virtual int foreachRequiringResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *user_data) = 0;
+ virtual int foreachConflictingResItem (constDependencyPtr dep, ResItemAndDepFn fn, void *user_data) = 0;
+
+ // upgrades
+
+ int foreachUpgrade (constResItemPtr resItem, ChannelPtr channel, CResItemFn fn, void *data);
+ PackageUpdateList getUpgrades (constResItemPtr resItem, constChannelPtr channel);
+ constResItemPtr getBestUpgrade (constResItemPtr resItem, bool subscribed_only);
+ int foreachSystemUpgrade (bool subscribed_only, ResItemPairFn fn, void *data);
+
+ // provider
+
+ bool getSingleProvider (constDependencyPtr dep, constChannelPtr channel, constResItemPtr *resItem);
+
+ // Transacting
+
+ bool canTransactResItem (constResItemPtr resItem);
+ bool transact (const ResItemList & installResItems, const ResItemList & remove_resItems, int flags);
+
+ // XML serialization
+
+ void serialize (XmlNodePtr parent);
+ void toFile (const char *filename);
+
+ // Duplicating (primarily for atomic refreshes)
+ WorldPtr dup (void);
+
+ // only used for bindings
+ void setRefreshFunction (WorldRefreshFn refresh_fn);
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _World_h
#include <y2util/RepDef.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////
// CLASS NAME : WorldPtr
// CLASS NAME : constWorldPtr
///////////////////////////////////////////////////////////////////
DEFINE_BASE_POINTER(World);
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _WorldPtr_h
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-IMPL_BASE_POINTER(XmlNode);
-
-//---------------------------------------------------------------------------
-
-XmlNode::XmlNode (const xmlNodePtr node)
- : _node(node)
-{
-}
-
-XmlNode::XmlNode (const char *name)
- : _node(xmlNewNode (NULL, (const xmlChar *)name))
-{
-}
-
-XmlNode::~XmlNode ()
-{
-}
-
-//---------------------------------------------------------------------------
-
-string
-XmlNode::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-XmlNode::toString ( const XmlNode & node )
-{
- return "<xmlnode/>";
-}
-
-
-ostream &
-XmlNode::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const XmlNode& node)
-{
- return os << node.asString();
-}
-
-//---------------------------------------------------------------------------
-
-const char *
-XmlNode::getValue (const char *name, const char *deflt) const
-{
- char *ret;
- xmlChar *xml_s;
- xmlNode *child;
-
- xml_s = xmlGetProp(_node, (const xmlChar *)name);
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) xmlGetProp '%s'\n", name, (char *)xml_s);
-
- if (xml_s) {
- ret = strdup ((const char *)xml_s);
- xmlFree (xml_s);
- return ret;
- }
-
- child = _node->xmlChildrenNode;
-
- while (child) {
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) child '%s'\n", name, (const char *)(child->name));
- if (strcasecmp((const char *)(child->name), name) == 0) {
- xml_s = xmlNodeGetContent(child);
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) xmlNodeGetContent '%s'\n", name, (char *)xml_s);
- if (xml_s) {
- ret = strdup ((const char *)xml_s);
- xmlFree (xml_s);
- return ret;
- }
- }
- child = child->next;
- }
-
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) NULL\n", name);
- return deflt;
-}
-
-
-const char *
-XmlNode::getProp (const char *name, const char *deflt) const
-{
- xmlChar *ret;
- char *gs;
-
- ret = xmlGetProp (_node, (const xmlChar *)name);
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getProp(%s) xmlGetProp '%s'\n", name, (char *)ret);
- if (ret) {
- gs = strdup ((const char *)ret);
- xmlFree (ret);
- return gs;
- }
- return deflt;
-}
-
-
-bool
-XmlNode::getIntValue (const char *name, int *value) const
-{
- const char *strval;
- char *ret;
- int z;
-
- strval = this->getValue (name, NULL);
- if (!strval) {
- return false;
- }
-
- z = strtol (strval, &ret, 10);
- if (*ret != '\0') {
- free ((void *)strval);
- return false;
- }
-
- free ((void *)strval);
- *value = z;
- return true;
-}
-
-
-int
-XmlNode::getIntValueDefault (const char *name, int def) const
-{
- int z;
- if (this->getIntValue (name, &z))
- return z;
- else
- return def;
-}
-
-
-unsigned int
-XmlNode::getUnsignedIntValueDefault (const char *name, unsigned int def) const
-{
- unsigned int z;
- if (this->getUnsignedIntValue (name, &z))
- return z;
- else
- return def;
-}
-
-
-bool
-XmlNode::getUnsignedIntValue (const char *name, unsigned int *value) const
-{
- const char *strval;
- char *ret;
- int z;
-
- strval = this->getValue (name, NULL);
- if (!strval) {
- return false;
- }
-
- z = strtoul (strval, &ret, 10);
- if (*ret != '\0') {
- free ((void *)strval);
- return false;
- }
-
- free ((void *)strval);
- *value = z;
- return true;
-}
-
-
-unsigned int
-XmlNode::getUnsignedIntPropDefault (const char *name, unsigned int def) const
-{
- xmlChar *buf;
- unsigned int ret;
-
- buf = xmlGetProp (_node, (const xmlChar *)name);
-
- if (buf) {
- ret = strtol ((const char *)buf, NULL, 10);
- xmlFree (buf);
- return (ret);
- } else {
- return (def);
- }
-}
-
-
-const char *
-XmlNode::getContent (void) const
-{
- xmlChar *buf;
- char *ret;
-
- buf = xmlNodeGetContent (_node);
-
- ret = strdup ((const char *)buf);
-
- xmlFree (buf);
-
- return (ret);
-}
-
-
-unsigned int
-XmlNode::getUnsignedIntContentDefault (unsigned int def) const
-{
- xmlChar *buf;
- unsigned int ret;
-
- buf = xmlNodeGetContent (_node);
-
- if (buf) {
- ret = strtol ((const char *)buf, NULL, 10);
- xmlFree (buf);
- return (ret);
- } else {
- return (def);
- }
-}
-
-
-const XmlNodePtr
-XmlNode::getNode (const char *name) const
-{
- xmlNodePtr iter;
-
- for (iter = _node->xmlChildrenNode; iter; iter = iter->next) {
- if (strcasecmp ((const char *)(iter->name), name) == 0) {
- return new XmlNode (iter);
- }
- }
-
- return NULL;
-}
-
-
-//---------------------------------------------------------------------------
-
-
-void
-XmlNode::addTextChild (const char *name, const char *content)
-{
- xmlNewTextChild (_node, NULL, (const xmlChar *)name, (const xmlChar *)content);
-}
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ IMPL_BASE_POINTER(XmlNode);
+
+ //---------------------------------------------------------------------------
+
+ XmlNode::XmlNode (const xmlNodePtr node)
+ : _node(node)
+ {
+ }
+
+ XmlNode::XmlNode (const char *name)
+ : _node(xmlNewNode (NULL, (const xmlChar *)name))
+ {
+ }
+
+ XmlNode::~XmlNode ()
+ {
+ }
+
+ //---------------------------------------------------------------------------
+
+ string
+ XmlNode::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ XmlNode::toString ( const XmlNode & node )
+ {
+ return "<xmlnode/>";
+ }
+
+
+ ostream &
+ XmlNode::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const XmlNode& node)
+ {
+ return os << node.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ const char *
+ XmlNode::getValue (const char *name, const char *deflt) const
+ {
+ char *ret;
+ xmlChar *xml_s;
+ xmlNode *child;
+
+ xml_s = xmlGetProp(_node, (const xmlChar *)name);
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) xmlGetProp '%s'\n", name, (char *)xml_s);
+
+ if (xml_s) {
+ ret = strdup ((const char *)xml_s);
+ xmlFree (xml_s);
+ return ret;
+ }
+
+ child = _node->xmlChildrenNode;
+
+ while (child) {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) child '%s'\n", name, (const char *)(child->name));
+ if (strcasecmp((const char *)(child->name), name) == 0) {
+ xml_s = xmlNodeGetContent(child);
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) xmlNodeGetContent '%s'\n", name, (char *)xml_s);
+ if (xml_s) {
+ ret = strdup ((const char *)xml_s);
+ xmlFree (xml_s);
+ return ret;
+ }
+ }
+ child = child->next;
+ }
+
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getValue(%s) NULL\n", name);
+ return deflt;
+ }
+
+
+ const char *
+ XmlNode::getProp (const char *name, const char *deflt) const
+ {
+ xmlChar *ret;
+ char *gs;
+
+ ret = xmlGetProp (_node, (const xmlChar *)name);
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlNode::getProp(%s) xmlGetProp '%s'\n", name, (char *)ret);
+ if (ret) {
+ gs = strdup ((const char *)ret);
+ xmlFree (ret);
+ return gs;
+ }
+ return deflt;
+ }
+
+
+ bool
+ XmlNode::getIntValue (const char *name, int *value) const
+ {
+ const char *strval;
+ char *ret;
+ int z;
+
+ strval = this->getValue (name, NULL);
+ if (!strval) {
+ return false;
+ }
+
+ z = strtol (strval, &ret, 10);
+ if (*ret != '\0') {
+ free ((void *)strval);
+ return false;
+ }
+
+ free ((void *)strval);
+ *value = z;
+ return true;
+ }
+
+
+ int
+ XmlNode::getIntValueDefault (const char *name, int def) const
+ {
+ int z;
+ if (this->getIntValue (name, &z))
+ return z;
+ else
+ return def;
+ }
+
+
+ unsigned int
+ XmlNode::getUnsignedIntValueDefault (const char *name, unsigned int def) const
+ {
+ unsigned int z;
+ if (this->getUnsignedIntValue (name, &z))
+ return z;
+ else
+ return def;
+ }
+
+
+ bool
+ XmlNode::getUnsignedIntValue (const char *name, unsigned int *value) const
+ {
+ const char *strval;
+ char *ret;
+ int z;
+
+ strval = this->getValue (name, NULL);
+ if (!strval) {
+ return false;
+ }
+
+ z = strtoul (strval, &ret, 10);
+ if (*ret != '\0') {
+ free ((void *)strval);
+ return false;
+ }
+
+ free ((void *)strval);
+ *value = z;
+ return true;
+ }
+
+
+ unsigned int
+ XmlNode::getUnsignedIntPropDefault (const char *name, unsigned int def) const
+ {
+ xmlChar *buf;
+ unsigned int ret;
+
+ buf = xmlGetProp (_node, (const xmlChar *)name);
+
+ if (buf) {
+ ret = strtol ((const char *)buf, NULL, 10);
+ xmlFree (buf);
+ return (ret);
+ } else {
+ return (def);
+ }
+ }
+
+
+ const char *
+ XmlNode::getContent (void) const
+ {
+ xmlChar *buf;
+ char *ret;
+
+ buf = xmlNodeGetContent (_node);
+
+ ret = strdup ((const char *)buf);
+
+ xmlFree (buf);
+
+ return (ret);
+ }
+
+
+ unsigned int
+ XmlNode::getUnsignedIntContentDefault (unsigned int def) const
+ {
+ xmlChar *buf;
+ unsigned int ret;
+
+ buf = xmlNodeGetContent (_node);
+
+ if (buf) {
+ ret = strtol ((const char *)buf, NULL, 10);
+ xmlFree (buf);
+ return (ret);
+ } else {
+ return (def);
+ }
+ }
+
+
+ const XmlNodePtr
+ XmlNode::getNode (const char *name) const
+ {
+ xmlNodePtr iter;
+
+ for (iter = _node->xmlChildrenNode; iter; iter = iter->next) {
+ if (strcasecmp ((const char *)(iter->name), name) == 0) {
+ return new XmlNode (iter);
+ }
+ }
+
+ return NULL;
+ }
+
+
+ //---------------------------------------------------------------------------
+
+
+ void
+ XmlNode::addTextChild (const char *name, const char *content)
+ {
+ xmlNewTextChild (_node, NULL, (const xmlChar *)name, (const xmlChar *)content);
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/XmlNodePtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
//
void addTextChild (const char *name, const char *content);
};
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
#endif // _XmlNode_h
#include <y2util/RepDef.h>
///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-// CLASS NAME : XmlNodePtr
-// CLASS NAME : constXmlNodePtr
-///////////////////////////////////////////////////////////////////
-DEFINE_BASE_POINTER(XmlNode);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
+namespace zypp
+{ //////////////////////////////////////////////////////////////////
+ //////////////////////////////////////////////////////////////////
+ namespace solver
+ { ///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : XmlNodePtr
+ // CLASS NAME : constXmlNodePtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_BASE_POINTER(XmlNode);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ ///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+};// namespace zypp
///////////////////////////////////////////////////////////////////
#endif // _XmlNodePtr_h
#include <config.h>
#include <ctype.h>
#include <assert.h>
-
#include <zypp/solver/detail/XmlParser.h>
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/OrDependency.h>
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-//---------------------------------------------------------------------------
-
-static DependencyPtr
-parse_dep_attrs(bool *is_obsolete, const xmlChar **attrs)
-{
- int i;
- bool op_present = false;
- /* Temporary variables dependent upon the presense of an 'op' attribute */
- const char *name = NULL;
- int epoch = -1;
- string version;
- string release;
- string arch;
- Relation relation = Relation::Any;
-
- *is_obsolete = false;
-
- for (i = 0; attrs[i]; i++) {
- const char *attr = (const char *)attrs[i++];
- const char *value = (const char *)attrs[i];
-
- if (!strcasecmp(attr, "name")) name = value;
- else if (!strcasecmp(attr, "op")) { op_present = true; relation = Relation::parse(value); }
- else if (!strcasecmp(attr, "epoch")) epoch = atoi (value);
- else if (!strcasecmp(attr, "version")) version = value;
- else if (!strcasecmp(attr, "release")) release = value;
- else if (!strcasecmp(attr, "arch")) arch = value;
- else if (!strcasecmp (attr, "obsoletes")) *is_obsolete = true;
- else {
- if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Unknown attribute: %s = %s", attr, value);
- }
-
- }
-
- /* FIXME: should get Channel from XML */
- /* FIXME: should get Kind from XML */
- return new Dependency (name, relation, Kind::Package, new Channel(CHANNEL_TYPE_ANY), epoch, version, release, Arch::create(arch));
-}
-
-
-//---------------------------------------------------------------------------
-// SAX callbacks
-
-static void
-sax_start_document(void *ptr)
-{
- XmlParser *ctx = (XmlParser *)ptr;
- if (ctx->processing()) return;
-
-// if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* Start document");
-
- ctx->setProcessing (true);
-}
-
-
-static void
-sax_end_document(void *ptr)
-{
- XmlParser *ctx = (XmlParser *)ptr;
- if (!ctx->processing()) return;
-
-// if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* End document");
-
- ctx->setProcessing (false);
-}
-
-
-static void
-sax_start_element(void *ptr, const xmlChar *name, const xmlChar **attrs)
-{
- XmlParser *ctx = (XmlParser *)ptr;
-
- ctx->releaseBuffer();
-
-#if 0
-// if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* Start element (%s)", (const char *)name);
-
- if (attrs) {
- for (int i = 0; attrs[i]; i += 2) {
- if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, " - Attribute (%s=%s)", (const char *)attrs[i], (const char *)attrs[i+1]);
- }
- }
-#endif
- if (!strcmp((const char *)name, "channel") || !strcmp((const char *)name, "subchannel")) {
- /* Unneeded container tags. Ignore */
- return;
- }
-
- return ctx->startElement ((const char *)name, attrs);
-
-}
-
-
-static void
-sax_end_element(void *ptr, const xmlChar *name)
-{
- XmlParser *ctx = (XmlParser *)ptr;
-
-// if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* End element (%s)", (const char *)name);
-
- if (!strcmp((const char *)name, "channel") || !strcmp((const char *)name, "subchannel")) {
- /* Unneeded container tags. Ignore */
- name = NULL;
- }
-
- return ctx->endElement ((const char *)name);
-}
-
-
-static void
-sax_characters(void *ptr, const xmlChar *ch, int len)
-{
- XmlParser *ctx = (XmlParser *)ptr;
-
- ctx->toBuffer ((const char *)ch, len);
- return;
-}
-
-
-static void
-sax_warning(void *ptr, const char *msg, ...)
-{
- va_list args;
- char tmp[2048];
-
- va_start(args, msg);
-
- if (vsnprintf(tmp, 2048, msg, args) >= 2048) fprintf (stderr, "vsnprintf overflow\n");
- rc_debug (RC_DEBUG_LEVEL_WARNING, "* SAX Warning: %s", tmp);
-
- va_end(args);
-}
-
-
-static void
-sax_error(void *ptr, const char *msg, ...)
-{
- va_list args;
- char tmp[2048];
-
- va_start(args, msg);
-
- if (vsnprintf(tmp, 2048, msg, args) >= 2048) fprintf (stderr, "vsnprintf overflow\n");
- rc_debug (RC_DEBUG_LEVEL_ERROR, "* SAX Error: %s", tmp);
-
- va_end(args);
-}
-
-
-static xmlSAXHandler sax_handler = {
- NULL, /* internalSubset */
- NULL, /* isStandalone */
- NULL, /* hasInternalSubset */
- NULL, /* hasExternalSubset */
- NULL, /* resolveEntity */
- NULL, /* getEntity */
- NULL, /* entityDecl */
- NULL, /* notationDecl */
- NULL, /* attributeDecl */
- NULL, /* elementDecl */
- NULL, /* unparsedEntityDecl */
- NULL, /* setDocumentLocator */
- sax_start_document, /* startDocument */
- sax_end_document, /* endDocument */
- sax_start_element, /* startElement */
- sax_end_element, /* endElement */
- NULL, /* reference */
- sax_characters, /* characters */
- NULL, /* ignorableWhitespace */
- NULL, /* processingInstruction */
- NULL, /* comment */
- sax_warning, /* warning */
- sax_error, /* error */
- sax_error /* fatalError */
-};
-
-//---------------------------------------------------------------------------
-
-XmlParser::XmlParser (constChannelPtr channel)
- : _channel (channel)
- , _processing (false)
- , _xml_context (NULL)
- , _state (PARSER_TOPLEVEL)
- , _current_package (NULL)
- , _current_update (NULL)
- , _toplevel_dep_list (NULL)
- , _current_dep_list (NULL)
- , _text_buffer (NULL)
- , _text_buffer_size (0)
-{
-// if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* Context created (%p)", this);
-}
-
-
-XmlParser::~XmlParser()
-{
- releaseBuffer ();
-}
-
-//---------------------------------------------------------------------------
-
-string
-XmlParser::asString ( void ) const
-{
- return toString (*this);
-}
-
-
-string
-XmlParser::toString ( const XmlParser & context )
-{
- return "<XmlParser/>";
-}
-
-
-ostream &
-XmlParser::dumpOn( ostream & str ) const
-{
- str << asString();
- return str;
-}
-
-
-ostream&
-operator<<( ostream& os, const XmlParser& context)
-{
- return os << context.asString();
-}
-
-//---------------------------------------------------------------------------
-
-void
-XmlParser::toBuffer (const char *data, size_t size)
-{
- _text_buffer = (char *)realloc (_text_buffer, _text_buffer_size + size + 1);
- strncpy (_text_buffer + _text_buffer_size, (char *)data, size);
- _text_buffer_size += size;
- _text_buffer[_text_buffer_size] = 0;
-
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser[%p]::toBuffer(%.32s...,%ld)\n", this, data, (long)size);
-}
-
-
-void
-XmlParser::releaseBuffer ()
-{
- if (_text_buffer)
- free (_text_buffer);
- _text_buffer = NULL;
- _text_buffer_size = 0;
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser[%p]::releaseBuffer()\n", this);
-}
-
-
-void
-XmlParser::parseChunk(const char *xmlbuf, size_t size)
-{
- if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::parseChunk(%.32s...,%ld)\n", xmlbuf, (long)size);
-
- xmlSubstituteEntitiesDefault(true);
-
- if (!_xml_context) {
- _xml_context = xmlCreatePushParserCtxt(&sax_handler, this, NULL, 0, NULL);
- }
-
- xmlParseChunk(_xml_context, xmlbuf, size, 0);
-}
-
-
-PackageList
-XmlParser::done()
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::done()\n");
-
- if (_processing)
- xmlParseChunk(_xml_context, NULL, 0, 1);
-
- if (_xml_context)
- xmlFreeParserCtxt(_xml_context);
-
- if (_current_package) {
- fprintf (stderr, "Incomplete package lost\n");
- }
-
- if (_current_update) {
- fprintf (stderr, "Incomplete update lost");
- }
-
- return _all_packages;
-}
-
-
-//---------------------------------------------------------------------------
-// Parser state callbacks
-
-void
-XmlParser::startElement(const char *name, const xmlChar **attrs)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::startElement(%s)\n", name);
-
- switch (_state) {
- case PARSER_TOPLEVEL:
- toplevelStart(name, attrs);
- break;
- case PARSER_PACKAGE:
- packageStart(name, attrs);
- break;
- case PARSER_HISTORY:
- historyStart(name, attrs);
- break;
- case PARSER_DEP:
- dependencyStart(name, attrs);
- break;
- default:
- break;
- }
-
- return;
-}
-
-
-void
-XmlParser::endElement(const char *name)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::endElement(%s)\n", name);
-
- if (name != NULL) { // sax_end_element might set name to NULL
- switch (_state) {
- case PARSER_PACKAGE:
- packageEnd(name);
- break;
- case PARSER_HISTORY:
- historyEnd(name);
- break;
- case PARSER_UPDATE:
- updateEnd(name);
- break;
- case PARSER_DEP:
- dependencyEnd(name);
- break;
- default:
- break;
- }
- }
-
- releaseBuffer();
-
- return;
-}
-
-
-void
-XmlParser::toplevelStart(const char * name, const xmlChar **attrs)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::toplevelStart(%s)\n", name);
-
- if (!strcmp(name, "package")) {
- assert(_current_package == NULL);
-
- _state = PARSER_PACKAGE;
-
- _current_package = new Package(_channel);
- _current_requires.clear();
- _current_provides.clear();
- _current_conflicts.clear();
- _current_children.clear();
- _current_recommends.clear();
- _current_suggests.clear();
- _current_obsoletes.clear();
-
- }
- else {
- if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s at toplevel", (const char *)name);
- }
-}
-
-
-void
-XmlParser::packageStart(const char * name, const xmlChar **attrs)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageStart(%s)\n", name);
-
- assert(_current_package != NULL);
-
- /* Only care about the containers here */
- if (!strcmp((const char *)name, "history")) {
- _state = PARSER_HISTORY;
- }
- else if (!strcmp (name, "deps")) {
- /*
- * We can get a <deps> tag surrounding the actual package
- * dependency sections (requires, provides, conflicts, etc).
- * In this case, we'll just ignore this tag quietly.
- */
- }
- else if (!strcmp(name, "requires")) {
- _state = PARSER_DEP;
- _current_dep_list = _toplevel_dep_list = &_current_requires;
- }
- else if (!strcmp(name, "recommends")) {
- _state = PARSER_DEP;
- _current_dep_list = _toplevel_dep_list = &_current_recommends;
- }
- else if (!strcmp(name, "suggests")) {
- _state = PARSER_DEP;
- _current_dep_list = _toplevel_dep_list = &_current_suggests;
- }
- else if (!strcmp(name, "conflicts")) {
- bool is_obsolete = false;
- int i;
-
- _state = PARSER_DEP;
-
- for (i = 0; attrs && attrs[i] && !is_obsolete; i += 2) {
-
- if (!strcasecmp ((const char *)(attrs[i]), "obsoletes"))
- is_obsolete = true;
- }
-
- if (is_obsolete)
- _current_dep_list = _toplevel_dep_list = &_current_obsoletes;
- else {
- _current_dep_list = _toplevel_dep_list = &_current_conflicts;
- }
- }
- else if (!strcmp(name, "obsoletes")) {
- _state = PARSER_DEP;
- _current_dep_list = _toplevel_dep_list = &_current_obsoletes;
- }
- else if (!strcmp(name, "provides")) {
- _state = PARSER_DEP;
- _current_dep_list = _toplevel_dep_list = &_current_provides;
- }
- else if (!strcmp(name, "children")) {
- _state = PARSER_DEP;
- _current_dep_list = _toplevel_dep_list = &_current_children;
- }
- else {
-// if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s in package start", name);
- }
-}
-
-
-void
-XmlParser::historyStart(const char * name, const xmlChar **attrs)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::historyStart(%s)\n", name);
-
- assert(_current_package != NULL);
-
- if (!strcmp(name, "update")) {
- assert(_current_update == NULL);
-
- _current_update = new PackageUpdate(_current_package->name());
-
- _state = PARSER_UPDATE;
- }
- else {
- if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s in history", name);
- }
-}
-
-
-void
-XmlParser::dependencyStart(const char *name, const xmlChar **attrs)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::dependencyStart(%s)\n", name);
-
- if (!strcmp(name, "dep")) {
- DependencyPtr dep;
- bool is_obsolete;
-
- dep = parse_dep_attrs(&is_obsolete, attrs);
-
- if (is_obsolete)
- _current_obsoletes.push_back (dep);
- else {
- _current_dep_list->push_back (dep);
- }
- }
- else if (!strcmp(name, "or"))
- _current_dep_list = new CDependencyList;
- else {
- if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s in dependency", name);
- }
-}
-
-
-//---------------------------------------------------------------------------
-
-
-void
-XmlParser::packageEnd(const char *name)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd(%s)\n", name);
-
- assert(_current_package != NULL);
-
- if (!strcmp(name, "package")) {
- PackageUpdatePtr update;
-
- /* If possible, grab the version info from the most recent update.
- * Otherwise, try to find where the package provides itself and use
- * that version info.
- */
- update = _current_package->getLatestUpdate();
-
- if (update) {
- _current_package->setName (update->name());
- _current_package->setKind (update->kind());
- _current_package->setEdition (update->edition());
- _current_package->setFileSize (update->packageSize());
- _current_package->setInstalledSize (update->installedSize());
- }
- else {
- for (CDependencyList::const_iterator iter = _current_provides.begin(); iter != _current_provides.end(); iter++) {
- if ((*iter)->relation().isEqual()
- && ((*iter)->name() == _current_package->name()))
- {
- _current_package->setKind ((*iter)->kind());
- _current_package->setEdition ((*iter)->edition());
- break;
- }
- }
- }
-
- /* Hack for the old XML */
- if (_current_package->arch()->isUnknown()) {
- _current_package->setArch (Arch::System);
- }
-
- // check if we provide ourselfs properly
-
- CDependencyList::const_iterator piter;
- for (piter = _current_provides.begin(); piter != _current_provides.end(); piter++) {
- if ((*piter)->relation().isEqual()
- && ((*piter)->name() == _current_package->name()))
- {
- break;
- }
- }
-
- if (piter == _current_provides.end()) { // no self provide found, construct one
- constDependencyPtr selfdep = new Dependency (_current_package->name(), Relation::Equal, _current_package->kind(), _current_package->channel(), _current_package->edition());
-//if (getenv ("RC_SPEW")) fprintf (stderr, "Adding self-provide [%s]\n", selfdep->asString().c_str());
- _current_provides.push_front (selfdep);
- }
-
- _current_package->setRequires (_current_requires);
- _current_package->setProvides (_current_provides);
- _current_package->setConflicts (_current_conflicts);
- _current_package->setObsoletes (_current_obsoletes);
- _current_package->setSuggests (_current_suggests);
- _current_package->setRecommends (_current_recommends);
-
- _all_packages.push_back (_current_package);
-
- if (getenv ("RC_SPEW")) fprintf (stderr, "%s\n", _current_package->asString(true).c_str());
- if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd done: '%s'\n", _current_package->asString(true).c_str());
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd now %ld packages\n", _all_packages.size());
- _current_package = NULL;
- _state = PARSER_TOPLEVEL;
- }
- else if (!strcmp(name, "name")) { _current_package->setName (strstrip (_text_buffer));
- } else if (!strcmp(name, "pretty_name")) { _current_package->setPrettyName (strstrip (_text_buffer));
- } else if (!strcmp(name, "summary")) { _current_package->setSummary (strstrip (_text_buffer));
- } else if (!strcmp(name, "description")) { _current_package->setDescription (strstrip (_text_buffer));
- } else if (!strcmp(name, "section")) { _current_package->setSection (new Section(strstrip (_text_buffer)));
- } else if (!strcmp(name, "arch")) { _current_package->setArch (strstrip (_text_buffer));
- } else if (!strcmp(name, "filesize")) { _current_package->setFileSize (atoi(_text_buffer));
- } else if (!strcmp(name, "installedsize")) { _current_package->setInstalledSize (atoi(_text_buffer));
- } else if (!strcmp(name, "install_only")) { _current_package->setInstallOnly (true);
- } else if (!strcmp(name, "package_set")) { _current_package->setPackageSet (true);
- } else {
- if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd(%s) unknown\n", name);
- }
-
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd(%s) done\n", name);
-
- releaseBuffer();
-}
-
-
-void
-XmlParser::historyEnd(const char *name)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::historyEnd(%s)\n", name);
- assert(_current_package != NULL);
-
- if (!strcmp(name, "history")) {
- assert(_current_update == NULL);
-
- _state = PARSER_PACKAGE;
- }
-}
-
-
-void
-XmlParser::updateEnd(const char *name)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::updateEnd(%s)\n", name);
-
- constChannelPtr channel;
- const char *url_prefix = NULL;
-
- assert(_current_package != NULL);
- assert(_current_update != NULL);
-
- channel = _current_package->channel();
-
- if (channel != NULL) {
- url_prefix = channel->filePath ();
- }
-
- if (!strcmp(name, "update")) {
- _current_package->addUpdate(_current_update);
-
- _current_update = NULL;
- _state = PARSER_HISTORY;
-
- } else if (!strcmp(name, "epoch")) { _current_update->setEpoch (atoi(_text_buffer));
- } else if (!strcmp(name, "version")) { _current_update->setVersion (strstrip (_text_buffer));
- } else if (!strcmp(name, "release")) { _current_update->setRelease (strstrip (_text_buffer));
- } else if (!strcmp(name, "arch")) { _current_update->setArch (strstrip (_text_buffer));
- } else if (!strcmp(name, "filename")) {
- strstrip (_text_buffer);
- if (url_prefix) {
- _current_update->setPackageUrl (maybe_merge_paths(url_prefix, _text_buffer));
- }
- else {
- _current_update->setPackageUrl (_text_buffer);
- }
- } else if (!strcmp(name, "filesize")) { _current_update->setPackageSize (atoi(_text_buffer));
- } else if (!strcmp(name, "installedsize")) { _current_update->setInstalledSize (atoi (_text_buffer));
- } else if (!strcmp(name, "signaturename")) {
- strstrip (_text_buffer);
- if (url_prefix) {
- _current_update->setSignatureUrl (maybe_merge_paths(url_prefix, _text_buffer));
- }
- else {
- _current_update->setSignatureUrl (_text_buffer);
- }
- } else if (!strcmp(name, "signaturesize")) { _current_update->setSignatureSize (atoi (_text_buffer));
- } else if (!strcmp(name, "md5sum")) { _current_update->setMd5sum (strstrip (_text_buffer));
- } else if (!strcmp(name, "importance")) { _current_update->setImportance (new Importance (strstrip (_text_buffer)));
- } else if (!strcmp(name, "description")) { _current_update->setDescription (strstrip (_text_buffer));
- } else if (!strcmp(name, "hid")) { _current_update->setHid (atoi(_text_buffer));
- } else if (!strcmp (name, "license")) { _current_update->setLicense (strstrip (_text_buffer));
- } else {
- fprintf (stderr, "XmlParser::updateEnd(%s) unknown\n", name);
- }
-
-// if (_current_update != NULL && getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::updateEnd(%s) => '%s'\n", name, _current_update->asString().c_str());
-
- releaseBuffer();
-
-}
-
-
-void
-XmlParser::dependencyEnd(const char *name)
-{
-// if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::dependencyEnd(%s)\n", name);
-
- if (!strcmp(name, "or")) {
- OrDependencyPtr or_dep = OrDependency::fromDependencyList (*_current_dep_list);
- DependencyPtr dep = new Dependency (or_dep);
-
- (*_current_dep_list).clear();
-
- (*_toplevel_dep_list).push_back (dep);
- _current_dep_list = _toplevel_dep_list;
- }
- else if (!strcmp(name, "dep")) {
- /* We handled everything we needed for dep in start */
- }
- else {
- /* All of the dep lists (requires, provides, etc.) */
- _toplevel_dep_list = NULL;
- _current_dep_list = NULL;
- _state = PARSER_PACKAGE;
- }
-}
-
-
-
-//===================================================================================================================
-
-#if 0
-//---------------------------------------------------------------------------
-
-/* ------ */
-
-
-static RCResItemDep *
-rc_xml_node_to_resItem_dep_internal (const xmlNode *node)
-{
- gchar *name = NULL, *version = NULL, *release = NULL;
- gboolean has_epoch = false;
- guint32 epoch = 0;
- RCResItemRelation relation;
- RCResItemDep *dep;
-
- gchar *tmp;
-
- if (g_strcasecmp (node->name, "dep")) {
- return (NULL);
- }
-
- name = xml_get_prop (node, "name");
- tmp = xml_get_prop (node, "op");
- if (tmp) {
- relation = rc_resItem_relation_from_string (tmp);
-
- has_epoch = xml_get_guint32_value (node, "epoch", &epoch);
-
- version = xml_get_prop (node, "version");
- release = xml_get_prop (node, "release");
- } else {
- relation = RC_RELATION_ANY;
- }
-
- /* FIXME: should get channel from XML */
- dep = rc_resItem_dep_new (name, has_epoch, epoch, version, release,
- relation, RC_TYPE_RESOLVABLE, RC_CHANNEL_ANY,
- false, false);
-
- g_free (tmp);
- g_free (name);
- g_free (version);
- g_free (release);
-
- return dep;
-} /* rc_xml_node_to_resItem_dep_internal */
-
-RCResItemDep *
-rc_xml_node_to_resItem_dep (const xmlNode *node)
-{
- RCResItemDep *dep = NULL;
-
- if (!g_strcasecmp (node->name, "dep")) {
- dep = rc_xml_node_to_resItem_dep_internal (node);
- return (dep);
- } else if (!g_strcasecmp (node->name, "or")) {
- RCResItemDepSList *or_dep_slist = NULL;
- RCDepOr *or;
- xmlNode *iter = node->xmlChildrenNode;
-
- while (iter) {
- if (iter->type == XML_ELEMENT_NODE) {
- or_dep_slist = g_slist_append(
- or_dep_slist,
- rc_xml_node_to_resItem_dep_internal (iter));
- }
-
- iter = iter->next;
- }
-
- or = rc_dep_or_new (or_dep_slist);
- dep = rc_dep_or_new_provide (or);
- }
-
- return (dep);
-} /* rc_xml_node_to_resItem_dep */
-
-/* ------ */
-
-/* This hack cleans 8-bit characters out of a string. This is a very
- problematic "solution" to the problem of non-UTF-8 package info. */
-static gchar *
-sanitize_string (const char *str)
-{
- gchar *dup = g_strdup (str);
- gchar *c;
-
- return dup;
-
- if (dup) {
- for (c = dup; *c; ++c) {
- if ((guint)*c > 0x7f)
- *c = '_';
- }
- }
-
- return dup;
-}
-
-#endif
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ //---------------------------------------------------------------------------
+
+ static DependencyPtr
+ parse_dep_attrs(bool *is_obsolete, const xmlChar **attrs)
+ {
+ int i;
+ bool op_present = false;
+ /* Temporary variables dependent upon the presense of an 'op' attribute */
+ const char *name = NULL;
+ int epoch = -1;
+ string version;
+ string release;
+ string arch;
+ Relation relation = Relation::Any;
+
+ *is_obsolete = false;
+
+ for (i = 0; attrs[i]; i++) {
+ const char *attr = (const char *)attrs[i++];
+ const char *value = (const char *)attrs[i];
+
+ if (!strcasecmp(attr, "name")) name = value;
+ else if (!strcasecmp(attr, "op")) { op_present = true; relation = Relation::parse(value); }
+ else if (!strcasecmp(attr, "epoch")) epoch = atoi (value);
+ else if (!strcasecmp(attr, "version")) version = value;
+ else if (!strcasecmp(attr, "release")) release = value;
+ else if (!strcasecmp(attr, "arch")) arch = value;
+ else if (!strcasecmp (attr, "obsoletes")) *is_obsolete = true;
+ else {
+ if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Unknown attribute: %s = %s", attr, value);
+ }
+
+ }
+
+ /* FIXME: should get Channel from XML */
+ /* FIXME: should get Kind from XML */
+ return new Dependency (name, relation, Kind::Package, new Channel(CHANNEL_TYPE_ANY), epoch, version, release, Arch::create(arch));
+ }
+
+
+ //---------------------------------------------------------------------------
+ // SAX callbacks
+
+ static void
+ sax_start_document(void *ptr)
+ {
+ XmlParser *ctx = (XmlParser *)ptr;
+ if (ctx->processing()) return;
+
+ // if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* Start document");
+
+ ctx->setProcessing (true);
+ }
+
+
+ static void
+ sax_end_document(void *ptr)
+ {
+ XmlParser *ctx = (XmlParser *)ptr;
+ if (!ctx->processing()) return;
+
+ // if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* End document");
+
+ ctx->setProcessing (false);
+ }
+
+
+ static void
+ sax_start_element(void *ptr, const xmlChar *name, const xmlChar **attrs)
+ {
+ XmlParser *ctx = (XmlParser *)ptr;
+
+ ctx->releaseBuffer();
+
+ #if 0
+ // if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* Start element (%s)", (const char *)name);
+
+ if (attrs) {
+ for (int i = 0; attrs[i]; i += 2) {
+ if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, " - Attribute (%s=%s)", (const char *)attrs[i], (const char *)attrs[i+1]);
+ }
+ }
+ #endif
+ if (!strcmp((const char *)name, "channel") || !strcmp((const char *)name, "subchannel")) {
+ /* Unneeded container tags. Ignore */
+ return;
+ }
+
+ return ctx->startElement ((const char *)name, attrs);
+
+ }
+
+
+ static void
+ sax_end_element(void *ptr, const xmlChar *name)
+ {
+ XmlParser *ctx = (XmlParser *)ptr;
+
+ // if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* End element (%s)", (const char *)name);
+
+ if (!strcmp((const char *)name, "channel") || !strcmp((const char *)name, "subchannel")) {
+ /* Unneeded container tags. Ignore */
+ name = NULL;
+ }
+
+ return ctx->endElement ((const char *)name);
+ }
+
+
+ static void
+ sax_characters(void *ptr, const xmlChar *ch, int len)
+ {
+ XmlParser *ctx = (XmlParser *)ptr;
+
+ ctx->toBuffer ((const char *)ch, len);
+ return;
+ }
+
+
+ static void
+ sax_warning(void *ptr, const char *msg, ...)
+ {
+ va_list args;
+ char tmp[2048];
+
+ va_start(args, msg);
+
+ if (vsnprintf(tmp, 2048, msg, args) >= 2048) fprintf (stderr, "vsnprintf overflow\n");
+ rc_debug (RC_DEBUG_LEVEL_WARNING, "* SAX Warning: %s", tmp);
+
+ va_end(args);
+ }
+
+
+ static void
+ sax_error(void *ptr, const char *msg, ...)
+ {
+ va_list args;
+ char tmp[2048];
+
+ va_start(args, msg);
+
+ if (vsnprintf(tmp, 2048, msg, args) >= 2048) fprintf (stderr, "vsnprintf overflow\n");
+ rc_debug (RC_DEBUG_LEVEL_ERROR, "* SAX Error: %s", tmp);
+
+ va_end(args);
+ }
+
+
+ static xmlSAXHandler sax_handler = {
+ NULL, /* internalSubset */
+ NULL, /* isStandalone */
+ NULL, /* hasInternalSubset */
+ NULL, /* hasExternalSubset */
+ NULL, /* resolveEntity */
+ NULL, /* getEntity */
+ NULL, /* entityDecl */
+ NULL, /* notationDecl */
+ NULL, /* attributeDecl */
+ NULL, /* elementDecl */
+ NULL, /* unparsedEntityDecl */
+ NULL, /* setDocumentLocator */
+ sax_start_document, /* startDocument */
+ sax_end_document, /* endDocument */
+ sax_start_element, /* startElement */
+ sax_end_element, /* endElement */
+ NULL, /* reference */
+ sax_characters, /* characters */
+ NULL, /* ignorableWhitespace */
+ NULL, /* processingInstruction */
+ NULL, /* comment */
+ sax_warning, /* warning */
+ sax_error, /* error */
+ sax_error /* fatalError */
+ };
+
+ //---------------------------------------------------------------------------
+
+ XmlParser::XmlParser (constChannelPtr channel)
+ : _channel (channel)
+ , _processing (false)
+ , _xml_context (NULL)
+ , _state (PARSER_TOPLEVEL)
+ , _current_package (NULL)
+ , _current_update (NULL)
+ , _toplevel_dep_list (NULL)
+ , _current_dep_list (NULL)
+ , _text_buffer (NULL)
+ , _text_buffer_size (0)
+ {
+ // if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "* Context created (%p)", this);
+ }
+
+
+ XmlParser::~XmlParser()
+ {
+ releaseBuffer ();
+ }
+
+ //---------------------------------------------------------------------------
+
+ string
+ XmlParser::asString ( void ) const
+ {
+ return toString (*this);
+ }
+
+
+ string
+ XmlParser::toString ( const XmlParser & context )
+ {
+ return "<XmlParser/>";
+ }
+
+
+ ostream &
+ XmlParser::dumpOn( ostream & str ) const
+ {
+ str << asString();
+ return str;
+ }
+
+
+ ostream&
+ operator<<( ostream& os, const XmlParser& context)
+ {
+ return os << context.asString();
+ }
+
+ //---------------------------------------------------------------------------
+
+ void
+ XmlParser::toBuffer (const char *data, size_t size)
+ {
+ _text_buffer = (char *)realloc (_text_buffer, _text_buffer_size + size + 1);
+ strncpy (_text_buffer + _text_buffer_size, (char *)data, size);
+ _text_buffer_size += size;
+ _text_buffer[_text_buffer_size] = 0;
+
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser[%p]::toBuffer(%.32s...,%ld)\n", this, data, (long)size);
+ }
+
+
+ void
+ XmlParser::releaseBuffer ()
+ {
+ if (_text_buffer)
+ free (_text_buffer);
+ _text_buffer = NULL;
+ _text_buffer_size = 0;
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser[%p]::releaseBuffer()\n", this);
+ }
+
+
+ void
+ XmlParser::parseChunk(const char *xmlbuf, size_t size)
+ {
+ if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::parseChunk(%.32s...,%ld)\n", xmlbuf, (long)size);
+
+ xmlSubstituteEntitiesDefault(true);
+
+ if (!_xml_context) {
+ _xml_context = xmlCreatePushParserCtxt(&sax_handler, this, NULL, 0, NULL);
+ }
+
+ xmlParseChunk(_xml_context, xmlbuf, size, 0);
+ }
+
+
+ PackageList
+ XmlParser::done()
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::done()\n");
+
+ if (_processing)
+ xmlParseChunk(_xml_context, NULL, 0, 1);
+
+ if (_xml_context)
+ xmlFreeParserCtxt(_xml_context);
+
+ if (_current_package) {
+ fprintf (stderr, "Incomplete package lost\n");
+ }
+
+ if (_current_update) {
+ fprintf (stderr, "Incomplete update lost");
+ }
+
+ return _all_packages;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // Parser state callbacks
+
+ void
+ XmlParser::startElement(const char *name, const xmlChar **attrs)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::startElement(%s)\n", name);
+
+ switch (_state) {
+ case PARSER_TOPLEVEL:
+ toplevelStart(name, attrs);
+ break;
+ case PARSER_PACKAGE:
+ packageStart(name, attrs);
+ break;
+ case PARSER_HISTORY:
+ historyStart(name, attrs);
+ break;
+ case PARSER_DEP:
+ dependencyStart(name, attrs);
+ break;
+ default:
+ break;
+ }
+
+ return;
+ }
+
+
+ void
+ XmlParser::endElement(const char *name)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::endElement(%s)\n", name);
+
+ if (name != NULL) { // sax_end_element might set name to NULL
+ switch (_state) {
+ case PARSER_PACKAGE:
+ packageEnd(name);
+ break;
+ case PARSER_HISTORY:
+ historyEnd(name);
+ break;
+ case PARSER_UPDATE:
+ updateEnd(name);
+ break;
+ case PARSER_DEP:
+ dependencyEnd(name);
+ break;
+ default:
+ break;
+ }
+ }
+
+ releaseBuffer();
+
+ return;
+ }
+
+
+ void
+ XmlParser::toplevelStart(const char * name, const xmlChar **attrs)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::toplevelStart(%s)\n", name);
+
+ if (!strcmp(name, "package")) {
+ assert(_current_package == NULL);
+
+ _state = PARSER_PACKAGE;
+
+ _current_package = new Package(_channel);
+ _current_requires.clear();
+ _current_provides.clear();
+ _current_conflicts.clear();
+ _current_children.clear();
+ _current_recommends.clear();
+ _current_suggests.clear();
+ _current_obsoletes.clear();
+
+ }
+ else {
+ if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s at toplevel", (const char *)name);
+ }
+ }
+
+
+ void
+ XmlParser::packageStart(const char * name, const xmlChar **attrs)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageStart(%s)\n", name);
+
+ assert(_current_package != NULL);
+
+ /* Only care about the containers here */
+ if (!strcmp((const char *)name, "history")) {
+ _state = PARSER_HISTORY;
+ }
+ else if (!strcmp (name, "deps")) {
+ /*
+ * We can get a <deps> tag surrounding the actual package
+ * dependency sections (requires, provides, conflicts, etc).
+ * In this case, we'll just ignore this tag quietly.
+ */
+ }
+ else if (!strcmp(name, "requires")) {
+ _state = PARSER_DEP;
+ _current_dep_list = _toplevel_dep_list = &_current_requires;
+ }
+ else if (!strcmp(name, "recommends")) {
+ _state = PARSER_DEP;
+ _current_dep_list = _toplevel_dep_list = &_current_recommends;
+ }
+ else if (!strcmp(name, "suggests")) {
+ _state = PARSER_DEP;
+ _current_dep_list = _toplevel_dep_list = &_current_suggests;
+ }
+ else if (!strcmp(name, "conflicts")) {
+ bool is_obsolete = false;
+ int i;
+
+ _state = PARSER_DEP;
+
+ for (i = 0; attrs && attrs[i] && !is_obsolete; i += 2) {
+
+ if (!strcasecmp ((const char *)(attrs[i]), "obsoletes"))
+ is_obsolete = true;
+ }
+
+ if (is_obsolete)
+ _current_dep_list = _toplevel_dep_list = &_current_obsoletes;
+ else {
+ _current_dep_list = _toplevel_dep_list = &_current_conflicts;
+ }
+ }
+ else if (!strcmp(name, "obsoletes")) {
+ _state = PARSER_DEP;
+ _current_dep_list = _toplevel_dep_list = &_current_obsoletes;
+ }
+ else if (!strcmp(name, "provides")) {
+ _state = PARSER_DEP;
+ _current_dep_list = _toplevel_dep_list = &_current_provides;
+ }
+ else if (!strcmp(name, "children")) {
+ _state = PARSER_DEP;
+ _current_dep_list = _toplevel_dep_list = &_current_children;
+ }
+ else {
+ // if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s in package start", name);
+ }
+ }
+
+
+ void
+ XmlParser::historyStart(const char * name, const xmlChar **attrs)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::historyStart(%s)\n", name);
+
+ assert(_current_package != NULL);
+
+ if (!strcmp(name, "update")) {
+ assert(_current_update == NULL);
+
+ _current_update = new PackageUpdate(_current_package->name());
+
+ _state = PARSER_UPDATE;
+ }
+ else {
+ if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s in history", name);
+ }
+ }
+
+
+ void
+ XmlParser::dependencyStart(const char *name, const xmlChar **attrs)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::dependencyStart(%s)\n", name);
+
+ if (!strcmp(name, "dep")) {
+ DependencyPtr dep;
+ bool is_obsolete;
+
+ dep = parse_dep_attrs(&is_obsolete, attrs);
+
+ if (is_obsolete)
+ _current_obsoletes.push_back (dep);
+ else {
+ _current_dep_list->push_back (dep);
+ }
+ }
+ else if (!strcmp(name, "or"))
+ _current_dep_list = new CDependencyList;
+ else {
+ if (getenv ("RC_SPEW_XML")) rc_debug (RC_DEBUG_LEVEL_ALWAYS, "! Not handling %s in dependency", name);
+ }
+ }
+
+
+ //---------------------------------------------------------------------------
+
+
+ void
+ XmlParser::packageEnd(const char *name)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd(%s)\n", name);
+
+ assert(_current_package != NULL);
+
+ if (!strcmp(name, "package")) {
+ PackageUpdatePtr update;
+
+ /* If possible, grab the version info from the most recent update.
+ * Otherwise, try to find where the package provides itself and use
+ * that version info.
+ */
+ update = _current_package->getLatestUpdate();
+
+ if (update) {
+ _current_package->setName (update->name());
+ _current_package->setKind (update->kind());
+ _current_package->setEdition (update->edition());
+ _current_package->setFileSize (update->packageSize());
+ _current_package->setInstalledSize (update->installedSize());
+ }
+ else {
+ for (CDependencyList::const_iterator iter = _current_provides.begin(); iter != _current_provides.end(); iter++) {
+ if ((*iter)->relation().isEqual()
+ && ((*iter)->name() == _current_package->name()))
+ {
+ _current_package->setKind ((*iter)->kind());
+ _current_package->setEdition ((*iter)->edition());
+ break;
+ }
+ }
+ }
+
+ /* Hack for the old XML */
+ if (_current_package->arch()->isUnknown()) {
+ _current_package->setArch (Arch::System);
+ }
+
+ // check if we provide ourselfs properly
+
+ CDependencyList::const_iterator piter;
+ for (piter = _current_provides.begin(); piter != _current_provides.end(); piter++) {
+ if ((*piter)->relation().isEqual()
+ && ((*piter)->name() == _current_package->name()))
+ {
+ break;
+ }
+ }
+
+ if (piter == _current_provides.end()) { // no self provide found, construct one
+ constDependencyPtr selfdep = new Dependency (_current_package->name(), Relation::Equal, _current_package->kind(), _current_package->channel(), _current_package->edition());
+ //if (getenv ("RC_SPEW")) fprintf (stderr, "Adding self-provide [%s]\n", selfdep->asString().c_str());
+ _current_provides.push_front (selfdep);
+ }
+
+ _current_package->setRequires (_current_requires);
+ _current_package->setProvides (_current_provides);
+ _current_package->setConflicts (_current_conflicts);
+ _current_package->setObsoletes (_current_obsoletes);
+ _current_package->setSuggests (_current_suggests);
+ _current_package->setRecommends (_current_recommends);
+
+ _all_packages.push_back (_current_package);
+
+ if (getenv ("RC_SPEW")) fprintf (stderr, "%s\n", _current_package->asString(true).c_str());
+ if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd done: '%s'\n", _current_package->asString(true).c_str());
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd now %ld packages\n", _all_packages.size());
+ _current_package = NULL;
+ _state = PARSER_TOPLEVEL;
+ }
+ else if (!strcmp(name, "name")) { _current_package->setName (strstrip (_text_buffer));
+ } else if (!strcmp(name, "pretty_name")) { _current_package->setPrettyName (strstrip (_text_buffer));
+ } else if (!strcmp(name, "summary")) { _current_package->setSummary (strstrip (_text_buffer));
+ } else if (!strcmp(name, "description")) { _current_package->setDescription (strstrip (_text_buffer));
+ } else if (!strcmp(name, "section")) { _current_package->setSection (new Section(strstrip (_text_buffer)));
+ } else if (!strcmp(name, "arch")) { _current_package->setArch (strstrip (_text_buffer));
+ } else if (!strcmp(name, "filesize")) { _current_package->setFileSize (atoi(_text_buffer));
+ } else if (!strcmp(name, "installedsize")) { _current_package->setInstalledSize (atoi(_text_buffer));
+ } else if (!strcmp(name, "install_only")) { _current_package->setInstallOnly (true);
+ } else if (!strcmp(name, "package_set")) { _current_package->setPackageSet (true);
+ } else {
+ if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd(%s) unknown\n", name);
+ }
+
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::packageEnd(%s) done\n", name);
+
+ releaseBuffer();
+ }
+
+
+ void
+ XmlParser::historyEnd(const char *name)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::historyEnd(%s)\n", name);
+ assert(_current_package != NULL);
+
+ if (!strcmp(name, "history")) {
+ assert(_current_update == NULL);
+
+ _state = PARSER_PACKAGE;
+ }
+ }
+
+
+ void
+ XmlParser::updateEnd(const char *name)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::updateEnd(%s)\n", name);
+
+ constChannelPtr channel;
+ const char *url_prefix = NULL;
+
+ assert(_current_package != NULL);
+ assert(_current_update != NULL);
+
+ channel = _current_package->channel();
+
+ if (channel != NULL) {
+ url_prefix = channel->filePath ();
+ }
+
+ if (!strcmp(name, "update")) {
+ _current_package->addUpdate(_current_update);
+
+ _current_update = NULL;
+ _state = PARSER_HISTORY;
+
+ } else if (!strcmp(name, "epoch")) { _current_update->setEpoch (atoi(_text_buffer));
+ } else if (!strcmp(name, "version")) { _current_update->setVersion (strstrip (_text_buffer));
+ } else if (!strcmp(name, "release")) { _current_update->setRelease (strstrip (_text_buffer));
+ } else if (!strcmp(name, "arch")) { _current_update->setArch (strstrip (_text_buffer));
+ } else if (!strcmp(name, "filename")) {
+ strstrip (_text_buffer);
+ if (url_prefix) {
+ _current_update->setPackageUrl (maybe_merge_paths(url_prefix, _text_buffer));
+ }
+ else {
+ _current_update->setPackageUrl (_text_buffer);
+ }
+ } else if (!strcmp(name, "filesize")) { _current_update->setPackageSize (atoi(_text_buffer));
+ } else if (!strcmp(name, "installedsize")) { _current_update->setInstalledSize (atoi (_text_buffer));
+ } else if (!strcmp(name, "signaturename")) {
+ strstrip (_text_buffer);
+ if (url_prefix) {
+ _current_update->setSignatureUrl (maybe_merge_paths(url_prefix, _text_buffer));
+ }
+ else {
+ _current_update->setSignatureUrl (_text_buffer);
+ }
+ } else if (!strcmp(name, "signaturesize")) { _current_update->setSignatureSize (atoi (_text_buffer));
+ } else if (!strcmp(name, "md5sum")) { _current_update->setMd5sum (strstrip (_text_buffer));
+ } else if (!strcmp(name, "importance")) { _current_update->setImportance (new Importance (strstrip (_text_buffer)));
+ } else if (!strcmp(name, "description")) { _current_update->setDescription (strstrip (_text_buffer));
+ } else if (!strcmp(name, "hid")) { _current_update->setHid (atoi(_text_buffer));
+ } else if (!strcmp (name, "license")) { _current_update->setLicense (strstrip (_text_buffer));
+ } else {
+ fprintf (stderr, "XmlParser::updateEnd(%s) unknown\n", name);
+ }
+
+ // if (_current_update != NULL && getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::updateEnd(%s) => '%s'\n", name, _current_update->asString().c_str());
+
+ releaseBuffer();
+
+ }
+
+
+ void
+ XmlParser::dependencyEnd(const char *name)
+ {
+ // if (getenv ("RC_SPEW_XML")) fprintf (stderr, "XmlParser::dependencyEnd(%s)\n", name);
+
+ if (!strcmp(name, "or")) {
+ OrDependencyPtr or_dep = OrDependency::fromDependencyList (*_current_dep_list);
+ DependencyPtr dep = new Dependency (or_dep);
+
+ (*_current_dep_list).clear();
+
+ (*_toplevel_dep_list).push_back (dep);
+ _current_dep_list = _toplevel_dep_list;
+ }
+ else if (!strcmp(name, "dep")) {
+ /* We handled everything we needed for dep in start */
+ }
+ else {
+ /* All of the dep lists (requires, provides, etc.) */
+ _toplevel_dep_list = NULL;
+ _current_dep_list = NULL;
+ _state = PARSER_PACKAGE;
+ }
+ }
+
+
+
+ //===================================================================================================================
+
+ #if 0
+ //---------------------------------------------------------------------------
+
+ /* ------ */
+
+
+ static RCResItemDep *
+ rc_xml_node_to_resItem_dep_internal (const xmlNode *node)
+ {
+ gchar *name = NULL, *version = NULL, *release = NULL;
+ gboolean has_epoch = false;
+ guint32 epoch = 0;
+ RCResItemRelation relation;
+ RCResItemDep *dep;
+
+ gchar *tmp;
+
+ if (g_strcasecmp (node->name, "dep")) {
+ return (NULL);
+ }
+
+ name = xml_get_prop (node, "name");
+ tmp = xml_get_prop (node, "op");
+ if (tmp) {
+ relation = rc_resItem_relation_from_string (tmp);
+
+ has_epoch = xml_get_guint32_value (node, "epoch", &epoch);
+
+ version = xml_get_prop (node, "version");
+ release = xml_get_prop (node, "release");
+ } else {
+ relation = RC_RELATION_ANY;
+ }
+
+ /* FIXME: should get channel from XML */
+ dep = rc_resItem_dep_new (name, has_epoch, epoch, version, release,
+ relation, RC_TYPE_RESOLVABLE, RC_CHANNEL_ANY,
+ false, false);
+
+ g_free (tmp);
+ g_free (name);
+ g_free (version);
+ g_free (release);
+
+ return dep;
+ } /* rc_xml_node_to_resItem_dep_internal */
+
+ RCResItemDep *
+ rc_xml_node_to_resItem_dep (const xmlNode *node)
+ {
+ RCResItemDep *dep = NULL;
+
+ if (!g_strcasecmp (node->name, "dep")) {
+ dep = rc_xml_node_to_resItem_dep_internal (node);
+ return (dep);
+ } else if (!g_strcasecmp (node->name, "or")) {
+ RCResItemDepSList *or_dep_slist = NULL;
+ RCDepOr *or;
+ xmlNode *iter = node->xmlChildrenNode;
+
+ while (iter) {
+ if (iter->type == XML_ELEMENT_NODE) {
+ or_dep_slist = g_slist_append(
+ or_dep_slist,
+ rc_xml_node_to_resItem_dep_internal (iter));
+ }
+
+ iter = iter->next;
+ }
+
+ or = rc_dep_or_new (or_dep_slist);
+ dep = rc_dep_or_new_provide (or);
+ }
+
+ return (dep);
+ } /* rc_xml_node_to_resItem_dep */
+
+ /* ------ */
+
+ /* This hack cleans 8-bit characters out of a string. This is a very
+ problematic "solution" to the problem of non-UTF-8 package info. */
+ static gchar *
+ sanitize_string (const char *str)
+ {
+ gchar *dup = g_strdup (str);
+ gchar *c;
+
+ return dup;
+
+ if (dup) {
+ for (c = dup; *c; ++c) {
+ if ((guint)*c > 0x7f)
+ *c = '_';
+ }
+ }
+
+ return dup;
+ }
+
+ #endif
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/Dependency.h>
#include <zypp/solver/detail/XmlNode.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : XmlParser
-
-class XmlParser
-{
- public:
- enum _XmlParserState {
- PARSER_TOPLEVEL = 0,
- PARSER_PACKAGE,
- PARSER_HISTORY,
- PARSER_UPDATE,
- PARSER_DEP,
- };
- typedef enum _XmlParserState XmlParserState;
-
- private:
- constChannelPtr _channel;
- bool _processing;
- xmlParserCtxtPtr _xml_context;
- XmlParserState _state;
-
- PackageList _all_packages;
-
- /* Temporary state */
- PackagePtr _current_package;
- CDependencyList _current_requires;
- CDependencyList _current_provides;
- CDependencyList _current_conflicts;
- CDependencyList _current_children;
- CDependencyList _current_recommends;
- CDependencyList _current_suggests;
- CDependencyList _current_obsoletes;
- PackageUpdatePtr _current_update;
-
- // these point to one of the above lists during dependency parsing
- CDependencyList *_toplevel_dep_list;
- CDependencyList *_current_dep_list;
-
- char *_text_buffer;
- size_t _text_buffer_size;
-
- protected:
- void setState (XmlParserState state) { _state = state; }
-
- public:
-
- XmlParser (constChannelPtr channel);
- virtual ~XmlParser();
-
- // ---------------------------------- I/O
-
- static std::string toString ( const XmlParser & parser);
-
- virtual std::ostream & dumpOn( std::ostream & str ) const;
-
- friend std::ostream& operator<<( std::ostream & str, const XmlParser & parser);
-
- std::string asString ( void ) const;
-
- // ---------------------------------- accessors
-
- bool processing() const { return _processing; }
- void setProcessing (bool processing) { _processing = processing; }
-
- XmlParserState state (void) const { return _state; }
-
-#if 0 // are they needed ?
- constChannelPtr channel() const { return _channel; }
- void setChannel (constChannelPtr channel) { _channel = channel; }
-
- xmlParserCtxtPtr xmlContext() const { return _xml_context; }
- void setXmlContext (xmlParserCtxtPtr xml_context) { _xml_context = xml_context; }
-#endif
- // ---------------------------------- methods
-
- void toBuffer (const char *data, size_t size);
- void releaseBuffer (void); // free _text_buffer
-
- void startElement(const char *name, const xmlChar **attrs);
- void endElement(const char *name);
-
- void toplevelStart(const char *name, const xmlChar **attrs);
- void packageStart(const char *name, const xmlChar **attrs);
- void historyStart(const char *name, const xmlChar **attrs);
- void dependencyStart(const char *name, const xmlChar **attrs);
-
- void updateEnd(const char *name);
- void packageEnd(const char *name);
- void historyEnd(const char *name);
- void dependencyEnd(const char *name);
-
- void parseChunk (const char *xmlbuf, size_t size);
- PackageList done (void);
-};
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+
+ ///////////////////////////////////////////////////////////////////
+ //
+ // CLASS NAME : XmlParser
+
+ class XmlParser
+ {
+ public:
+ enum _XmlParserState {
+ PARSER_TOPLEVEL = 0,
+ PARSER_PACKAGE,
+ PARSER_HISTORY,
+ PARSER_UPDATE,
+ PARSER_DEP,
+ };
+ typedef enum _XmlParserState XmlParserState;
+
+ private:
+ constChannelPtr _channel;
+ bool _processing;
+ xmlParserCtxtPtr _xml_context;
+ XmlParserState _state;
+
+ PackageList _all_packages;
+
+ /* Temporary state */
+ PackagePtr _current_package;
+ CDependencyList _current_requires;
+ CDependencyList _current_provides;
+ CDependencyList _current_conflicts;
+ CDependencyList _current_children;
+ CDependencyList _current_recommends;
+ CDependencyList _current_suggests;
+ CDependencyList _current_obsoletes;
+ PackageUpdatePtr _current_update;
+
+ // these point to one of the above lists during dependency parsing
+ CDependencyList *_toplevel_dep_list;
+ CDependencyList *_current_dep_list;
+
+ char *_text_buffer;
+ size_t _text_buffer_size;
+
+ protected:
+ void setState (XmlParserState state) { _state = state; }
+
+ public:
+
+ XmlParser (constChannelPtr channel);
+ virtual ~XmlParser();
+
+ // ---------------------------------- I/O
+
+ static std::string toString ( const XmlParser & parser);
+
+ virtual std::ostream & dumpOn( std::ostream & str ) const;
+
+ friend std::ostream& operator<<( std::ostream & str, const XmlParser & parser);
+
+ std::string asString ( void ) const;
+
+ // ---------------------------------- accessors
+
+ bool processing() const { return _processing; }
+ void setProcessing (bool processing) { _processing = processing; }
+
+ XmlParserState state (void) const { return _state; }
+
+ #if 0 // are they needed ?
+ constChannelPtr channel() const { return _channel; }
+ void setChannel (constChannelPtr channel) { _channel = channel; }
+
+ xmlParserCtxtPtr xmlContext() const { return _xml_context; }
+ void setXmlContext (xmlParserCtxtPtr xml_context) { _xml_context = xml_context; }
+ #endif
+ // ---------------------------------- methods
+
+ void toBuffer (const char *data, size_t size);
+ void releaseBuffer (void); // free _text_buffer
+
+ void startElement(const char *name, const xmlChar **attrs);
+ void endElement(const char *name);
+
+ void toplevelStart(const char *name, const xmlChar **attrs);
+ void packageStart(const char *name, const xmlChar **attrs);
+ void historyStart(const char *name, const xmlChar **attrs);
+ void dependencyStart(const char *name, const xmlChar **attrs);
+
+ void updateEnd(const char *name);
+ void packageEnd(const char *name);
+ void historyEnd(const char *name);
+ void dependencyEnd(const char *name);
+
+ void parseChunk (const char *xmlbuf, size_t size);
+ PackageList done (void);
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif // _XmlParser_h
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-
-int
-extract_packages_from_xml_node (XmlNodePtr node, ChannelPtr channel, CResItemFn callback, void *data)
-{
- PackagePtr package;
- int count = 0;
-
- if (getenv ("RC_SPEW_XML")) fprintf (stderr, "extract_packages_from_xml_node ()\n");
- // search the 'package' node
-
- while (node && !node->equals("package")) {
- if (!node->isElement()) {
- node = node->next();
- continue;
- }
-
- node = node->children();
- }
-
- // extract the 'package' node, if found
-
- while (node) {
- if (node->equals("package")) {
- package = new Package (node, channel);
- if (package) {
- if (getenv ("RC_SPEW")) fprintf (stderr, "%s\n", package->asString(true).c_str());
- bool ok = true;
- if (callback)
- ok = callback (package, data);
- if (! ok)
- return -1;
- ++count;
- }
- }
- node = node->next();
- }
-
- return count;
-}
-
-
-int
-extract_packages_from_helix_buffer (const char *buf, size_t len, ChannelPtr channel, CResItemFn callback, void *data)
-{
- unsigned int count = 0;
- PackageList packages;
-
- if (getenv ("RC_SPEW_XML")) fprintf (stderr, "extract_packages_from_helix_buffer(%.32s...,%ld,...)\n", buf, (long)len);
-
- if (buf == NULL || len == 0)
- return 0;
-
- XmlParser parser (channel);
- parser.parseChunk (buf, len);
- packages = parser.done ();
-
- if (packages.empty())
- return 0;
-
- count = packages.size();
-
- if (getenv ("RC_SPEW_XML")) fprintf (stderr, "extract_packages_from_helix_buffer: parsed %d packages\n", count);
-
- if (callback != NULL) {
- for (PackageList::iterator iter = packages.begin(); iter != packages.end(); iter++) {
- callback (*iter, data);
- }
- }
-
- return count;
-}
-
-
-int
-extract_packages_from_helix_file (const string & filename, ChannelPtr channel, CResItemFn callback, void *data)
-{
- Buffer *buf;
- int count;
-
- if (filename.empty())
- return -1;
-
- buf = buffer_map_file (filename);
- if (buf == NULL)
- return -1;
-
- count = extract_packages_from_helix_buffer ((const char *)(buf->data), buf->size, channel, callback, data);
-
- buffer_unmap_file (buf);
-
- return count;
-}
-
-
-int
-extract_packages_from_undump_buffer (const char *buf, size_t len, ChannelAndSubscribedFn channel_callback, CResItemFn resItem_callback, MatchFn lock_callback, void *data)
-{
- xmlDoc *doc;
- XmlNodePtr dump_node;
- ChannelPtr system_channel = NULL;
- ChannelPtr current_channel = NULL;
- XmlNodePtr channel_node;
- int count = 0;
-
- doc = parse_xml_from_buffer (buf, len);
- if (doc == NULL)
- return -1;
-
- dump_node = new XmlNode (xmlDocGetRootElement (doc));
- if (dump_node == NULL)
- return -1;
-
- if (!dump_node->equals("world")) {
- debug (DEBUG_LEVEL_WARNING, "Unrecognized top-level node for undump: '%s'", dump_node->name());
- return -1;
- }
-
- channel_node = dump_node->children();
-
- while (channel_node != NULL) {
-
- if (channel_node->equals("locks")) {
- XmlNodePtr lock_node = channel_node->children();
-
- while (lock_node) {
- MatchPtr lock;
-
- lock = new Match (lock_node);
-
- if (lock_callback)
- lock_callback (lock, data);
-
- lock_node = lock_node->next();
- }
-
- } else if (channel_node->equals("system_packages")) {
-
- int subcount;
-
- if (!system_channel) {
- system_channel = new Channel ("@system", "System Packages", "@system", "System Packages");
- system_channel->setSystem (true);
- system_channel->setHidden (true);
- }
-
- if (channel_callback) {
- channel_callback (system_channel, false, data);
- }
-
- subcount = extract_packages_from_xml_node (channel_node, system_channel, resItem_callback, data);
-
- if (subcount < 0) {
- /* Do something clever */
- fprintf (stderr, "No packages found\n");
- abort ();
- }
-
- count += subcount;
-
- } else if (channel_node->equals("channel")) {
-
- int subscribed;
- current_channel = new Channel (channel_node, &subscribed, (World *)data);
-
- if (channel_callback) {
- channel_callback (current_channel, subscribed != 0, data);
- }
-
- if (resItem_callback) {
- int subcount;
- subcount = extract_packages_from_xml_node (channel_node, current_channel, resItem_callback, data);
- if (subcount < 0) {
- /* FIXME: do something clever */
- fprintf (stderr, "No packages found\n");
- abort ();
- }
- count += subcount;
- }
- }
-
- channel_node = channel_node->next();
- }
-
- xmlFreeDoc (doc);
-
- return count;
-}
-
-
-int
-extract_packages_from_undump_file (const string & filename, ChannelAndSubscribedFn channel_callback, CResItemFn resItem_callback, MatchFn lock_callback, void *data)
-{
- Buffer *buf;
- int count;
-
- if (filename.empty())
- return -1;
-
- buf = buffer_map_file (filename);
- if (buf == NULL)
- return -1;
-
- count = extract_packages_from_undump_buffer ((const char *)(buf->data), buf->size, channel_callback, resItem_callback, lock_callback, data);
-
- buffer_unmap_file (buf);
-
- return count;
-}
-
-#if 0
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-static ResItemPtr
-fill_debian_package (const char *buf, const char *url_prefix, int *off)
-{
- const char *ibuf;
- RCPackageUpdate *up = NULL;
- ResItemPtr r;
- ResItemList requires, provides, conflicts, suggests, recommends;
-
- up = rc_package_update_new ();
-
- ibuf = buf;
- while (1) {
- char *key;
- GString *value = NULL;
- const char *p;
- int ind;
-
- /* Linebreaks indicate the end of a package block. */
- if (*ibuf == '\0' || *ibuf == '\n') break;
-
- p = strchr (ibuf, ':');
-
- /* Something bad happened, we're supposed to have a colon. */
- if (!p) break;
-
- /* Copy the name of the key and lowercase it */
- key = g_ascii_strdown (ibuf, p - ibuf);
-
- /* Move past the colon and any spaces */
- ibuf = p;
- while (*ibuf && (*ibuf == ':' || *ibuf == ' ')) ibuf++;
-
- ind = 0;
- while ((p = strchr (ibuf, '\n'))) {
- if (!value)
- value = g_string_new ("");
-
- g_string_append_len (value, ibuf, p - ibuf);
- ind += p - ibuf;
-
- ibuf = p;
-
- /* Move past the newline */
- ibuf++;
-
- /* Check to see if this is a continuation of the previous line */
- if (*ibuf == ' ') {
- /* It is. Move past the space */
- ibuf++;
-
- /*
- * This is a hack. Description is special because it's
- * intended to be multiline and user-visible. So if we're
- * dealing with description, add a newline.
- */
-
- if (strncmp (key, "description",
- strlen ("description")) == 0) {
- g_string_append_c (value, '\n');
-
- /*
- * A period on a line by itself indicates that it
- * should be a blank line. A newline will follow the
- * period, so we'll just skip over it.
- */
- if (*ibuf == '.')
- ibuf++;
- }
- }
- else {
- /* It isn't. Break out. */
- break;
- }
- }
-
- if (!strncmp (key, "package", strlen ("package"))) {
- rc_resItem_spec_set_name (RC_RESOLVABLE_SPEC (pkg), value->str);
- } else if (!strncmp (key, "installed-size",
- strlen ("installed-size"))) {
- up->installed_size = strtoul (value->str, NULL, 10) * 1024;
- } else if (!strncmp (key, "size", strlen ("size"))) {
- up->package_size = strtoul(value->str, NULL, 10);
- } else if (!strncmp (key, "description", strlen ("description"))) {
- char *newline;
-
- /*
- * We only want the first line for the summary, and all the
- * other lines for the description.
- */
-
- newline = strchr (value->str, '\n');
- if (!newline) {
- pkg->summary = strdup (value->str);
- pkg->description = g_strconcat (value->str, "\n", NULL);
- }
- else {
- pkg->summary = g_strndup (value->str, newline - value->str);
- pkg->description = g_strconcat (newline + 1, "\n", NULL);
- }
- } else if (!strncmp (key, "version", strlen ("version"))) {
- RCResItemSpec *spec = RC_RESOLVABLE_SPEC (pkg);
- rc_version_parse (value->str, spec);
- } else if (!strncmp (key, "section", strlen ("section"))) {
- pkg->section = rc_debman_section_to_package_section (value->str);
- } else if (!strncmp (key, "depends", strlen ("depends"))) {
- requires = g_slist_concat (
- requires,
- rc_debman_fill_depends (value->str, false));
- } else if (!strncmp (key, "recommends", strlen ("recommends"))) {
- recommends = g_slist_concat (
- recommends,
- rc_debman_fill_depends (value->str, false));
- } else if (!strncmp (key, "suggests", strlen ("suggests"))) {
- suggests = g_slist_concat (
- suggests,
- rc_debman_fill_depends (value->str, false));
- } else if (!strncmp (key, "pre-depends", strlen ("pre-depends"))) {
- requires = g_slist_concat (
- requires,
- rc_debman_fill_depends (value->str, true));
- } else if (!strncmp (key, "conflicts", strlen ("conflicts"))) {
- conflicts = g_slist_concat (
- conflicts,
- rc_debman_fill_depends (value->str, false));
- } else if (!strncmp (key, "provides", strlen ("provides"))) {
- provides = g_slist_concat (
- provides,
- rc_debman_fill_depends (value->str, false));
- } else if (!strncmp (key, "filename", strlen ("filename"))) {
- /* Build a new update with just this version */
- if (url_prefix) {
- up->package_url = g_strconcat (url_prefix, "/",
- value->str,
- NULL);
- } else {
- up->package_url = strdup (value->str);
- }
- } else if (!strncmp (key, "md5sum", strlen ("md5sum"))) {
- up->md5sum = strdup (value->str);
- } else if (!strncmp (key, "architecture", strlen ("architecture"))) {
- rc_resItem_spec_set_arch (RC_RESOLVABLE_SPEC (pkg), rc_arch_from_string (value->str));
- }
-
- g_string_free (value, true);
- }
-
- up->importance = RC_IMPORTANCE_SUGGESTED;
- up->description = strdup ("Upstream Debian release");
- rc_resItem_spec_copy (rc_package_update_get_spec(up), RC_RESOLVABLE_SPEC (pkg));
- rc_package_add_update (pkg, up);
-
- r = RC_RESOLVABLE (pkg);
-
- /* Make sure to provide myself, for the dep code! */
- provides = g_slist_append (provides, rc_resItem_dep_new_from_spec
- (RC_RESOLVABLE_SPEC (pkg),
- RC_RELATION_EQUAL,
- RC_TYPE_PACKAGE,
- rc_resItem_get_channel (r),
- false, false));
-
- rc_resItem_set_requires (r, requires);
- rc_resItem_set_provides (r, provides);
- rc_resItem_set_conflicts (r, conflicts);
- rc_resItem_set_obsoletes (r, NULL);
- rc_resItem_set_suggests (r, suggests);
- rc_resItem_set_recommends(r, recommends);
- /* returns the number of characters we processed */
- return ibuf - buf;
-}
-
-#endif
-
-int
-extract_packages_from_debian_buffer (const char *buf, size_t len, ChannelPtr channel, CResItemFn callback, void *data)
-{
- const char *pos;
- int count = 0;
-
- /* Keep looking for a "Package: " */
- pos = buf;
-#if 0
- while ((pos = strstr (pos, "Package: ")) != NULL) {
- int off;
-
- /* All debian packages "have" epochs */
- ResItemPtr resItem = fill_debian_package (iter, channel->getFilePath (), &off);
-
- resItem->setEpoch (0);
- resItem->setArch (Arch::Noarch);
- resItem->setChannel (channel);
-
- if (callback)
- callback (resItem, data);
-
- ++count;
-
- iter += off;
- }
-#endif
- return count;
-}
-
-
-int
-extract_packages_from_debian_file (const string & filename, ChannelPtr channel, CResItemFn callback, void *data)
-{
- Buffer *buf;
- int count;
-
- if (filename.empty())
- return -1;
-
- buf = buffer_map_file (filename);
- if (buf == NULL)
- return -1;
-
- count = extract_packages_from_debian_buffer ((const char *)(buf->data), buf->size, channel, callback, data);
- buffer_unmap_file (buf);
-
- return count;
-}
-
-#if 0
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-PackagePtr
-extract_yum_package (const guint8 *data, size_t len,
- RCPackman *packman, char *url)
-{
-#ifndef ENABLE_RPM
- /* We can't support yum without rpm support */
- debug (RC_DEBUG_LEVEL_ERROR, "RPM support is not enabled");
- return NULL;
-#else
- RCRpmman *rpmman;
- Header h;
- PackagePtr p;
- RCPackageUpdate *pu;
- char *tmpc;
- int typ, n;
-
- g_return_val_if_fail (packman != NULL, NULL);
-
- if (!g_type_is_a (G_TYPE_FROM_INSTANCE (packman), RC_TYPE_RPMMAN)) {
- debug (RC_DEBUG_LEVEL_ERROR,
- "yum support is not available on non-RPM systems");
- return NULL;
- }
-
- rpmman = RC_RPMMAN (packman);
-
- h = rpmman->headerLoad (data);
-
- if (h == NULL) {
- debug (RC_DEBUG_LEVEL_ERROR,
- "Unable to get header from headerCopyLoad!");
- return NULL;
- }
-
- rpmman->headerGetEntry (h, RPMTAG_ARCH, &typ, (void **) &tmpc, &n);
-
- p = rc_package_new ();
-
- rc_rpmman_read_header (rpmman, h, p);
- rc_rpmman_depends_fill (rpmman, h, p, true);
-
- pu = rc_package_update_new ();
- rc_resItem_spec_copy (rc_package_update_get_spec (pu), RC_RESOLVABLE_SPEC (p));
- pu->importance = RC_IMPORTANCE_SUGGESTED;
- pu->description = strdup ("No information available.");
- pu->package_url = url;
-
- p->history = g_slist_append (p->history, pu);
-
- rpmman->headerFree (h);
-
- return p;
-#endif
-}
-
-int
-extract_packages_from_aptrpm_buffer (const guint8 *data, size_t len,
- RCPackman *packman,
- ChannelPtr channel,
- CResItemFn callback,
- void * user_data)
-{
-#ifndef ENABLE_RPM
- /* We can't support apt-rpm without rpm support */
- debug (RC_DEBUG_LEVEL_ERROR, "RPM support is not enabled");
- return -1;
-#else
- RCRpmman *rpmman;
- int count = 0;
- const int hdrmagic_len = 8;
- const char *hdrmagic;
- const guint8 *cur_ptr;
- RCResItemSpec *spec;
-
-
- g_return_val_if_fail (packman != NULL, -1);
-
- if (!g_type_is_a (G_TYPE_FROM_INSTANCE (packman), RC_TYPE_RPMMAN)) {
- debug (RC_DEBUG_LEVEL_ERROR,
- "apt-rpm support is not available on non-RPM systems");
- return -1;
- }
-
- rpmman = RC_RPMMAN (packman);
-
- if (len < hdrmagic_len) {
- debug (RC_DEBUG_LEVEL_ERROR,
- "Data is too small to possibly be correct");
- return 0;
- }
-
- /*
- * The apt-rpm pkglist files are a set of rpm headers, each prefixed
- * with the header magic, one right after the other. If opened on disk,
- * they can be iterated using headerRead(). Since we have an in-memory
- * buffer, we use headerCopyLoad to read them. We could, potentially,
- * use headerLoad(); but I'm unsure as to what happens when headerFree
- * is called on a Header returned from headerLoad. It may be a small
- * memory savings to do so.
- */
-
- /* Skip the inital RPM header magic */
- hdrmagic = data;
- cur_ptr = data + hdrmagic_len;
-
- while (cur_ptr != NULL) {
- Header h;
- PackagePtr p;
- RCPackageUpdate *pu;
- int bytesleft, i;
- char *tmpc;
- int typ, n;
- char *archstr;
-
- h = rpmman->headerLoad (cur_ptr);
-
- if (h == NULL) {
- debug (RC_DEBUG_LEVEL_ERROR,
- "Unable to get header from headerCopyLoad!");
- return 0;
- }
-
- rpmman->headerGetEntry (h, RPMTAG_ARCH, &typ, (void **) &tmpc, &n);
-
- if (n && typ == RPM_STRING_TYPE)
- archstr = tmpc;
- else {
- debug (RC_DEBUG_LEVEL_WARNING, "No arch available!");
- goto cleanup;
- }
-
- p = rc_package_new ();
-
- rc_rpmman_read_header (rpmman, h, p);
- rc_rpmman_depends_fill (rpmman, h, p, true);
-
- rc_resItem_set_channel (RC_RESOLVABLE (p), channel);
-
- pu = rc_package_update_new ();
- rc_resItem_spec_copy (rc_package_update_get_spec (pu), RC_RESOLVABLE_SPEC (p));
- pu->importance = RC_IMPORTANCE_SUGGESTED;
- pu->description = strdup ("No information available.");
-
- /* Build a filename from the spec */
- spec = RC_RESOLVABLE_SPEC (p);
- pu->package_url = strdup_printf ("%s/%s-%s-%s.%s.rpm",
- rc_channel_get_file_path (channel),
- rc_resItem_spec_get_name (spec),
- rc_resItem_spec_get_version (spec),
- rc_resItem_spec_get_release (spec),
- archstr);
-
- p->history = g_slist_append (p->history, pu);
-
- if (callback)
- callback ((RCResItem *) p, user_data);
-
- g_object_unref (p);
-
- ++count;
-
- cleanup:
- rpmman->headerFree (h);
-
- /* This chunk of ugly could be removed if a) memmem() was portable;
- * or b) if rpmlib didn't suck, and I could figure out how much
- * data it read from the buffer.
- */
- bytesleft = len - (cur_ptr - data);
- for (i = 0; i < bytesleft - hdrmagic_len; i++) {
- if (memcmp (cur_ptr + i, hdrmagic, hdrmagic_len) == 0) {
- /* We found a match */
- cur_ptr = cur_ptr + i + hdrmagic_len;
- break;
- }
- }
-
- if (i >= bytesleft - hdrmagic_len) {
- /* No match was found */
- cur_ptr = NULL;
- }
- }
-
- return count;
-#endif
-}
-
-int
-extract_packages_from_aptrpm_file (const char *filename,
- RCPackman *packman,
- ChannelPtr channel,
- CResItemFn callback,
- void * user_data)
-{
- WorldPtr world = *((WorldPtr *)data);
- RCBuffer *buf;
- int count;
-
- g_return_val_if_fail (filename != NULL, -1);
- g_return_val_if_fail (packman != NULL, -1);
-
- buf = rc_buffer_map_file (filename);
- if (buf == NULL)
- return -1;
-
- count = extract_packages_from_aptrpm_buffer (buf->data, buf->size,
- packman, channel,
- callback, user_data);
-
- rc_buffer_unmap_file (buf);
-
- return count;
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-static void
-package_into_hash (PackagePtr pkg, GHashTable *hash)
-{
- void * nameq;
- PackagePtr hashed_pkg;
-
- nameq = GINT_TO_POINTER (RC_RESOLVABLE_SPEC (pkg)->nameq);
- hashed_pkg = g_hash_table_lookup (hash, nameq);
- if (hashed_pkg == NULL) {
- g_hash_table_insert (hash, nameq, g_object_ref (pkg));
- } else if (rc_version_compare (RC_RESOLVABLE_SPEC (pkg),
- RC_RESOLVABLE_SPEC (hashed_pkg)) > 0) {
- g_hash_table_replace (hash, nameq, g_object_ref (pkg));
- g_object_unref (hashed_pkg);
- }
-}
-
-static bool
-hash_recurse_cb (PackagePtr pkg, void * user_data)
-{
- GHashTable *hash = user_data;
- package_into_hash (pkg, hash);
- return true;
-}
-
-struct HashIterInfo {
- CResItemFn callback;
- void * user_data;
- int count;
-};
-
-static void
-hash_iter_cb (void * key, void * val, void * user_data)
-{
- RCResItem *r = val;
- struct HashIterInfo *info = user_data;
-
- if (info->callback)
- info->callback (r, info->user_data);
-
- g_object_unref (r);
- ++info->count;
-}
-
-
-static void
-add_fake_history (PackagePtr pkg)
-{
- RCPackageUpdate *up;
-
- up = rc_package_update_new ();
- rc_resItem_spec_copy ((RCResItemSpec *) up,
- RC_RESOLVABLE_SPEC (pkg));
- up->importance = RC_IMPORTANCE_SUGGESTED;
- rc_package_add_update (pkg, up);
-}
-
-typedef struct {
- CResItemFn user_callback;
- void * user_data;
- const gchar *path;
-} PackagesFromDirInfo;
-
-static bool
-packages_from_dir_cb (PackagePtr package, void * user_data)
-{
- PackagesFromDirInfo *info = user_data;
- RCPackageUpdate *update;
-
- /* Set package path */
- update = rc_package_get_latest_update (package);
- if (update && update->package_url)
- package->package_filename = g_build_path (G_DIR_SEPARATOR_S,
- info->path,
- update->package_url,
- NULL);
- if (info->user_callback)
- return info->user_callback ((RCResItem *)package, info->user_data);
-
- return true;
-}
-
-int
-extract_packages_from_directory (const char *path,
- ChannelPtr channel,
- RCPackman *packman,
- bool recursive,
- CResItemFn callback,
- void * user_data)
-{
- WorldPtr world = *((WorldPtr *)data);
- GDir *dir;
- GHashTable *hash;
- struct HashIterInfo info;
- const char *filename;
- char *magic;
- bool distro_magic, pkginfo_magic;
-
- g_return_val_if_fail (path && *path, -1);
- g_return_val_if_fail (channel != NULL, -1);
-
- /*
- Check for magic files that indicate how to treat the
- directory. The files aren't read -- it is sufficient that
- they exist.
- */
-
- magic = g_strconcat (path, "/RC_SKIP", NULL);
- if (g_file_test (magic, G_FILE_TEST_EXISTS)) {
- g_free (magic);
- return 0;
- }
- g_free (magic);
-
- magic = g_strconcat (path, "/RC_RECURSIVE", NULL);
- if (g_file_test (magic, G_FILE_TEST_EXISTS))
- recursive = true;
- g_free (magic);
-
- magic = g_strconcat (path, "/RC_BY_DISTRO", NULL);
- distro_magic = g_file_test (magic, G_FILE_TEST_EXISTS);
- g_free (magic);
-
- pkginfo_magic = true;
- magic = g_strconcat (path, "/RC_IGNORE_PKGINFO", NULL);
- if (g_file_test (magic, G_FILE_TEST_EXISTS))
- pkginfo_magic = false;
- g_free (magic);
-
- /* If distro_magic is set, we search for packages in two
- subdirectories of path: path/distro-target (i.e.
- path/redhat-9-i386) and path/x-cross.
- */
-
-#if 0
- if (distro_magic) {
- char *distro_path, *cross_distro_path;
- bool found_distro_magic = false;
- int count = 0, c;
-
- distro_path = g_strconcat (path, "/", rc_distro_get_target (), NULL);
- if (g_file_test (distro_path, G_FILE_TEST_IS_DIR)) {
- found_distro_magic = true;
-
- c = extract_packages_from_directory (distro_path,
- channel, packman,
- callback, user_data);
- if (c >= 0)
- count += c;
- }
-
- cross_distro_path = g_strconcat (path, "/x-distro", NULL);
- if (g_file_test (cross_distro_path, G_FILE_TEST_IS_DIR)) {
- c = extract_packages_from_directory (cross_distro_path,
- channel, packman,
- callback, user_data);
- if (c >= 0)
- count += c;
- }
-
- g_free (cross_distro_path);
- g_free (distro_path);
-
- return count;
- }
-#endif
-
- /* If pkginfo_magic is set and if a packageinfo.xml or
- packageinfo.xml.gz file exists in the directory, use it
- instead of just scanning the files in the directory
- looking for packages. */
-
- if (pkginfo_magic) {
- int i, count;
- gchar *pkginfo_path = NULL;
- const gchar *pkginfo[] = { "packageinfo.xml",
- "packageinfo.xml.gz",
- NULL };
-
- for (i = 0; pkginfo[i]; i++) {
- pkginfo_path = g_build_path (G_DIR_SEPARATOR_S, path, pkginfo[i], NULL);
- if (g_file_test (pkginfo_path, G_FILE_TEST_EXISTS))
- break;
-
- g_free (pkginfo_path);
- pkginfo_path = NULL;
- }
-
- if (pkginfo_path) {
- PackagesFromDirInfo info;
-
- info.user_callback = callback;
- info.user_data = user_data;
- info.path = path;
-
- count = extract_packages_from_helix_file (pkginfo_path, channel, packages_from_dir_cb, &info);
- g_free (pkginfo_path);
- return count;
- }
- }
-
- dir = g_dir_open (path, 0, NULL);
- if (dir == NULL)
- return -1;
-
- hash = g_hash_table_new (NULL, NULL);
-
- while ( (filename = g_dir_read_name (dir)) ) {
- gchar *file_path;
-
- file_path = g_strconcat (path, "/", filename, NULL);
-
- if (recursive && g_file_test (file_path, G_FILE_TEST_IS_DIR)) {
- extract_packages_from_directory (file_path,
- channel,
- packman,
- true,
- hash_recurse_cb,
- hash);
- } else if (g_file_test (file_path, G_FILE_TEST_IS_REGULAR)) {
- PackagePtr pkg;
-
- pkg = rc_packman_query_file (packman, file_path, true);
- if (pkg != NULL) {
- rc_resItem_set_channel (RC_RESOLVABLE (pkg), channel);
- pkg->package_filename = strdup (file_path);
- pkg->local_package = false;
- add_fake_history (pkg);
- package_into_hash (pkg, hash);
- g_object_unref (pkg);
- }
- }
-
- g_free (file_path);
- }
-
- g_dir_close (dir);
-
- info.callback = callback;
- info.user_data = user_data;
- info.count = 0;
-
- /* Walk across the hash and:
- 1) Invoke the callback on each package
- 2) Unref each package
- */
- g_hash_table_foreach (hash, hash_iter_cb, &info);
-
- g_hash_table_destroy (hash);
-
- return info.count;
-}
-#endif
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+
+ int
+ extract_packages_from_xml_node (XmlNodePtr node, ChannelPtr channel, CResItemFn callback, void *data)
+ {
+ PackagePtr package;
+ int count = 0;
+
+ if (getenv ("RC_SPEW_XML")) fprintf (stderr, "extract_packages_from_xml_node ()\n");
+ // search the 'package' node
+
+ while (node && !node->equals("package")) {
+ if (!node->isElement()) {
+ node = node->next();
+ continue;
+ }
+
+ node = node->children();
+ }
+
+ // extract the 'package' node, if found
+
+ while (node) {
+ if (node->equals("package")) {
+ package = new Package (node, channel);
+ if (package) {
+ if (getenv ("RC_SPEW")) fprintf (stderr, "%s\n", package->asString(true).c_str());
+ bool ok = true;
+ if (callback)
+ ok = callback (package, data);
+ if (! ok)
+ return -1;
+ ++count;
+ }
+ }
+ node = node->next();
+ }
+
+ return count;
+ }
+
+
+ int
+ extract_packages_from_helix_buffer (const char *buf, size_t len, ChannelPtr channel, CResItemFn callback, void *data)
+ {
+ unsigned int count = 0;
+ PackageList packages;
+
+ if (getenv ("RC_SPEW_XML")) fprintf (stderr, "extract_packages_from_helix_buffer(%.32s...,%ld,...)\n", buf, (long)len);
+
+ if (buf == NULL || len == 0)
+ return 0;
+
+ XmlParser parser (channel);
+ parser.parseChunk (buf, len);
+ packages = parser.done ();
+
+ if (packages.empty())
+ return 0;
+
+ count = packages.size();
+
+ if (getenv ("RC_SPEW_XML")) fprintf (stderr, "extract_packages_from_helix_buffer: parsed %d packages\n", count);
+
+ if (callback != NULL) {
+ for (PackageList::iterator iter = packages.begin(); iter != packages.end(); iter++) {
+ callback (*iter, data);
+ }
+ }
+
+ return count;
+ }
+
+
+ int
+ extract_packages_from_helix_file (const string & filename, ChannelPtr channel, CResItemFn callback, void *data)
+ {
+ Buffer *buf;
+ int count;
+
+ if (filename.empty())
+ return -1;
+
+ buf = buffer_map_file (filename);
+ if (buf == NULL)
+ return -1;
+
+ count = extract_packages_from_helix_buffer ((const char *)(buf->data), buf->size, channel, callback, data);
+
+ buffer_unmap_file (buf);
+
+ return count;
+ }
+
+
+ int
+ extract_packages_from_undump_buffer (const char *buf, size_t len, ChannelAndSubscribedFn channel_callback, CResItemFn resItem_callback, MatchFn lock_callback, void *data)
+ {
+ xmlDoc *doc;
+ XmlNodePtr dump_node;
+ ChannelPtr system_channel = NULL;
+ ChannelPtr current_channel = NULL;
+ XmlNodePtr channel_node;
+ int count = 0;
+
+ doc = parse_xml_from_buffer (buf, len);
+ if (doc == NULL)
+ return -1;
+
+ dump_node = new XmlNode (xmlDocGetRootElement (doc));
+ if (dump_node == NULL)
+ return -1;
+
+ if (!dump_node->equals("world")) {
+ debug (DEBUG_LEVEL_WARNING, "Unrecognized top-level node for undump: '%s'", dump_node->name());
+ return -1;
+ }
+
+ channel_node = dump_node->children();
+
+ while (channel_node != NULL) {
+
+ if (channel_node->equals("locks")) {
+ XmlNodePtr lock_node = channel_node->children();
+
+ while (lock_node) {
+ MatchPtr lock;
+
+ lock = new Match (lock_node);
+
+ if (lock_callback)
+ lock_callback (lock, data);
+
+ lock_node = lock_node->next();
+ }
+
+ } else if (channel_node->equals("system_packages")) {
+
+ int subcount;
+
+ if (!system_channel) {
+ system_channel = new Channel ("@system", "System Packages", "@system", "System Packages");
+ system_channel->setSystem (true);
+ system_channel->setHidden (true);
+ }
+
+ if (channel_callback) {
+ channel_callback (system_channel, false, data);
+ }
+
+ subcount = extract_packages_from_xml_node (channel_node, system_channel, resItem_callback, data);
+
+ if (subcount < 0) {
+ /* Do something clever */
+ fprintf (stderr, "No packages found\n");
+ abort ();
+ }
+
+ count += subcount;
+
+ } else if (channel_node->equals("channel")) {
+
+ int subscribed;
+ current_channel = new Channel (channel_node, &subscribed, (World *)data);
+
+ if (channel_callback) {
+ channel_callback (current_channel, subscribed != 0, data);
+ }
+
+ if (resItem_callback) {
+ int subcount;
+ subcount = extract_packages_from_xml_node (channel_node, current_channel, resItem_callback, data);
+ if (subcount < 0) {
+ /* FIXME: do something clever */
+ fprintf (stderr, "No packages found\n");
+ abort ();
+ }
+ count += subcount;
+ }
+ }
+
+ channel_node = channel_node->next();
+ }
+
+ xmlFreeDoc (doc);
+
+ return count;
+ }
+
+
+ int
+ extract_packages_from_undump_file (const string & filename, ChannelAndSubscribedFn channel_callback, CResItemFn resItem_callback, MatchFn lock_callback, void *data)
+ {
+ Buffer *buf;
+ int count;
+
+ if (filename.empty())
+ return -1;
+
+ buf = buffer_map_file (filename);
+ if (buf == NULL)
+ return -1;
+
+ count = extract_packages_from_undump_buffer ((const char *)(buf->data), buf->size, channel_callback, resItem_callback, lock_callback, data);
+
+ buffer_unmap_file (buf);
+
+ return count;
+ }
+
+ #if 0
+ /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+ static ResItemPtr
+ fill_debian_package (const char *buf, const char *url_prefix, int *off)
+ {
+ const char *ibuf;
+ RCPackageUpdate *up = NULL;
+ ResItemPtr r;
+ ResItemList requires, provides, conflicts, suggests, recommends;
+
+ up = rc_package_update_new ();
+
+ ibuf = buf;
+ while (1) {
+ char *key;
+ GString *value = NULL;
+ const char *p;
+ int ind;
+
+ /* Linebreaks indicate the end of a package block. */
+ if (*ibuf == '\0' || *ibuf == '\n') break;
+
+ p = strchr (ibuf, ':');
+
+ /* Something bad happened, we're supposed to have a colon. */
+ if (!p) break;
+
+ /* Copy the name of the key and lowercase it */
+ key = g_ascii_strdown (ibuf, p - ibuf);
+
+ /* Move past the colon and any spaces */
+ ibuf = p;
+ while (*ibuf && (*ibuf == ':' || *ibuf == ' ')) ibuf++;
+
+ ind = 0;
+ while ((p = strchr (ibuf, '\n'))) {
+ if (!value)
+ value = g_string_new ("");
+
+ g_string_append_len (value, ibuf, p - ibuf);
+ ind += p - ibuf;
+
+ ibuf = p;
+
+ /* Move past the newline */
+ ibuf++;
+
+ /* Check to see if this is a continuation of the previous line */
+ if (*ibuf == ' ') {
+ /* It is. Move past the space */
+ ibuf++;
+
+ /*
+ * This is a hack. Description is special because it's
+ * intended to be multiline and user-visible. So if we're
+ * dealing with description, add a newline.
+ */
+
+ if (strncmp (key, "description",
+ strlen ("description")) == 0) {
+ g_string_append_c (value, '\n');
+
+ /*
+ * A period on a line by itself indicates that it
+ * should be a blank line. A newline will follow the
+ * period, so we'll just skip over it.
+ */
+ if (*ibuf == '.')
+ ibuf++;
+ }
+ }
+ else {
+ /* It isn't. Break out. */
+ break;
+ }
+ }
+
+ if (!strncmp (key, "package", strlen ("package"))) {
+ rc_resItem_spec_set_name (RC_RESOLVABLE_SPEC (pkg), value->str);
+ } else if (!strncmp (key, "installed-size",
+ strlen ("installed-size"))) {
+ up->installed_size = strtoul (value->str, NULL, 10) * 1024;
+ } else if (!strncmp (key, "size", strlen ("size"))) {
+ up->package_size = strtoul(value->str, NULL, 10);
+ } else if (!strncmp (key, "description", strlen ("description"))) {
+ char *newline;
+
+ /*
+ * We only want the first line for the summary, and all the
+ * other lines for the description.
+ */
+
+ newline = strchr (value->str, '\n');
+ if (!newline) {
+ pkg->summary = strdup (value->str);
+ pkg->description = g_strconcat (value->str, "\n", NULL);
+ }
+ else {
+ pkg->summary = g_strndup (value->str, newline - value->str);
+ pkg->description = g_strconcat (newline + 1, "\n", NULL);
+ }
+ } else if (!strncmp (key, "version", strlen ("version"))) {
+ RCResItemSpec *spec = RC_RESOLVABLE_SPEC (pkg);
+ rc_version_parse (value->str, spec);
+ } else if (!strncmp (key, "section", strlen ("section"))) {
+ pkg->section = rc_debman_section_to_package_section (value->str);
+ } else if (!strncmp (key, "depends", strlen ("depends"))) {
+ requires = g_slist_concat (
+ requires,
+ rc_debman_fill_depends (value->str, false));
+ } else if (!strncmp (key, "recommends", strlen ("recommends"))) {
+ recommends = g_slist_concat (
+ recommends,
+ rc_debman_fill_depends (value->str, false));
+ } else if (!strncmp (key, "suggests", strlen ("suggests"))) {
+ suggests = g_slist_concat (
+ suggests,
+ rc_debman_fill_depends (value->str, false));
+ } else if (!strncmp (key, "pre-depends", strlen ("pre-depends"))) {
+ requires = g_slist_concat (
+ requires,
+ rc_debman_fill_depends (value->str, true));
+ } else if (!strncmp (key, "conflicts", strlen ("conflicts"))) {
+ conflicts = g_slist_concat (
+ conflicts,
+ rc_debman_fill_depends (value->str, false));
+ } else if (!strncmp (key, "provides", strlen ("provides"))) {
+ provides = g_slist_concat (
+ provides,
+ rc_debman_fill_depends (value->str, false));
+ } else if (!strncmp (key, "filename", strlen ("filename"))) {
+ /* Build a new update with just this version */
+ if (url_prefix) {
+ up->package_url = g_strconcat (url_prefix, "/",
+ value->str,
+ NULL);
+ } else {
+ up->package_url = strdup (value->str);
+ }
+ } else if (!strncmp (key, "md5sum", strlen ("md5sum"))) {
+ up->md5sum = strdup (value->str);
+ } else if (!strncmp (key, "architecture", strlen ("architecture"))) {
+ rc_resItem_spec_set_arch (RC_RESOLVABLE_SPEC (pkg), rc_arch_from_string (value->str));
+ }
+
+ g_string_free (value, true);
+ }
+
+ up->importance = RC_IMPORTANCE_SUGGESTED;
+ up->description = strdup ("Upstream Debian release");
+ rc_resItem_spec_copy (rc_package_update_get_spec(up), RC_RESOLVABLE_SPEC (pkg));
+ rc_package_add_update (pkg, up);
+
+ r = RC_RESOLVABLE (pkg);
+
+ /* Make sure to provide myself, for the dep code! */
+ provides = g_slist_append (provides, rc_resItem_dep_new_from_spec
+ (RC_RESOLVABLE_SPEC (pkg),
+ RC_RELATION_EQUAL,
+ RC_TYPE_PACKAGE,
+ rc_resItem_get_channel (r),
+ false, false));
+
+ rc_resItem_set_requires (r, requires);
+ rc_resItem_set_provides (r, provides);
+ rc_resItem_set_conflicts (r, conflicts);
+ rc_resItem_set_obsoletes (r, NULL);
+ rc_resItem_set_suggests (r, suggests);
+ rc_resItem_set_recommends(r, recommends);
+ /* returns the number of characters we processed */
+ return ibuf - buf;
+ }
+
+ #endif
+
+ int
+ extract_packages_from_debian_buffer (const char *buf, size_t len, ChannelPtr channel, CResItemFn callback, void *data)
+ {
+ const char *pos;
+ int count = 0;
+
+ /* Keep looking for a "Package: " */
+ pos = buf;
+ #if 0
+ while ((pos = strstr (pos, "Package: ")) != NULL) {
+ int off;
+
+ /* All debian packages "have" epochs */
+ ResItemPtr resItem = fill_debian_package (iter, channel->getFilePath (), &off);
+
+ resItem->setEpoch (0);
+ resItem->setArch (Arch::Noarch);
+ resItem->setChannel (channel);
+
+ if (callback)
+ callback (resItem, data);
+
+ ++count;
+
+ iter += off;
+ }
+ #endif
+ return count;
+ }
+
+
+ int
+ extract_packages_from_debian_file (const string & filename, ChannelPtr channel, CResItemFn callback, void *data)
+ {
+ Buffer *buf;
+ int count;
+
+ if (filename.empty())
+ return -1;
+
+ buf = buffer_map_file (filename);
+ if (buf == NULL)
+ return -1;
+
+ count = extract_packages_from_debian_buffer ((const char *)(buf->data), buf->size, channel, callback, data);
+ buffer_unmap_file (buf);
+
+ return count;
+ }
+
+ #if 0
+ /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+ PackagePtr
+ extract_yum_package (const guint8 *data, size_t len,
+ RCPackman *packman, char *url)
+ {
+ #ifndef ENABLE_RPM
+ /* We can't support yum without rpm support */
+ debug (RC_DEBUG_LEVEL_ERROR, "RPM support is not enabled");
+ return NULL;
+ #else
+ RCRpmman *rpmman;
+ Header h;
+ PackagePtr p;
+ RCPackageUpdate *pu;
+ char *tmpc;
+ int typ, n;
+
+ g_return_val_if_fail (packman != NULL, NULL);
+
+ if (!g_type_is_a (G_TYPE_FROM_INSTANCE (packman), RC_TYPE_RPMMAN)) {
+ debug (RC_DEBUG_LEVEL_ERROR,
+ "yum support is not available on non-RPM systems");
+ return NULL;
+ }
+
+ rpmman = RC_RPMMAN (packman);
+
+ h = rpmman->headerLoad (data);
+
+ if (h == NULL) {
+ debug (RC_DEBUG_LEVEL_ERROR,
+ "Unable to get header from headerCopyLoad!");
+ return NULL;
+ }
+
+ rpmman->headerGetEntry (h, RPMTAG_ARCH, &typ, (void **) &tmpc, &n);
+
+ p = rc_package_new ();
+
+ rc_rpmman_read_header (rpmman, h, p);
+ rc_rpmman_depends_fill (rpmman, h, p, true);
+
+ pu = rc_package_update_new ();
+ rc_resItem_spec_copy (rc_package_update_get_spec (pu), RC_RESOLVABLE_SPEC (p));
+ pu->importance = RC_IMPORTANCE_SUGGESTED;
+ pu->description = strdup ("No information available.");
+ pu->package_url = url;
+
+ p->history = g_slist_append (p->history, pu);
+
+ rpmman->headerFree (h);
+
+ return p;
+ #endif
+ }
+
+ int
+ extract_packages_from_aptrpm_buffer (const guint8 *data, size_t len,
+ RCPackman *packman,
+ ChannelPtr channel,
+ CResItemFn callback,
+ void * user_data)
+ {
+ #ifndef ENABLE_RPM
+ /* We can't support apt-rpm without rpm support */
+ debug (RC_DEBUG_LEVEL_ERROR, "RPM support is not enabled");
+ return -1;
+ #else
+ RCRpmman *rpmman;
+ int count = 0;
+ const int hdrmagic_len = 8;
+ const char *hdrmagic;
+ const guint8 *cur_ptr;
+ RCResItemSpec *spec;
+
+
+ g_return_val_if_fail (packman != NULL, -1);
+
+ if (!g_type_is_a (G_TYPE_FROM_INSTANCE (packman), RC_TYPE_RPMMAN)) {
+ debug (RC_DEBUG_LEVEL_ERROR,
+ "apt-rpm support is not available on non-RPM systems");
+ return -1;
+ }
+
+ rpmman = RC_RPMMAN (packman);
+
+ if (len < hdrmagic_len) {
+ debug (RC_DEBUG_LEVEL_ERROR,
+ "Data is too small to possibly be correct");
+ return 0;
+ }
+
+ /*
+ * The apt-rpm pkglist files are a set of rpm headers, each prefixed
+ * with the header magic, one right after the other. If opened on disk,
+ * they can be iterated using headerRead(). Since we have an in-memory
+ * buffer, we use headerCopyLoad to read them. We could, potentially,
+ * use headerLoad(); but I'm unsure as to what happens when headerFree
+ * is called on a Header returned from headerLoad. It may be a small
+ * memory savings to do so.
+ */
+
+ /* Skip the inital RPM header magic */
+ hdrmagic = data;
+ cur_ptr = data + hdrmagic_len;
+
+ while (cur_ptr != NULL) {
+ Header h;
+ PackagePtr p;
+ RCPackageUpdate *pu;
+ int bytesleft, i;
+ char *tmpc;
+ int typ, n;
+ char *archstr;
+
+ h = rpmman->headerLoad (cur_ptr);
+
+ if (h == NULL) {
+ debug (RC_DEBUG_LEVEL_ERROR,
+ "Unable to get header from headerCopyLoad!");
+ return 0;
+ }
+
+ rpmman->headerGetEntry (h, RPMTAG_ARCH, &typ, (void **) &tmpc, &n);
+
+ if (n && typ == RPM_STRING_TYPE)
+ archstr = tmpc;
+ else {
+ debug (RC_DEBUG_LEVEL_WARNING, "No arch available!");
+ goto cleanup;
+ }
+
+ p = rc_package_new ();
+
+ rc_rpmman_read_header (rpmman, h, p);
+ rc_rpmman_depends_fill (rpmman, h, p, true);
+
+ rc_resItem_set_channel (RC_RESOLVABLE (p), channel);
+
+ pu = rc_package_update_new ();
+ rc_resItem_spec_copy (rc_package_update_get_spec (pu), RC_RESOLVABLE_SPEC (p));
+ pu->importance = RC_IMPORTANCE_SUGGESTED;
+ pu->description = strdup ("No information available.");
+
+ /* Build a filename from the spec */
+ spec = RC_RESOLVABLE_SPEC (p);
+ pu->package_url = strdup_printf ("%s/%s-%s-%s.%s.rpm",
+ rc_channel_get_file_path (channel),
+ rc_resItem_spec_get_name (spec),
+ rc_resItem_spec_get_version (spec),
+ rc_resItem_spec_get_release (spec),
+ archstr);
+
+ p->history = g_slist_append (p->history, pu);
+
+ if (callback)
+ callback ((RCResItem *) p, user_data);
+
+ g_object_unref (p);
+
+ ++count;
+
+ cleanup:
+ rpmman->headerFree (h);
+
+ /* This chunk of ugly could be removed if a) memmem() was portable;
+ * or b) if rpmlib didn't suck, and I could figure out how much
+ * data it read from the buffer.
+ */
+ bytesleft = len - (cur_ptr - data);
+ for (i = 0; i < bytesleft - hdrmagic_len; i++) {
+ if (memcmp (cur_ptr + i, hdrmagic, hdrmagic_len) == 0) {
+ /* We found a match */
+ cur_ptr = cur_ptr + i + hdrmagic_len;
+ break;
+ }
+ }
+
+ if (i >= bytesleft - hdrmagic_len) {
+ /* No match was found */
+ cur_ptr = NULL;
+ }
+ }
+
+ return count;
+ #endif
+ }
+
+ int
+ extract_packages_from_aptrpm_file (const char *filename,
+ RCPackman *packman,
+ ChannelPtr channel,
+ CResItemFn callback,
+ void * user_data)
+ {
+ WorldPtr world = *((WorldPtr *)data);
+ RCBuffer *buf;
+ int count;
+
+ g_return_val_if_fail (filename != NULL, -1);
+ g_return_val_if_fail (packman != NULL, -1);
+
+ buf = rc_buffer_map_file (filename);
+ if (buf == NULL)
+ return -1;
+
+ count = extract_packages_from_aptrpm_buffer (buf->data, buf->size,
+ packman, channel,
+ callback, user_data);
+
+ rc_buffer_unmap_file (buf);
+
+ return count;
+ }
+
+ /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+ static void
+ package_into_hash (PackagePtr pkg, GHashTable *hash)
+ {
+ void * nameq;
+ PackagePtr hashed_pkg;
+
+ nameq = GINT_TO_POINTER (RC_RESOLVABLE_SPEC (pkg)->nameq);
+ hashed_pkg = g_hash_table_lookup (hash, nameq);
+ if (hashed_pkg == NULL) {
+ g_hash_table_insert (hash, nameq, g_object_ref (pkg));
+ } else if (rc_version_compare (RC_RESOLVABLE_SPEC (pkg),
+ RC_RESOLVABLE_SPEC (hashed_pkg)) > 0) {
+ g_hash_table_replace (hash, nameq, g_object_ref (pkg));
+ g_object_unref (hashed_pkg);
+ }
+ }
+
+ static bool
+ hash_recurse_cb (PackagePtr pkg, void * user_data)
+ {
+ GHashTable *hash = user_data;
+ package_into_hash (pkg, hash);
+ return true;
+ }
+
+ struct HashIterInfo {
+ CResItemFn callback;
+ void * user_data;
+ int count;
+ };
+
+ static void
+ hash_iter_cb (void * key, void * val, void * user_data)
+ {
+ RCResItem *r = val;
+ struct HashIterInfo *info = user_data;
+
+ if (info->callback)
+ info->callback (r, info->user_data);
+
+ g_object_unref (r);
+ ++info->count;
+ }
+
+
+ static void
+ add_fake_history (PackagePtr pkg)
+ {
+ RCPackageUpdate *up;
+
+ up = rc_package_update_new ();
+ rc_resItem_spec_copy ((RCResItemSpec *) up,
+ RC_RESOLVABLE_SPEC (pkg));
+ up->importance = RC_IMPORTANCE_SUGGESTED;
+ rc_package_add_update (pkg, up);
+ }
+
+ typedef struct {
+ CResItemFn user_callback;
+ void * user_data;
+ const gchar *path;
+ } PackagesFromDirInfo;
+
+ static bool
+ packages_from_dir_cb (PackagePtr package, void * user_data)
+ {
+ PackagesFromDirInfo *info = user_data;
+ RCPackageUpdate *update;
+
+ /* Set package path */
+ update = rc_package_get_latest_update (package);
+ if (update && update->package_url)
+ package->package_filename = g_build_path (G_DIR_SEPARATOR_S,
+ info->path,
+ update->package_url,
+ NULL);
+ if (info->user_callback)
+ return info->user_callback ((RCResItem *)package, info->user_data);
+
+ return true;
+ }
+
+ int
+ extract_packages_from_directory (const char *path,
+ ChannelPtr channel,
+ RCPackman *packman,
+ bool recursive,
+ CResItemFn callback,
+ void * user_data)
+ {
+ WorldPtr world = *((WorldPtr *)data);
+ GDir *dir;
+ GHashTable *hash;
+ struct HashIterInfo info;
+ const char *filename;
+ char *magic;
+ bool distro_magic, pkginfo_magic;
+
+ g_return_val_if_fail (path && *path, -1);
+ g_return_val_if_fail (channel != NULL, -1);
+
+ /*
+ Check for magic files that indicate how to treat the
+ directory. The files aren't read -- it is sufficient that
+ they exist.
+ */
+
+ magic = g_strconcat (path, "/RC_SKIP", NULL);
+ if (g_file_test (magic, G_FILE_TEST_EXISTS)) {
+ g_free (magic);
+ return 0;
+ }
+ g_free (magic);
+
+ magic = g_strconcat (path, "/RC_RECURSIVE", NULL);
+ if (g_file_test (magic, G_FILE_TEST_EXISTS))
+ recursive = true;
+ g_free (magic);
+
+ magic = g_strconcat (path, "/RC_BY_DISTRO", NULL);
+ distro_magic = g_file_test (magic, G_FILE_TEST_EXISTS);
+ g_free (magic);
+
+ pkginfo_magic = true;
+ magic = g_strconcat (path, "/RC_IGNORE_PKGINFO", NULL);
+ if (g_file_test (magic, G_FILE_TEST_EXISTS))
+ pkginfo_magic = false;
+ g_free (magic);
+
+ /* If distro_magic is set, we search for packages in two
+ subdirectories of path: path/distro-target (i.e.
+ path/redhat-9-i386) and path/x-cross.
+ */
+
+ #if 0
+ if (distro_magic) {
+ char *distro_path, *cross_distro_path;
+ bool found_distro_magic = false;
+ int count = 0, c;
+
+ distro_path = g_strconcat (path, "/", rc_distro_get_target (), NULL);
+ if (g_file_test (distro_path, G_FILE_TEST_IS_DIR)) {
+ found_distro_magic = true;
+
+ c = extract_packages_from_directory (distro_path,
+ channel, packman,
+ callback, user_data);
+ if (c >= 0)
+ count += c;
+ }
+
+ cross_distro_path = g_strconcat (path, "/x-distro", NULL);
+ if (g_file_test (cross_distro_path, G_FILE_TEST_IS_DIR)) {
+ c = extract_packages_from_directory (cross_distro_path,
+ channel, packman,
+ callback, user_data);
+ if (c >= 0)
+ count += c;
+ }
+
+ g_free (cross_distro_path);
+ g_free (distro_path);
+
+ return count;
+ }
+ #endif
+
+ /* If pkginfo_magic is set and if a packageinfo.xml or
+ packageinfo.xml.gz file exists in the directory, use it
+ instead of just scanning the files in the directory
+ looking for packages. */
+
+ if (pkginfo_magic) {
+ int i, count;
+ gchar *pkginfo_path = NULL;
+ const gchar *pkginfo[] = { "packageinfo.xml",
+ "packageinfo.xml.gz",
+ NULL };
+
+ for (i = 0; pkginfo[i]; i++) {
+ pkginfo_path = g_build_path (G_DIR_SEPARATOR_S, path, pkginfo[i], NULL);
+ if (g_file_test (pkginfo_path, G_FILE_TEST_EXISTS))
+ break;
+
+ g_free (pkginfo_path);
+ pkginfo_path = NULL;
+ }
+
+ if (pkginfo_path) {
+ PackagesFromDirInfo info;
+
+ info.user_callback = callback;
+ info.user_data = user_data;
+ info.path = path;
+
+ count = extract_packages_from_helix_file (pkginfo_path, channel, packages_from_dir_cb, &info);
+ g_free (pkginfo_path);
+ return count;
+ }
+ }
+
+ dir = g_dir_open (path, 0, NULL);
+ if (dir == NULL)
+ return -1;
+
+ hash = g_hash_table_new (NULL, NULL);
+
+ while ( (filename = g_dir_read_name (dir)) ) {
+ gchar *file_path;
+
+ file_path = g_strconcat (path, "/", filename, NULL);
+
+ if (recursive && g_file_test (file_path, G_FILE_TEST_IS_DIR)) {
+ extract_packages_from_directory (file_path,
+ channel,
+ packman,
+ true,
+ hash_recurse_cb,
+ hash);
+ } else if (g_file_test (file_path, G_FILE_TEST_IS_REGULAR)) {
+ PackagePtr pkg;
+
+ pkg = rc_packman_query_file (packman, file_path, true);
+ if (pkg != NULL) {
+ rc_resItem_set_channel (RC_RESOLVABLE (pkg), channel);
+ pkg->package_filename = strdup (file_path);
+ pkg->local_package = false;
+ add_fake_history (pkg);
+ package_into_hash (pkg, hash);
+ g_object_unref (pkg);
+ }
+ }
+
+ g_free (file_path);
+ }
+
+ g_dir_close (dir);
+
+ info.callback = callback;
+ info.user_data = user_data;
+ info.count = 0;
+
+ /* Walk across the hash and:
+ 1) Invoke the callback on each package
+ 2) Unref each package
+ */
+ g_hash_table_foreach (hash, hash_iter_cb, &info);
+
+ g_hash_table_destroy (hash);
+
+ return info.count;
+ }
+ #endif
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <zypp/solver/detail/StoreWorldPtr.h>
#include <zypp/solver/detail/PackmanPtr.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-
-int extract_packages_from_helix_buffer (const char data[], size_t len, ChannelPtr channel, CResItemFn callback, void *data);
-int extract_packages_from_helix_file (const std::string & filename, ChannelPtr channel, CResItemFn callback, void *data);
-
-int extract_packages_from_xml_node (constXmlNodePtr node, ChannelPtr channel, ResItemFn callback, void *data);
-
-int extract_packages_from_debian_buffer (const char *data, size_t len, ChannelPtr channel, CResItemFn callback, void *data);
-int extract_packages_from_debian_file (const std::string & filename, ChannelPtr channel, CResItemFn callback, void *data);
-
-PackagePtr extract_yum_package (const char *data, size_t len, PackmanPtr packman, const std::string & url);
-
-int extract_packages_from_aptrpm_buffer (const char *data, size_t len, PackmanPtr packman, ChannelPtr channel, ResItemFn callback, void *data);
-int extract_packages_from_aptrpm_file (const std::string & filename, PackmanPtr packman, ChannelPtr channel, ResItemFn callback, void *data);
-
-int extract_packages_from_undump_buffer (const char *data, size_t len, ChannelAndSubscribedFn channel_callback, CResItemFn package_callback, MatchFn lock_callback, void *data);
-int extract_packages_from_undump_file (const std::string & filename, ChannelAndSubscribedFn channel_callback, CResItemFn package_callback, MatchFn lock_callback, void *data);
-
-int extract_packages_from_directory (const std::string & path, ChannelPtr channel, PackmanPtr packman, bool recursive, ResItemFn callback, void *data);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
-
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ int extract_packages_from_helix_buffer (const char data[], size_t len, ChannelPtr channel, CResItemFn callback, void *data);
+ int extract_packages_from_helix_file (const std::string & filename, ChannelPtr channel, CResItemFn callback, void *data);
+
+ int extract_packages_from_xml_node (constXmlNodePtr node, ChannelPtr channel, ResItemFn callback, void *data);
+
+ int extract_packages_from_debian_buffer (const char *data, size_t len, ChannelPtr channel, CResItemFn callback, void *data);
+ int extract_packages_from_debian_file (const std::string & filename, ChannelPtr channel, CResItemFn callback, void *data);
+
+ PackagePtr extract_yum_package (const char *data, size_t len, PackmanPtr packman, const std::string & url);
+
+ int extract_packages_from_aptrpm_buffer (const char *data, size_t len, PackmanPtr packman, ChannelPtr channel, ResItemFn callback, void *data);
+ int extract_packages_from_aptrpm_file (const std::string & filename, PackmanPtr packman, ChannelPtr channel, ResItemFn callback, void *data);
+
+ int extract_packages_from_undump_buffer (const char *data, size_t len, ChannelAndSubscribedFn channel_callback, CResItemFn package_callback, MatchFn lock_callback, void *data);
+ int extract_packages_from_undump_file (const std::string & filename, ChannelAndSubscribedFn channel_callback, CResItemFn package_callback, MatchFn lock_callback, void *data);
+
+ int extract_packages_from_directory (const std::string & path, ChannelPtr channel, PackmanPtr packman, bool recursive, ResItemFn callback, void *data);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#endif /* __EXTRACT_H__ */
#include <zypp/solver/detail/debug.h>
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-using namespace std;
-
-//---------------------------------------------------------------------------
-// string stuff
-
-/* Like g_strstrip(), only returns NULL on an empty string */
-char *
-strstrip (const char *str)
-{
- const char *start;
- const char *end;
-
- if (str == NULL)
- return "";
-
- start = str;
- while (isblank (*start)) {
- start++;
- }
-
- end = start + strlen (start) - 1;
- while (end > start
- && isblank (*end)) {
- end--;
- }
-
- if (start > end) { // empty string
- return NULL;
- }
-
- if (start > str
- || *(end+1) != 0) { // we stripped at least one blank somewhere
- return strndup (start, end - start + 1);
- }
- return strdup (str); // no blanks stripped
-}
-
-
-//---------------------------------------------------------------------------
-// url and path stuff
-
-char *
-maybe_merge_paths(const char *parent_path, const char *child_path)
-{
- /* Child path is NULL, so we return a dup of the parent path.
- Ex: maybe_merge_paths("/foo", NULL) => "/foo" */
- if (!child_path)
- return strdup(parent_path);
-
- /* Child path is a fully qualified URL, so we return a dup of it.
- Ex: maybe_merge_paths("/foo", "http://www.ximian.com") =>
- "http://www.ximian.com"
-
- OR
-
- Child path is an absolute path, so we just return a dup of it.
- Ex: maybe_merge_paths("/foo", "/bar/baz") => "/bar/baz" */
-
- if (url_is_absolute(child_path) || child_path[0] == '/')
- return strdup(child_path);
-
- /* Child path is a relative path, so we tack child path onto the end of
- parent path.
- Ex: maybe_merge_paths("/foo", "bar/baz") => "/foo/bar/baz" */
-
- char *s = (char *)malloc (strlen (parent_path) + strlen (child_path) + 1 + 1); // +1 for /, +1 for \0
- strcpy (s, parent_path);
-
- if (parent_path[strlen(parent_path) - 1] != '/')
- strcat (s, "/");
-
- strcat (s, child_path);
-
- return s;
-}
-
-
-bool
-url_is_absolute (const char *url)
-{
- if (strncasecmp (url, "http:", 5) == 0 ||
- strncasecmp (url, "https:", 6) == 0 ||
- strncasecmp (url, "ftp:", 4) == 0 ||
- strncasecmp (url, "cd:", 3) == 0 ||
- strncasecmp (url, "dvd:", 4) == 0 ||
- strncasecmp (url, "dir:", 4) == 0 ||
- strncasecmp (url, "file:", 5) == 0)
- {
- return true;
- }
-
- return false;
-}
-
-
-//---------------------------------------------------------------------------
-// compress/uncompress stuff
-
-/*
- * Magic gunzipping goodness
- */
-
-/*
- * Count number of bytes to skip at start of buf
- */
-static int gz_magic[2] = {0x1f, 0x8b};
-/* gzip flag byte */
-#define GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define GZ_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
-#define GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define GZ_COMMENT 0x10 /* bit 4 set: file comment present */
-#define GZ_RESERVED 0xE0 /* bits 5..7: reserved */
-
-static int
-count_gzip_header (const unsigned char *buf, unsigned int input_length)
-{
- int method, flags;
- const unsigned char *s = buf;
- unsigned int left_len = input_length;
-
- if (left_len < 4) return -1;
- if (*s++ != gz_magic[0] || *s++ != gz_magic[1]) {
- return -2;
- }
-
- method = *s++;
- flags = *s++;
- left_len -= 4;
-
- if (method != Z_DEFLATED || (flags & GZ_RESERVED) != 0) {
- /* If it's not deflated, or the reserved isn't 0 */
- return -3;
- }
-
- /* Skip time, xflags, OS code */
- if (left_len < 6) return -4;
- s += 6;
- left_len -= 6;
-
- if (flags & GZ_EXTRA_FIELD) {
- unsigned int len;
- if (left_len < 2) return -5;
- len = (unsigned int)(*s++);
- len += ((unsigned int)(*s++)) << 8;
- if (left_len < len) return -6;
- s += len;
- left_len -= len;
- }
-
- /* Skip filename */
- if (flags & GZ_ORIG_NAME) {
- while (--left_len != 0 && *s++ != '\0') ;
- if (left_len == 0) return -7;
- }
- /* Skip comment */
- if (flags & GZ_COMMENT) {
- while (--left_len != 0 && *s++ != '\0') ;
- if (left_len == 0) return -7;
- }
- /* Skip CRC */
- if (flags & GZ_HEAD_CRC) {
- if (left_len < 2) return -7;
- s += 2;
- left_len -= 2;
- }
-
- return input_length - left_len;
-}
-
-
-int
-gunzip_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
-{
- z_stream zs;
- char *outbuf = NULL;
- ByteArray *ba = NULL;
- int zret;
-
- int gzip_hdr;
-
- if (input_buffer == NULL) return -1;
- if (input_length == 0) return -2;
- if (out_ba == NULL) return -3;
-
- ba = (ByteArray *)malloc (sizeof (ByteArray));
- ba->data = NULL;
- ba->len = 0;
-
- gzip_hdr = count_gzip_header (input_buffer, input_length);
- if (gzip_hdr < 0)
- return -1;
-
- zs.next_in = (unsigned char *) input_buffer + gzip_hdr;
- zs.avail_in = input_length - gzip_hdr;
- zs.zalloc = NULL;
- zs.zfree = NULL;
- zs.opaque = NULL;
-
-#define OUTBUFSIZE 10000
- outbuf = (char *)malloc (OUTBUFSIZE);
- zs.next_out = (Bytef *)outbuf;
- zs.avail_out = OUTBUFSIZE;
-
- /* Negative inflateinit is magic to tell zlib that there is no
- * zlib header */
- inflateInit2 (&zs, -MAX_WBITS);
-
- while (1) {
- zret = inflate (&zs, Z_SYNC_FLUSH);
- if (zret != Z_OK && zret != Z_STREAM_END)
- break;
-
- ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
- memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
- ba->len += (OUTBUFSIZE - zs.avail_out);
-
- zs.next_out = (Bytef *)outbuf;
- zs.avail_out = OUTBUFSIZE;
-
- if (zret == Z_STREAM_END)
- break;
- }
-
- inflateEnd (&zs);
- free ((void *)outbuf);
-
- if (zret != Z_STREAM_END) {
- fprintf (stderr, "libz inflate failed! (%d)", zret);
- free (ba->data);
- free (ba);
- ba = NULL;
- } else {
- zret = 0;
- }
-
- *out_ba = ba;
- return zret;
-}
-
-
-int
-gzip_memory (const char *input_buffer, unsigned int input_length, ByteArray **out_ba)
-{
- z_stream zs;
- char *outbuf = NULL;
- ByteArray *ba = NULL;
- int zret;
-
- if (input_buffer == NULL) return -1;
- if (input_length == 0) return -2;
- if (out_ba == NULL) return -3;
-
- ba = (ByteArray *)malloc (sizeof (ByteArray));
- ba->data = NULL;
- ba->len = 0;
-
- zs.next_in = (unsigned char *) input_buffer;
- zs.avail_in = input_length;
- zs.zalloc = NULL;
- zs.zfree = NULL;
- zs.opaque = NULL;
-
- outbuf = (char *)malloc (OUTBUFSIZE);
- zs.next_out = (Bytef *)outbuf;
- zs.avail_out = OUTBUFSIZE;
-
- deflateInit (&zs, Z_DEFAULT_COMPRESSION);
-
- while (1) {
- if (zs.avail_in)
- zret = deflate (&zs, Z_SYNC_FLUSH);
- else
- zret = deflate (&zs, Z_FINISH);
-
- if (zret != Z_OK && zret != Z_STREAM_END)
- break;
-
- ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
- memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
- ba->len += (OUTBUFSIZE - zs.avail_out);
-
- zs.next_out = (Bytef *)outbuf;
- zs.avail_out = OUTBUFSIZE;
-
- if (zret == Z_STREAM_END)
- break;
- }
-
- deflateEnd (&zs);
- free ((void *)outbuf);
-
- if (zret != Z_STREAM_END) {
- fprintf (stderr, "libz deflate failed! (%d)", zret);
- free (ba->data);
- free (ba);
- ba = NULL;
- } else {
- zret = 0;
- }
-
- *out_ba = ba;
- return zret;
-} /* gzip_memory */
-
-
-bool
-memory_looks_gzipped (const unsigned char *buffer)
-{
- if (buffer == NULL)
- return false;
-
- /* This is from RFC 1952 */
-
- return buffer[0] == gz_magic[0] /* ID1 */
- && buffer[1] == gz_magic[1]; /* ID2 */
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-static char bz2_magic[3] = { 'B', 'Z', 'h' };
-
-int
-bunzip2_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
-{
-#ifndef HAVE_BZ2
-
- fprintf (stderr, "bz2 support not compiled in");
- *out_ba = NULL;
-
- return -1;
-
-#else
-
- bz_stream bzs;
- ByteArray *ba;
- char *outbuf;
- int bzret;
-
- if (input_buffer == NULL) return -1;
- if (input_length == 0) return -2;
- if (out_ba == NULL) return -3;
-
- ba = (ByteArray *)malloc (sizeof (ByteArray));
- ba->data = NULL;
- ba->len = 0;
-
- bzs.next_in = (unsigned char *) input_buffer;
- bzs.avail_in = input_length;
- bzs.bzalloc = NULL;
- bzs.bzfree = NULL;
- bzs.opaque = NULL;
-
- outbuf = (char *)malloc (OUTBUFSIZE);
- bzs.next_out = (Bytef *)outbuf;
- bzs.avail_out = OUTBUFSIZE;
-
- BZ2_bzDecompressInit (&bzs, 1, 0);
-
- while (1) {
- bzret = BZ2_bzDecompress (&bzs);
- if (bzret != BZ_OK && bzret != BZ_STREAM_END)
- break;
-
- ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
- memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
- ba->len += (OUTBUFSIZE - zs.avail_out);
-
- bzs.next_out = (Bytef *)outbuf;
- bzs.avail_out = OUTBUFSIZE;
-
- if (bzret == BZ_STREAM_END)
- break;
-
- if (bzs.avail_in == 0) {
- /* The data is incomplete */
- bzret = -1;
- break;
- }
- }
-
- BZ2_bzDecompressEnd (&bzs);
- free ((void *)outbuf);
-
- if (bzret != BZ_STREAM_END) {
- fprintf (stderr, "libbzip2 decompress failed (%d)", bzret);
- free (ba->data);
- free (ba);
- ba = NULL;
- } else {
- bzret = 0;
- }
-
- *out_ba = ba;
- return bzret;
-#endif
-}
-
-
-int
-bzip2_memory (const char *input_buffer, unsigned int input_length, ByteArray **out_ba)
-{
-#ifndef HAVE_BZ2
-
- fprintf (stderr, "bz2 support not compiled in");
- *out_ba = NULL;
-
- return -1;
-
-#else
-
- bz_stream bzs;
- ByteArray *ba;
- char *outbuf;
- int bzret;
-
- if (input_buffer == NULL) return -1;
- if (input_length == 0) return -2;
- if (out_ba == NULL) return -3;
-
- ba = (ByteArray *)malloc (sizeof (ByteArray));
- ba->data = NULL;
- ba->len = 0;
-
- bzs.next_in = (unsigned char *) input_buffer;
- bzs.avail_in = input_length;
- bzs.bzalloc = NULL;
- bzs.bzfree = NULL;
- bzs.opaque = NULL;
-
- outbuf = (char *)malloc (OUTBUFSIZE);
- bzs.next_out = (Bytef *)outbuf;
- bzs.avail_out = OUTBUFSIZE;
-
- BZ2_bzCompressInit (&bzs, 5, 1, 0);
-
- while (1) {
- if (bzs.avail_in)
- bzret = BZ2_bzCompress (&bzs, BZ_RUN);
- else
- bzret = BZ2_bzCompress (&bzs, BZ_FINISH);
-
- if (bzret != BZ_OK && bzret != BZ_STREAM_END)
- break;
-
- ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
- memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
- ba->len += (OUTBUFSIZE - zs.avail_out);
-
- bzs.next_out = (Bytef *)outbuf;
- bzs.avail_out = OUTBUFSIZE;
-
- if (bzret == BZ_STREAM_END)
- break;
- }
-
- BZ2_bzCompressEnd (&bzs);
- free ((void *)outbuf);
-
- if (bzret != BZ_STREAM_END) {
- fprintf (stderr, "bz2 compress failed! (%d)", bzret);
- free (ba->data);
- free (ba);
- ba = NULL;
- } else {
- bzret = 0;
- }
-
- *out_ba = ba;
- return bzret;
-#endif
-}
-
-
-bool
-memory_looks_bzip2ed (const unsigned char *buffer)
-{
- if (buffer == NULL)
- return false;
-
- return buffer[0] == bz2_magic[0]
- && buffer[1] == bz2_magic[1]
- && buffer[2] == bz2_magic[2];
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-int
-uncompress_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
-{
- if (input_length > 2 && memory_looks_bzip2ed (input_buffer))
- return bunzip2_memory (input_buffer, input_length, out_ba);
- else if (input_length > 3 && memory_looks_gzipped (input_buffer))
- return gunzip_memory (input_buffer, input_length, out_ba);
- else
- return -1;
-}
-
-bool
-memory_looks_compressed (const unsigned char *buffer, size_t size)
-{
-#ifdef HAVE_BZ2
- if (size > 2 && memory_looks_bzip2ed (buffer))
- return true;
-#endif
-
- if (size > 4 && memory_looks_gzipped (buffer))
- return true;
-
- return false;
-}
-
-//---------------------------------------------------------------------------
-// I/O stuff
-
-/*
- * This just allows reading from the buffer for now. It could be extended to
- * do writing if necessary.
- */
-
-Buffer *
-buffer_map_file (const string & filename)
-{
- struct stat s;
- int fd;
- unsigned char *data;
- Buffer *buf = NULL;
-
- if (filename.empty())
- return NULL;
-
- if (stat(filename.c_str(), &s) < 0)
- return NULL;
-
- fd = open(filename.c_str(), O_RDONLY);
-
- if (fd < 0)
- return NULL;
-
- data = (unsigned char *)mmap(NULL, s.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
-
- close (fd);
-
- if (data == MAP_FAILED)
- return NULL;
-
- /* Transparently uncompress */
- if (memory_looks_compressed (data, s.st_size)) {
- ByteArray *byte_array = NULL;
-
- if (uncompress_memory (data, s.st_size, &byte_array)) {
- debug (RC_DEBUG_LEVEL_WARNING, "Uncompression of '%s' failed", filename.c_str());
- } else {
- buf = (Buffer *)malloc(sizeof (Buffer));
- buf->data = byte_array->data;
- buf->size = byte_array->len;
- buf->is_mmapped = false;
- }
-
- munmap (data, s.st_size);
-
- if (byte_array) {
- free (byte_array);
- }
-
- } else {
- buf = (Buffer *)malloc(sizeof (Buffer));
- buf->data = (byte *)data;
- buf->size = s.st_size;
- buf->is_mmapped = true;
- }
-
- return buf;
-} /* buffer_map_file */
-
-void
-buffer_unmap_file (Buffer *buf)
-{
- if (buf == NULL) return;
-
- if (buf->is_mmapped)
- munmap (buf->data, buf->size);
- else
- free (buf->data);
-
- free (buf);
-}
-
-//---------------------------------------------------------------------------
-// XML stuff
-
-xmlDoc *
-parse_xml_from_buffer (const char *input_buffer, size_t input_length)
-{
- xmlDoc *doc = NULL;
-
- if (input_buffer == NULL) return NULL;
-
- if (input_length > 3 && memory_looks_gzipped ((const unsigned char *)input_buffer)) {
- ByteArray *buf;
-
- if (uncompress_memory ((const unsigned char *)input_buffer, input_length, &buf)) {
- return NULL;
- }
- doc = xmlParseMemory ((const char *)(buf->data), buf->len);
- free (buf->data);
- free (buf);
- } else {
- doc = xmlParseMemory (input_buffer, input_length);
- }
-
- return doc;
-}
-
-
-xmlDoc *
-parse_xml_from_file (const string & filename)
-{
- Buffer *buf;
- xmlDoc *doc = NULL;
-
- if (filename.empty()) return NULL;
-
- buf = buffer_map_file (filename);
- if (buf) {
- doc = xmlParseMemory ((const char *)(buf->data), buf->size);
- buffer_unmap_file (buf);
- }
-
- return doc;
-}
-
-
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ using namespace std;
+
+ //---------------------------------------------------------------------------
+ // string stuff
+
+ /* Like g_strstrip(), only returns NULL on an empty string */
+ char *
+ strstrip (const char *str)
+ {
+ const char *start;
+ const char *end;
+
+ if (str == NULL)
+ return "";
+
+ start = str;
+ while (isblank (*start)) {
+ start++;
+ }
+
+ end = start + strlen (start) - 1;
+ while (end > start
+ && isblank (*end)) {
+ end--;
+ }
+
+ if (start > end) { // empty string
+ return NULL;
+ }
+
+ if (start > str
+ || *(end+1) != 0) { // we stripped at least one blank somewhere
+ return strndup (start, end - start + 1);
+ }
+ return strdup (str); // no blanks stripped
+ }
+
+
+ //---------------------------------------------------------------------------
+ // url and path stuff
+
+ char *
+ maybe_merge_paths(const char *parent_path, const char *child_path)
+ {
+ /* Child path is NULL, so we return a dup of the parent path.
+ Ex: maybe_merge_paths("/foo", NULL) => "/foo" */
+ if (!child_path)
+ return strdup(parent_path);
+
+ /* Child path is a fully qualified URL, so we return a dup of it.
+ Ex: maybe_merge_paths("/foo", "http://www.ximian.com") =>
+ "http://www.ximian.com"
+
+ OR
+
+ Child path is an absolute path, so we just return a dup of it.
+ Ex: maybe_merge_paths("/foo", "/bar/baz") => "/bar/baz" */
+
+ if (url_is_absolute(child_path) || child_path[0] == '/')
+ return strdup(child_path);
+
+ /* Child path is a relative path, so we tack child path onto the end of
+ parent path.
+ Ex: maybe_merge_paths("/foo", "bar/baz") => "/foo/bar/baz" */
+
+ char *s = (char *)malloc (strlen (parent_path) + strlen (child_path) + 1 + 1); // +1 for /, +1 for \0
+ strcpy (s, parent_path);
+
+ if (parent_path[strlen(parent_path) - 1] != '/')
+ strcat (s, "/");
+
+ strcat (s, child_path);
+
+ return s;
+ }
+
+
+ bool
+ url_is_absolute (const char *url)
+ {
+ if (strncasecmp (url, "http:", 5) == 0 ||
+ strncasecmp (url, "https:", 6) == 0 ||
+ strncasecmp (url, "ftp:", 4) == 0 ||
+ strncasecmp (url, "cd:", 3) == 0 ||
+ strncasecmp (url, "dvd:", 4) == 0 ||
+ strncasecmp (url, "dir:", 4) == 0 ||
+ strncasecmp (url, "file:", 5) == 0)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ //---------------------------------------------------------------------------
+ // compress/uncompress stuff
+
+ /*
+ * Magic gunzipping goodness
+ */
+
+ /*
+ * Count number of bytes to skip at start of buf
+ */
+ static int gz_magic[2] = {0x1f, 0x8b};
+ /* gzip flag byte */
+ #define GZ_ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+ #define GZ_HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+ #define GZ_EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+ #define GZ_ORIG_NAME 0x08 /* bit 3 set: original file name present */
+ #define GZ_COMMENT 0x10 /* bit 4 set: file comment present */
+ #define GZ_RESERVED 0xE0 /* bits 5..7: reserved */
+
+ static int
+ count_gzip_header (const unsigned char *buf, unsigned int input_length)
+ {
+ int method, flags;
+ const unsigned char *s = buf;
+ unsigned int left_len = input_length;
+
+ if (left_len < 4) return -1;
+ if (*s++ != gz_magic[0] || *s++ != gz_magic[1]) {
+ return -2;
+ }
+
+ method = *s++;
+ flags = *s++;
+ left_len -= 4;
+
+ if (method != Z_DEFLATED || (flags & GZ_RESERVED) != 0) {
+ /* If it's not deflated, or the reserved isn't 0 */
+ return -3;
+ }
+
+ /* Skip time, xflags, OS code */
+ if (left_len < 6) return -4;
+ s += 6;
+ left_len -= 6;
+
+ if (flags & GZ_EXTRA_FIELD) {
+ unsigned int len;
+ if (left_len < 2) return -5;
+ len = (unsigned int)(*s++);
+ len += ((unsigned int)(*s++)) << 8;
+ if (left_len < len) return -6;
+ s += len;
+ left_len -= len;
+ }
+
+ /* Skip filename */
+ if (flags & GZ_ORIG_NAME) {
+ while (--left_len != 0 && *s++ != '\0') ;
+ if (left_len == 0) return -7;
+ }
+ /* Skip comment */
+ if (flags & GZ_COMMENT) {
+ while (--left_len != 0 && *s++ != '\0') ;
+ if (left_len == 0) return -7;
+ }
+ /* Skip CRC */
+ if (flags & GZ_HEAD_CRC) {
+ if (left_len < 2) return -7;
+ s += 2;
+ left_len -= 2;
+ }
+
+ return input_length - left_len;
+ }
+
+
+ int
+ gunzip_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+ {
+ z_stream zs;
+ char *outbuf = NULL;
+ ByteArray *ba = NULL;
+ int zret;
+
+ int gzip_hdr;
+
+ if (input_buffer == NULL) return -1;
+ if (input_length == 0) return -2;
+ if (out_ba == NULL) return -3;
+
+ ba = (ByteArray *)malloc (sizeof (ByteArray));
+ ba->data = NULL;
+ ba->len = 0;
+
+ gzip_hdr = count_gzip_header (input_buffer, input_length);
+ if (gzip_hdr < 0)
+ return -1;
+
+ zs.next_in = (unsigned char *) input_buffer + gzip_hdr;
+ zs.avail_in = input_length - gzip_hdr;
+ zs.zalloc = NULL;
+ zs.zfree = NULL;
+ zs.opaque = NULL;
+
+ #define OUTBUFSIZE 10000
+ outbuf = (char *)malloc (OUTBUFSIZE);
+ zs.next_out = (Bytef *)outbuf;
+ zs.avail_out = OUTBUFSIZE;
+
+ /* Negative inflateinit is magic to tell zlib that there is no
+ * zlib header */
+ inflateInit2 (&zs, -MAX_WBITS);
+
+ while (1) {
+ zret = inflate (&zs, Z_SYNC_FLUSH);
+ if (zret != Z_OK && zret != Z_STREAM_END)
+ break;
+
+ ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+ memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+ ba->len += (OUTBUFSIZE - zs.avail_out);
+
+ zs.next_out = (Bytef *)outbuf;
+ zs.avail_out = OUTBUFSIZE;
+
+ if (zret == Z_STREAM_END)
+ break;
+ }
+
+ inflateEnd (&zs);
+ free ((void *)outbuf);
+
+ if (zret != Z_STREAM_END) {
+ fprintf (stderr, "libz inflate failed! (%d)", zret);
+ free (ba->data);
+ free (ba);
+ ba = NULL;
+ } else {
+ zret = 0;
+ }
+
+ *out_ba = ba;
+ return zret;
+ }
+
+
+ int
+ gzip_memory (const char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+ {
+ z_stream zs;
+ char *outbuf = NULL;
+ ByteArray *ba = NULL;
+ int zret;
+
+ if (input_buffer == NULL) return -1;
+ if (input_length == 0) return -2;
+ if (out_ba == NULL) return -3;
+
+ ba = (ByteArray *)malloc (sizeof (ByteArray));
+ ba->data = NULL;
+ ba->len = 0;
+
+ zs.next_in = (unsigned char *) input_buffer;
+ zs.avail_in = input_length;
+ zs.zalloc = NULL;
+ zs.zfree = NULL;
+ zs.opaque = NULL;
+
+ outbuf = (char *)malloc (OUTBUFSIZE);
+ zs.next_out = (Bytef *)outbuf;
+ zs.avail_out = OUTBUFSIZE;
+
+ deflateInit (&zs, Z_DEFAULT_COMPRESSION);
+
+ while (1) {
+ if (zs.avail_in)
+ zret = deflate (&zs, Z_SYNC_FLUSH);
+ else
+ zret = deflate (&zs, Z_FINISH);
+
+ if (zret != Z_OK && zret != Z_STREAM_END)
+ break;
+
+ ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+ memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+ ba->len += (OUTBUFSIZE - zs.avail_out);
+
+ zs.next_out = (Bytef *)outbuf;
+ zs.avail_out = OUTBUFSIZE;
+
+ if (zret == Z_STREAM_END)
+ break;
+ }
+
+ deflateEnd (&zs);
+ free ((void *)outbuf);
+
+ if (zret != Z_STREAM_END) {
+ fprintf (stderr, "libz deflate failed! (%d)", zret);
+ free (ba->data);
+ free (ba);
+ ba = NULL;
+ } else {
+ zret = 0;
+ }
+
+ *out_ba = ba;
+ return zret;
+ } /* gzip_memory */
+
+
+ bool
+ memory_looks_gzipped (const unsigned char *buffer)
+ {
+ if (buffer == NULL)
+ return false;
+
+ /* This is from RFC 1952 */
+
+ return buffer[0] == gz_magic[0] /* ID1 */
+ && buffer[1] == gz_magic[1]; /* ID2 */
+ }
+
+ /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+ static char bz2_magic[3] = { 'B', 'Z', 'h' };
+
+ int
+ bunzip2_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+ {
+ #ifndef HAVE_BZ2
+
+ fprintf (stderr, "bz2 support not compiled in");
+ *out_ba = NULL;
+
+ return -1;
+
+ #else
+
+ bz_stream bzs;
+ ByteArray *ba;
+ char *outbuf;
+ int bzret;
+
+ if (input_buffer == NULL) return -1;
+ if (input_length == 0) return -2;
+ if (out_ba == NULL) return -3;
+
+ ba = (ByteArray *)malloc (sizeof (ByteArray));
+ ba->data = NULL;
+ ba->len = 0;
+
+ bzs.next_in = (unsigned char *) input_buffer;
+ bzs.avail_in = input_length;
+ bzs.bzalloc = NULL;
+ bzs.bzfree = NULL;
+ bzs.opaque = NULL;
+
+ outbuf = (char *)malloc (OUTBUFSIZE);
+ bzs.next_out = (Bytef *)outbuf;
+ bzs.avail_out = OUTBUFSIZE;
+
+ BZ2_bzDecompressInit (&bzs, 1, 0);
+
+ while (1) {
+ bzret = BZ2_bzDecompress (&bzs);
+ if (bzret != BZ_OK && bzret != BZ_STREAM_END)
+ break;
+
+ ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+ memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+ ba->len += (OUTBUFSIZE - zs.avail_out);
+
+ bzs.next_out = (Bytef *)outbuf;
+ bzs.avail_out = OUTBUFSIZE;
+
+ if (bzret == BZ_STREAM_END)
+ break;
+
+ if (bzs.avail_in == 0) {
+ /* The data is incomplete */
+ bzret = -1;
+ break;
+ }
+ }
+
+ BZ2_bzDecompressEnd (&bzs);
+ free ((void *)outbuf);
+
+ if (bzret != BZ_STREAM_END) {
+ fprintf (stderr, "libbzip2 decompress failed (%d)", bzret);
+ free (ba->data);
+ free (ba);
+ ba = NULL;
+ } else {
+ bzret = 0;
+ }
+
+ *out_ba = ba;
+ return bzret;
+ #endif
+ }
+
+
+ int
+ bzip2_memory (const char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+ {
+ #ifndef HAVE_BZ2
+
+ fprintf (stderr, "bz2 support not compiled in");
+ *out_ba = NULL;
+
+ return -1;
+
+ #else
+
+ bz_stream bzs;
+ ByteArray *ba;
+ char *outbuf;
+ int bzret;
+
+ if (input_buffer == NULL) return -1;
+ if (input_length == 0) return -2;
+ if (out_ba == NULL) return -3;
+
+ ba = (ByteArray *)malloc (sizeof (ByteArray));
+ ba->data = NULL;
+ ba->len = 0;
+
+ bzs.next_in = (unsigned char *) input_buffer;
+ bzs.avail_in = input_length;
+ bzs.bzalloc = NULL;
+ bzs.bzfree = NULL;
+ bzs.opaque = NULL;
+
+ outbuf = (char *)malloc (OUTBUFSIZE);
+ bzs.next_out = (Bytef *)outbuf;
+ bzs.avail_out = OUTBUFSIZE;
+
+ BZ2_bzCompressInit (&bzs, 5, 1, 0);
+
+ while (1) {
+ if (bzs.avail_in)
+ bzret = BZ2_bzCompress (&bzs, BZ_RUN);
+ else
+ bzret = BZ2_bzCompress (&bzs, BZ_FINISH);
+
+ if (bzret != BZ_OK && bzret != BZ_STREAM_END)
+ break;
+
+ ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+ memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+ ba->len += (OUTBUFSIZE - zs.avail_out);
+
+ bzs.next_out = (Bytef *)outbuf;
+ bzs.avail_out = OUTBUFSIZE;
+
+ if (bzret == BZ_STREAM_END)
+ break;
+ }
+
+ BZ2_bzCompressEnd (&bzs);
+ free ((void *)outbuf);
+
+ if (bzret != BZ_STREAM_END) {
+ fprintf (stderr, "bz2 compress failed! (%d)", bzret);
+ free (ba->data);
+ free (ba);
+ ba = NULL;
+ } else {
+ bzret = 0;
+ }
+
+ *out_ba = ba;
+ return bzret;
+ #endif
+ }
+
+
+ bool
+ memory_looks_bzip2ed (const unsigned char *buffer)
+ {
+ if (buffer == NULL)
+ return false;
+
+ return buffer[0] == bz2_magic[0]
+ && buffer[1] == bz2_magic[1]
+ && buffer[2] == bz2_magic[2];
+ }
+
+ /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+ int
+ uncompress_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+ {
+ if (input_length > 2 && memory_looks_bzip2ed (input_buffer))
+ return bunzip2_memory (input_buffer, input_length, out_ba);
+ else if (input_length > 3 && memory_looks_gzipped (input_buffer))
+ return gunzip_memory (input_buffer, input_length, out_ba);
+ else
+ return -1;
+ }
+
+ bool
+ memory_looks_compressed (const unsigned char *buffer, size_t size)
+ {
+ #ifdef HAVE_BZ2
+ if (size > 2 && memory_looks_bzip2ed (buffer))
+ return true;
+ #endif
+
+ if (size > 4 && memory_looks_gzipped (buffer))
+ return true;
+
+ return false;
+ }
+
+ //---------------------------------------------------------------------------
+ // I/O stuff
+
+ /*
+ * This just allows reading from the buffer for now. It could be extended to
+ * do writing if necessary.
+ */
+
+ Buffer *
+ buffer_map_file (const string & filename)
+ {
+ struct stat s;
+ int fd;
+ unsigned char *data;
+ Buffer *buf = NULL;
+
+ if (filename.empty())
+ return NULL;
+
+ if (stat(filename.c_str(), &s) < 0)
+ return NULL;
+
+ fd = open(filename.c_str(), O_RDONLY);
+
+ if (fd < 0)
+ return NULL;
+
+ data = (unsigned char *)mmap(NULL, s.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+
+ close (fd);
+
+ if (data == MAP_FAILED)
+ return NULL;
+
+ /* Transparently uncompress */
+ if (memory_looks_compressed (data, s.st_size)) {
+ ByteArray *byte_array = NULL;
+
+ if (uncompress_memory (data, s.st_size, &byte_array)) {
+ debug (RC_DEBUG_LEVEL_WARNING, "Uncompression of '%s' failed", filename.c_str());
+ } else {
+ buf = (Buffer *)malloc(sizeof (Buffer));
+ buf->data = byte_array->data;
+ buf->size = byte_array->len;
+ buf->is_mmapped = false;
+ }
+
+ munmap (data, s.st_size);
+
+ if (byte_array) {
+ free (byte_array);
+ }
+
+ } else {
+ buf = (Buffer *)malloc(sizeof (Buffer));
+ buf->data = (byte *)data;
+ buf->size = s.st_size;
+ buf->is_mmapped = true;
+ }
+
+ return buf;
+ } /* buffer_map_file */
+
+ void
+ buffer_unmap_file (Buffer *buf)
+ {
+ if (buf == NULL) return;
+
+ if (buf->is_mmapped)
+ munmap (buf->data, buf->size);
+ else
+ free (buf->data);
+
+ free (buf);
+ }
+
+ //---------------------------------------------------------------------------
+ // XML stuff
+
+ xmlDoc *
+ parse_xml_from_buffer (const char *input_buffer, size_t input_length)
+ {
+ xmlDoc *doc = NULL;
+
+ if (input_buffer == NULL) return NULL;
+
+ if (input_length > 3 && memory_looks_gzipped ((const unsigned char *)input_buffer)) {
+ ByteArray *buf;
+
+ if (uncompress_memory ((const unsigned char *)input_buffer, input_length, &buf)) {
+ return NULL;
+ }
+ doc = xmlParseMemory ((const char *)(buf->data), buf->len);
+ free (buf->data);
+ free (buf);
+ } else {
+ doc = xmlParseMemory (input_buffer, input_length);
+ }
+
+ return doc;
+ }
+
+
+ xmlDoc *
+ parse_xml_from_file (const string & filename)
+ {
+ Buffer *buf;
+ xmlDoc *doc = NULL;
+
+ if (filename.empty()) return NULL;
+
+ buf = buffer_map_file (filename);
+ if (buf) {
+ doc = xmlParseMemory ((const char *)(buf->data), buf->size);
+ buffer_unmap_file (buf);
+ }
+
+ return doc;
+ }
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
#include <string>
#include <libxml/parser.h>
#include <libxml/tree.h>
-
-///////////////////////////////////////////////////////////////////
-namespace zypp {
-//////////////////////////////////////////////////////////////////
-
-typedef unsigned char byte;
-
-char *strstrip (const char *str);
-char *maybe_merge_paths(const char *parent_path, const char *child_path);
-bool url_is_absolute (const char *url);
-
-
-typedef struct {
- byte *data;
- size_t len;
-} ByteArray;
-
-// An easy way to map files. If we map a compressed file,
-// it will be magically uncompressed for us.
-
-typedef struct {
- byte *data;
- size_t size;
- bool is_mmapped;
-} Buffer;
-
-Buffer *buffer_map_file (const std::string & filename);
-void buffer_unmap_file (Buffer *buffer);
-
-
-xmlDoc *parse_xml_from_buffer (const char *input_buffer, size_t input_length);
-xmlDoc *parse_xml_from_file (const std::string & filename);
-
-///////////////////////////////////////////////////////////////////
-}; // namespace zypp
-///////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ typedef unsigned char byte;
+
+ char *strstrip (const char *str);
+ char *maybe_merge_paths(const char *parent_path, const char *child_path);
+ bool url_is_absolute (const char *url);
+
+
+ typedef struct {
+ byte *data;
+ size_t len;
+ } ByteArray;
+
+ // An easy way to map files. If we map a compressed file,
+ // it will be magically uncompressed for us.
+
+ typedef struct {
+ byte *data;
+ size_t size;
+ bool is_mmapped;
+ } Buffer;
+
+ Buffer *buffer_map_file (const std::string & filename);
+ void buffer_unmap_file (Buffer *buffer);
+
+
+ xmlDoc *parse_xml_from_buffer (const char *input_buffer, size_t input_length);
+ xmlDoc *parse_xml_from_file (const std::string & filename);
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
using namespace std;
-using namespace zypp;
+using namespace zypp::solver::detail;
static MultiWorldPtr world = NULL;
#include <zypp/solver/detail/Edition.h>
using namespace std;
-using namespace zypp;
+using namespace zypp::solver::detail;
//---------------------------------------------------------------------------
#include <zypp/solver/detail/Spec.h>
using namespace std;
-using namespace zypp;
+using namespace zypp::solver::detail;
bool
emptySpec (void)
#include <string.h>
#include <zypp/solver/detail/utils.h>
-using namespace zypp;
+using namespace zypp::solver::detail;
int
main (int argc, char *argv[])