Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmCommandArgumentsHelper.h
1 /*============================================================================
2   CMake - Cross Platform Makefile Generator
3   Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5   Distributed under the OSI-approved BSD License (the "License");
6   see accompanying file Copyright.txt for details.
7
8   This software is distributed WITHOUT ANY WARRANTY; without even the
9   implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10   See the License for more information.
11 ============================================================================*/
12 #ifndef cmCommandArgumentsHelper_h
13 #define cmCommandArgumentsHelper_h
14
15 #include "cmStandardIncludes.h"
16
17 class cmCommandArgumentsHelper;
18 class cmCommandArgumentGroup;
19
20 /* cmCommandArgumentsHelper, cmCommandArgumentGroup and cmCommandArgument (i.e.
21 its derived classes cmCAXXX can be used to simplify the processing of 
22 arguments to cmake commands. Maybe they can also be used to generate
23 documentation.
24
25 For every argument supported by a command one cmCommandArgument is created
26 and added to cmCommandArgumentsHelper. cmCommand has a cmCommandArgumentsHelper
27 as member variable so this should be used.
28
29 The order of the arguments is defined using the Follows(arg) method. It says 
30 that this argument follows immediateley the given argument. It can be used
31 with multiple arguments if the argument can follow after different arguments.
32
33 Arguments can be arranged in groups using cmCommandArgumentGroup. Every 
34 member of a group can follow any other member of the group. These groups
35 can also be used to define the order.
36
37 Once all arguments and groups are set up, cmCommandArgumentsHelper::Parse()
38 is called and afterwards the values of the arguments can be evaluated.
39
40 For an example see cmExportCommand.cxx.
41 */
42 class cmCommandArgument
43 {
44   public:
45     cmCommandArgument(cmCommandArgumentsHelper* args, 
46                       const char* key, 
47                       cmCommandArgumentGroup* group=0);
48     virtual ~cmCommandArgument() {}
49
50     /// this argument may follow after arg. 0 means it comes first.
51     void Follows(const cmCommandArgument* arg);
52
53     /// this argument may follow after any of the arguments in the given group
54     void FollowsGroup(const cmCommandArgumentGroup* group);
55
56     /// Returns true if the argument was found in the argument list
57     bool WasFound() const                             {return this->WasActive;}
58
59     // The following methods are only called from 
60     // cmCommandArgumentsHelper::Parse(), but making this a friend would 
61     // give it access to everything
62
63     /// Make the current argument the currently active argument
64     void Activate();
65     /// Consume the current string
66     bool Consume(const std::string& arg);
67
68     /// Return true if this argument may follow after the given argument.
69     bool MayFollow(const cmCommandArgument* current) const;
70
71     /** Returns true if the given key matches the key for this argument.
72     If this argument has an empty key everything matches. */
73     bool KeyMatches(const std::string& key) const;
74
75     /// Make this argument follow all members of the own group
76     void ApplyOwnGroup();
77
78     /// Reset argument, so it's back to its initial state
79     void Reset();
80   private:
81     const char* Key;
82     std::set<const cmCommandArgument*> ArgumentsBefore;
83     cmCommandArgumentGroup* Group;
84     bool WasActive;
85     bool ArgumentsBeforeEmpty;
86     unsigned int CurrentIndex;
87
88     virtual bool DoConsume(const std::string& arg, unsigned int index) = 0;
89     virtual void DoReset() = 0;
90 };
91
92 /** cmCAStringVector is to be used for arguments which can consist of more 
93 than one string, e.g. the FILES argument in INSTALL(FILES f1 f2 f3 ...). */
94 class cmCAStringVector : public cmCommandArgument
95 {
96   public:
97     cmCAStringVector(cmCommandArgumentsHelper* args, 
98                      const char* key, 
99                      cmCommandArgumentGroup* group=0);
100
101     /// Return the vector of strings
102     const std::vector<std::string>& GetVector() const    {return this->Vector;}
103
104     /** Is there a keyword which should be skipped in 
105     the arguments (e.g. ARGS for ADD_CUSTOM_COMMAND) ? */
106     void SetIgnore(const char* ignore)                   {this->Ignore=ignore;}
107   private:
108     std::vector<std::string> Vector;
109     unsigned int DataStart;
110     const char* Ignore;
111     cmCAStringVector();
112     virtual bool DoConsume(const std::string& arg, unsigned int index);
113     virtual void DoReset();
114 };
115
116 /** cmCAString is to be used for arguments which consist of one value,
117 e.g. the executable name in ADD_EXECUTABLE(). */
118 class cmCAString : public cmCommandArgument
119 {
120   public:
121     cmCAString(cmCommandArgumentsHelper* args, 
122                const char* key, 
123                cmCommandArgumentGroup* group=0);
124
125     /// Return the string
126     const std::string& GetString() const                 {return this->String;}
127     const char* GetCString() const               {return this->String.c_str();}
128   private:
129     std::string String;
130     unsigned int DataStart;
131     virtual bool DoConsume(const std::string& arg, unsigned int index);
132     virtual void DoReset();
133     cmCAString();
134 };
135
136 /** cmCAEnabler is to be used for options which are off by default and can be
137 enabled using a special argument, e.g. EXCLUDE_FROM_ALL in ADD_EXECUTABLE(). */
138 class cmCAEnabler : public cmCommandArgument
139 {
140   public:
141     cmCAEnabler(cmCommandArgumentsHelper* args, 
142                 const char* key, 
143                 cmCommandArgumentGroup* group=0);
144
145     /// Has it been enabled ?
146     bool IsEnabled() const                              {return this->Enabled;}
147   private:
148     bool Enabled;
149     virtual bool DoConsume(const std::string& arg, unsigned int index);
150     virtual void DoReset();
151     cmCAEnabler();
152 };
153
154 /** cmCADisable is to be used for options which are on by default and can be
155 disabled using a special argument.*/
156 class cmCADisabler : public cmCommandArgument
157 {
158   public:
159     cmCADisabler(cmCommandArgumentsHelper* args, 
160                  const char* key, 
161                  cmCommandArgumentGroup* group=0);
162
163     /// Is it still enabled ?
164     bool IsEnabled() const                              {return this->Enabled;}
165   private:
166     bool Enabled;
167     virtual bool DoConsume(const std::string& arg, unsigned int index);
168     virtual void DoReset();
169     cmCADisabler();
170 };
171
172
173 /** Group of arguments, needed for ordering. E.g. WIN32, EXCLUDE_FROM_ALL and 
174 MACSOX_BUNDLE from ADD_EXECUTABLE() are a group.
175 */
176 class cmCommandArgumentGroup
177 {
178   friend class cmCommandArgument;
179   public:
180     cmCommandArgumentGroup() {}
181
182     /// All members of this group may follow the given argument
183     void Follows(const cmCommandArgument* arg);
184
185     /// All members of this group may follow all members of the given group
186     void FollowsGroup(const cmCommandArgumentGroup* group);
187   private:
188     std::vector<cmCommandArgument*> ContainedArguments;
189 };
190
191 class cmCommandArgumentsHelper
192 {
193   public:
194     /// Parse the argument list
195     void Parse(const std::vector<std::string>* args, 
196                std::vector<std::string>* unconsumedArgs);
197     /// Add an argument.
198     void AddArgument(cmCommandArgument* arg);
199   private:
200     std::vector<cmCommandArgument*> Arguments;
201 };
202
203
204 #endif