summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakumi Asaki <asaki@sra.co.jp>2014-03-06 16:56:52 +0900
committerKai Koehne <kai.koehne@digia.com>2014-06-27 08:28:50 +0200
commit71c6fdf871d6a66c85a7618ec4ced25cf2bb9b5d (patch)
tree5f575e46627f2c9613c876401b1a363003338c92
parent7638c0d78310e1e6b979b1f734f2324afd598ddb (diff)
Introduce qUtf8Printable() macro to qglobal.h
This macro is equivalent to arg.toUtf8().constData(). It is usable for "%s" arguments of qDebug(), qWarning(), qFatal(), qCritical(). Change-Id: I2d9956e6651271e1e2183dce9c835511cf923bf3 Reviewed-by: Kai Koehne <kai.koehne@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp4
-rw-r--r--src/corelib/global/qglobal.cpp32
-rw-r--r--src/corelib/global/qglobal.h4
-rw-r--r--tests/auto/corelib/global/qglobal/tst_qglobal.cpp64
4 files changed, 93 insertions, 11 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
index b907c9acb1..5befebc982 100644
--- a/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
@@ -305,7 +305,7 @@ void load(const QString &fileName)
{
QFile file(fileName);
if (!file.exists())
- qCritical("File '%s' does not exist!", qPrintable(fileName));
+ qCritical("File '%s' does not exist!", qUtf8Printable(fileName));
}
//! [28]
@@ -424,7 +424,7 @@ void TheClass::addLabels()
//! [37]
-qWarning("%s: %s", qPrintable(key), qPrintable(value));
+qWarning("%s: %s", qUtf8Printable(key), qUtf8Printable(value));
//! [37]
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index fb95a1966f..98460481ca 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -580,8 +580,8 @@ Q_STATIC_ASSERT_X(UCHAR_MAX == 255, "Qt assumes that char is 8 bits");
64-bit integer literals in a platform-independent way. The
Q_CHECK_PTR() macro prints a warning containing the source code's
file name and line number, saying that the program ran out of
- memory, if the pointer is 0. The qPrintable() macro represent an
- easy way of printing text.
+ memory, if the pointer is 0. The qPrintable() and qUtf8Printable()
+ macros represent an easy way of printing text.
Finally, the QT_POINTER_SIZE macro expands to the size of a
pointer in bytes, and the QT_VERSION and QT_VERSION_STR macros
@@ -3356,17 +3356,31 @@ int qrand()
qPrintable() is used. This is because the array returned by
QString::toLocal8Bit() will fall out of scope.
+ \note qDebug(), qWarning(), qCritical(), qFatal() expect %s
+ arguments to be UTF-8 encoded, while qPrintable() converts to
+ local 8-bit encoding. Therefore qUtf8Printable() should be used
+ for logging strings instead of qPrintable().
+
+ \sa qUtf8Printable()
+*/
+
+/*!
+ \macro const char *qUtf8Printable(const QString &str)
+ \relates <QtGlobal>
+ \since 5.4
+
+ Returns \a str as a \c{const char *}. This is equivalent to
+ \a{str}.toUtf8().constData().
+
+ The char pointer will be invalid after the statement in which
+ qUtf8Printable() is used. This is because the array returned by
+ QString::toUtf8() will fall out of scope.
+
Example:
\snippet code/src_corelib_global_qglobal.cpp 37
- \note qDebug(), qWarning(), qCritical(), qFatal() expect %s
- arguments to be UTF-8 encoded, while qPrintable() converts to
- local 8-bit encoding. Therefore using qPrintable for logging
- strings is only safe if the argument contains only ASCII
- characters.
-
- \sa qDebug(), qWarning(), qCritical(), qFatal()
+ \sa qPrintable(), qDebug(), qWarning(), qCritical(), qFatal()
*/
/*!
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index a9621e744c..80c9992e25 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -645,6 +645,10 @@ inline void qUnused(T &x) { (void)x; }
# define qPrintable(string) QString(string).toLocal8Bit().constData()
#endif
+#ifndef qUtf8Printable
+# define qUtf8Printable(string) QString(string).toUtf8().constData()
+#endif
+
class QString;
Q_CORE_EXPORT QString qt_error_string(int errorCode = -1);
diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
index 4eb3e4fc98..0389ae7976 100644
--- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
+++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
@@ -43,6 +43,9 @@
#include <QtTest/QtTest>
#include <QtCore/qtypetraits.h>
+#include <QPair>
+#include <QTextCodec>
+
class tst_QGlobal: public QObject
{
Q_OBJECT
@@ -60,6 +63,8 @@ private slots:
void isEnum();
void qAlignOf();
void integerForSize();
+ void qprintable();
+ void qprintable_data();
};
void tst_QGlobal::qIsNull()
@@ -588,5 +593,64 @@ void tst_QGlobal::integerForSize()
Q_STATIC_ASSERT(sizeof(QIntegerForSize<8>::Unsigned) == 8);
}
+typedef QPair<const char *, const char *> stringpair;
+Q_DECLARE_METATYPE(stringpair)
+
+void tst_QGlobal::qprintable()
+{
+ QFETCH(QList<stringpair>, localestrings);
+ QFETCH(int, utf8index);
+
+ QVERIFY(utf8index >= 0 && utf8index < localestrings.count());
+ if (utf8index < 0 || utf8index >= localestrings.count())
+ return;
+
+ const char *const utf8string = localestrings.at(utf8index).second;
+
+ QString string = QString::fromUtf8(utf8string);
+
+ foreach (const stringpair &pair, localestrings) {
+ QTextCodec *codec = QTextCodec::codecForName(pair.first);
+ if (!codec)
+ continue;
+ QTextCodec::setCodecForLocale(codec);
+ // test qPrintable()
+ QVERIFY(qstrcmp(qPrintable(string), pair.second) == 0);
+ foreach (const stringpair &pair2, localestrings) {
+ if (pair2.second == pair.second)
+ continue;
+ QVERIFY(qstrcmp(qPrintable(string), pair2.second) != 0);
+ }
+ // test qUtf8Printable()
+ QVERIFY(qstrcmp(qUtf8Printable(string), utf8string) == 0);
+ foreach (const stringpair &pair2, localestrings) {
+ if (qstrcmp(pair2.second, utf8string) == 0)
+ continue;
+ QVERIFY(qstrcmp(qUtf8Printable(string), pair2.second) != 0);
+ }
+ }
+
+ QTextCodec::setCodecForLocale(0);
+}
+
+void tst_QGlobal::qprintable_data()
+{
+ QTest::addColumn<QList<stringpair> >("localestrings");
+ QTest::addColumn<int>("utf8index"); // index of utf8 string
+
+ // Unicode: HIRAGANA LETTER A, I, U, E, O (U+3442, U+3444, U+3446, U+3448, U+344a)
+ static const char *const utf8string = "\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a";
+ static const char *const eucjpstring = "\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa";
+ static const char *const sjisstring = "\x82\xa0\x82\xa2\x82\xa4\x82\xa6\x82\xa8";
+
+ QList<stringpair> japanesestrings;
+ japanesestrings << stringpair("UTF-8", utf8string)
+ << stringpair("EUC-JP", eucjpstring)
+ << stringpair("Shift_JIS", sjisstring);
+
+ QTest::newRow("Japanese") << japanesestrings << 0;
+
+}
+
QTEST_APPLESS_MAIN(tst_QGlobal)
#include "tst_qglobal.moc"