8#include <QtCore/qhash.h>
9#include <QtCore/qlist.h>
10#include <QtCore/qstring.h>
11#include <QtCore/qtextstream.h>
12#include <QtCore/qstack.h>
24
25
26
43
44
45
71 {
"return", Tok_return},
73 {
"__trUtf8", Tok_trUtf8}
91using ContextPair = QPair<QByteArray,
int>;
93using ContextStack = QStack<ContextPair>;
126 int (*peekCharFunc)())
146 static const char tab[] =
"abfnrtv";
147 static const char backTab[] =
"\a\b\f\n\r\t\v";
154 if (
yyCh != quoteChar)
162 QByteArray hex =
"0";
174 sscanf_s(hex,
"%x", &n);
176 std::sscanf(hex,
"%x", &n);
178 if (yyStringLen <
sizeof(
yyString) - 1)
192 }
while (
yyCh >=
'0' &&
yyCh <
'8' && n < 3);
194 sscanf_s(oct,
"%o", &n);
196 std::sscanf(oct,
"%o", &n);
198 if (yyStringLen <
sizeof(
yyString) - 1)
203 const char *p =
std::strchr(tab,
yyCh);
204 if (yyStringLen <
sizeof(
yyString) - 1) {
205 yyString[yyStringLen++] = p ==
nullptr
206 ?
char(
yyCh) : backTab[p - tab];
214 int quoteChar =
yyCh;
215 bool tripleQuote =
false;
216 bool singleQuote =
true;
221 while (
yyCh != EOF) {
222 if (singleQuote && (
yyCh ==
'\n' || (in &&
yyCh == quoteChar)))
225 if (
yyCh == quoteChar) {
235 if (
yyCh == quoteChar) {
240 }
else if (tripleQuote) {
241 if (yyStringLen <
sizeof(
yyString) - 1)
256 char *yStart =
yyString + yyStringLen;
258 while (
yyCh != EOF && (tripleQuote ||
yyCh !=
'\n') &&
yyCh != quoteChar
268 if (
yyCh != quoteChar) {
269 printf(
"%c\n",
yyCh);
271 qWarning(
"%s:%d: Unterminated string",
288 result.append(
char(
yyCh));
298 while (
yyCh != EOF) {
313 extraComments.append({readLine().trimmed(), yyCurLineNo});
316 ids.append({readLine().trimmed(), yyCurLineNo});
325 }
while (
yyCh != EOF &&
yyCh !=
'\n');
359 const bool hex =
yyCh ==
'x';
369 auto v = ba.toLongLong(&ok);
383
384
385
386
387
388
389
390
391
397 const bool matches = (
yyTok == t);
446 ||
std::strcmp(yyIdent,
"QtCore") == 0)) {
456 if (
std::strcmp(yyIdent,
"QApplication") == 0
457 ||
std::strcmp(yyIdent,
"QGuiApplication") == 0
458 ||
std::strcmp(yyIdent,
"QCoreApplication") == 0) {
465 *utf8 = QByteArray(yyIdent).endsWith(
"UTF8");
474 bool matches = matchString(s);
483
484
485
486
487
488
489
490
491
492
493
494
516 }
else if (parenlevel == 0) {
523static bool parseTranslate(QByteArray *text, QByteArray *context, QByteArray *comment,
524 bool *utf8,
bool *plural)
533 if (!match(Tok_LeftParen) || !matchString(context) || !match(Tok_Comma)
534 || !matchString(text)) {
550 if (!matchStringOrNone(comment))
600 QByteArray extraComment;
601 while (!extraComments.isEmpty() && extraComments.constFirst().lineNo <= lineNo) {
602 if (!extraComment.isEmpty())
604 extraComment += extraComments.takeFirst().extraComment;
607 if (!extraComment.isEmpty())
608 message->setExtraComment(QString::fromUtf8(extraComment));
610 while (!ids.isEmpty() && ids.constFirst().lineNo <= lineNo)
611 message->setId(QString::fromUtf8(ids.takeFirst().extraComment));
615 const QByteArray &initialContext = {},
616 const QByteArray &defaultContext = {})
633 while (!yyContextStack.isEmpty() && yyContextStack.top().second >= indent)
643 if (!yyContextStack.isEmpty()) {
648 while (!yyContextStack.isEmpty() && yyContextStack.top().second > classIndent)
658 if (match(Tok_LeftParen) && matchString(&text)) {
664 }
else if (match(Tok_Comma) && matchStringOrNone(&comment)) {
674 if (prefix.isEmpty())
675 context = defaultContext;
676 else if (prefix ==
"self")
677 context = yyContextStack.isEmpty()
678 ? initialContext : yyContextStack.top().first;
684 if (!text.isEmpty()) {
686 QString::fromUtf8(text),
687 QString::fromUtf8(comment),
688 {}, yyFileName, yyLineNo,
689 {}, TranslatorMessage::Unfinished, plural);
699 if (parseTranslate(&text, &context, &comment, &utf8, &plural)
700 && !text.isEmpty()) {
702 QString::fromUtf8(text),
703 QString::fromUtf8(comment),
704 {}, yyFileName, yyLineNo,
705 {}, TranslatorMessage::Unfinished, plural);
712 if (!prefix.isEmpty())
721 comment = comment.simplified();
724 int k = comment.indexOf(
' ');
728 context = comment.left(k);
729 comment.remove( 0, k + 1);
731 {}, QString::fromUtf8(comment), {},
732 yyFileName, yyLineNo, {});
744 qWarning(
"%s: Unbalanced parentheses in Python code",
745 qPrintable(yyFileName));
752 static bool firstTime =
true;
755 const auto &nameMap = trFunctionAliasManager.nameToTrFunctionMap();
756 for (
auto it = nameMap.cbegin(), end = nameMap.cend(); it != end; ++it) {
757 switch (it.value()) {
778 const auto *fileNameC =
reinterpret_cast<
const wchar_t *>(fileName.utf16());
779 const bool ok = _wfopen_s(&yyInFile, fileNameC, L"r") == 0;
781 const QByteArray fileNameC = QFile::encodeName(fileName);
782 yyInFile =
std::fopen( fileNameC.constData(),
"r");
783 const bool ok =
yyInFile !=
nullptr;
786 cd.appendError(QStringLiteral(
"Cannot open %1").arg(fileName));
void extend(const TranslatorMessage &msg, ConversionData &cd)
bool loadPython(Translator &translator, const QString &fileName, ConversionData &cd)
static bool match(Token t)
static Token parseString(StringType stringType=StringType::NoString)
static int getCharFromFile()
static QByteArray readLine()
static size_t yyStringLen
static bool matchEncoding(bool *utf8)
static size_t yyCommentLen
static bool parseTranslate(QByteArray *text, QByteArray *context, QByteArray *comment, bool *utf8, bool *plural)
static void parse(Translator &tor, ConversionData &cd, const QByteArray &initialContext={}, const QByteArray &defaultContext={})
static bool matchExpression()
static Token getToken(StringType stringType=StringType::NoString)
static char yyComment[65536]
static char yyString[65536]
static bool yyCountingIndentation
static int yyContinuousSpaceCount
static QString yyFileName
static QList< ExtraComment > extraComments
static QList< ExtraComment > ids
static bool matchStringStart()
static QByteArray yyIdent
static int yyIndentationSize
static bool matchString(QByteArray *s)
static ContextStack yyContextStack
static bool matchStringOrNone(QByteArray *s)
static bool parseStringEscape(int quoteChar, StringType stringType)
QHash< QByteArray, Token > tokens
static void setMessageParameters(TranslatorMessage *message, int lineNo)
static void startTokenizer(const QString &fileName, int(*getCharFunc)(), int(*peekCharFunc)())
static int peekCharFromFile()
static QT_BEGIN_NAMESPACE const char PythonMagicComment[]