📄 fetchtr.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the Qt Linguist of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <metatranslator.h>#include <QFile>#include <QRegExp>#include <QString>#include <QStack>#include <QtXml>#include <QTextCodec>#include <ctype.h>#include <errno.h>#include <stdio.h>#include <string.h>/* qmake ignore Q_OBJECT */static const char MagicComment[] = "TRANSLATOR ";static QMap<QByteArray, int> needs_Q_OBJECT;static QMap<QByteArray, int> lacks_Q_OBJECT;/* The first part of this source file is the C++ tokenizer. We skip most of C++; the only tokens that interest us are defined here. Thus, the code fragment int main() { printf( "Hello, world!\n" ); return 0; } is broken down into the following tokens (Tok_ omitted): Ident Ident LeftParen RightParen LeftBrace Ident LeftParen String RightParen Semicolon return Semicolon RightBrace. The 0 doesn't produce any token.*/enum { Tok_Eof, Tok_class, Tok_namespace, Tok_return, Tok_tr, Tok_trUtf8, Tok_translate, Tok_Q_OBJECT, Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_Gulbrandsen, Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon, Tok_Integer };/* The tokenizer maintains the following global variables. The names should be self-explanatory.*/static QByteArray yyFileName;static int yyCh;static char yyIdent[128];static size_t yyIdentLen;static char yyComment[65536];static size_t yyCommentLen;static char yyString[65536];static size_t yyStringLen;static qlonglong yyInteger;static QStack<int> yySavedBraceDepth;static QStack<int> yySavedParenDepth;static int yyBraceDepth;static int yyParenDepth;static int yyLineNo;static int yyCurLineNo;static int yyBraceLineNo;static int yyParenLineNo;static QTextCodec *yyCodecForTr = 0;static QTextCodec *yyCodecForSource = 0;// the file to read from (if reading from a file)static FILE *yyInFile;// the string to read from and current position in the string (otherwise)static QString yyInStr;static int yyInPos;static int (*getChar)();static bool yyParsingUtf8;static int getCharFromFile(){ int c = getc( yyInFile ); if ( c == '\n' ) yyCurLineNo++; return c;}static int getCharFromString(){ if ( yyInPos == (int) yyInStr.length() ) { return EOF; } else { return yyInStr[yyInPos++].toLatin1(); }}static void startTokenizer( const char *fileName, int (*getCharFunc)(), QTextCodec *codecForTr, QTextCodec *codecForSource ){ yyInPos = 0; getChar = getCharFunc; yyFileName = fileName; yyCh = getChar(); yySavedBraceDepth.clear(); yySavedParenDepth.clear(); yyBraceDepth = 0; yyParenDepth = 0; yyCurLineNo = 1; yyBraceLineNo = 1; yyParenLineNo = 1; yyCodecForTr = codecForTr; if (!yyCodecForTr) yyCodecForTr = QTextCodec::codecForName("ISO-8859-1"); Q_ASSERT(yyCodecForTr); yyCodecForSource = codecForSource; yyParsingUtf8 = false;}static int getToken(){ const char tab[] = "abfnrtv"; const char backTab[] = "\a\b\f\n\r\t\v"; uint n; bool quiet; yyIdentLen = 0; yyCommentLen = 0; yyStringLen = 0; while ( yyCh != EOF ) { yyLineNo = yyCurLineNo; if ( isalpha(yyCh) || yyCh == '_' ) { do { if ( yyIdentLen < sizeof(yyIdent) - 1 ) yyIdent[yyIdentLen++] = (char) yyCh; yyCh = getChar(); } while ( isalnum(yyCh) || yyCh == '_' ); yyIdent[yyIdentLen] = '\0'; switch ( yyIdent[0] ) { case 'Q': if ( strcmp(yyIdent + 1, "_OBJECT") == 0 ) { return Tok_Q_OBJECT; } else if ( strcmp(yyIdent + 1, "T_TR_NOOP") == 0 ) { yyParsingUtf8 = false; return Tok_tr; } else if ( strcmp(yyIdent + 1, "T_TRANSLATE_NOOP") == 0 ) { yyParsingUtf8 = false; return Tok_translate; } break; case 'T': // TR() for when all else fails if ( qstricmp(yyIdent + 1, "R") == 0 ) { yyParsingUtf8 = false; return Tok_tr; } break; case 'c': if ( strcmp(yyIdent + 1, "lass") == 0 ) return Tok_class; break; case 'f': /* QTranslator::findMessage() has the same parameters as QApplication::translate(). */ if ( strcmp(yyIdent + 1, "indMessage") == 0 ) return Tok_translate; break; case 'n': if ( strcmp(yyIdent + 1, "amespace") == 0 ) return Tok_namespace; break; case 'r': if ( strcmp(yyIdent + 1, "eturn") == 0 ) return Tok_return; break; case 's': if ( strcmp(yyIdent + 1, "truct") == 0 ) return Tok_class; break; case 't': if ( strcmp(yyIdent + 1, "r") == 0 ) { yyParsingUtf8 = false; return Tok_tr; } else if ( qstrcmp(yyIdent + 1, "rUtf8") == 0 ) { yyParsingUtf8 = true; return Tok_trUtf8; } else if ( qstrcmp(yyIdent + 1, "ranslate") == 0 ) { yyParsingUtf8 = false; return Tok_translate; } } return Tok_Ident; } else { switch ( yyCh ) { case '#': /* Early versions of lupdate complained about unbalanced braces in the following code: #ifdef ALPHA while ( beta ) { #else while ( gamma ) { #endif delta; } The code contains, indeed, two opening braces for one closing brace; yet there's no reason to panic. The solution is to remember yyBraceDepth as it was when #if, #ifdef or #ifndef was met, and to set yyBraceDepth to that value when meeting #elif or #else. */ do { yyCh = getChar(); } while ( isspace(yyCh) && yyCh != '\n' ); switch ( yyCh ) { case 'i': yyCh = getChar(); if ( yyCh == 'f' ) { // if, ifdef, ifndef yySavedBraceDepth.push( yyBraceDepth ); yySavedParenDepth.push( yyParenDepth ); } break; case 'e': yyCh = getChar(); if ( yyCh == 'l' ) { // elif, else if ( !yySavedBraceDepth.isEmpty() ) { yyBraceDepth = yySavedBraceDepth.top(); yyParenDepth = yySavedParenDepth.top(); } } else if ( yyCh == 'n' ) { // endif if ( !yySavedBraceDepth.isEmpty() ) { yySavedBraceDepth.pop(); yySavedParenDepth.pop(); } } } while ( isalnum(yyCh) || yyCh == '_' ) yyCh = getChar(); break; case '/': yyCh = getChar(); if ( yyCh == '/' ) { do { yyCh = getChar(); } while ( yyCh != EOF && yyCh != '\n' ); } else if ( yyCh == '*' ) { bool metAster = false; bool metAsterSlash = false; while ( !metAsterSlash ) { yyCh = getChar(); if ( yyCh == EOF ) { fprintf( stderr, "%s: Unterminated C++ comment starting at" " line %d\n", (const char *) yyFileName, yyLineNo ); yyComment[yyCommentLen] = '\0'; return Tok_Comment; } if ( yyCommentLen < sizeof(yyComment) - 1 ) yyComment[yyCommentLen++] = (char) yyCh; if ( yyCh == '*' ) metAster = true; else if ( metAster && yyCh == '/' ) metAsterSlash = true; else metAster = false; } yyCh = getChar(); yyCommentLen -= 2; yyComment[yyCommentLen] = '\0'; return Tok_Comment; } break; case '"': yyCh = getChar();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -