io/qfilesystemwatcher.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
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 Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qfilesystemwatcher.h" -
43#include "qfilesystemwatcher_p.h" -
44 -
45#ifndef QT_NO_FILESYSTEMWATCHER -
46 -
47#include <qdatetime.h> -
48#include <qdebug.h> -
49#include <qdir.h> -
50#include <qfileinfo.h> -
51#include <qset.h> -
52#include <qtimer.h> -
53 -
54#if defined(Q_OS_LINUX) || (defined(Q_OS_QNX) && !defined(QT_NO_INOTIFY)) -
55#define USE_INOTIFY -
56#endif -
57 -
58#include "qfilesystemwatcher_polling_p.h" -
59#if defined(Q_OS_WIN) -
60# include "qfilesystemwatcher_win_p.h" -
61#elif defined(USE_INOTIFY) -
62# include "qfilesystemwatcher_inotify_p.h" -
63#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC) -
64# include "qfilesystemwatcher_kqueue_p.h" -
65#endif -
66 -
67QT_BEGIN_NAMESPACE -
68 -
69QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject *parent) -
70{ -
71#if defined(Q_OS_WIN) -
72 return new QWindowsFileSystemWatcherEngine(parent); -
73#elif defined(USE_INOTIFY) -
74 // there is a chance that inotify may fail on Linux pre-2.6.13 (August -
75 // 2005), so we can't just new inotify directly. -
76 return QInotifyFileSystemWatcherEngine::create(parent);
executed: return QInotifyFileSystemWatcherEngine::create(parent);
Execution Count:289
289
77#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC) -
78 return QKqueueFileSystemWatcherEngine::create(parent); -
79#else -
80 return 0; -
81#endif -
82} -
83 -
84QFileSystemWatcherPrivate::QFileSystemWatcherPrivate() -
85 : native(0), poller(0) -
86{ -
87}
executed: }
Execution Count:289
289
88 -
89void QFileSystemWatcherPrivate::init() -
90{ -
91 Q_Q(QFileSystemWatcher);
executed (the execution status of this line is deduced): QFileSystemWatcher * const q = q_func();
-
92 native = createNativeEngine(q);
executed (the execution status of this line is deduced): native = createNativeEngine(q);
-
93 if (native) {
partially evaluated: native
TRUEFALSE
yes
Evaluation Count:289
no
Evaluation Count:0
0-289
94 QObject::connect(native,
executed (the execution status of this line is deduced): QObject::connect(native,
-
95 SIGNAL(fileChanged(QString,bool)),
executed (the execution status of this line is deduced): "2""fileChanged(QString,bool)",
-
96 q,
executed (the execution status of this line is deduced): q,
-
97 SLOT(_q_fileChanged(QString,bool)));
executed (the execution status of this line is deduced): "1""_q_fileChanged(QString,bool)");
-
98 QObject::connect(native,
executed (the execution status of this line is deduced): QObject::connect(native,
-
99 SIGNAL(directoryChanged(QString,bool)),
executed (the execution status of this line is deduced): "2""directoryChanged(QString,bool)",
-
100 q,
executed (the execution status of this line is deduced): q,
-
101 SLOT(_q_directoryChanged(QString,bool)));
executed (the execution status of this line is deduced): "1""_q_directoryChanged(QString,bool)");
-
102 }
executed: }
Execution Count:289
289
103}
executed: }
Execution Count:289
289
104 -
105void QFileSystemWatcherPrivate::initPollerEngine() -
106{ -
107 if(poller)
evaluated: poller
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:4
4-5
108 return;
executed: return;
Execution Count:5
5
109 -
110 Q_Q(QFileSystemWatcher);
executed (the execution status of this line is deduced): QFileSystemWatcher * const q = q_func();
-
111 poller = new QPollingFileSystemWatcherEngine(q); // that was a mouthful
executed (the execution status of this line is deduced): poller = new QPollingFileSystemWatcherEngine(q);
-
112 QObject::connect(poller,
executed (the execution status of this line is deduced): QObject::connect(poller,
-
113 SIGNAL(fileChanged(QString,bool)),
executed (the execution status of this line is deduced): "2""fileChanged(QString,bool)",
-
114 q,
executed (the execution status of this line is deduced): q,
-
115 SLOT(_q_fileChanged(QString,bool)));
executed (the execution status of this line is deduced): "1""_q_fileChanged(QString,bool)");
-
116 QObject::connect(poller,
executed (the execution status of this line is deduced): QObject::connect(poller,
-
117 SIGNAL(directoryChanged(QString,bool)),
executed (the execution status of this line is deduced): "2""directoryChanged(QString,bool)",
-
118 q,
executed (the execution status of this line is deduced): q,
-
119 SLOT(_q_directoryChanged(QString,bool)));
executed (the execution status of this line is deduced): "1""_q_directoryChanged(QString,bool)");
-
120}
executed: }
Execution Count:4
4
121 -
122void QFileSystemWatcherPrivate::_q_fileChanged(const QString &path, bool removed) -
123{ -
124 Q_Q(QFileSystemWatcher);
executed (the execution status of this line is deduced): QFileSystemWatcher * const q = q_func();
-
125 if (!files.contains(path)) {
partially evaluated: !files.contains(path)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:12
0-12
126 // the path was removed after a change was detected, but before we delivered the signal -
127 return;
never executed: return;
0
128 } -
129 if (removed)
evaluated: removed
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:8
4-8
130 files.removeAll(path);
executed: files.removeAll(path);
Execution Count:4
4
131 emit q->fileChanged(path, QFileSystemWatcher::QPrivateSignal());
executed (the execution status of this line is deduced): q->fileChanged(path, QFileSystemWatcher::QPrivateSignal());
-
132}
executed: }
Execution Count:12
12
133 -
134void QFileSystemWatcherPrivate::_q_directoryChanged(const QString &path, bool removed) -
135{ -
136 Q_Q(QFileSystemWatcher);
executed (the execution status of this line is deduced): QFileSystemWatcher * const q = q_func();
-
137 if (!directories.contains(path)) {
partially evaluated: !directories.contains(path)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:55
0-55
138 // perhaps the path was removed after a change was detected, but before we delivered the signal -
139 return;
never executed: return;
0
140 } -
141 if (removed)
evaluated: removed
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:51
4-51
142 directories.removeAll(path);
executed: directories.removeAll(path);
Execution Count:4
4
143 emit q->directoryChanged(path, QFileSystemWatcher::QPrivateSignal());
executed (the execution status of this line is deduced): q->directoryChanged(path, QFileSystemWatcher::QPrivateSignal());
-
144}
executed: }
Execution Count:55
55
145 -
146 -
147 -
148/*! -
149 \class QFileSystemWatcher -
150 \inmodule QtCore -
151 \brief The QFileSystemWatcher class provides an interface for monitoring files and directories for modifications. -
152 \ingroup io -
153 \since 4.2 -
154 \reentrant -
155 -
156 QFileSystemWatcher monitors the file system for changes to files -
157 and directories by watching a list of specified paths. -
158 -
159 Call addPath() to watch a particular file or directory. Multiple -
160 paths can be added using the addPaths() function. Existing paths can -
161 be removed by using the removePath() and removePaths() functions. -
162 -
163 QFileSystemWatcher examines each path added to it. Files that have -
164 been added to the QFileSystemWatcher can be accessed using the -
165 files() function, and directories using the directories() function. -
166 -
167 The fileChanged() signal is emitted when a file has been modified, -
168 renamed or removed from disk. Similarly, the directoryChanged() -
169 signal is emitted when a directory or its contents is modified or -
170 removed. Note that QFileSystemWatcher stops monitoring files once -
171 they have been renamed or removed from disk, and directories once -
172 they have been removed from disk. -
173 -
174 \note On systems running a Linux kernel without inotify support, -
175 file systems that contain watched paths cannot be unmounted. -
176 -
177 \note Windows CE does not support directory monitoring by -
178 default as this depends on the file system driver installed. -
179 -
180 \note The act of monitoring files and directories for -
181 modifications consumes system resources. This implies there is a -
182 limit to the number of files and directories your process can -
183 monitor simultaneously. On Mac OS X 10.4 and all BSD variants, for -
184 example, an open file descriptor is required for each monitored -
185 file. Some system limits the number of open file descriptors to 256 -
186 by default. This means that addPath() and addPaths() will fail if -
187 your process tries to add more than 256 files or directories to -
188 the file system monitor. Also note that your process may have -
189 other file descriptors open in addition to the ones for files -
190 being monitored, and these other open descriptors also count in -
191 the total. Mac OS X 10.5 and up use a different backend and do not -
192 suffer from this issue. -
193 -
194 -
195 \sa QFile, QDir -
196*/ -
197 -
198 -
199/*! -
200 Constructs a new file system watcher object with the given \a parent. -
201*/ -
202QFileSystemWatcher::QFileSystemWatcher(QObject *parent) -
203 : QObject(*new QFileSystemWatcherPrivate, parent) -
204{ -
205 d_func()->init();
executed (the execution status of this line is deduced): d_func()->init();
-
206}
executed: }
Execution Count:289
289
207 -
208/*! -
209 Constructs a new file system watcher object with the given \a parent -
210 which monitors the specified \a paths list. -
211*/ -
212QFileSystemWatcher::QFileSystemWatcher(const QStringList &paths, QObject *parent) -
213 : QObject(*new QFileSystemWatcherPrivate, parent) -
214{ -
215 d_func()->init();
never executed (the execution status of this line is deduced): d_func()->init();
-
216 addPaths(paths);
never executed (the execution status of this line is deduced): addPaths(paths);
-
217}
never executed: }
0
218 -
219/*! -
220 Destroys the file system watcher. -
221*/ -
222QFileSystemWatcher::~QFileSystemWatcher() -
223{ } -
224 -
225/*! -
226 Adds \a path to the file system watcher if \a path exists. The -
227 path is not added if it does not exist, or if it is already being -
228 monitored by the file system watcher. -
229 -
230 If \a path specifies a directory, the directoryChanged() signal -
231 will be emitted when \a path is modified or removed from disk; -
232 otherwise the fileChanged() signal is emitted when \a path is -
233 modified, renamed or removed. -
234 -
235 If the watch was successful, true is returned. -
236 -
237 Reasons for a watch failure are generally system-dependent, but -
238 may include the resource not existing, access failures, or the -
239 total watch count limit, if the platform has one. -
240 -
241 \note There may be a system dependent limit to the number of -
242 files and directories that can be monitored simultaneously. -
243 If this limit is been reached, \a path will not be monitored, -
244 and false is returned. -
245 -
246 \sa addPaths(), removePath() -
247*/ -
248bool QFileSystemWatcher::addPath(const QString &path) -
249{ -
250 if (path.isEmpty()) {
evaluated: path.isEmpty()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:324
1-324
251 qWarning("QFileSystemWatcher::addPath: path is empty");
executed (the execution status of this line is deduced): QMessageLogger("io/qfilesystemwatcher.cpp", 251, __PRETTY_FUNCTION__).warning("QFileSystemWatcher::addPath: path is empty");
-
252 return true;
executed: return true;
Execution Count:1
1
253 } -
254 -
255 QStringList paths = addPaths(QStringList(path));
executed (the execution status of this line is deduced): QStringList paths = addPaths(QStringList(path));
-
256 return paths.isEmpty();
executed: return paths.isEmpty();
Execution Count:324
324
257} -
258 -
259/*! -
260 Adds each path in \a paths to the file system watcher. Paths are -
261 not added if they not exist, or if they are already being -
262 monitored by the file system watcher. -
263 -
264 If a path specifies a directory, the directoryChanged() signal -
265 will be emitted when the path is modified or removed from disk; -
266 otherwise the fileChanged() signal is emitted when the path is -
267 modified, renamed, or removed. -
268 -
269 The return value is a list of paths that could not be watched. -
270 -
271 Reasons for a watch failure are generally system-dependent, but -
272 may include the resource not existing, access failures, or the -
273 total watch count limit, if the platform has one. -
274 -
275 \note There may be a system dependent limit to the number of -
276 files and directories that can be monitored simultaneously. -
277 If this limit has been reached, the excess \a paths will not -
278 be monitored, and they will be added to the returned QStringList. -
279 -
280 \sa addPath(), removePaths() -
281*/ -
282QStringList QFileSystemWatcher::addPaths(const QStringList &paths) -
283{ -
284 Q_D(QFileSystemWatcher);
executed (the execution status of this line is deduced): QFileSystemWatcherPrivate * const d = d_func();
-
285 -
286 QStringList p = paths;
executed (the execution status of this line is deduced): QStringList p = paths;
-
287 QMutableListIterator<QString> it(p);
executed (the execution status of this line is deduced): QMutableListIterator<QString> it(p);
-
288 -
289 while (it.hasNext()) {
evaluated: it.hasNext()
TRUEFALSE
yes
Evaluation Count:330
yes
Evaluation Count:329
329-330
290 const QString &path = it.next();
executed (the execution status of this line is deduced): const QString &path = it.next();
-
291 if (path.isEmpty())
evaluated: path.isEmpty()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:329
1-329
292 it.remove();
executed: it.remove();
Execution Count:1
1
293 }
executed: }
Execution Count:330
330
294 -
295 if (p.isEmpty()) {
evaluated: p.isEmpty()
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:327
2-327
296 qWarning("QFileSystemWatcher::addPaths: list is empty");
executed (the execution status of this line is deduced): QMessageLogger("io/qfilesystemwatcher.cpp", 296, __PRETTY_FUNCTION__).warning("QFileSystemWatcher::addPaths: list is empty");
-
297 return QStringList();
executed: return QStringList();
Execution Count:2
2
298 } -
299 -
300 QFileSystemWatcherEngine *engine = 0;
executed (the execution status of this line is deduced): QFileSystemWatcherEngine *engine = 0;
-
301 -
302 if(!objectName().startsWith(QLatin1String("_qt_autotest_force_engine_"))) {
evaluated: !objectName().startsWith(QLatin1String("_qt_autotest_force_engine_"))
TRUEFALSE
yes
Evaluation Count:309
yes
Evaluation Count:18
18-309
303 // Normal runtime case - search intelligently for best engine -
304 if(d->native) {
partially evaluated: d->native
TRUEFALSE
yes
Evaluation Count:309
no
Evaluation Count:0
0-309
305 engine = d->native;
executed (the execution status of this line is deduced): engine = d->native;
-
306 } else {
executed: }
Execution Count:309
309
307 d_func()->initPollerEngine();
never executed (the execution status of this line is deduced): d_func()->initPollerEngine();
-
308 engine = d->poller;
never executed (the execution status of this line is deduced): engine = d->poller;
-
309 }
never executed: }
0
310 -
311 } else { -
312 // Autotest override case - use the explicitly selected engine only -
313 QString forceName = objectName().mid(26);
executed (the execution status of this line is deduced): QString forceName = objectName().mid(26);
-
314 if(forceName == QLatin1String("poller")) {
evaluated: forceName == QLatin1String("poller")
TRUEFALSE
yes
Evaluation Count:9
yes
Evaluation Count:9
9
315 qDebug() << "QFileSystemWatcher: skipping native engine, using only polling engine";
executed (the execution status of this line is deduced): QMessageLogger("io/qfilesystemwatcher.cpp", 315, __PRETTY_FUNCTION__).debug() << "QFileSystemWatcher: skipping native engine, using only polling engine";
-
316 d_func()->initPollerEngine();
executed (the execution status of this line is deduced): d_func()->initPollerEngine();
-
317 engine = d->poller;
executed (the execution status of this line is deduced): engine = d->poller;
-
318 } else if(forceName == QLatin1String("native")) {
executed: }
Execution Count:9
partially evaluated: forceName == QLatin1String("native")
TRUEFALSE
yes
Evaluation Count:9
no
Evaluation Count:0
0-9
319 qDebug() << "QFileSystemWatcher: skipping polling engine, using only native engine";
executed (the execution status of this line is deduced): QMessageLogger("io/qfilesystemwatcher.cpp", 319, __PRETTY_FUNCTION__).debug() << "QFileSystemWatcher: skipping polling engine, using only native engine";
-
320 engine = d->native;
executed (the execution status of this line is deduced): engine = d->native;
-
321 }
executed: }
Execution Count:9
9
322 } -
323 -
324 if(engine)
partially evaluated: engine
TRUEFALSE
yes
Evaluation Count:327
no
Evaluation Count:0
0-327
325 p = engine->addPaths(p, &d->files, &d->directories);
executed: p = engine->addPaths(p, &d->files, &d->directories);
Execution Count:327
327
326 -
327 return p;
executed: return p;
Execution Count:327
327
328} -
329 -
330/*! -
331 Removes the specified \a path from the file system watcher. -
332 -
333 If the watch is successfully removed, true is returned. -
334 -
335 Reasons for watch removal failing are generally system-dependent, -
336 but may be due to the path having already been deleted, for example. -
337 -
338 \sa removePaths(), addPath() -
339*/ -
340bool QFileSystemWatcher::removePath(const QString &path) -
341{ -
342 if (path.isEmpty()) {
evaluated: path.isEmpty()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:65
1-65
343 qWarning("QFileSystemWatcher::removePath: path is empty");
executed (the execution status of this line is deduced): QMessageLogger("io/qfilesystemwatcher.cpp", 343, __PRETTY_FUNCTION__).warning("QFileSystemWatcher::removePath: path is empty");
-
344 return true;
executed: return true;
Execution Count:1
1
345 } -
346 -
347 QStringList paths = removePaths(QStringList(path));
executed (the execution status of this line is deduced): QStringList paths = removePaths(QStringList(path));
-
348 return paths.isEmpty();
executed: return paths.isEmpty();
Execution Count:65
65
349} -
350 -
351/*! -
352 Removes the specified \a paths from the file system watcher. -
353 -
354 The return value is a list of paths which were not able to be -
355 unwatched successfully. -
356 -
357 Reasons for watch removal failing are generally system-dependent, -
358 but may be due to the path having already been deleted, for example. -
359 -
360 \sa removePath(), addPaths() -
361*/ -
362QStringList QFileSystemWatcher::removePaths(const QStringList &paths) -
363{ -
364 Q_D(QFileSystemWatcher);
executed (the execution status of this line is deduced): QFileSystemWatcherPrivate * const d = d_func();
-
365 -
366 QStringList p = paths;
executed (the execution status of this line is deduced): QStringList p = paths;
-
367 QMutableListIterator<QString> it(p);
executed (the execution status of this line is deduced): QMutableListIterator<QString> it(p);
-
368 -
369 while (it.hasNext()) {
evaluated: it.hasNext()
TRUEFALSE
yes
Evaluation Count:68
yes
Evaluation Count:68
68
370 const QString &path = it.next();
executed (the execution status of this line is deduced): const QString &path = it.next();
-
371 if (path.isEmpty())
evaluated: path.isEmpty()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:67
1-67
372 it.remove();
executed: it.remove();
Execution Count:1
1
373 }
executed: }
Execution Count:68
68
374 -
375 if (p.isEmpty()) {
evaluated: p.isEmpty()
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:66
2-66
376 qWarning("QFileSystemWatcher::removePaths: list is empty");
executed (the execution status of this line is deduced): QMessageLogger("io/qfilesystemwatcher.cpp", 376, __PRETTY_FUNCTION__).warning("QFileSystemWatcher::removePaths: list is empty");
-
377 return QStringList();
executed: return QStringList();
Execution Count:2
2
378 } -
379 -
380 if (d->native)
partially evaluated: d->native
TRUEFALSE
yes
Evaluation Count:66
no
Evaluation Count:0
0-66
381 p = d->native->removePaths(p, &d->files, &d->directories);
executed: p = d->native->removePaths(p, &d->files, &d->directories);
Execution Count:66
66
382 if (d->poller)
evaluated: d->poller
TRUEFALSE
yes
Evaluation Count:5
yes
Evaluation Count:61
5-61
383 p = d->poller->removePaths(p, &d->files, &d->directories);
executed: p = d->poller->removePaths(p, &d->files, &d->directories);
Execution Count:5
5
384 -
385 return p;
executed: return p;
Execution Count:66
66
386} -
387 -
388/*! -
389 \fn void QFileSystemWatcher::fileChanged(const QString &path) -
390 -
391 This signal is emitted when the file at the specified \a path is -
392 modified, renamed or removed from disk. -
393 -
394 \sa directoryChanged() -
395*/ -
396 -
397/*! -
398 \fn void QFileSystemWatcher::directoryChanged(const QString &path) -
399 -
400 This signal is emitted when the directory at a specified \a path, -
401 is modified (e.g., when a file is added, modified or deleted) or -
402 removed from disk. Note that if there are several changes during a -
403 short period of time, some of the changes might not emit this -
404 signal. However, the last change in the sequence of changes will -
405 always generate this signal. -
406 -
407 \sa fileChanged() -
408*/ -
409 -
410/*! -
411 \fn QStringList QFileSystemWatcher::directories() const -
412 -
413 Returns a list of paths to directories that are being watched. -
414 -
415 \sa files() -
416*/ -
417 -
418/*! -
419 \fn QStringList QFileSystemWatcher::files() const -
420 -
421 Returns a list of paths to files that are being watched. -
422 -
423 \sa directories() -
424*/ -
425 -
426QStringList QFileSystemWatcher::directories() const -
427{ -
428 Q_D(const QFileSystemWatcher);
executed (the execution status of this line is deduced): const QFileSystemWatcherPrivate * const d = d_func();
-
429 return d->directories;
executed: return d->directories;
Execution Count:352
352
430} -
431 -
432QStringList QFileSystemWatcher::files() const -
433{ -
434 Q_D(const QFileSystemWatcher);
never executed (the execution status of this line is deduced): const QFileSystemWatcherPrivate * const d = d_func();
-
435 return d->files;
never executed: return d->files;
0
436} -
437 -
438QT_END_NAMESPACE -
439 -
440#include "moc_qfilesystemwatcher.cpp" -
441 -
442#endif // QT_NO_FILESYSTEMWATCHER -
443 -
444 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial