/* * Copyright (C) 2006 Matthias Langer * * This file is part of Gatt - a Gentoo tool for arch testers. * * Gatt is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef H_GATT_USE_FLAG #define H_GATT_USE_FLAG #include "src/package.h" #include namespace Gatt { /** This class represents an USE flag. * @note * This class should only be used when it makes sense to activate/deactivate the flag, or * more detailed information about the USE flag is needed. Otherwise, a plain std::string * may be better suited.*/ class UseFlag : boost::equality_comparable { public: /** Constructs a new UseFlag. * @param[in] name * the name of the USE flag. * @param[in] active * wether the flag should be activated or deactivated. * @throw Gatt::InvalidUseFlag * if the USE flag does not exist.*/ UseFlag(const std::string& name, bool active); /** Constructs a UseFlag from a string like "-gtk". * @throw Gatt::InvalidUseFlag * if the USE flag doesn't exist.*/ explicit UseFlag(const std::string& str); /** Returns the name of the USE flag like "gtk".*/ const std::string& getName() const { return _name; } /** Converts the object to a string, like "-gtk".*/ const std::string toString() const { return _active ? _name : ("-" + _name); } /** Activates/deactivates the USE flag.*/ void activate(bool setting) { _active = setting; } /** Returns true if an only if the USE flag is active.*/ bool isActive() const { return _active; } /** Returns true for global USE flags, false otherwise.*/ bool isGlobal() const { return _global; } /** Returns true if and only if this USE flag is masked. * @attention * USE flags may be masked on a per package basis. When in doubt, use * UseFlag::isMaskedFor(const Package&) const.*/ bool isMasked() const { return parseUseMaskForce(_useMaskList); } /** Returns true if and only of this USE flag is masked for a given package.*/ bool isMaskedFor(const Package& package) const { return parseUseMaskForce(_useMaskList, package); } /** Returns true if this USE flag is forces. * @attention * USE flags may be forced on a per package basis. When in doubt, use * UseFlag::isForcedFor(const Package&) const.*/ bool isForced() const { if(isMasked()) return false; return parseUseMaskForce(_useForceList); } /** Returns true if and only if this USE flag is forced for a given package.*/ bool isForcedFor(const Package& package) const { if(isMaskedFor(package)) return false; return parseUseMaskForce(_useForceList, package); } /** Returns a description for the USE flag.*/ const std::string& getDescription() const { return _desc; } /** Returns true if and only if this flag is in IUSE for the given package.*/ bool isValidFor(const Package& package) const; /** Returns true if and only if this flag is a USE_EXPAND type USE flag. * @see http://devmanual.gentoo.org/general-concepts/use-flags/index.html#local-and-global-use-flags*/ bool isFromUseExpand() const { return _useExpand; } /** Returns true if and only if this and other refer to the same flag. * @attention * This method behaves differently from operator==(const UseFlag&) as * it does only compares the names of the flags, but not their state.*/ bool sameFlag(const UseFlag& other) const { return _name == other._name; } /** Compares to UseFlag objects for equality.*/ bool operator==(const UseFlag& other) const { return (_name == other._name) && (_active == other._active); } private: struct UseMaskForce { UseMaskForce() : plain(boost::logic::indeterminate) {} //represents the relevant information from use.(mask|force). boost::logic::tribool plain; //represents the relevant information from package.use.(mask|force) // dep atom state // | | std::list > perPackage; bool relevant() const { return (!boost::logic::indeterminate(plain)) || (!perPackage.empty()); } }; static bool hasExpectedFormat(const std::string& name); static std::string grabUseDescGlobal(const std::string& name); static std::string grabUseDescLocal(const std::string& name); static bool grabUseDescFromFile(const std::string& name, const std::string& filename, std::string& desc); /*!@attention * This method throws if no description can be found and useExpand should be upper case.*/ static std::string grabUseDescForUseExpand(const std::string& useExpand, const std::string& name); void initFromName(); void initUseLists(); //it is perfectly ok to pass a filename for a file that does not exist; in this case the //method will return boost::logic::indeterminate boost::logic::tribool stateFromUseMaskOrForceFile(const std::string& filename) const; //it is ok to pass a filename that doesn't reference an exsiting file void relevantLinesFromPackageUseMaskOrForceFile( const std::string& filename, std::list >& perPackage) const; static std::string fullFlagName(const std::string& useExpandVar, const std::string& name); static std::string extractUseExpandFromFlagName(const std::string& flagName); static bool parseUseMaskForce(const std::list& useMaskForceList); static bool parseUseMaskForce(const std::list& useMaskForceList, const Package& package); std::string _name; bool _active; std::string _desc; bool _global; bool _useExpand; std::list _useMaskList; std::list _useForceList; }; }//namespace #endif