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 #include "qplatformdefs.h"
41 
42 #include "qbytearray.h"
43 #include "qstring.h"
44 
45 #include "string.h"
46 
47 QT_BEGIN_NAMESPACE
48 
49 #if !defined(QT_VSNPRINTF) || defined(Q_CLANG_QDOC)
50 
51 /*!
52     \relates QByteArray
53 
54     A portable \c vsnprintf() function. Will call \c ::vsnprintf(), \c
55     ::_vsnprintf(), or \c ::vsnprintf_s depending on the system, or
56     fall back to an internal version.
57 
58     \a fmt is the \c printf() format string. The result is put into
59     \a str, which is a buffer of at least \a n bytes.
60 
61     The caller is responsible to call \c va_end() on \a ap.
62 
63     \warning Since vsnprintf() shows different behavior on certain
64     platforms, you should not rely on the return value or on the fact
65     that you will always get a 0 terminated string back.
66 
67     Ideally, you should never call this function but use QString::asprintf()
68     instead.
69 
70     \sa qsnprintf(), QString::asprintf()
71 */
72 
qvsnprintf(char * str,size_t n,const char * fmt,va_list ap)73 int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
74 {
75     if (!str || !fmt)
76         return -1;
77 
78     const QByteArray ba = QString::vasprintf(fmt, ap).toLocal8Bit();
79 
80     if (n > 0) {
81         size_t blen = qMin(size_t(ba.length()), size_t(n - 1));
82         memcpy(str, ba.constData(), blen);
83         str[blen] = '\0'; // make sure str is always 0 terminated
84     }
85 
86     return ba.length();
87 }
88 
89 #else
90 
91 QT_BEGIN_INCLUDE_NAMESPACE
92 #include <stdio.h>
93 QT_END_INCLUDE_NAMESPACE
94 
95 int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
96 {
97     return QT_VSNPRINTF(str, n, fmt, ap);
98 }
99 
100 #endif
101 
102 /*!
103     \target bytearray-qsnprintf
104     \relates QByteArray
105 
106     A portable snprintf() function, calls qvsnprintf.
107 
108     \a fmt is the \c printf() format string. The result is put into
109     \a str, which is a buffer of at least \a n bytes.
110 
111     \warning Call this function only when you know what you are doing
112     since it shows different behavior on certain platforms.
113     Use QString::asprintf() to format a string instead.
114 
115     \sa qvsnprintf(), QString::asprintf()
116 */
117 
qsnprintf(char * str,size_t n,const char * fmt,...)118 int qsnprintf(char *str, size_t n, const char *fmt, ...)
119 {
120     va_list ap;
121     va_start(ap, fmt);
122 
123     int ret = qvsnprintf(str, n, fmt, ap);
124     va_end(ap);
125 
126     return ret;
127 }
128 
129 QT_END_NAMESPACE
130