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 QMAKEVFS_H
30#define QMAKEVFS_H
31
32#include "qmake_global.h"
33
34#include <qiodevice.h>
35#include <qhash.h>
36#include <qstring.h>
37#ifdef PROEVALUATOR_THREAD_SAFE
38# include <qmutex.h>
39#endif
40
41#ifdef PROEVALUATOR_DUAL_VFS
42# ifndef PROEVALUATOR_CUMULATIVE
43# error PROEVALUATOR_DUAL_VFS requires PROEVALUATOR_CUMULATIVE
44# endif
45#endif
46
47QT_BEGIN_NAMESPACE
48
49class QMAKE_EXPORT QMakeVfs
50{
51public:
52 enum ReadResult {
53 ReadOk,
54 ReadNotFound,
55 ReadOtherError
56 };
57
58 enum VfsFlag {
59 VfsExecutable = 1,
60 VfsExact = 0,
61#ifdef PROEVALUATOR_DUAL_VFS
62 VfsCumulative = 2,
63 VfsCreate = 4,
64 VfsCreatedOnly = 8,
65#else
66 VfsCumulative = 0,
67 VfsCreate = 0,
68 VfsCreatedOnly = 0,
69#endif
70 VfsAccessedOnly = 16
71 };
72 Q_DECLARE_FLAGS(VfsFlags, VfsFlag)
73
74 QMakeVfs();
75 ~QMakeVfs();
76
77 static void ref();
78 static void deref();
79
80 int idForFileName(const QString &fn, VfsFlags flags);
81 QString fileNameForId(int id);
82 bool writeFile(int id, QIODevice::OpenMode mode, VfsFlags flags, const QString &contents, QString *errStr);
83 ReadResult readFile(int id, QString *contents, QString *errStr);
84 bool exists(const QString &fn, QMakeVfs::VfsFlags flags);
85
86#ifndef PROEVALUATOR_FULL
87 void invalidateCache();
88 void invalidateContents();
89#endif
90
91private:
92#ifdef PROEVALUATOR_THREAD_SAFE
93 static QMutex s_mutex;
94#endif
95 static int s_refCount;
96 static QAtomicInt s_fileIdCounter;
97 // Qt Creator's ProFile cache is a singleton to maximize its cross-project
98 // effectiveness (shared prf files from QtVersions).
99 // For this to actually work, real files need a global mapping.
100 // This is fine, because the namespace of real files is indeed global.
101 static QHash<QString, int> s_fileIdMap;
102 static QHash<int, QString> s_idFileMap;
103#ifdef PROEVALUATOR_DUAL_VFS
104# ifdef PROEVALUATOR_THREAD_SAFE
105 // The simple way to avoid recursing m_mutex.
106 QMutex m_vmutex;
107# endif
108 // Virtual files are bound to the project context they were created in,
109 // so their ids need to be local as well.
110 // We violate that rule in lupdate (which has a non-dual VFS), but that
111 // does not matter, because it has only one project context anyway.
112 QHash<QString, int> m_virtualFileIdMap[2]; // Exact and cumulative
113 QHash<int, QString> m_virtualIdFileMap; // Only one map, as ids are unique across realms.
114#endif
115
116#ifndef PROEVALUATOR_FULL
117# ifdef PROEVALUATOR_THREAD_SAFE
118 QMutex m_mutex;
119# endif
120 QHash<int, QString> m_files;
121 QString m_magicMissing;
122 QString m_magicExisting;
123#endif
124};
125
126Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeVfs::VfsFlags)
127
128QT_END_NAMESPACE
129
130#endif // QMAKEVFS_H
131