summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucie Gérard <lucie.gerard@qt.io>2023-08-30 10:14:03 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-09-13 22:10:08 +0000
commita7f85d4e8e4e6006a1e0e2acdd8cb20b1516f087 (patch)
tree277ea714ce13e2bf4c6870e69e78fb7e191aff24
parent8b0f48885e3be8abc0cb2f035cf97fef34ef8438 (diff)
lupdate: remove number heuristics
Adapt the troll print example [ChangeLog][lupdate][Important Behavior Changes] Removed the number heuristics feature. Users are advised to avoid hard-coded numbers in translatable strings and use QString::arg instead. Task-number: QTBUG-115962 Change-Id: I64e920e7b6496924f2c1ee6d07bea6e73964177a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> (cherry picked from commit cda38d3d08e689deab506a11ed8c54a04d3f40d4) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit de619b5eec88a677e51d206fb32b5eb47a018108)
-rw-r--r--examples/linguist/doc/src/trollprint.qdoc19
-rw-r--r--examples/linguist/trollprint/mainwindow.cpp8
-rw-r--r--examples/linguist/trollprint/trollprint_pt.ts12
-rw-r--r--src/linguist/linguist/doc/src/linguist-manual.qdoc2
-rw-r--r--src/linguist/lupdate/lupdate.12
-rw-r--r--src/linguist/lupdate/lupdate.h1
-rw-r--r--src/linguist/lupdate/main.cpp6
-rw-r--r--src/linguist/lupdate/merge.cpp216
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt5
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp6
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before16
-rw-r--r--tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result12
12 files changed, 20 insertions, 285 deletions
diff --git a/examples/linguist/doc/src/trollprint.qdoc b/examples/linguist/doc/src/trollprint.qdoc
index fc664594a..868bf69b1 100644
--- a/examples/linguist/doc/src/trollprint.qdoc
+++ b/examples/linguist/doc/src/trollprint.qdoc
@@ -195,20 +195,6 @@
Linguist}. The following items are of special interest:
\list
- \li \c MainWindow
- \list
- \li Troll Print 1.0 - marked "(obs.)", obsolete
- \li About Troll Print 1.0 - marked "(obs.)", obsolete
- \li Troll Print 1.0. Copyright 1999 Software, Inc. -
- marked obsolete
- \li Troll Print 1.1 - automatically translated as
- "Troll Imprimir 1.1"
- \li About Troll Print 1.1 - automatically translated as
- "Troll Imprimir 1.1"
- \li Troll Print 1.1. Copyright 1999-2000 Software,
- Inc. - automatically translated as "Troll Imprimir 1.1.
- Copyright 1999-2000 Software, Inc."
- \endlist
\li \c PrintPanel
\list
\li 2-sided - marked "(obs.)", obsolete
@@ -217,8 +203,9 @@
\endlist
\endlist
- Notice that \c lupdate works hard behind the scenes to make revisions
- easier, and it's pretty smart with numbers.
+ In order to make revisions easier, instead of tr("Troll Print 1.0")
+ you can use tr("Troll Print %1").arg("1.0") or such to avoid having to update
+ the string on every release.
Go over the translations in \c MainWindow and mark these as "done".
Translate "\<b\>TROLL PRINT\</b\>" as "\<b\>TROLL IMPRIMIR\</b\>".
diff --git a/examples/linguist/trollprint/mainwindow.cpp b/examples/linguist/trollprint/mainwindow.cpp
index eb8fef9a4..b099af15b 100644
--- a/examples/linguist/trollprint/mainwindow.cpp
+++ b/examples/linguist/trollprint/mainwindow.cpp
@@ -15,15 +15,15 @@ MainWindow::MainWindow()
createMenus();
//! [0]
- setWindowTitle(tr("Troll Print 1.0"));
+ setWindowTitle(tr("Troll Print %1").arg("1.0"));
//! [0]
}
void MainWindow::about()
{
- QMessageBox::information(this, tr("About Troll Print 1.0"),
- tr("Troll Print 1.0.\n\n"
- "Copyright 1999 Software, Inc."));
+ QMessageBox::information(this, tr("About Troll Print %1").arg("1.0"),
+ tr("Troll Print %1.\n\n"
+ "Copyright 1999 Software, Inc.").arg("1.0"));
}
//! [1]
diff --git a/examples/linguist/trollprint/trollprint_pt.ts b/examples/linguist/trollprint/trollprint_pt.ts
index e5871bd08..82165ffd3 100644
--- a/examples/linguist/trollprint/trollprint_pt.ts
+++ b/examples/linguist/trollprint/trollprint_pt.ts
@@ -2,8 +2,8 @@
<context>
<name>MainWindow</name>
<message>
- <source>Troll Print 1.0</source>
- <translation>Troll Imprimir 1.0</translation>
+ <source>Troll Print %1</source>
+ <translation>Troll Imprimir %1</translation>
</message>
<message>
<source>E&amp;xit</source>
@@ -26,14 +26,14 @@
<translation>A&amp;juda</translation>
</message>
<message>
- <source>About Troll Print 1.0</source>
- <translation>Sobre Troll Imprimir 1.0</translation>
+ <source>About Troll Print %1</source>
+ <translation>Sobre Troll Imprimir %1</translation>
</message>
<message>
- <source>Troll Print 1.0.
+ <source>Troll Print %1.
Copyright 1999 Software, Inc.</source>
- <translation>Troll Imprimir 1.0
+ <translation>Troll Imprimir %1
Copyright 1999 Software, Inc.</translation>
</message>
diff --git a/src/linguist/linguist/doc/src/linguist-manual.qdoc b/src/linguist/linguist/doc/src/linguist-manual.qdoc
index cd026b40b..fe557048e 100644
--- a/src/linguist/linguist/doc/src/linguist-manual.qdoc
+++ b/src/linguist/linguist/doc/src/linguist-manual.qdoc
@@ -279,7 +279,7 @@
\li \c {-no-ui-lines}
\li Do not record line numbers in references to UI files.
\row
- \li \c {-disable-heuristic {sametext|similartext|number}}
+ \li \c {-disable-heuristic {sametext|similartext}}
\li Disable the named merge heuristic. Can be specified multiple times.
\row
\li \c {-project <filename>}
diff --git a/src/linguist/lupdate/lupdate.1 b/src/linguist/lupdate/lupdate.1
index 861e5bfee..a866965ca 100644
--- a/src/linguist/lupdate/lupdate.1
+++ b/src/linguist/lupdate/lupdate.1
@@ -28,7 +28,7 @@ used with version control systems if required.
.PP
.SH OPTIONS
.TP
-.I "-disable-heuristic {sametext|similartext|number}"
+.I "-disable-heuristic {sametext|similartext}"
Disable the named merge heuristic. Can be specified multiple times.
.TP
.I "-extensions <ext>[,<ext>...]"
diff --git a/src/linguist/lupdate/lupdate.h b/src/linguist/lupdate/lupdate.h
index 6b7b25e02..5cc0f8c2b 100644
--- a/src/linguist/lupdate/lupdate.h
+++ b/src/linguist/lupdate/lupdate.h
@@ -27,7 +27,6 @@ enum UpdateOption {
NoSort = 8,
HeuristicSameText = 16,
HeuristicSimilarText = 32,
- HeuristicNumber = 64,
AbsoluteLocations = 256,
RelativeLocations = 512,
NoLocations = 1024,
diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp
index e3d83b7d2..0ebe43214 100644
--- a/src/linguist/lupdate/main.cpp
+++ b/src/linguist/lupdate/main.cpp
@@ -254,7 +254,7 @@ static void printUsage()
" Default is absolute for new files.\n"
" -no-ui-lines\n"
" Do not record line numbers in references to UI files.\n"
- " -disable-heuristic {sametext|similartext|number}\n"
+ " -disable-heuristic {sametext|similartext}\n"
" Disable the named merge heuristic. Can be specified multiple times.\n"
" -project <filename>\n"
" Name of a file containing the project's description in JSON format.\n"
@@ -728,7 +728,7 @@ int main(int argc, char **argv)
UpdateOptions options =
Verbose | // verbose is on by default starting with Qt 4.2
- HeuristicSameText | HeuristicSimilarText | HeuristicNumber;
+ HeuristicSameText | HeuristicSimilarText;
int numFiles = 0;
bool metTsFlag = false;
bool metXTsFlag = false;
@@ -799,8 +799,6 @@ int main(int argc, char **argv)
options &= ~HeuristicSameText;
} else if (arg == QLatin1String("similartext")) {
options &= ~HeuristicSimilarText;
- } else if (arg == QLatin1String("number")) {
- options &= ~HeuristicNumber;
} else {
printErr(u"Invalid heuristic name passed to -disable-heuristic.\n"_s);
return 1;
diff --git a/src/linguist/lupdate/merge.cpp b/src/linguist/lupdate/merge.cpp
index 273ace6ad..f204fc73d 100644
--- a/src/linguist/lupdate/merge.cpp
+++ b/src/linguist/lupdate/merge.cpp
@@ -14,212 +14,6 @@
QT_BEGIN_NAMESPACE
-static bool isDigitFriendly(QChar c)
-{
- return c.isPunct() || c.isSpace();
-}
-
-static int numberLength(const QString &s, int i)
-{
- if (i >= s.size() || !s.at(i).isDigit())
- return 0;
-
- int pos = i;
- do {
- ++i;
- } while (i < s.size()
- && (s.at(i).isDigit()
- || (isDigitFriendly(s[i])
- && i + 1 < s.size()
- && (s[i + 1].isDigit()
- || (isDigitFriendly(s[i + 1])
- && i + 2 < s.size()
- && s[i + 2].isDigit())))));
- return i - pos;
-}
-
-
-/*
- Returns a version of 'key' where all numbers have been replaced by zeroes. If
- there were none, returns "".
-*/
-static QString zeroKey(const QString &key)
-{
- QString zeroed;
- bool metSomething = false;
-
- for (int i = 0; i < key.size(); ++i) {
- int len = numberLength(key, i);
- if (len > 0) {
- i += len;
- zeroed.append(QLatin1Char('0'));
- metSomething = true;
- } else {
- zeroed.append(key.at(i));
- }
- }
- return metSomething ? zeroed : QString();
-}
-
-static QString translationAttempt(const QString &oldTranslation,
- const QString &oldSource, const QString &newSource)
-{
- int p = zeroKey(oldSource).count(QLatin1Char('0'));
- QString attempt;
- QStringList oldNumbers;
- QStringList newNumbers;
- QList<bool> met(p);
- QList<int> matchedYet(p);
- int i, j;
- int k = 0, ell, best;
- int m, n;
- int pass;
-
- /*
- This algorithm is hard to follow, so we'll consider an example
- all along: oldTranslation is "XeT 3.0", oldSource is "TeX 3.0"
- and newSource is "XeT 3.1".
-
- First, we set up two tables: oldNumbers and newNumbers. In our
- example, oldNumber[0] is "3.0" and newNumber[0] is "3.1".
- */
- for (i = 0, j = 0; i < oldSource.size(); i++, j++) {
- m = numberLength(oldSource, i);
- n = numberLength(newSource, j);
- if (m > 0) {
- oldNumbers.append(oldSource.mid(i, m + 1));
- newNumbers.append(newSource.mid(j, n + 1));
- i += m;
- j += n;
- met[k] = false;
- matchedYet[k] = 0;
- k++;
- }
- }
-
- /*
- We now go over the old translation, "XeT 3.0", one letter at a
- time, looking for numbers found in oldNumbers. Whenever such a
- number is met, it is replaced with its newNumber equivalent. In
- our example, the "3.0" of "XeT 3.0" becomes "3.1".
- */
- for (i = 0; i < oldTranslation.size(); i++) {
- attempt += oldTranslation[i];
- for (k = 0; k < p; k++) {
- if (matchedYet[k] < oldNumbers[k].size() &&
- oldTranslation[i] == oldNumbers[k][matchedYet[k]]) {
- matchedYet[k]++;
- } else {
- matchedYet[k] = 0;
- }
- }
-
- /*
- Let's find out if the last character ended a match. We make
- two passes over the data. In the first pass, we try to
- match only numbers that weren't matched yet; if that fails,
- the second pass does the trick. This is useful in some
- suspicious cases, flagged below.
- */
- for (pass = 0; pass < 2; pass++) {
- best = p; // an impossible value
- for (k = 0; k < p; k++) {
- if ((!met[k] || pass > 0) &&
- matchedYet[k] == oldNumbers[k].size() &&
- numberLength(oldTranslation, i + 1 - matchedYet[k]) == matchedYet[k]) {
- // the longer the better
- if (best == p || matchedYet[k] > matchedYet[best])
- best = k;
- }
- }
- if (best != p) {
- attempt.truncate(attempt.size() - matchedYet[best]);
- attempt += newNumbers[best];
- met[best] = true;
- for (k = 0; k < p; k++)
- matchedYet[k] = 0;
- break;
- }
- }
- }
-
- /*
- We flag two kinds of suspicious cases. They are identified as
- such with comments such as "{2000?}" at the end.
-
- Example of the first kind: old source text "TeX 3.0" translated
- as "XeT 2.0" is flagged "TeX 2.0 {3.0?}", no matter what the
- new text is.
- */
- for (k = 0; k < p; k++) {
- if (!met[k])
- attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String("?}");
- }
-
- /*
- Example of the second kind: "1 of 1" translated as "1 af 1",
- with new source text "1 of 2", generates "1 af 2 {1 or 2?}"
- because it's not clear which of "1 af 2" and "2 af 1" is right.
- */
- for (k = 0; k < p; k++) {
- for (ell = 0; ell < p; ell++) {
- if (k != ell && oldNumbers[k] == oldNumbers[ell] &&
- newNumbers[k] < newNumbers[ell])
- attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String(" or ") +
- newNumbers[ell] + QLatin1String("?}");
- }
- }
- return attempt;
-}
-
-
-/*
- Augments a Translator with translations easily derived from
- similar existing (probably obsolete) translations.
-
- For example, if "TeX 3.0" is translated as "XeT 3.0" and "TeX 3.1"
- has no translation, "XeT 3.1" is added to the translator and is
- marked Unfinished.
-
- Returns the number of additional messages that this heuristic translated.
-*/
-int applyNumberHeuristic(Translator &tor)
-{
- QMap<QString, QPair<QString, QString> > translated;
- QList<bool> untranslated(tor.messageCount());
- int inserted = 0;
-
- for (int i = 0; i < tor.messageCount(); ++i) {
- const TranslatorMessage &msg = tor.message(i);
- bool hasTranslation = msg.isTranslated();
- if (msg.type() == TranslatorMessage::Unfinished) {
- if (!hasTranslation)
- untranslated[i] = true;
- } else if (hasTranslation && msg.translations().size() == 1) {
- const QString &key = zeroKey(msg.sourceText());
- if (!key.isEmpty())
- translated.insert(key, qMakePair(msg.sourceText(), msg.translation()));
- }
- }
-
- for (int i = 0; i < tor.messageCount(); ++i) {
- if (untranslated[i]) {
- TranslatorMessage &msg = tor.message(i);
- const QString &key = zeroKey(msg.sourceText());
- if (!key.isEmpty()) {
- const auto t = translated.constFind(key);
- if (t != translated.constEnd() && t->first != msg.sourceText()) {
- msg.setTranslation(translationAttempt(t->second, t->first,
- msg.sourceText()));
- inserted++;
- }
- }
- }
- }
- return inserted;
-}
-
-
/*
Augments a Translator with trivially derived translations.
@@ -493,13 +287,6 @@ Translator merge(
*/
int sameTextHeuristicCount = (options & HeuristicSameText) ? applySameTextHeuristic(outTor) : 0;
- /*
- The number heuristic handles cases where a message has an
- obsolete counterpart with mostly numbers differing in the
- source text.
- */
- int sameNumberHeuristicCount = (options & HeuristicNumber) ? applyNumberHeuristic(outTor) : 0;
-
if (options & Verbose) {
int totalFound = neww + known;
err += QStringLiteral(" Found %1 source text(s) (%2 new and %3 already existing)\n")
@@ -513,9 +300,6 @@ Translator merge(
}
}
- if (sameNumberHeuristicCount)
- err += QStringLiteral(" Number heuristic provided %1 translation(s)\n")
- .arg(sameNumberHeuristicCount);
if (sameTextHeuristicCount)
err += QStringLiteral(" Same-text heuristic provided %1 translation(s)\n")
.arg(sameTextHeuristicCount);
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt b/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt
index e363cc8cb..f8c994f34 100644
--- a/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/expectedoutput.txt
@@ -1,5 +1,4 @@
Updating 'project\.ts'\.\.\.
- Found 4 source text\(s\) \(4 new and 0 already existing\)
- Removed 6 obsolete entries
- Number heuristic provided 2 translation\(s\)
+ Found 2 source text\(s\) \(2 new and 0 already existing\)
+ Removed 4 obsolete entries
Same-text heuristic provided 1 translation\(s\)
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp b/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp
index 0915b556c..ef37410ec 100644
--- a/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/main.cpp
@@ -36,17 +36,11 @@ class A: public QObject {
Q_OBJECT
void foo()
{
- // number Heuristics
- tr("version 2.0 now");
-
// same text match
tr("this is the matched same text");
// failed same text
tr("this is the non-matched same text");
-
- // number heuristics QTBUG-111775
- tr("1xb");
}
};
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before
index ca731d961..2d1b201a9 100644
--- a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.before
@@ -2,14 +2,6 @@
<!DOCTYPE TS>
<TS version="2.0" language="de_DE">
<context>
- <name>A</name>
- <message>
- <location filename="main.cpp" line="53"/>
- <source>version 1.0 now</source>
- <translation>teraz wersja 1.0</translation>
- </message>
-</context>
-<context>
<name>B</name>
<message>
<location filename="main.cpp" line="56"/>
@@ -35,12 +27,4 @@
<translation>völlig andere variante des reinfalls mit same-text</translation>
</message>
</context>
-<context>
- <name>D</name>
- <message>
- <location filename="main.cpp" line="62"/>
- <source>1ab</source>
- <translation>1ab</translation>
- </message>
-</context>
</TS>
diff --git a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result
index 546d1f1f4..3c150a30c 100644
--- a/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result
+++ b/tests/auto/linguist/lupdate/testdata/good/heuristics/project.ts.result
@@ -5,23 +5,13 @@
<name>A</name>
<message>
<location filename="main.cpp" line="40"/>
- <source>version 2.0 now</source>
- <translation type="unfinished">teraz wersja 1.0 {2.0 ?}</translation>
- </message>
- <message>
- <location filename="main.cpp" line="43"/>
<source>this is the matched same text</source>
<translation type="unfinished">der same-text-treffer</translation>
</message>
<message>
- <location filename="main.cpp" line="46"/>
+ <location filename="main.cpp" line="43"/>
<source>this is the non-matched same text</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <location filename="main.cpp" line="49"/>
- <source>1xb</source>
- <translation type="unfinished">1ab {1x?}</translation>
- </message>
</context>
</TS>