Imported Upstream version 2.8.9
[platform/upstream/cmake.git] / Source / cmIDEOptions.cxx
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 #include "cmIDEOptions.h"
13
14 #include "cmSystemTools.h"
15
16 //----------------------------------------------------------------------------
17 cmIDEOptions::cmIDEOptions()
18 {
19   this->DoingDefine = false;
20   this->AllowDefine = true;
21   this->AllowSlash = false;
22   for(int i=0; i < FlagTableCount; ++i)
23     {
24     this->FlagTable[i] = 0;
25     }
26 }
27
28 //----------------------------------------------------------------------------
29 cmIDEOptions::~cmIDEOptions()
30 {
31 }
32
33 //----------------------------------------------------------------------------
34 void cmIDEOptions::HandleFlag(const char* flag)
35 {
36   // If the last option was -D then this option is the definition.
37   if(this->DoingDefine)
38     {
39     this->DoingDefine = false;
40     this->Defines.push_back(flag);
41     return;
42     }
43
44   // Look for known arguments.
45   if(flag[0] == '-' || (this->AllowSlash && flag[0] == '/'))
46     {
47     // Look for preprocessor definitions.
48     if(this->AllowDefine && flag[1] == 'D')
49       {
50       if(flag[2] == '\0')
51         {
52         // The next argument will have the definition.
53         this->DoingDefine = true;
54         }
55       else
56         {
57         // Store this definition.
58         this->Defines.push_back(flag+2);
59         }
60       return;
61       }
62
63     // Look through the available flag tables.
64     bool flag_handled = false;
65     for(int i=0; i < FlagTableCount && this->FlagTable[i]; ++i)
66       {
67       if(this->CheckFlagTable(this->FlagTable[i], flag, flag_handled))
68         {
69         return;
70         }
71       }
72
73     // If any map entry handled the flag we are done.
74     if(flag_handled)
75       {
76       return;
77       }
78     }
79
80   // This option is not known.  Store it in the output flags.
81   this->StoreUnknownFlag(flag);
82 }
83
84 //----------------------------------------------------------------------------
85 bool cmIDEOptions::CheckFlagTable(cmIDEFlagTable const* table,
86                                   const char* flag, bool& flag_handled)
87 {
88   // Look for an entry in the flag table matching this flag.
89   for(cmIDEFlagTable const* entry = table; entry->IDEName; ++entry)
90     {
91     bool entry_found = false;
92     if(entry->special & cmIDEFlagTable::UserValue)
93       {
94       // This flag table entry accepts a user-specified value.  If
95       // the entry specifies UserRequired we must match only if a
96       // non-empty value is given.
97       int n = static_cast<int>(strlen(entry->commandFlag));
98       if(strncmp(flag+1, entry->commandFlag, n) == 0 &&
99          (!(entry->special & cmIDEFlagTable::UserRequired) ||
100           static_cast<int>(strlen(flag+1)) > n))
101         {
102         if(entry->special & cmIDEFlagTable::UserIgnored)
103           {
104           // Ignore the user-specified value.
105           this->FlagMap[entry->IDEName] = entry->value;
106           }
107         else if(entry->special & cmIDEFlagTable::SemicolonAppendable)
108           {
109           const char *new_value = flag+1+n;
110
111           std::map<cmStdString,cmStdString>::iterator itr;
112           itr = this->FlagMap.find(entry->IDEName);
113           if(itr != this->FlagMap.end())
114             {
115             // Append to old value (if present) with semicolons;
116             itr->second += ";";
117             itr->second += new_value;
118             }
119           else
120             {
121             this->FlagMap[entry->IDEName] = new_value;
122             }
123           }
124         else
125           {
126           // Use the user-specified value.
127           this->FlagMap[entry->IDEName] = flag+1+n;
128           }
129         entry_found = true;
130         }
131       }
132     else if(strcmp(flag+1, entry->commandFlag) == 0)
133       {
134       // This flag table entry provides a fixed value.
135       this->FlagMap[entry->IDEName] = entry->value;
136       entry_found = true;
137       }
138
139     // If the flag has been handled by an entry not requesting a
140     // search continuation we are done.
141     if(entry_found && !(entry->special & cmIDEFlagTable::Continue))
142       {
143       return true;
144       }
145
146     // If the entry was found the flag has been handled.
147     flag_handled = flag_handled || entry_found;
148     }
149
150   return false;
151 }
152
153 //----------------------------------------------------------------------------
154 void cmIDEOptions::AddDefine(const std::string& def)
155 {
156   this->Defines.push_back(def);
157 }
158
159 //----------------------------------------------------------------------------
160 void cmIDEOptions::AddDefines(const char* defines)
161 {
162   if(defines)
163     {
164     // Expand the list of definitions.
165     cmSystemTools::ExpandListArgument(defines, this->Defines);
166     }
167 }
168
169 //----------------------------------------------------------------------------
170 void cmIDEOptions::AddFlag(const char* flag, const char* value)
171 {
172   this->FlagMap[flag] = value;
173 }
174
175 //----------------------------------------------------------------------------
176 void cmIDEOptions::RemoveFlag(const char* flag)
177 {
178   this->FlagMap.erase(flag);
179 }