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 
39 QT_BEGIN_NAMESPACE
40 
41 // Tree & Flat view of files --------------------------------------------------
42 class XNode
43 {
44 public:
~XNode()45     virtual ~XNode() { }
addElement(const VCFilterFile & file)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 
56 class XTreeNode : public XNode
57 {
58     typedef QMap<QString, XTreeNode*> ChildrenMap;
59     VCFilterFile info;
60     ChildrenMap children;
61 
62 public:
~XTreeNode()63     virtual ~XTreeNode() { removeElements(); }
64 
pathIndex(const QString & filepath)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 
addElement(const QString & filepath,const VCFilterFile & allInfo)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 
removeElements()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;
hasElements()104     bool hasElements() override {
105         return children.size() != 0;
106     }
107 };
108 
109 class XFlatNode : public XNode
110 {
111     typedef QMap<QString, VCFilterFile> ChildrenMapFlat;
112     ChildrenMapFlat children;
113 
114 public:
~XFlatNode()115     virtual ~XFlatNode() { removeElements(); }
116 
pathIndex(const QString & filepath)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 
addElement(const QString & filepath,const VCFilterFile & allInfo)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 
removeElements()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;
hasElements()145     bool hasElements() override {
146         return children.size() != 0;
147     }
148 };
149 
150 class VCXProjectWriter : public VCProjectWriter
151 {
152 public:
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 
168 private:
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 
191 QT_END_NAMESPACE
192 
193 #endif // MSVC_OBJECTMODEL_H
194