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) |
33 | extern "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 | |
51 | QT_BEGIN_NAMESPACE |
52 | |
53 | using 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 | */ |
113 | Q_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 | |
136 | void 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 | |
169 | struct QInternal_CallBackTable |
170 | { |
171 | QList<QList<qInternalCallback>> callbacks; |
172 | }; |
173 | |
174 | Q_GLOBAL_STATIC(QInternal_CallBackTable, global_callback_table) |
175 | |
176 | bool 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 | |
187 | bool 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 | |
198 | bool 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 | |
387 | namespace QtPrivate { |
388 | Q_LOGGING_CATEGORY(lcNativeInterface, "qt.nativeinterface" ) |
389 | } |
390 | |
391 | QT_END_NAMESPACE |
392 | |