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 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 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 Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QDOUBLESCANPRINT_P_H
41#define QDOUBLESCANPRINT_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists for the convenience
48// of internal files. This header file may change from version to version
49// without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <qglobal.h>
55
56#if defined(Q_CC_MSVC) && (defined(QT_BOOTSTRAPPED) || defined(QT_NO_DOUBLECONVERSION))
57# include <stdio.h>
58# include <locale.h>
59
60QT_BEGIN_NAMESPACE
61
62// We can always use _sscanf_l and _snprintf_l on MSVC as those were introduced in 2005.
63
64// MSVC doesn't document what it will do with a NULL locale passed to _sscanf_l or _snprintf_l.
65// The documentation for _create_locale() does not formally document "C" to be valid, but an example
66// code snippet in the same documentation shows it.
67
68struct QCLocaleT {
69 QCLocaleT() : locale(_create_locale(LC_ALL, "C"))
70 {
71 }
72
73 ~QCLocaleT()
74 {
75 _free_locale(locale);
76 }
77
78 const _locale_t locale;
79};
80
81# define QT_CLOCALE_HOLDER Q_GLOBAL_STATIC(QCLocaleT, cLocaleT)
82# define QT_CLOCALE cLocaleT()->locale
83
84inline int qDoubleSscanf(const char *buf, _locale_t locale, const char *format, double *d,
85 int *processed)
86{
87 return _sscanf_l(buf, format, locale, d, processed);
88}
89
90inline int qDoubleSnprintf(char *buf, size_t buflen, _locale_t locale, const char *format, double d)
91{
92 return _snprintf_l(buf, buflen, format, locale, d);
93}
94
95QT_END_NAMESPACE
96
97#elif defined(QT_BOOTSTRAPPED)
98# include <stdio.h>
99
100QT_BEGIN_NAMESPACE
101
102// When bootstrapping we don't have libdouble-conversion available, yet. We can also not use locale
103// aware snprintf and sscanf variants in the general case because those are only available on select
104// platforms. We can use the regular snprintf and sscanf because we don't do setlocale(3) when
105// bootstrapping and the locale is always "C" then.
106
107# define QT_CLOCALE_HOLDER
108# define QT_CLOCALE 0
109
110inline int qDoubleSscanf(const char *buf, int, const char *format, double *d, int *processed)
111{
112 return sscanf(buf, format, d, processed);
113}
114inline int qDoubleSnprintf(char *buf, size_t buflen, int, const char *format, double d)
115{
116 return snprintf(buf, buflen, format, d);
117}
118
119QT_END_NAMESPACE
120
121#else // !QT_BOOTSTRAPPED && (!Q_CC_MSVC || !QT_NO_DOUBLECONVERSION)
122# ifdef QT_NO_DOUBLECONVERSION
123# include <stdio.h>
124# include <xlocale.h>
125
126QT_BEGIN_NAMESPACE
127
128// OS X and FreeBSD both treat NULL as the "C" locale for snprintf_l and sscanf_l.
129// When other implementations with different behavior show up, we'll have to do newlocale(3) and
130// freelocale(3) here. The arguments to those will depend on what the other implementations will
131// offer. OS X and FreeBSD again interpret a locale name of NULL as "C", but "C" itself is not
132// documented as valid locale name. Mind that the names of the LC_* constants differ between e.g.
133// BSD variants and linux.
134
135# define QT_CLOCALE_HOLDER
136# define QT_CLOCALE NULL
137
138inline int qDoubleSscanf(const char *buf, locale_t locale, const char *format, double *d,
139 int *processed)
140{
141 return sscanf_l(buf, locale, format, d, processed);
142}
143inline int qDoubleSnprintf(char *buf, size_t buflen, locale_t locale, const char *format, double d)
144{
145 return snprintf_l(buf, buflen, locale, format, d);
146}
147
148QT_END_NAMESPACE
149
150# else // !QT_NO_DOUBLECONVERSION
151# include <double-conversion/double-conversion.h>
152# define QT_CLOCALE_HOLDER
153# endif // QT_NO_DOUBLECONVERSION
154#endif // QT_BOOTSTRAPPED
155
156#endif // QDOUBLESCANPRINT_P_H
157