summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qstring.cpp
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2012-02-20 13:54:26 +0100
committerMarc Mutz <marc.mutz@kdab.com>2015-02-12 09:58:00 +0000
commitd251cae7b7370af328307948aca9bb63def22fe4 (patch)
treee70c25f582e5e890e0886320d3899a8f460a156b /src/corelib/tools/qstring.cpp
parent63114f4d3ce568e05346f7dba815b567da47894d (diff)
Long live QString::asprintf()!
asprintf() is a GNU extension that prints into a string it allocates internally. Arguably, that's a better name for QString::sprintf() since it also allocates memory internally. The main problem with QString::sprintf() isn't that it's dangerous to use (it is), but that it's not static. It also returns a reference instead of by-value, breaking RVO. There is a comment about removing this function completely in Qt 6.0, but it remains the only printf-style function in Qt that can allocate the target string, so it's vital for logging, e.g., and the recommended replacement code (http://linux.die.net/man/3/vsnprintf) is a nightmare. So this patch adds static (v)asprintf() methods to replace it. Further patches will fix up all in-tree callers and finally deprecate the old (v)sprintf(). Test coverage is provided through the existing tests of sprintf(), which is implemented in terms of asprintf(). Arguably, the in-tree callers show that QByteArray would benefit from having an asprintf(), too, as most of the in-tree code works around its lack with calls to to{Latin1,Local8Bit}() after using the QString version. [ChangeLog][QtCore][QString] Added asprintf(), vasprintf(). Change-Id: I8510f8d67c22230653ec0f1c252c01bc95f3c386 Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r--src/corelib/tools/qstring.cpp47
1 files changed, 34 insertions, 13 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 4018a0bb80..5d8b5a6af5 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -5661,9 +5661,22 @@ QString QString::toUpper_helper(QString &str)
return QUnicodeTables::convertCase<QUnicodeTables::UppercaseTraits>(str);
}
+/*!
+ \obsolete Use asprintf(), arg() or QTextStream instead.
+*/
+QString &QString::sprintf(const char *cformat, ...)
+{
+ va_list ap;
+ va_start(ap, cformat);
+ *this = vasprintf(cformat, ap);
+ va_end(ap);
+ return *this;
+}
// ### Qt 6: Consider whether this function shouldn't be removed See task 202871.
/*!
+ \since 5.5
+
Safely builds a formatted string from the format string \a cformat
and an arbitrary list of arguments.
@@ -5680,7 +5693,7 @@ QString QString::toUpper_helper(QString &str)
a \c{wchar_t*}, and might also produce compiler warnings on platforms
where the size of \c {wchar_t} is not 16 bits.
- \warning We do not recommend using QString::sprintf() in new Qt
+ \warning We do not recommend using QString::asprintf() in new Qt
code. Instead, consider using QTextStream or arg(), both of
which support Unicode strings seamlessly and are type-safe.
Here's an example that uses QTextStream:
@@ -5695,32 +5708,42 @@ QString QString::toUpper_helper(QString &str)
\sa arg()
*/
-QString &QString::sprintf(const char *cformat, ...)
+QString QString::asprintf(const char *cformat, ...)
{
va_list ap;
va_start(ap, cformat);
- QString &s = vsprintf(cformat, ap);
+ const QString s = vasprintf(cformat, ap);
va_end(ap);
return s;
}
/*!
- Equivalent method to sprintf(), but takes a va_list \a ap
- instead a list of variable arguments. See the sprintf()
+ \obsolete Use vasprintf(), arg() or QTextStream instead.
+*/
+QString &QString::vsprintf(const char *cformat, va_list ap)
+{
+ return *this = vasprintf(cformat, ap);
+}
+
+/*!
+ \fn QString::vasprintf(const char *cformat, va_list ap)
+ \since 5.5
+
+ Equivalent method to asprintf(), but takes a va_list \a ap
+ instead a list of variable arguments. See the asprintf()
documentation for an explanation of \a cformat.
This method does not call the va_end macro, the caller
is responsible to call va_end on \a ap.
- \sa sprintf()
+ \sa asprintf()
*/
-QString &QString::vsprintf(const char* cformat, va_list ap)
+QString QString::vasprintf(const char *cformat, va_list ap)
{
if (!cformat || !*cformat) {
// Qt 1.x compat
- *this = fromLatin1("");
- return *this;
+ return fromLatin1("");
}
// Parse cformat
@@ -6036,9 +6059,7 @@ QString &QString::vsprintf(const char* cformat, va_list ap)
result.append(subst.rightJustified(width));
}
- *this = result;
-
- return *this;
+ return result;
}
/*!
@@ -7167,7 +7188,7 @@ static QString replaceArgEscapes(const QString &s, const ArgEscapeData &d, int f
First, \c arg(i) replaces \c %1. Then \c arg(total) replaces \c
%2. Finally, \c arg(fileName) replaces \c %3.
- One advantage of using arg() over sprintf() is that the order of the
+ One advantage of using arg() over asprintf() is that the order of the
numbered place markers can change, if the application's strings are
translated into other languages, but each arg() will still replace
the lowest numbered unreplaced place marker, no matter where it