summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qvsnprintf.cpp
blob: afe526516ff97b58d17d948b40e915c7a2b2a52a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#include "qplatformdefs.h"

#include "qbytearray.h"
#include "qstring.h"

#include "string.h"

QT_BEGIN_NAMESPACE

/*!
    \macro QT_NO_QSNPRINTF
    \since 6.8
    \relates QByteArray

    Defining this macro removes the availability of the qsnprintf() and
    qvsnprintf() functions. See the functions' documentation for why you may
    want to disable them.

    \sa qsnprintf(), qvsnprintf().
*/

#if !defined(QT_VSNPRINTF) || defined(Q_QDOC)

/*!
    \fn int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
    \relates QByteArray

    \obsolete

    Use C++11's \c{std::vsnprintf()} from \c{<cstdio>} instead.

    A portable \c vsnprintf() function. Will call \c ::vsnprintf(), \c
    ::_vsnprintf(), or \c ::vsnprintf_s depending on the system, or
    fall back to an internal version.

    \a fmt is the \c printf() format string. The result is put into
    \a str, which is a buffer of at least \a n bytes.

    The caller is responsible to call \c va_end() on \a ap.

    \warning Since vsnprintf() shows different behavior on certain
    platforms, you should not rely on the return value or on the fact
    that you will always get a 0 terminated string back. There are also
    differences in how \c{%a} (hex floats) and \c{%ls} (wide strings) are
    handled on WebAssembly and Android.

    Ideally, you should never call this function but use QString::asprintf()
    instead.

    \sa qsnprintf(), QString::asprintf()
*/

Q_CORE_EXPORT // QT_NO_QSNPRINTF is in effect
int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
{
    if (!str || !fmt)
        return -1;

    const QByteArray ba = QString::vasprintf(fmt, ap).toLocal8Bit();

    if (n > 0) {
        size_t blen = qMin(size_t(ba.length()), size_t(n - 1));
        memcpy(str, ba.constData(), blen);
        str[blen] = '\0'; // make sure str is always 0 terminated
    }

    return ba.length();
}

#else

QT_BEGIN_INCLUDE_NAMESPACE
#include <stdio.h>
QT_END_INCLUDE_NAMESPACE

Q_CORE_EXPORT // QT_NO_QSNPRINTF is in effect
int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
{
    return QT_VSNPRINTF(str, n, fmt, ap);
}

#endif

/*!
    \fn int qsnprintf(char *str, size_t n, const char *fmt, ...)
    \target bytearray-qsnprintf
    \relates QByteArray

    \obsolete

    Use C++11's \c{std::snprintf()} from \c{<cstdio>} instead.

    A portable snprintf() function, calls qvsnprintf.

    \a fmt is the \c printf() format string. The result is put into
    \a str, which is a buffer of at least \a n bytes.

    \warning Call this function only when you know what you are doing
    since it shows different behavior on certain platforms.
    Use QString::asprintf() to format a string instead.

    \sa qvsnprintf(), QString::asprintf()
*/

Q_CORE_EXPORT // QT_NO_QSNPRINTF is in effect
int qsnprintf(char *str, size_t n, const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);

    int ret = qvsnprintf(str, n, fmt, ap);
    va_end(ap);

    return ret;
}

QT_END_NAMESPACE