1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
/*
* Copyright (C) 2006 Matthias Langer <mlangc@gmx.at>
*
* 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 <boost/logic/tribool.hpp>
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<UseFlag>
{
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<std::pair<std::string, bool> > 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<std::pair<std::string, bool> >& 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<UseMaskForce>& useMaskForceList);
static bool parseUseMaskForce(const std::list<UseMaskForce>& useMaskForceList, const Package& package);
std::string _name;
bool _active;
std::string _desc;
bool _global;
bool _useExpand;
std::list<UseMaskForce> _useMaskList;
std::list<UseMaskForce> _useForceList;
};
}//namespace
#endif
|