1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2017 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qplatformdefs.h"
6#include "qstring.h"
7#include "qbytearrayview.h"
8#include "qlist.h"
9#include "qdir.h"
10#include "qdatetime.h"
11#include <private/qlocale_tools_p.h>
12#include "qnativeinterface.h"
13#include "qnativeinterface_p.h"
14
15#include <stdlib.h>
16#include <stdarg.h>
17#include <string.h>
18
19#include <errno.h>
20#if defined(Q_CC_MSVC)
21# include <crtdbg.h>
22#endif
23
24#ifdef Q_OS_WIN
25# include <qt_windows.h>
26#endif
27
28#if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL)
29# include <envLib.h>
30#endif
31
32#if defined(Q_OS_INTEGRITY)
33extern "C" {
34 // Function mmap resides in libshm_client.a. To be able to link with it one needs
35 // to define symbols 'shm_area_password' and 'shm_area_name', because the library
36 // is meant to allow the application that links to it to use POSIX shared memory
37 // without full system POSIX.
38# pragma weak shm_area_password
39# pragma weak shm_area_name
40 char shm_area_password[] = "dummy";
41 char shm_area_name[] = "dummy";
42}
43#endif
44
45#ifdef qFatal
46// the qFatal in this file are just redirections from elsewhere, so
47// don't capture any context again
48# undef qFatal
49#endif
50
51QT_BEGIN_NAMESPACE
52
53using namespace Qt::StringLiterals;
54
55/*!
56 \headerfile <QtGlobal>
57 \inmodule QtCore
58 \title Global Qt Declarations
59 \ingroup funclists
60
61 \brief The <QtGlobal> header file includes an assortment of other headers.
62
63 Up to Qt 6.5, most Qt header files included <QtGlobal>. Before Qt 6.5,
64 <QtGlobal> defined an assortment of global declarations. Most of these
65 have moved, at Qt 6.5, to separate headers, so that source code can
66 include only what it needs, rather than the whole assortment. For now,
67 <QtGlobal> includes those other headers (see next section), but future
68 releases of Qt may remove some of these headers from <QtGlobal> or
69 condition their inclusion on a version check. Likewise, in future
70 releases, some Qt headers that currently include <QtGlobal> may stop
71 doing so. The hope is that this will improve compilation times by
72 avoiding global declarations when they are not used.
73
74 \section1 List of Headers Extracted from <QtGlobal>
75
76 \table
77 \header \li Header \li Summary
78 \row \li <QFlags> \li Type-safe way of combining enum values
79 \row \li \l <QForeach> \li Qt's implementation of foreach and forever loops
80 \row \li \l <QFunctionPointer> \li Typedef for a pointer-to-function type
81 \row \li <QGlobalStatic> \li Thread-safe initialization of global static objects
82 \row \li \l <QOverload> \li Helpers for resolving member function overloads
83 \row \li <QSysInfo> \li A helper class to get system information
84 \row \li \l <QTypeInfo> \li Helpers to get type information
85 \row \li \l <QtAssert> \li Q_ASSERT and other runtime checks
86 \row \li \l <QtClassHelperMacros> \li Qt class helper macros
87 \row \li \l <QtCompilerDetection> \li Compiler-specific macro definitions
88 \row \li \l <QtDeprecationMarkers> \li Deprecation helper macros
89 \row \li \l <QtEnvironmentVariables> \li Helpers for working with environment variables
90 \row \li <QtExceptionHandling> \li Helpers for exception handling
91 \row \li \l <QtLogging> \li Qt logging helpers
92 \row \li <QtMalloc> \li Memory allocation helpers
93 \row \li \l <QtMinMax> \li Helpers for comparing values
94 \row \li \l <QtNumeric> \li Various numeric functions
95 \row \li \l <QtPreprocessorSupport> \li Helper preprocessor macros
96 \row \li \l <QtProcessorDetection> \li Architecture-specific macro definitions
97 \row \li \l <QtResource> \li Helpers for initializing and cleaning resources
98 \row \li \l <QtSwap> \li Implementation of qSwap()
99 \row \li \l <QtSystemDetection> \li Platform-specific macro definitions
100 \row \li \l <QtTranslation> \li Qt translation helpers
101 \row \li \l <QtTypeTraits> \li Qt type traits
102 \row \li \l <QtTypes> \li Qt fundamental type declarations
103 \row \li \l <QtVersionChecks> \li QT_VERSION_CHECK and related checks
104 \row \li \l <QtVersion> \li QT_VERSION_STR and qVersion()
105 \endtable
106*/
107
108/*
109 Dijkstra's bisection algorithm to find the square root of an integer.
110 Deliberately not exported as part of the Qt API, but used in both
111 qsimplerichtext.cpp and qgfxraster_qws.cpp
112*/
113Q_CORE_EXPORT Q_DECL_CONST_FUNCTION unsigned int qt_int_sqrt(unsigned int n)
114{
115 // n must be in the range 0...UINT_MAX/2-1
116 if (n >= (UINT_MAX >> 2)) {
117 unsigned int r = 2 * qt_int_sqrt(n: n / 4);
118 unsigned int r2 = r + 1;
119 return (n >= r2 * r2) ? r2 : r;
120 }
121 uint h, p = 0, q = 1, r = n;
122 while (q <= n)
123 q <<= 2;
124 while (q != 1) {
125 q >>= 2;
126 h = p + q;
127 p >>= 1;
128 if (r >= h) {
129 p += q;
130 r -= h;
131 }
132 }
133 return p;
134}
135
136void qAbort()
137{
138#ifdef Q_OS_WIN
139 // std::abort() in the MSVC runtime will call _exit(3) if the abort
140 // behavior is _WRITE_ABORT_MSG - see also _set_abort_behavior(). This is
141 // the default for a debug-mode build of the runtime. Worse, MinGW's
142 // std::abort() implementation (in msvcrt.dll) is basically a call to
143 // _exit(3) too. Unfortunately, _exit() and _Exit() *do* run the static
144 // destructors of objects in DLLs, a violation of the C++ standard (see
145 // [support.start.term]). So we bypass std::abort() and directly
146 // terminate the application.
147
148# if defined(Q_CC_MSVC)
149 if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE))
150 __fastfail(FAST_FAIL_FATAL_APP_EXIT);
151# else
152 RaiseFailFastException(nullptr, nullptr, 0);
153# endif
154
155 // Fallback
156 TerminateProcess(GetCurrentProcess(), STATUS_FATAL_APP_EXIT);
157
158 // Tell the compiler the application has stopped.
159 Q_UNREACHABLE_IMPL();
160#else // !Q_OS_WIN
161 std::abort();
162#endif
163}
164
165// Also specified to behave as if they call tzset():
166// localtime() -- but not localtime_r(), which we use when threaded
167// strftime() -- not used (except in tests)
168
169struct QInternal_CallBackTable
170{
171 QList<QList<qInternalCallback>> callbacks;
172};
173
174Q_GLOBAL_STATIC(QInternal_CallBackTable, global_callback_table)
175
176bool QInternal::registerCallback(Callback cb, qInternalCallback callback)
177{
178 if (unsigned(cb) < unsigned(QInternal::LastCallback)) {
179 QInternal_CallBackTable *cbt = global_callback_table();
180 cbt->callbacks.resize(size: cb + 1);
181 cbt->callbacks[cb].append(t: callback);
182 return true;
183 }
184 return false;
185}
186
187bool QInternal::unregisterCallback(Callback cb, qInternalCallback callback)
188{
189 if (unsigned(cb) < unsigned(QInternal::LastCallback)) {
190 if (global_callback_table.exists()) {
191 QInternal_CallBackTable *cbt = global_callback_table();
192 return cbt->callbacks[cb].removeAll(t: callback) > 0;
193 }
194 }
195 return false;
196}
197
198bool QInternal::activateCallbacks(Callback cb, void **parameters)
199{
200 Q_ASSERT_X(cb >= 0, "QInternal::activateCallback()", "Callback id must be a valid id");
201
202 if (!global_callback_table.exists())
203 return false;
204
205 QInternal_CallBackTable *cbt = &(*global_callback_table);
206 if (cbt && cb < cbt->callbacks.size()) {
207 QList<qInternalCallback> callbacks = cbt->callbacks[cb];
208 bool ret = false;
209 for (int i = 0; i < callbacks.size(); ++i)
210 ret |= (callbacks.at(i))(parameters);
211 return ret;
212 }
213 return false;
214}
215
216/*!
217 \macro QT_NAMESPACE
218 \internal
219
220 If this macro is defined to \c ns all Qt classes are put in a namespace
221 called \c ns. Also, moc will output code putting metaobjects etc.
222 into namespace \c ns.
223
224 \sa QT_BEGIN_NAMESPACE, QT_END_NAMESPACE,
225 QT_PREPEND_NAMESPACE, QT_USE_NAMESPACE,
226 QT_BEGIN_INCLUDE_NAMESPACE, QT_END_INCLUDE_NAMESPACE,
227 QT_BEGIN_MOC_NAMESPACE, QT_END_MOC_NAMESPACE,
228*/
229
230/*!
231 \macro QT_PREPEND_NAMESPACE(identifier)
232 \internal
233
234 This macro qualifies \a identifier with the full namespace.
235 It expands to \c{::QT_NAMESPACE::identifier} if \c QT_NAMESPACE is defined
236 and only \a identifier otherwise.
237
238 \sa QT_NAMESPACE
239*/
240
241/*!
242 \macro QT_USE_NAMESPACE
243 \internal
244
245 This macro expands to using QT_NAMESPACE if QT_NAMESPACE is defined
246 and nothing otherwise.
247
248 \sa QT_NAMESPACE
249*/
250
251/*!
252 \macro QT_BEGIN_NAMESPACE
253 \internal
254
255 This macro expands to
256
257 \snippet code/src_corelib_global_qglobal.cpp begin namespace macro
258
259 if \c QT_NAMESPACE is defined and nothing otherwise. If should always
260 appear in the file-level scope and be followed by \c QT_END_NAMESPACE
261 at the same logical level with respect to preprocessor conditionals
262 in the same file.
263
264 As a rule of thumb, \c QT_BEGIN_NAMESPACE should appear in all Qt header
265 and Qt source files after the last \c{#include} line and before the first
266 declaration.
267
268 If that rule can't be followed because, e.g., \c{#include} lines and
269 declarations are wildly mixed, place \c QT_BEGIN_NAMESPACE before
270 the first declaration and wrap the \c{#include} lines in
271 \c QT_BEGIN_INCLUDE_NAMESPACE and \c QT_END_INCLUDE_NAMESPACE.
272
273 When using the \c QT_NAMESPACE feature in user code
274 (e.g., when building plugins statically linked to Qt) where
275 the user code is not intended to go into the \c QT_NAMESPACE
276 namespace, all forward declarations of Qt classes need to
277 be wrapped in \c QT_BEGIN_NAMESPACE and \c QT_END_NAMESPACE.
278 After that, a \c QT_USE_NAMESPACE should follow.
279 No further changes should be needed.
280
281 \sa QT_NAMESPACE
282*/
283
284/*!
285 \macro QT_END_NAMESPACE
286 \internal
287
288 This macro expands to
289
290 \snippet code/src_corelib_global_qglobal.cpp end namespace macro
291
292 if \c QT_NAMESPACE is defined and nothing otherwise. It is used to cancel
293 the effect of \c QT_BEGIN_NAMESPACE.
294
295 If a source file ends with a \c{#include} directive that includes a moc file,
296 \c QT_END_NAMESPACE should be placed before that \c{#include}.
297
298 \sa QT_NAMESPACE
299*/
300
301/*!
302 \macro QT_BEGIN_INCLUDE_NAMESPACE
303 \internal
304
305 This macro is equivalent to \c QT_END_NAMESPACE.
306 It only serves as syntactic sugar and is intended
307 to be used before #include lines within a
308 \c QT_BEGIN_NAMESPACE ... \c QT_END_NAMESPACE block.
309
310 \sa QT_NAMESPACE
311*/
312
313/*!
314 \macro QT_END_INCLUDE_NAMESPACE
315 \internal
316
317 This macro is equivalent to \c QT_BEGIN_NAMESPACE.
318 It only serves as syntactic sugar and is intended
319 to be used after #include lines within a
320 \c QT_BEGIN_NAMESPACE ... \c QT_END_NAMESPACE block.
321
322 \sa QT_NAMESPACE
323*/
324
325/*!
326 \macro QT_BEGIN_MOC_NAMESPACE
327 \internal
328
329 This macro is output by moc at the beginning of
330 moc files. It is equivalent to \c QT_USE_NAMESPACE.
331
332 \sa QT_NAMESPACE
333*/
334
335/*!
336 \macro QT_END_MOC_NAMESPACE
337 \internal
338
339 This macro is output by moc at the beginning of
340 moc files. It expands to nothing.
341
342 \sa QT_NAMESPACE
343*/
344
345/*!
346 \macro qMove(x)
347 \relates <QtGlobal>
348 \deprecated
349
350 Use \c std::move instead.
351
352 It expands to "std::move".
353
354 qMove takes an rvalue reference to its parameter \a x, and converts it to an xvalue.
355*/
356
357/*!
358 \macro QT_TERMINATE_ON_EXCEPTION(expr)
359 \relates <QtGlobal>
360 \internal
361
362 In general, use of the Q_DECL_NOEXCEPT macro is preferred over
363 Q_DECL_NOTHROW, because it exhibits well-defined behavior and
364 supports the more powerful Q_DECL_NOEXCEPT_EXPR variant. However,
365 use of Q_DECL_NOTHROW has the advantage that Windows builds
366 benefit on a wide range or compiler versions that do not yet
367 support the C++11 noexcept feature.
368
369 It may therefore be beneficial to use Q_DECL_NOTHROW and emulate
370 the C++11 behavior manually with an embedded try/catch.
371
372 Qt provides the QT_TERMINATE_ON_EXCEPTION(expr) macro for this
373 purpose. It either expands to \c expr (if Qt is compiled without
374 exception support or the compiler supports C++11 noexcept
375 semantics) or to
376 \snippet code/src_corelib_global_qglobal.cpp qterminate
377 otherwise.
378
379 Since this macro expands to just \c expr if the compiler supports
380 C++11 noexcept, expecting the compiler to take over responsibility
381 of calling std::terminate() in that case, it should not be used
382 outside Q_DECL_NOTHROW functions.
383
384 \sa Q_DECL_NOEXCEPT, Q_DECL_NOTHROW, qTerminate()
385*/
386
387namespace QtPrivate {
388Q_LOGGING_CATEGORY(lcNativeInterface, "qt.nativeinterface")
389}
390
391QT_END_NAMESPACE
392

source code of qtbase/src/corelib/global/qglobal.cpp