mirror of https://github.com/procxx/kepka.git
codegen_style project started, basic (common) tokenizer done.
This commit is contained in:
parent
b61c0941ef
commit
19f9b56d2c
|
@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Telegram", "Telegram\Telegram.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Telegram", "Telegram\Telegram.vcxproj", "{B12702AD-ABFB-343A-A199-8E24837244A3}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0} = {6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}
|
{6F483617-7C84-4E7E-91D8-1FF28A4CE3A0} = {6F483617-7C84-4E7E-91D8-1FF28A4CE3A0}
|
||||||
|
{E4DF8176-4DEF-4859-962F-B497E3E7A323} = {E4DF8176-4DEF-4859-962F-B497E3E7A323}
|
||||||
{E417CAA4-259B-4C99-88E3-805F1300E8EB} = {E417CAA4-259B-4C99-88E3-805F1300E8EB}
|
{E417CAA4-259B-4C99-88E3-805F1300E8EB} = {E417CAA4-259B-4C99-88E3-805F1300E8EB}
|
||||||
{EB7D16AC-EACF-4577-B05A-F28E5F356794} = {EB7D16AC-EACF-4577-B05A-F28E5F356794}
|
{EB7D16AC-EACF-4577-B05A-F28E5F356794} = {EB7D16AC-EACF-4577-B05A-F28E5F356794}
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Legacy styles
|
||||||
|
using "./style_classes.txt";
|
||||||
|
using "./style.txt";
|
||||||
|
|
||||||
|
//using "./../SourceFiles/overview/overview.style";
|
|
@ -18,14 +18,13 @@ to link the code of portions of this program with the OpenSSL library.
|
||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
defaultFontFamily: 'Open Sans';
|
defaultFontFamily: "Open Sans";
|
||||||
semibold: 'Open Sans Semibold';
|
semibold: "Open Sans Semibold";
|
||||||
|
|
||||||
fsize: 13px;
|
fsize: 13px;
|
||||||
normalFont: font(fsize);
|
normalFont: font(fsize);
|
||||||
semiboldFont: font(fsize semibold);
|
semiboldFont: font(fsize semibold);
|
||||||
|
|
||||||
spriteFile: ':/gui/art/sprite.png' / 2:':/gui/art/sprite_125x.png' / 3:':/gui/art/sprite_150x.png' / 4:':/gui/art/sprite_200x.png';
|
|
||||||
emojiImgSize: 18px; // exceptional value for retina
|
emojiImgSize: 18px; // exceptional value for retina
|
||||||
emojiSize: 18px;
|
emojiSize: 18px;
|
||||||
emojiPadding: 0px;
|
emojiPadding: 0px;
|
||||||
|
@ -1116,8 +1115,8 @@ msgLinkColor: #2a6dc2;
|
||||||
msgPressedLinkColor: #004bad;
|
msgPressedLinkColor: #004bad;
|
||||||
msgSkip: 40px;
|
msgSkip: 40px;
|
||||||
msgPtr: 8px;
|
msgPtr: 8px;
|
||||||
msgBG: ':/gui/art/bg.jpg';
|
msgBG: ":/gui/art/bg.jpg";
|
||||||
msgBG0: ':/gui/art/bg0.png';
|
msgBG0: ":/gui/art/bg0.png";
|
||||||
|
|
||||||
msgCheckPos: point(3px, 1px);
|
msgCheckPos: point(3px, 1px);
|
||||||
msgSendingImg: sprite(260px, 20px, 20px, 20px);
|
msgSendingImg: sprite(260px, 20px, 20px, 20px);
|
||||||
|
@ -1548,7 +1547,7 @@ reportSpamButton: flatButton(reportSpamHide) {
|
||||||
reportSpamSeparator: 30px;
|
reportSpamSeparator: 30px;
|
||||||
reportSpamBg: #fffffff0;
|
reportSpamBg: #fffffff0;
|
||||||
|
|
||||||
newMsgSound: ':/gui/art/newmsg.wav';
|
newMsgSound: ":/gui/art/newmsg.wav";
|
||||||
|
|
||||||
unreadBarHeight: 32px;
|
unreadBarHeight: 32px;
|
||||||
unreadBarMargin: 8px;
|
unreadBarMargin: 8px;
|
||||||
|
|
|
@ -1994,10 +1994,19 @@ namespace {
|
||||||
::monofont = style::font(st::normalFont->f.pixelSize(), 0, family);
|
::monofont = style::font(st::normalFont->f.pixelSize(), 0, family);
|
||||||
}
|
}
|
||||||
if (!::sprite) {
|
if (!::sprite) {
|
||||||
|
QString spriteFilePostfix;
|
||||||
|
if (cRetina() || cScale() == dbisTwo) {
|
||||||
|
spriteFilePostfix = qsl("_200x");
|
||||||
|
} else if (cScale() == dbisOneAndQuarter) {
|
||||||
|
spriteFilePostfix = qsl("_125x");
|
||||||
|
} else if (cScale() == dbisOneAndHalf) {
|
||||||
|
spriteFilePostfix = qsl("_150x");
|
||||||
|
}
|
||||||
|
QString spriteFile = qsl(":/gui/art/sprite") + spriteFilePostfix + qsl(".png");
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
::sprite = new QPixmap(QPixmap::fromImage(QImage(st::spriteFile).mirrored(true, false)));
|
::sprite = new QPixmap(QPixmap::fromImage(QImage(spriteFile).mirrored(true, false)));
|
||||||
} else {
|
} else {
|
||||||
::sprite = new QPixmap(st::spriteFile);
|
::sprite = new QPixmap(spriteFile);
|
||||||
}
|
}
|
||||||
if (cRetina()) ::sprite->setDevicePixelRatio(cRetinaFactor());
|
if (cRetina()) ::sprite->setDevicePixelRatio(cRetinaFactor());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "codegen/common/basic_tokenized_file.h"
|
||||||
|
|
||||||
|
#include "codegen/common/logging.h"
|
||||||
|
#include "codegen/common/clean_file_reader.h"
|
||||||
|
#include "codegen/common/checked_utf8_string.h"
|
||||||
|
|
||||||
|
using Token = codegen::common::BasicTokenizedFile::Token;
|
||||||
|
using Type = Token::Type;
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr int kErrorUnterminatedStringLiteral = 201;
|
||||||
|
constexpr int kErrorIncorrectUtf8String = 202;
|
||||||
|
constexpr int kErrorIncorrectToken = 203;
|
||||||
|
constexpr int kErrorUnexpectedToken = 204;
|
||||||
|
|
||||||
|
bool isDigitChar(char ch) {
|
||||||
|
return (ch >= '0') && (ch <= '9');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNameChar(char ch) {
|
||||||
|
return isDigitChar(ch) || ((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWhitespaceChar(char ch) {
|
||||||
|
return (ch == '\n' || ch == ' ' || ch == '\t');
|
||||||
|
}
|
||||||
|
|
||||||
|
Token invalidToken() {
|
||||||
|
return { Type::Invalid, QString(), ConstUtf8String(nullptr, 0) };
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
BasicTokenizedFile::BasicTokenizedFile(const QString &filepath) : reader_(filepath) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BasicTokenizedFile::putBack() {
|
||||||
|
if (currentToken_ > 0) {
|
||||||
|
--currentToken_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token BasicTokenizedFile::getAnyToken() {
|
||||||
|
if (currentToken_ >= tokens_.size()) {
|
||||||
|
if (readToken() == Type::Invalid) {
|
||||||
|
return invalidToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tokens_.at(currentToken_++);
|
||||||
|
}
|
||||||
|
|
||||||
|
Token BasicTokenizedFile::getToken(Type typeCondition) {
|
||||||
|
if (auto token = getAnyToken()) {
|
||||||
|
if (token.type == typeCondition) {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
putBack();
|
||||||
|
}
|
||||||
|
return invalidToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type BasicTokenizedFile::readToken() {
|
||||||
|
auto result = readOneToken(StartWithWhitespace::Allow);
|
||||||
|
|
||||||
|
// Try to read double token.
|
||||||
|
if (result == Type::Int) {
|
||||||
|
if (readOneToken(StartWithWhitespace::Deny) == Type::Dot) {
|
||||||
|
// We got int and dot, so it is double already.
|
||||||
|
result = uniteLastTokens(Type::Double);
|
||||||
|
|
||||||
|
// Try to read one more int (after dot).
|
||||||
|
if (readOneToken(StartWithWhitespace::Deny) == Type::Int) {
|
||||||
|
result = uniteLastTokens(Type::Double);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (result == Type::Dot) {
|
||||||
|
if (readOneToken(StartWithWhitespace::Deny) == Type::Int) {
|
||||||
|
//We got dot and int, so it is double.
|
||||||
|
result = uniteLastTokens(Type::Double);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type BasicTokenizedFile::readOneToken(StartWithWhitespace condition) {
|
||||||
|
skipWhitespaces();
|
||||||
|
if (tokenStartWhitespace_ && condition == StartWithWhitespace::Deny) {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
if (reader_.atEnd()) {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ch = reader_.currentChar();
|
||||||
|
if (ch == '"') {
|
||||||
|
return readString();
|
||||||
|
} else if (isNameChar(ch)) {
|
||||||
|
return readNameOrNumber();
|
||||||
|
}
|
||||||
|
return readSingleLetter();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type BasicTokenizedFile::saveToken(Type type, const QString &value) {
|
||||||
|
ConstUtf8String original = { tokenStart_, reader_.currentPtr() };
|
||||||
|
tokens_.push_back({ type, value, original, tokenStartWhitespace_ });
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type BasicTokenizedFile::uniteLastTokens(Type type) {
|
||||||
|
auto size = tokens_.size();
|
||||||
|
if (size < 2) {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &token(tokens_[size - 2]);
|
||||||
|
auto originalFrom = token.original.data();
|
||||||
|
auto originalTill = tokens_.back().original.end();
|
||||||
|
token.type = type;
|
||||||
|
token.original = { originalFrom, originalTill };
|
||||||
|
token.value += tokens_.back().value;
|
||||||
|
tokens_.pop_back();
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type BasicTokenizedFile::readNameOrNumber() {
|
||||||
|
bool onlyDigits = true;
|
||||||
|
while (!reader_.atEnd()) {
|
||||||
|
if (!isDigitChar(reader_.currentChar())) {
|
||||||
|
onlyDigits = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reader_.skipChar();
|
||||||
|
}
|
||||||
|
while (!reader_.atEnd()) {
|
||||||
|
if (!isNameChar(reader_.currentChar())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
reader_.skipChar();
|
||||||
|
}
|
||||||
|
return saveToken(onlyDigits ? Type::Int : Type::Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type BasicTokenizedFile::readString() {
|
||||||
|
reader_.skipChar();
|
||||||
|
auto offset = reader_.currentPtr();
|
||||||
|
|
||||||
|
QByteArray value;
|
||||||
|
while (!reader_.atEnd()) {
|
||||||
|
auto ch = reader_.currentChar();
|
||||||
|
if (ch == '"') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch == '\n') {
|
||||||
|
reader_.logError(kErrorUnterminatedStringLiteral, lineNumber_) << "unterminated string literal.";
|
||||||
|
failed_ = true;
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
if (ch == '\\') {
|
||||||
|
reader_.skipChar();
|
||||||
|
ch = reader_.currentChar();
|
||||||
|
if (reader_.atEnd() || ch == '\n') {
|
||||||
|
reader_.logError(kErrorUnterminatedStringLiteral, lineNumber_) << "unterminated string literal.";
|
||||||
|
failed_ = true;
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
if (reader_.currentPtr() > offset + 1) {
|
||||||
|
value.append(offset, reader_.currentPtr() - offset - 1);
|
||||||
|
}
|
||||||
|
offset = reader_.currentPtr() + 1;
|
||||||
|
if (ch == 'n') {
|
||||||
|
value.append('\n');
|
||||||
|
} else if (ch == 't') {
|
||||||
|
value.append('\t');
|
||||||
|
} else if (ch == '"') {
|
||||||
|
value.append('"');
|
||||||
|
} else if (ch == '\\') {
|
||||||
|
value.append('\\');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value.append(ch);
|
||||||
|
}
|
||||||
|
reader_.skipChar();
|
||||||
|
}
|
||||||
|
if (reader_.atEnd()) {
|
||||||
|
reader_.logError(kErrorUnterminatedStringLiteral, lineNumber_) << "unterminated string literal.";
|
||||||
|
failed_ = true;
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
CheckedUtf8String checked(value);
|
||||||
|
if (!checked.isValid()) {
|
||||||
|
reader_.logError(kErrorIncorrectUtf8String, lineNumber_) << "incorrect UTF-8 string literal.";
|
||||||
|
failed_ = true;
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
reader_.skipChar();
|
||||||
|
return saveToken(Type::String, checked.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
Type BasicTokenizedFile::readSingleLetter() {
|
||||||
|
auto type = singleLetterTokens_.value(reader_.currentChar(), Type::Invalid);
|
||||||
|
if (type == Type::Invalid) {
|
||||||
|
reader_.logError(kErrorIncorrectToken, lineNumber_) << "incorrect token '" << reader_.currentChar() << "'.";
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
reader_.skipChar();
|
||||||
|
return saveToken(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicTokenizedFile::skipWhitespaces() {
|
||||||
|
if (reader_.atEnd()) return;
|
||||||
|
|
||||||
|
auto ch = reader_.currentChar();
|
||||||
|
tokenStartWhitespace_ = isWhitespaceChar(ch);
|
||||||
|
if (tokenStartWhitespace_) {
|
||||||
|
do {
|
||||||
|
if (ch == '\n') {
|
||||||
|
++lineNumber_;
|
||||||
|
}
|
||||||
|
reader_.skipChar();
|
||||||
|
ch = reader_.currentChar();
|
||||||
|
} while (!reader_.atEnd() && isWhitespaceChar(ch));
|
||||||
|
}
|
||||||
|
tokenStart_ = reader_.currentPtr();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogStream BasicTokenizedFile::logError(int code) const {
|
||||||
|
return reader_.logError(code, lineNumber_);
|
||||||
|
}
|
||||||
|
|
||||||
|
LogStream BasicTokenizedFile::logErrorUnexpectedToken(const std::string &expected) const {
|
||||||
|
std::string expectedTail;
|
||||||
|
if (!expected.empty()) {
|
||||||
|
expectedTail = ", expected " + expected;
|
||||||
|
}
|
||||||
|
if (currentToken_ < tokens_.size()) {
|
||||||
|
auto token = tokens_.at(currentToken_).original.toStdString();
|
||||||
|
return logError(kErrorUnexpectedToken) << "unexpected token '" << token << '\'' << expectedTail << '.';
|
||||||
|
}
|
||||||
|
return logError(kErrorUnexpectedToken) << "unexpected token" << expectedTail << '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicTokenizedFile::~BasicTokenizedFile() = default;
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QList>
|
||||||
|
|
||||||
|
#include "codegen/common/const_utf8_string.h"
|
||||||
|
#include "codegen/common/clean_file_reader.h"
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
|
||||||
|
class LogStream;
|
||||||
|
|
||||||
|
// Interface for reading a cleaned from comments file by basic tokens.
|
||||||
|
class BasicTokenizedFile {
|
||||||
|
public:
|
||||||
|
BasicTokenizedFile(const QString &filepath);
|
||||||
|
BasicTokenizedFile(const BasicTokenizedFile &other) = delete;
|
||||||
|
BasicTokenizedFile &operator=(const BasicTokenizedFile &other) = delete;
|
||||||
|
|
||||||
|
struct Token {
|
||||||
|
// String - utf8 string converted to QString.
|
||||||
|
enum class Type {
|
||||||
|
Invalid = 0,
|
||||||
|
Int,
|
||||||
|
Double,
|
||||||
|
String,
|
||||||
|
LeftParenthesis,
|
||||||
|
RightParenthesis,
|
||||||
|
LeftBrace,
|
||||||
|
RightBrace,
|
||||||
|
LeftBracket,
|
||||||
|
RightBracket,
|
||||||
|
Colon,
|
||||||
|
Semicolon,
|
||||||
|
Comma,
|
||||||
|
Dot,
|
||||||
|
Number,
|
||||||
|
Plus,
|
||||||
|
Minus,
|
||||||
|
Equals,
|
||||||
|
Name, // [0-9a-zA-Z_]+ with at least one letter.
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
QString value;
|
||||||
|
ConstUtf8String original;
|
||||||
|
bool hasLeftWhitespace;
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return (type != Type::Invalid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool read() {
|
||||||
|
return reader_.read();
|
||||||
|
}
|
||||||
|
bool atEnd() const {
|
||||||
|
return reader_.atEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
Token getAnyToken();
|
||||||
|
Token getToken(Token::Type typeCondition);
|
||||||
|
bool putBack();
|
||||||
|
bool failed() const {
|
||||||
|
return failed_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log error to std::cerr with 'code' at the current position in file.
|
||||||
|
LogStream logError(int code) const;
|
||||||
|
LogStream logErrorUnexpectedToken(const std::string &expected = std::string()) const;
|
||||||
|
|
||||||
|
~BasicTokenizedFile();
|
||||||
|
|
||||||
|
private:
|
||||||
|
using Type = Token::Type;
|
||||||
|
|
||||||
|
void skipWhitespaces();
|
||||||
|
|
||||||
|
// Reads a token, including complex tokens, like double numbers.
|
||||||
|
Type readToken();
|
||||||
|
|
||||||
|
// Read exactly one token, applying condition on the whitespaces.
|
||||||
|
enum class StartWithWhitespace {
|
||||||
|
Allow,
|
||||||
|
Deny,
|
||||||
|
};
|
||||||
|
Type readOneToken(StartWithWhitespace condition);
|
||||||
|
|
||||||
|
// helpers
|
||||||
|
Type readNameOrNumber();
|
||||||
|
Type readString();
|
||||||
|
Type readSingleLetter();
|
||||||
|
|
||||||
|
Type saveToken(Type type, const QString &value = QString());
|
||||||
|
Type uniteLastTokens(Type type);
|
||||||
|
|
||||||
|
CleanFileReader reader_;
|
||||||
|
QList<Token> tokens_;
|
||||||
|
int currentToken_ = 0;
|
||||||
|
int lineNumber_ = 1;
|
||||||
|
bool failed_ = false;
|
||||||
|
|
||||||
|
// Where the last (currently read) token has started.
|
||||||
|
const char *tokenStart_ = nullptr;
|
||||||
|
|
||||||
|
// Did the last (currently read) token start with a whitespace.
|
||||||
|
bool tokenStartWhitespace_ = false;
|
||||||
|
|
||||||
|
const QMap<char, Type> singleLetterTokens_ = {
|
||||||
|
{ '(', Type::LeftParenthesis },
|
||||||
|
{ ')', Type::RightParenthesis },
|
||||||
|
{ '{', Type::LeftBrace },
|
||||||
|
{ '}', Type::RightBrace },
|
||||||
|
{ '[', Type::LeftBracket },
|
||||||
|
{ ']', Type::RightBracket },
|
||||||
|
{ ':', Type::Colon },
|
||||||
|
{ ';', Type::Semicolon },
|
||||||
|
{ ',', Type::Comma },
|
||||||
|
{ '.', Type::Dot },
|
||||||
|
{ '#', Type::Number },
|
||||||
|
{ '+', Type::Plus },
|
||||||
|
{ '-', Type::Minus },
|
||||||
|
{ '=', Type::Equals },
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "codegen/common/checked_utf8_string.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <QtCore/QTextCodec>
|
||||||
|
|
||||||
|
#include "codegen/common/const_utf8_string.h"
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
|
||||||
|
CheckedUtf8String::CheckedUtf8String(const char *string, int size) {
|
||||||
|
if (size < 0) {
|
||||||
|
size = strlen(string);
|
||||||
|
}
|
||||||
|
if (!size) { // Valid empty string
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCodec::ConverterState state;
|
||||||
|
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
|
||||||
|
string_ = codec->toUnicode(string, size, &state);
|
||||||
|
if (state.invalidChars > 0) {
|
||||||
|
valid_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckedUtf8String::CheckedUtf8String(const QByteArray &string) : CheckedUtf8String(string.constData(), string.size()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckedUtf8String::CheckedUtf8String(const ConstUtf8String &string) : CheckedUtf8String(string.data(), string.size()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
|
class QByteArray;
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
|
||||||
|
class ConstUtf8String;
|
||||||
|
|
||||||
|
// Parses a char sequence to a QString using UTF-8 codec.
|
||||||
|
// You can check for invalid UTF-8 sequence by isValid() method.
|
||||||
|
class CheckedUtf8String {
|
||||||
|
public:
|
||||||
|
CheckedUtf8String(const CheckedUtf8String &other) = default;
|
||||||
|
CheckedUtf8String &operator=(const CheckedUtf8String &other) = default;
|
||||||
|
|
||||||
|
CheckedUtf8String(const char *string, int size = -1);
|
||||||
|
CheckedUtf8String(const QByteArray &string);
|
||||||
|
CheckedUtf8String(const ConstUtf8String &string);
|
||||||
|
|
||||||
|
bool isValid() const {
|
||||||
|
return valid_;
|
||||||
|
}
|
||||||
|
const QString &toString() const {
|
||||||
|
return string_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString string_;
|
||||||
|
bool valid_ = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "codegen/common/clean_file.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
|
#include "codegen/common/logging.h"
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr int kErrorFileNotFound = 101;
|
||||||
|
constexpr int kErrorFileTooLarge = 102;
|
||||||
|
constexpr int kErrorFileNotOpened = 103;
|
||||||
|
constexpr int kErrorUnexpectedEndOfFile = 104;
|
||||||
|
|
||||||
|
bool readFile(const QString &filepath, QByteArray *outResult) {
|
||||||
|
QFile f(filepath);
|
||||||
|
if (!f.exists()) {
|
||||||
|
logError(kErrorFileNotFound, filepath) << ": error: file does not exist.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (f.size() > CleanFile::MaxSize) {
|
||||||
|
logError(kErrorFileTooLarge, filepath) << "' is too large, size=" << f.size() << " > maxsize=" << CleanFile::MaxSize;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!f.open(QIODevice::ReadOnly)) {
|
||||||
|
logError(kErrorFileNotOpened, filepath) << "' for read.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*outResult = f.readAll();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
CleanFile::CleanFile(const QString &filepath) : filepath_(filepath) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CleanFile::read() {
|
||||||
|
QByteArray content;
|
||||||
|
if (!readFile(filepath_, &content)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
filepath_ = QFileInfo(filepath_).absoluteFilePath();
|
||||||
|
|
||||||
|
enum class InsideComment {
|
||||||
|
None,
|
||||||
|
SingleLine,
|
||||||
|
MultiLine,
|
||||||
|
};
|
||||||
|
auto insideComment = InsideComment::None;
|
||||||
|
bool insideString = false;
|
||||||
|
|
||||||
|
const char *begin = content.cbegin(), *end = content.cend(), *offset = begin;
|
||||||
|
auto feedContent = [this, &offset, end](const char *ch) {
|
||||||
|
if (ch > offset) {
|
||||||
|
if (content_.isEmpty()) content_.reserve(end - offset - 2);
|
||||||
|
content_.append(offset, ch - offset);
|
||||||
|
offset = ch;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto feedComment = [this, &offset, end](const char *ch) {
|
||||||
|
if (ch > offset) {
|
||||||
|
// comments_.push_back({ content_.size(), QByteArray(offset, ch - offset) });
|
||||||
|
if (content_.isEmpty()) content_.reserve(end - offset - 2);
|
||||||
|
content_.append(' ');
|
||||||
|
offset = ch;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (const char *ch = offset; ch != end;) {
|
||||||
|
char currentChar = *ch;
|
||||||
|
char nextChar = (ch + 1 == end) ? 0 : *(ch + 1);
|
||||||
|
|
||||||
|
if (insideComment == InsideComment::None && currentChar == '"') {
|
||||||
|
bool escaped = ((ch > begin) && *(ch - 1) == '\\') && ((ch - 1 < begin) || *(ch - 2) != '\\');
|
||||||
|
if (!escaped) {
|
||||||
|
insideString = !insideString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (insideString) {
|
||||||
|
++ch;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insideComment == InsideComment::None && currentChar == '/' && nextChar == '/') {
|
||||||
|
feedContent(ch);
|
||||||
|
insideComment = InsideComment::SingleLine;
|
||||||
|
ch += 2;
|
||||||
|
} else if (insideComment == InsideComment::SingleLine && currentChar == '\r' && nextChar == '\n') {
|
||||||
|
feedComment(ch);
|
||||||
|
ch += 2;
|
||||||
|
insideComment = InsideComment::None;
|
||||||
|
} else if (insideComment == InsideComment::SingleLine && currentChar == '\n') {
|
||||||
|
feedComment(ch);
|
||||||
|
++ch;
|
||||||
|
insideComment = InsideComment::None;
|
||||||
|
} else if (insideComment == InsideComment::None && currentChar == '/' && nextChar == '*') {
|
||||||
|
feedContent(ch);
|
||||||
|
ch += 2;
|
||||||
|
insideComment = InsideComment::MultiLine;
|
||||||
|
} else if (insideComment == InsideComment::MultiLine && currentChar == '*' && nextChar == '/') {
|
||||||
|
ch += 2;
|
||||||
|
feedComment(ch);
|
||||||
|
insideComment = InsideComment::None;
|
||||||
|
} else if (insideComment == InsideComment::MultiLine && currentChar == '\r' && nextChar == '\n') {
|
||||||
|
feedComment(ch);
|
||||||
|
ch += 2;
|
||||||
|
feedContent(ch);
|
||||||
|
} else if (insideComment == InsideComment::MultiLine && currentChar == '\n') {
|
||||||
|
feedComment(ch);
|
||||||
|
++ch;
|
||||||
|
feedContent(ch);
|
||||||
|
} else {
|
||||||
|
++ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insideComment == InsideComment::MultiLine) {
|
||||||
|
common::logError(kErrorUnexpectedEndOfFile, filepath_);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (insideComment == InsideComment::None && end > offset) {
|
||||||
|
if (content_.isEmpty()) {
|
||||||
|
content_ = content;
|
||||||
|
} else {
|
||||||
|
content_.append(offset, end - offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogStream CleanFile::logError(int code, int line) const {
|
||||||
|
return common::logError(code, filepath_, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QByteArray>
|
||||||
|
#include <QtCore/QVector>
|
||||||
|
|
||||||
|
#include "codegen/common/logging.h"
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
|
||||||
|
// Reads a file removing all C-style comments.
|
||||||
|
class CleanFile {
|
||||||
|
public:
|
||||||
|
CleanFile(const QString &filepath);
|
||||||
|
CleanFile(const CleanFile &other) = delete;
|
||||||
|
CleanFile &operator=(const CleanFile &other) = delete;
|
||||||
|
|
||||||
|
bool read();
|
||||||
|
|
||||||
|
const char *data() const {
|
||||||
|
return content_.constData();
|
||||||
|
}
|
||||||
|
const char *end() const {
|
||||||
|
return content_.constEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr int MaxSize = 10 * 1024 * 1024;
|
||||||
|
|
||||||
|
// Log error to std::cerr with 'code' at line number 'line' in data().
|
||||||
|
LogStream logError(int code, int line) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString filepath_;
|
||||||
|
|
||||||
|
QByteArray content_;
|
||||||
|
//struct Comment {
|
||||||
|
// int offset;
|
||||||
|
// QByteArray content;
|
||||||
|
//};
|
||||||
|
//QVector<Comment> comments_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
|
#include "codegen/common/clean_file.h"
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
|
||||||
|
// Wrapper allows you to read forward the CleanFile without overflow checks.
|
||||||
|
class CleanFileReader {
|
||||||
|
public:
|
||||||
|
CleanFileReader(const QString &filepath) : file_(filepath) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read() {
|
||||||
|
if (!file_.read()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pos_ = file_.data();
|
||||||
|
end_ = file_.end();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool atEnd() const {
|
||||||
|
return (pos_ == end_);
|
||||||
|
}
|
||||||
|
char currentChar() const {
|
||||||
|
return atEnd() ? 0 : *pos_;
|
||||||
|
}
|
||||||
|
bool skipChar() {
|
||||||
|
if (atEnd()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
++pos_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const char *currentPtr() const {
|
||||||
|
return pos_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log error to std::cerr with 'code' at line number 'line' in data().
|
||||||
|
LogStream logError(int code, int line) const {
|
||||||
|
return std::forward<LogStream>(file_.logError(code, line));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
CleanFile file_;
|
||||||
|
const char *pos_ = nullptr;
|
||||||
|
const char *end_ = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QByteArray>
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
|
||||||
|
// This is a simple wrapper around (const char*, size).
|
||||||
|
// Not null-terminated! It does not hold any ownership.
|
||||||
|
class ConstUtf8String {
|
||||||
|
public:
|
||||||
|
ConstUtf8String(const char *string, int size = -1) : string_(string) {
|
||||||
|
if (size < 0) {
|
||||||
|
size = strlen(string);
|
||||||
|
}
|
||||||
|
size_ = size;
|
||||||
|
}
|
||||||
|
ConstUtf8String(const char *string, const char *end) : ConstUtf8String(string, end - string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray toByteArray() const {
|
||||||
|
return QByteArray(string_, size_);
|
||||||
|
}
|
||||||
|
std::string toStdString() const {
|
||||||
|
return std::string(string_, size_);
|
||||||
|
}
|
||||||
|
QString toStringUnchecked() const {
|
||||||
|
return QString::fromUtf8(string_, size_);
|
||||||
|
}
|
||||||
|
bool empty() const {
|
||||||
|
return size_ == 0;
|
||||||
|
}
|
||||||
|
const char *data() const {
|
||||||
|
return string_;
|
||||||
|
}
|
||||||
|
int size() const {
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
const char *end() const {
|
||||||
|
return data() + size();
|
||||||
|
}
|
||||||
|
ConstUtf8String mid(int pos, int size = -1) {
|
||||||
|
return ConstUtf8String(string_ + pos, std::max(std::min(size, size_ - pos), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *string_;
|
||||||
|
int size_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "codegen/common/logging.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string relativeLocalPath(const QString &filepath) {
|
||||||
|
auto name = QFile::encodeName(QDir().relativeFilePath(filepath));
|
||||||
|
return name.constData();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
LogStream logError(int code, const QString &filepath, int line) {
|
||||||
|
std::cerr << relativeLocalPath(filepath);
|
||||||
|
if (line > 0) {
|
||||||
|
std::cerr << '(' << line << ')';
|
||||||
|
}
|
||||||
|
std::cerr << ": error " << code << ": ";
|
||||||
|
return LogStream(std::cerr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace common {
|
||||||
|
|
||||||
|
// Wrapper around std::ostream that adds '\n' to the end of the logging line.
|
||||||
|
class LogStream {
|
||||||
|
public:
|
||||||
|
explicit LogStream(std::ostream &stream) : stream_(stream) {
|
||||||
|
}
|
||||||
|
LogStream(LogStream &&other) : stream_(other.stream_) {
|
||||||
|
other.final_ = false;
|
||||||
|
}
|
||||||
|
std::ostream &stream() const {
|
||||||
|
return stream_;
|
||||||
|
}
|
||||||
|
~LogStream() {
|
||||||
|
if (final_) {
|
||||||
|
stream_ << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::ostream &stream_;
|
||||||
|
bool final_ = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
LogStream operator<<(LogStream &&stream, T &&value) {
|
||||||
|
stream.stream() << value;
|
||||||
|
return std::forward<LogStream>(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputs file name, line number and error code to std::err. Usage:
|
||||||
|
// logError(kErrorFileTooLarge, filepath) << "file too large, size=" << size;
|
||||||
|
LogStream logError(int code, const QString &filepath, int line = 0);
|
||||||
|
|
||||||
|
} // namespace common
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "codegen/style/generator.h"
|
||||||
|
|
||||||
|
#include <QtGui/QImage>
|
||||||
|
#include "codegen/style/tokenized_file.h"
|
||||||
|
|
||||||
|
using Token = codegen::style::TokenizedFile::Token;
|
||||||
|
using Type = Token::Type;
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace style {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Generator::Generator(const QString &filepath, bool rebuildDependencies)
|
||||||
|
: file_(std::make_unique<TokenizedFile>(filepath))
|
||||||
|
, rebuild_(rebuildDependencies) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int Generator::process() {
|
||||||
|
if (!file_->read()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto token = file_->getToken();
|
||||||
|
if (token.type == Type::Using) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (file_->atEnd() && !file_->failed()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator::~Generator() = default;
|
||||||
|
|
||||||
|
} // namespace style
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace style {
|
||||||
|
|
||||||
|
class TokenizedFile;
|
||||||
|
|
||||||
|
// Walks through a file, parses it and parses dependency files if necessary.
|
||||||
|
class Generator {
|
||||||
|
public:
|
||||||
|
Generator(const QString &filepath, bool rebuildDependencies);
|
||||||
|
Generator(const Generator &other) = delete;
|
||||||
|
Generator &operator=(const Generator &other) = delete;
|
||||||
|
|
||||||
|
// Returns 0 on success.
|
||||||
|
int process();
|
||||||
|
|
||||||
|
~Generator();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<TokenizedFile> file_;
|
||||||
|
bool rebuild_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace style
|
||||||
|
} // namespace codegen
|
|
@ -1,3 +1,43 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
#include "codegen/style/generator.h"
|
||||||
|
|
||||||
|
using namespace codegen::style;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
return 0;
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
QString filepath;
|
||||||
|
bool rebuildOtherFiles = false;
|
||||||
|
for (const auto &arg : app.arguments()) {
|
||||||
|
if (arg == "--rebuild") {
|
||||||
|
rebuildOtherFiles = true;
|
||||||
|
} else {
|
||||||
|
filepath = arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Generator generator(filepath, rebuildOtherFiles);
|
||||||
|
return generator.process();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#include "codegen/style/tokenized_file.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
|
#include "codegen/common/basic_tokenized_file.h"
|
||||||
|
#include "codegen/common/logging.h"
|
||||||
|
|
||||||
|
using Token = codegen::style::TokenizedFile::Token;
|
||||||
|
using Type = Token::Type;
|
||||||
|
using BasicToken = codegen::common::BasicTokenizedFile::Token;
|
||||||
|
using BasicType = BasicToken::Type;
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace style {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
QString plainValue(const BasicToken &token) {
|
||||||
|
return token.original.toStringUnchecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
Token invalidToken() {
|
||||||
|
return { Type::Invalid, QString() };
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TokenizedFile::TokenizedFile(const QString &filepath) : file_(filepath) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TokenizedFile::putBack() {
|
||||||
|
if (currentToken_ > 0) {
|
||||||
|
--currentToken_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token TokenizedFile::getToken() {
|
||||||
|
if (currentToken_ >= tokens_.size()) {
|
||||||
|
if (readToken() == Type::Invalid) {
|
||||||
|
return invalidToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tokens_.at(currentToken_++);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readToken() {
|
||||||
|
switch (state_) {
|
||||||
|
case State::Default: return readInDefault();
|
||||||
|
case State::StructStarted: return readInStructStarted();
|
||||||
|
case State::StructFieldName: return readInStructFieldName();
|
||||||
|
case State::Variable: return readInVariable();
|
||||||
|
case State::VariableParents: return readInVariableParents();
|
||||||
|
case State::VariableStarted: return readInVariableStarted();
|
||||||
|
case State::VariableChild: return readInVariableChild();
|
||||||
|
}
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readInDefault() {
|
||||||
|
if (auto basicToken = file_.getToken(BasicType::Name)) {
|
||||||
|
if (plainValue(basicToken) == "using") {
|
||||||
|
if (auto usingFile = file_.getToken(BasicType::String)) {
|
||||||
|
if (file_.getToken(BasicType::Semicolon)) {
|
||||||
|
return saveToken(Type::Using, usingFile.value);
|
||||||
|
}
|
||||||
|
file_.logErrorUnexpectedToken("';'");
|
||||||
|
} else {
|
||||||
|
file_.logErrorUnexpectedToken("file path");
|
||||||
|
}
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
if (auto braceToken = file_.getToken(BasicType::LeftBrace)) {
|
||||||
|
state_ = State::StructStarted;
|
||||||
|
return saveToken(Type::DefineStruct, plainValue(basicToken));
|
||||||
|
} else if (auto colonToken = file_.getToken(BasicType::Colon)) {
|
||||||
|
state_ = State::Variable;
|
||||||
|
return saveToken(Type::DefineVariable, plainValue(basicToken));
|
||||||
|
}
|
||||||
|
file_.logErrorUnexpectedToken("using keyword, or struct definition, or variable definition");
|
||||||
|
}
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readInStructStarted() {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readInStructFieldName() {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readInVariable() {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readInVariableParents() {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readInVariableStarted() {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::readInVariableChild() {
|
||||||
|
return Type::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type TokenizedFile::saveToken(Type type, const QString &value) {
|
||||||
|
tokens_.push_back({ type, value });
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace style
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||||
|
|
||||||
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
It is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
In addition, as a special exception, the copyright holders give permission
|
||||||
|
to link the code of portions of this program with the OpenSSL library.
|
||||||
|
|
||||||
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||||
|
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
#include "codegen/common/basic_tokenized_file.h"
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace style {
|
||||||
|
|
||||||
|
// Parses a file as a list of tokens.
|
||||||
|
class TokenizedFile {
|
||||||
|
public:
|
||||||
|
TokenizedFile(const QString &filepath);
|
||||||
|
TokenizedFile(const TokenizedFile &other) = delete;
|
||||||
|
TokenizedFile &operator=(const TokenizedFile &other) = delete;
|
||||||
|
|
||||||
|
using ConstUtf8String = common::ConstUtf8String;
|
||||||
|
struct Token {
|
||||||
|
enum class Type {
|
||||||
|
Invalid,
|
||||||
|
|
||||||
|
Using,
|
||||||
|
|
||||||
|
DefineStruct,
|
||||||
|
DefineField,
|
||||||
|
FieldType,
|
||||||
|
|
||||||
|
DefineVariable,
|
||||||
|
Struct,
|
||||||
|
StructParent,
|
||||||
|
|
||||||
|
Int,
|
||||||
|
Double,
|
||||||
|
Pixels,
|
||||||
|
String,
|
||||||
|
Color,
|
||||||
|
Point,
|
||||||
|
Sprite,
|
||||||
|
Size,
|
||||||
|
Transition,
|
||||||
|
Cursor,
|
||||||
|
Align,
|
||||||
|
Margins,
|
||||||
|
Font,
|
||||||
|
};
|
||||||
|
Type type;
|
||||||
|
QString value;
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return type != Type::Invalid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool read() {
|
||||||
|
return file_.read();
|
||||||
|
}
|
||||||
|
bool atEnd() const {
|
||||||
|
return file_.atEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
Token getToken();
|
||||||
|
bool putBack();
|
||||||
|
bool failed() const {
|
||||||
|
return file_.failed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log error to std::cerr with 'code' at the current position in file.
|
||||||
|
common::LogStream logError(int code) const {
|
||||||
|
return file_.logError(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
using Type = Token::Type;
|
||||||
|
Type readToken();
|
||||||
|
|
||||||
|
// State value defines what are we waiting next.
|
||||||
|
enum class State {
|
||||||
|
Default, // [ using | struct name | variable name | end ]
|
||||||
|
StructStarted, // [ struct field name | struct end ]
|
||||||
|
StructFieldName, // [ struct field type ]
|
||||||
|
Variable, // [ struct name | variable value ]
|
||||||
|
VariableParents, // [ variable parent name | variable start ]
|
||||||
|
VariableStarted, // [ variable field name | variable end]
|
||||||
|
VariableChild, // [ variable child value ]
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper methods for readToken() being in specific State.
|
||||||
|
Type readInDefault();
|
||||||
|
Type readInStructStarted();
|
||||||
|
Type readInStructFieldName();
|
||||||
|
Type readInVariable();
|
||||||
|
Type readInVariableParents();
|
||||||
|
Type readInVariableStarted();
|
||||||
|
Type readInVariableChild();
|
||||||
|
|
||||||
|
Type saveToken(Type type, const QString &value = QString());
|
||||||
|
|
||||||
|
common::BasicTokenizedFile file_;
|
||||||
|
QList<Token> tokens_;
|
||||||
|
int currentToken_ = 0;
|
||||||
|
State state_ = State::Default;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace style
|
||||||
|
} // namespace codegen
|
|
@ -2378,8 +2378,12 @@
|
||||||
<None Include="Telegram.xcodeproj\qt_preprocess.mak" />
|
<None Include="Telegram.xcodeproj\qt_preprocess.mak" />
|
||||||
<None Include="Version" />
|
<None Include="Version" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CodegenStyleItem Include="Resources\all_files.style" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
<Import Project="build\vc\codegen_style\codegen_style.targets" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
|
|
|
@ -1535,4 +1535,9 @@
|
||||||
<Filter>Version</Filter>
|
<Filter>Version</Filter>
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<CodegenStyleItem Include="Resources\all_files.style">
|
||||||
|
<Filter>Resources</Filter>
|
||||||
|
</CodegenStyleItem>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml" />
|
||||||
|
<AvailableItemName Include="CodegenStyleItem">
|
||||||
|
<Targets>GenerateStyleCode</Targets>
|
||||||
|
</AvailableItemName>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<StyleFile Include="%(CodegenStyleItem.Identity)" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Target
|
||||||
|
Name="GenerateStyleCode"
|
||||||
|
BeforeTargets="ClCompile"
|
||||||
|
Inputs="%(CodegenStyleItem.Identity)"
|
||||||
|
Outputs=".\GeneratedFiles\styles\style_%(CodegenStyleItem.Filename).h;.\GeneratedFiles\styles\style_%(CodegenStyleItem.Filename).cpp">
|
||||||
|
<Message Text="Generating style: %(CodegenStyleItem.Identity)" />
|
||||||
|
<Exec Command="$(SolutionDir)$(Platform)\codegen\$(Configuration)\codegen_style.exe %(CodegenStyleItem.Identity)"/>
|
||||||
|
</Target>
|
||||||
|
</Project>
|
|
@ -11,8 +11,24 @@
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\checked_utf8_string.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\basic_tokenized_file.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\clean_file.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\logging.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\generator.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\tokenized_file.cpp" />
|
||||||
<ClCompile Include="..\..\..\SourceFiles\codegen\style\main.cpp" />
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\main.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\checked_utf8_string.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\clean_file_reader.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\basic_tokenized_file.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\clean_file.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\const_utf8_string.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\logging.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\generator.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\tokenized_file.h" />
|
||||||
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{E4DF8176-4DEF-4859-962F-B497E3E7A323}</ProjectGuid>
|
<ProjectGuid>{E4DF8176-4DEF-4859-962F-B497E3E7A323}</ProjectGuid>
|
||||||
<Keyword>Qt4VSv1.0</Keyword>
|
<Keyword>Qt4VSv1.0</Keyword>
|
||||||
|
@ -41,11 +57,12 @@
|
||||||
<_ProjectFileVersion>14.0.24730.2</_ProjectFileVersion>
|
<_ProjectFileVersion>14.0.24730.2</_ProjectFileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<IntDir>$(SolutionDir)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
<OutDir>$(SolutionDir)$(Platform)\codegen\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)$(Platform)\codegen\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)$(Platform)\obj\$(ProjectName)\</IntDir>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)$(Platform)\codegen\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
@ -53,8 +70,11 @@
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);.\..\..\..\SourceFiles;$(QTDIR)\include\QtCore;.\..\%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<AdditionalOptions>/w44062 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
@ -71,8 +91,9 @@
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>.;$(QTDIR)\include;.\GeneratedFiles\$(ConfigurationName);$(QTDIR)\include\QtCore;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<WarningLevel>EnableAllWarnings</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
<TreatWarningAsError>true</TreatWarningAsError>
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
|
<AdditionalOptions>/w44062 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
|
|
|
@ -1,28 +1,64 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Source Files">
|
<Filter Include="src">
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
<Extensions>cpp;cxx;c;def</Extensions>
|
<Extensions>cpp;cxx;c;def</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Header Files">
|
<Filter Include="src\common">
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
<UniqueIdentifier>{e722d237-774c-46d8-91c4-732e0c12d848}</UniqueIdentifier>
|
||||||
<Extensions>h</Extensions>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter Include="Resource Files">
|
<Filter Include="src\style">
|
||||||
<UniqueIdentifier>{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}</UniqueIdentifier>
|
<UniqueIdentifier>{fbf050c2-2ecd-4469-a24f-1dcf27e2520f}</UniqueIdentifier>
|
||||||
<Extensions>qrc;*</Extensions>
|
|
||||||
<ParseFiles>false</ParseFiles>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Generated Files">
|
|
||||||
<UniqueIdentifier>{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}</UniqueIdentifier>
|
|
||||||
<Extensions>moc;h;cpp</Extensions>
|
|
||||||
<SourceControlFiles>False</SourceControlFiles>
|
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\..\SourceFiles\codegen\style\main.cpp">
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>src\style</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\checked_utf8_string.cpp">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\logging.cpp">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\generator.cpp">
|
||||||
|
<Filter>src\style</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\clean_file.cpp">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\common\basic_tokenized_file.cpp">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\tokenized_file.cpp">
|
||||||
|
<Filter>src\style</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\generator.h">
|
||||||
|
<Filter>src\style</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\checked_utf8_string.h">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\logging.h">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\const_utf8_string.h">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\clean_file.h">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\clean_file_reader.h">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\basic_tokenized_file.h">
|
||||||
|
<Filter>src\common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\tokenized_file.h">
|
||||||
|
<Filter>src\style</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib">
|
||||||
|
<ItemType Name="CodegenStyleItem" DisplayName="Style File" />
|
||||||
|
<ContentType Name="CodegenStyleContent" ItemType="CodegenStyleItem" DisplayName="Style File" />
|
||||||
|
<FileExtension Name="*.style" ContentType="CodegenStyleContent" />
|
||||||
|
</ProjectSchemaDefinitions>
|
Loading…
Reference in New Issue