1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the qmake application of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#ifndef MSBUILD_OBJECTMODEL_H
30#define MSBUILD_OBJECTMODEL_H
31
32#include "project.h"
33#include "xmloutput.h"
34#include "msvc_objectmodel.h"
35#include <qlist.h>
36#include <qstring.h>
37#include <qmap.h>
38
39QT_BEGIN_NAMESPACE
40
41// Tree & Flat view of files --------------------------------------------------
42class XNode
43{
44public:
45 virtual ~XNode() { }
46 void addElement(const VCFilterFile &file) {
47 addElement(file.file, file);
48 }
49 virtual void addElement(const QString &filepath, const VCFilterFile &allInfo) = 0;
50 virtual void removeElements()= 0;
51 virtual void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName,
52 VCProject &tool, const QString &filter) = 0;
53 virtual bool hasElements() = 0;
54};
55
56class XTreeNode : public XNode
57{
58 typedef QMap<QString, XTreeNode*> ChildrenMap;
59 VCFilterFile info;
60 ChildrenMap children;
61
62public:
63 virtual ~XTreeNode() { removeElements(); }
64
65 int pathIndex(const QString &filepath) {
66 int Windex = filepath.indexOf("\\");
67 int Uindex = filepath.indexOf("/");
68 if (Windex != -1 && Uindex != -1)
69 return qMin(Windex, Uindex);
70 else if (Windex != -1)
71 return Windex;
72 return Uindex;
73 }
74
75 void addElement(const QString &filepath, const VCFilterFile &allInfo) override {
76 QString newNodeName(filepath);
77
78 int index = pathIndex(filepath);
79 if (index != -1)
80 newNodeName = filepath.left(index);
81
82 XTreeNode *n = children.value(newNodeName);
83 if (!n) {
84 n = new XTreeNode;
85 n->info = allInfo;
86 children.insert(newNodeName, n);
87 }
88 if (index != -1)
89 n->addElement(filepath.mid(index+1), allInfo);
90 }
91
92 void removeElements() override {
93 ChildrenMap::ConstIterator it = children.constBegin();
94 ChildrenMap::ConstIterator end = children.constEnd();
95 for( ; it != end; it++) {
96 (*it)->removeElements();
97 delete it.value();
98 }
99 children.clear();
100 }
101
102 void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCProject &tool,
103 const QString &filter) override;
104 bool hasElements() override {
105 return children.size() != 0;
106 }
107};
108
109class XFlatNode : public XNode
110{
111 typedef QMap<QString, VCFilterFile> ChildrenMapFlat;
112 ChildrenMapFlat children;
113
114public:
115 virtual ~XFlatNode() { removeElements(); }
116
117 int pathIndex(const QString &filepath) {
118 int Windex = filepath.lastIndexOf("\\");
119 int Uindex = filepath.lastIndexOf("/");
120 if (Windex != -1 && Uindex != -1)
121 return qMax(Windex, Uindex);
122 else if (Windex != -1)
123 return Windex;
124 return Uindex;
125 }
126
127 void addElement(const QString &filepath, const VCFilterFile &allInfo) override {
128 QString newKey(filepath);
129
130 int index = pathIndex(filepath);
131 if (index != -1)
132 newKey = filepath.mid(index+1);
133
134 // Key designed to sort files with same
135 // name in different paths correctly
136 children.insert(newKey + "\0" + allInfo.file, allInfo);
137 }
138
139 void removeElements() override {
140 children.clear();
141 }
142
143 void generateXML(XmlOutput &xml, XmlOutput &xmlFilter, const QString &tagName, VCProject &proj,
144 const QString &filter) override;
145 bool hasElements() override {
146 return children.size() != 0;
147 }
148};
149
150class VCXProjectWriter : public VCProjectWriter
151{
152public:
153 void write(XmlOutput &, VCProjectSingleConfig &) override;
154 void write(XmlOutput &, VCProject &) override;
155
156 void write(XmlOutput &, const VCCLCompilerTool &) override;
157 void write(XmlOutput &, const VCLinkerTool &) override;
158 void write(XmlOutput &, const VCMIDLTool &) override;
159 void write(XmlOutput &, const VCCustomBuildTool &) override;
160 void write(XmlOutput &, const VCLibrarianTool &) override;
161 void write(XmlOutput &, const VCResourceCompilerTool &) override;
162 void write(XmlOutput &, const VCEventTool &) override;
163 void write(XmlOutput &, const VCDeploymentTool &) override;
164 void write(XmlOutput &, const VCWinDeployQtTool &) override;
165 void write(XmlOutput &, const VCConfiguration &) override;
166 void write(XmlOutput &, VCFilter &) override;
167
168private:
169 struct OutputFilterData
170 {
171 VCFilter filter;
172 VCFilterFile info;
173 bool inBuild;
174 };
175
176 static void addFilters(VCProject &project, XmlOutput &xmlFilter, const QString &filterName);
177 static void outputFilter(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter, const QString &filtername);
178 static void outputFileConfigs(VCProject &project, XmlOutput &xml, XmlOutput &xmlFilter,
179 const VCFilterFile &info, const QString &filtername);
180 static bool outputFileConfig(OutputFilterData *d, XmlOutput &xml, XmlOutput &xmlFilter,
181 const QString &filename, const QString &fullFilterName,
182 bool fileAdded, bool hasCustomBuildStep);
183 static void outputFileConfig(XmlOutput &xml, XmlOutput &xmlFilter, const QString &fileName, const QString &filterName);
184 static QString generateCondition(const VCConfiguration &config);
185 static XmlOutput::xml_output attrTagToolsVersion(const VCConfiguration &config);
186
187 friend class XTreeNode;
188 friend class XFlatNode;
189};
190
191QT_END_NAMESPACE
192
193#endif // MSVC_OBJECTMODEL_H
194