#ifndef ZYPP_RESSTATUS_H
#define ZYPP_RESSTATUS_H
+#include <inttypes.h>
#include <iosfwd>
-
#include "zypp/Bit.h"
-#include "zypp/base/Logger.h"
///////////////////////////////////////////////////////////////////
namespace zypp
{ /////////////////////////////////////////////////////////////////
+ namespace resstatus
+ {
+ class UserLockQueryManip;
+ class StatusBackup;
+ }
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : ResStatus
/** Status bitfield.
*
* \li \c StateField Whether the resolvable is or uninstalled (available).
- * \li \c EstablishField Established status computed by the solver as
- * unneeded (have freshens but none of them trigger)
- * satisfied (no freshen or at least one triggered freshen and
- * all requires fulfilled)
- * or incomplete (no freshen or at least one triggered freshen and
- * NOT all requires fulfilled)
- * \li \c TransactField Wheter to transact this resolvable
+ * \li \c ValidateField Validate status computed by the solver as
+ * nonrelevant: it is unimportant for the user
+ * satisfied: it important nothing has to be done
+ * broken: it is incomplete. So e.g. an update is needed
+ * \li \c TransactField Whether to transact this resolvable
* (delete if installed install if uninstalled).
* In case the resolvable is locked, only USER may modify the
* transact bit.
* \li \c TransactDetailField Reason why the Resolvable transacts.
* Splitted into \c InstallDetailValue and \c RemoveDetailValue
* dependent on the kind of transaction.
+ * \li \c WeakField The solvable will be recommended/suggested by
+ * a to be installed/deleted solvable.
*
*/
class ResStatus
typedef uint16_t FieldType;
typedef bit::BitField<FieldType> BitFieldType;
// Bit Ranges within FieldType defined by 1st bit and size:
- typedef bit::Range<FieldType,0, 1> StateField;
- typedef bit::Range<FieldType,StateField::end, 2> EstablishField;
- typedef bit::Range<FieldType,EstablishField::end, 2> TransactField;
- typedef bit::Range<FieldType,TransactField::end, 2> TransactByField;
- typedef bit::Range<FieldType,TransactByField::end, 3> TransactDetailField;
- typedef bit::Range<FieldType,TransactDetailField::end, 2> SolverStateField;
- typedef bit::Range<FieldType,SolverStateField::end, 1> LicenceConfirmedField;
+ typedef bit::Range<FieldType,0, 1> StateField;
+ typedef bit::Range<FieldType,StateField::end, 2> ValidateField;
+ typedef bit::Range<FieldType,ValidateField::end, 2> TransactField;
+ typedef bit::Range<FieldType,TransactField::end, 2> TransactByField;
+ typedef bit::Range<FieldType,TransactByField::end, 2> TransactDetailField;
+ typedef bit::Range<FieldType,TransactDetailField::end, 1> LicenceConfirmedField;
+ typedef bit::Range<FieldType,LicenceConfirmedField::end, 4> WeakField;
+ typedef bit::Range<FieldType,WeakField::end, 1> UserLockQueryField; // internal
// enlarge FieldType if more bit's needed. It's not yet
// checked by the compiler.
//@}
UNINSTALLED = bit::RangeValue<StateField,0>::value,
INSTALLED = bit::RangeValue<StateField,1>::value
};
- enum EstablishValue
+ enum ValidateValue
{
- UNDETERMINED = bit::RangeValue<EstablishField,0>::value,
- UNNEEDED = bit::RangeValue<EstablishField,1>::value, // has freshens, none trigger
- SATISFIED = bit::RangeValue<EstablishField,2>::value, // has none or triggered freshens, all requirements fulfilled
- INCOMPLETE = bit::RangeValue<EstablishField,3>::value // installed: has none or triggered freshens, requirements unfulfilled
+ UNDETERMINED = bit::RangeValue<ValidateField,0>::value,
+ BROKEN = bit::RangeValue<ValidateField,1>::value,
+ SATISFIED = bit::RangeValue<ValidateField,2>::value,
+ NONRELEVANT = bit::RangeValue<ValidateField,3>::value
};
enum TransactValue
{
/** Detail for no transact, i.e. reset any Install/RemoveDetailValue. */
NO_DETAIL = bit::RangeValue<TransactDetailField,0>::value,
};
-
enum InstallDetailValue
{
EXPLICIT_INSTALL = bit::RangeValue<TransactDetailField,0>::value,
EXPLICIT_REMOVE = bit::RangeValue<TransactDetailField,0>::value,
SOFT_REMOVE = bit::RangeValue<TransactDetailField,1>::value,
DUE_TO_OBSOLETE = bit::RangeValue<TransactDetailField,2>::value,
- DUE_TO_UNLINK = bit::RangeValue<TransactDetailField,3>::value,
- DUE_TO_UPGRADE = bit::RangeValue<TransactDetailField,4>::value
- };
- enum SolverStateValue
- {
- NORMAL = bit::RangeValue<SolverStateField,0>::value, // default, notthing special
- SEEN = bit::RangeValue<SolverStateField,1>::value, // already seen during ResolverUpgrade
- IMPOSSIBLE = bit::RangeValue<SolverStateField,2>::value // impossible to install
+ DUE_TO_UPGRADE = bit::RangeValue<TransactDetailField,3>::value
};
enum LicenceConfirmedValue
LICENCE_UNCONFIRMED = bit::RangeValue<LicenceConfirmedField,0>::value,
LICENCE_CONFIRMED = bit::RangeValue<LicenceConfirmedField,1>::value
};
+
+ enum WeakValue // Unlike the other fields those are BITS that may be or'ed!
+ {
+ NO_WEAK = bit::RangeValue<WeakField,0>::value,
+ SUGGESTED = bit::RangeValue<WeakField,1<<0>::value,
+ RECOMMENDED = bit::RangeValue<WeakField,1<<1>::value,
+ ORPHANED = bit::RangeValue<WeakField,1<<2>::value,
+ UNNEEDED = bit::RangeValue<WeakField,1<<3>::value
+ };
+
+ enum UserLockQuery // internal
+ {
+ USERLOCK_NOMATCH = bit::RangeValue<UserLockQueryField,0>::value,
+ USERLOCK_MATCH = bit::RangeValue<UserLockQueryField,1>::value
+ };
//@}
public:
{ fieldValueAssign<LicenceConfirmedField>( toVal_r ? LICENCE_CONFIRMED : LICENCE_UNCONFIRMED ); }
public:
+ bool isRecommended() const
+ { return _bitfield.test( RECOMMENDED ); }
+
+ bool isSuggested() const
+ { return _bitfield.test( SUGGESTED ); }
+
+ bool isOrphaned() const
+ { return _bitfield.test( ORPHANED ); }
+
+ bool isUnneeded() const
+ { return _bitfield.test( UNNEEDED ); }
+
+ bool hasWeak() const
+ { return ! fieldValueIs<WeakField>( NO_WEAK ); }
+
+ void resetWeak()
+ { return fieldValueAssign<WeakField>( NO_WEAK ); }
+
+ void setRecommended( bool toVal_r = true )
+ { _bitfield.set( RECOMMENDED, toVal_r ); }
+
+ void setSuggested( bool toVal_r = true )
+ { _bitfield.set( SUGGESTED, toVal_r ); }
+
+ void setOrphaned( bool toVal_r = true )
+ { _bitfield.set( ORPHANED, toVal_r ); }
+
+ void setUnneeded( bool toVal_r = true )
+ { _bitfield.set( UNNEEDED, toVal_r ); }
+
+ public:
+ ValidateValue validate() const
+ { return (ValidateValue)_bitfield.value<ValidateField>(); }
+
+ bool isUndetermined() const
+ { return fieldValueIs<ValidateField>( UNDETERMINED ); }
+
+ bool isSatisfied() const
+ { return fieldValueIs<ValidateField>( SATISFIED ); }
+
+ bool isBroken() const
+ { return fieldValueIs<ValidateField>( BROKEN ); }
+
+ bool isNonRelevant() const
+ { return fieldValueIs<ValidateField>( NONRELEVANT ); }
+
+ public:
// These two are IMMUTABLE!
bool isInstalled() const
bool isToBeUninstalled() const
{ return isInstalled() && transacts(); }
- bool isUndetermined() const
- { return fieldValueIs<EstablishField>( UNDETERMINED ); }
-
- bool isEstablishedUneeded() const
- { return fieldValueIs<EstablishField>( UNNEEDED ); }
-
- bool isEstablishedSatisfied() const
- { return fieldValueIs<EstablishField>( SATISFIED ); }
-
- bool isEstablishedIncomplete() const
- { return fieldValueIs<EstablishField>( INCOMPLETE ); }
-
- bool isUnneeded() const
- { return isUninstalled() && fieldValueIs<EstablishField>( UNNEEDED ); }
-
- bool isSatisfied() const
- { return isUninstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
-
- bool isComplete () const
- { return isInstalled() && fieldValueIs<EstablishField>( SATISFIED ); }
+ bool isLocked() const
+ { return fieldValueIs<TransactField>( LOCKED ); }
- bool isIncomplete() const
- { return isInstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
+ bool isUserLocked() const
+ { return isLocked() && isByUser(); }
- bool isNeeded() const
- { return isUninstalled() && fieldValueIs<EstablishField>( INCOMPLETE ); }
+ bool isSoftLocked() const
+ { return isKept() && ( isByApplLow() || isByUser() ); }
- bool isLocked() const
- { return fieldValueIs<TransactField>( LOCKED ); }
+ bool isKept() const
+ { return fieldValueIs<TransactField>( KEEP_STATE ); }
bool transacts() const
{ return fieldValueIs<TransactField>( TRANSACT ); }
TransactValue getTransactValue() const
{ return (TransactValue)_bitfield.value<TransactField>(); }
+ /** True if would be on system after commit. */
+ bool onSystem() const
+ { return( isInstalled() != transacts() ); }
+
+ /** True if would be off system after commit. */
+ bool offSystem() const
+ { return ! onSystem(); }
+
bool isBySolver() const
{ return fieldValueIs<TransactByField>( SOLVER ); }
TransactByValue getTransactByValue() const
{ return (TransactByValue)_bitfield.value<TransactByField>(); }
+ bool setTransactByValue(TransactByValue causer)
+ {
+ if ( isLessThan<TransactByField>( causer ) ) {
+ fieldValueAssign<TransactByField>( causer );
+ return true;
+ } else {
+ return false;
+ }
+ }
+
bool isToBeUninstalledDueToObsolete () const
{ return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_OBSOLETE ); }
- bool isToBeUninstalledDueToUnlink() const
- { return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UNLINK ); }
-
bool isToBeUninstalledDueToUpgrade() const
{ return isToBeUninstalled() && fieldValueIs<TransactDetailField>( DUE_TO_UPGRADE ); }
bool isToBeInstalledSoft () const
{ return isToBeInstalled() && fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
+ bool isToBeInstalledNotSoft () const
+ { return isToBeInstalled() && !fieldValueIs<TransactDetailField>( SOFT_INSTALL ); }
+
bool isToBeUninstalledSoft () const
{ return isToBeUninstalled() && fieldValueIs<TransactDetailField>( SOFT_REMOVE ); }
+ private:
+
+ /** \name Internal hard lock maintainance */
+ //@{
+ friend class resstatus::UserLockQueryManip;
+
+ bool isUserLockQueryMatch() const
+ { return fieldValueIs<UserLockQueryField>( USERLOCK_MATCH ); }
+
+ void setUserLockQueryMatch( bool match_r )
+ { fieldValueAssign<UserLockQueryField>( match_r ? USERLOCK_MATCH : USERLOCK_NOMATCH ); }
+ //@}
+
public:
//------------------------------------------------------------------------
}
/** Apply a lock (prevent transaction).
- * Currently by USER only, but who knows... Set LOCKED
- * from KEEP_STATE to be shure all taransaction details
- * were reset properly.
+ * Currently by USER or APPL_HIGH only, but who knows...
+ * Set LOCKED from KEEP_STATE to be shure all transaction
+ * details were reset properly.
*/
bool setLock( bool toLock_r, TransactByValue causer_r )
{
return true;
}
// Here: Lock status is to be changed:
- if ( causer_r != USER )
+ if ( causer_r != USER && causer_r != APPL_HIGH )
return false;
- // Setting no transact removes an existing lock,
- // or brings this into KEEP_STATE, and we apply the lock.
- if ( ! setTransact( false, causer_r ) )
- return false;
- if ( toLock_r )
- fieldValueAssign<TransactField>( LOCKED );
- else
- fieldValueAssign<TransactField>( KEEP_STATE );
+ if ( toLock_r ) {
+ // We're in unlocked state, which includes TRANSACT.
+ // Causer must be allowed to reset this. But from
+ // KEEP_STATE every causer is allowed to set the lock.
+ if ( ! setTransact( false, causer_r ) )
+ return false;
+ fieldValueAssign<TransactField>( LOCKED );
+ fieldValueAssign<TransactByField>( causer_r );
+ } else {
+ // To leave Locked state it needs a superior causer.
+ if ( isGreaterThan<TransactByField>( causer_r ) )
+ return false;
+ fieldValueAssign<TransactField>( KEEP_STATE );
+ fieldValueAssign<TransactByField>( SOLVER ); // reset to lowest causer
+ // in order to distinguish from keep_state_by_user
+ }
return true;
}
// we're already in the desired state, but in case of
// TRANSACT, remember a superior causer.
if ( transacts() && isLessThan<TransactByField>( causer_r ) )
- {
fieldValueAssign<TransactByField>( causer_r );
- // ??? adapt TransactDetailField ?
- }
+
+ fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
return true;
}
// Here: transact status is to be changed:
if ( ! fieldValueIs<TransactField>( KEEP_STATE )
- && isGreaterThan<TransactByField>( causer_r ) )
+ && isGreaterThan<TransactByField>( causer_r ) ) {
return false;
+ }
if ( toTansact_r )
- {
+ {
fieldValueAssign<TransactField>( TRANSACT );
- // ??? adapt TransactDetailField ?
- }
+ }
else
- {
+ {
fieldValueAssign<TransactField>( KEEP_STATE );
- fieldValueAssign<TransactDetailField>( NO_DETAIL );
- }
+ }
+ fieldValueAssign<TransactDetailField>( NO_DETAIL ); // Details has to be set again
fieldValueAssign<TransactByField>( causer_r );
return true;
}
return ret;
}
+ /** */
+ bool setSoftLock( TransactByValue causer_r )
+ {
+ if ( ! setTransact( false, causer_r ) )
+ return false;
+ if ( fieldValueIs<TransactField>( KEEP_STATE )
+ && isLessThan<TransactByField>( causer_r ) )
+ fieldValueAssign<TransactByField>( causer_r );
+ return true;
+ }
+
/** Not the same as setTransact( false ).
*/
bool resetTransact( TransactByValue causer_r )
return false;
if ( fieldValueIs<TransactField>( KEEP_STATE ) )
fieldValueAssign<TransactByField>( SOLVER );
+ return true;
}
/** Soft toggle between TRANSACT and KEEP_STATE.
//------------------------------------------------------------------------
// *** These are only for the Resolver ***
- bool setToBeUninstalledDueToUnlink ( )
- {
- if (!setToBeUninstalled (SOLVER)) return false;
- fieldValueAssign<TransactDetailField>(DUE_TO_UNLINK);
- return true;
- }
-
bool setToBeUninstalledDueToObsolete ( )
{
if (!setToBeUninstalled (SOLVER)) return false;
bool setToBeInstalledSoft ( )
{
- if (!setToBeInstalled(SOLVER)) return false;
+ if (isInstalled()
+ || !setSoftTransact (true, SOLVER))
+ return false;
+
fieldValueAssign<TransactDetailField>(SOFT_INSTALL);
return true;
}
bool setToBeUninstalledSoft ( )
{
- if (!setToBeUninstalled(SOLVER)) return false;
+ if (!isInstalled()
+ || !setSoftTransact (true, SOLVER))
+ return false;
+
fieldValueAssign<TransactDetailField>(SOFT_REMOVE);
return true;
}
+ bool maySetToBeUninstalledSoft ()
+ {
+ bit::BitField<FieldType> savBitfield = _bitfield;
+ bool ret = setToBeUninstalledSoft ();
+ _bitfield = savBitfield;
+ return ret;
+ }
+
bool isSoftInstall () {
return fieldValueIs<TransactDetailField> (SOFT_INSTALL);
}
bool setUndetermined ()
{
- fieldValueAssign<EstablishField>(UNDETERMINED);
- return true;
- }
-
- bool setUnneeded ()
- {
- fieldValueAssign<EstablishField>(UNNEEDED);
+ fieldValueAssign<ValidateField>(UNDETERMINED);
return true;
}
bool setSatisfied ()
{
- fieldValueAssign<EstablishField>(SATISFIED);
- return true;
- }
-
- bool setIncomplete ()
- {
- fieldValueAssign<EstablishField>(INCOMPLETE);
+ fieldValueAssign<ValidateField>(SATISFIED);
return true;
}
- bool isSeen () const
- { return fieldValueIs<SolverStateField>( SEEN ); }
-
- bool isImpossible () const
- { return fieldValueIs<SolverStateField>( IMPOSSIBLE ); }
-
- bool setSeen (bool value)
+ bool setBroken ()
{
- fieldValueAssign<SolverStateField>( value ? SEEN : NORMAL );
+ fieldValueAssign<ValidateField>(BROKEN);
return true;
}
- bool setImpossible (bool value)
+ bool setNonRelevant ()
{
- fieldValueAssign<SolverStateField>( value ? IMPOSSIBLE : NORMAL );
+ fieldValueAssign<ValidateField>(NONRELEVANT);
return true;
}
/** \name Builtin ResStatus constants. */
//@{
static const ResStatus toBeInstalled;
- static const ResStatus toBeInstalledSoft;
static const ResStatus toBeUninstalled;
- static const ResStatus toBeUninstalledSoft;
- static const ResStatus toBeUninstalledDueToUnlink;
- static const ResStatus toBeUninstalledDueToObsolete;
static const ResStatus toBeUninstalledDueToUpgrade;
- static const ResStatus installed; // installed, status after successful target 'install' commit
- static const ResStatus uninstalled; // uninstalled, status after successful target 'uninstall' commit
- static const ResStatus satisfied; // uninstalled, satisfied
- static const ResStatus complete; // installed, satisfied
- static const ResStatus unneeded; // uninstalled, unneeded
- static const ResStatus needed; // uninstalled, incomplete
- static const ResStatus incomplete; // installed, incomplete
- static const ResStatus impossible; // uninstallable
+ static const ResStatus toBeUninstalledDueToObsolete;
//@}
private:
/** Ctor for intialization of builtin constants. */
ResStatus( StateValue s,
- EstablishValue e = UNDETERMINED,
+ ValidateValue v = UNDETERMINED,
TransactValue t = KEEP_STATE,
InstallDetailValue i = EXPLICIT_INSTALL,
- RemoveDetailValue r = EXPLICIT_REMOVE,
- SolverStateValue ssv = NORMAL );
+ RemoveDetailValue r = EXPLICIT_REMOVE );
/** Return whether the corresponding Field has value \a val_r.
*/
- template<class _Field>
+ template<class TField>
bool fieldValueIs( FieldType val_r ) const
- { return _bitfield.isEqual<_Field>( val_r ); }
+ { return _bitfield.isEqual<TField>( val_r ); }
/** Set the corresponding Field to value \a val_r.
*/
- template<class _Field>
+ template<class TField>
void fieldValueAssign( FieldType val_r )
- { _bitfield.assign<_Field>( val_r ); }
+ { _bitfield.assign<TField>( val_r ); }
/** compare two values.
*/
- template<class _Field>
+ template<class TField>
bool isGreaterThan( FieldType val_r )
- { return _bitfield.value<_Field>() > val_r; }
+ { return _bitfield.value<TField>() > val_r; }
- template<class _Field>
+ template<class TField>
bool isLessThan( FieldType val_r )
- { return _bitfield.value<_Field>() < val_r; }
+ { return _bitfield.value<TField>() < val_r; }
private:
+ friend class resstatus::StatusBackup;
BitFieldType _bitfield;
};
///////////////////////////////////////////////////////////////////
/** \relates ResStatus Stream output */
std::ostream & operator<<( std::ostream & str, const ResStatus & obj );
+ /** \relates ResStatus Stream output */
+ std::ostream & operator<<( std::ostream & str, ResStatus::TransactValue obj );
+
+ /** \relates ResStatus Stream output */
+ std::ostream & operator<<( std::ostream & str, ResStatus::TransactByValue obj );
+
/** \relates ResStatus */
inline bool operator==( const ResStatus & lhs, const ResStatus & rhs )
{ return lhs._bitfield == rhs._bitfield; }
inline bool operator!=( const ResStatus & lhs, const ResStatus & rhs )
{ return ! (lhs == rhs); }
- /////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////
+
+ namespace resstatus
+ {
+ class StatusBackup
+ {
+ public:
+ StatusBackup()
+ : _status( 0 )
+ {}
+
+ StatusBackup( ResStatus & status_r )
+ : _status( &status_r )
+ , _bitfield( _status->_bitfield )
+ {}
+
+ void replay()
+ { if ( _status ) _status->_bitfield = _bitfield; }
+
+ private:
+ ResStatus * _status;
+ ResStatus::BitFieldType _bitfield;
+ };
+ }
+
+ /////////////////////////////////////////////////////////////////
} // namespace zypp
///////////////////////////////////////////////////////////////////
#endif // ZYPP_RESSTATUS_H