mirror of https://github.com/procxx/kepka.git
Reading of old style format fully supported in codegen_style.
This commit is contained in:
parent
e0160f7d4c
commit
edd26b3224
|
@ -385,7 +385,7 @@ btnDefIconed: iconedButton {
|
||||||
font: font(fsize);
|
font: font(fsize);
|
||||||
|
|
||||||
opacity: 0.78;
|
opacity: 0.78;
|
||||||
overOpacity: 1;
|
overOpacity: 1.;
|
||||||
|
|
||||||
textPos: point(0px, 0px);
|
textPos: point(0px, 0px);
|
||||||
downTextPos: point(0px, 0px);
|
downTextPos: point(0px, 0px);
|
||||||
|
@ -433,7 +433,7 @@ titleBackButton: iconedButton(btnDefIconed) {
|
||||||
width: -30px;
|
width: -30px;
|
||||||
height: 39px;
|
height: 39px;
|
||||||
|
|
||||||
opacity: 1;
|
opacity: 1.;
|
||||||
cursor: cursor(default);
|
cursor: cursor(default);
|
||||||
|
|
||||||
textPos: point(23px, 10px);
|
textPos: point(23px, 10px);
|
||||||
|
@ -2189,7 +2189,7 @@ mvDropdown: dropdown(dropdownDef) {
|
||||||
shadow: sprite(0px, 0px, 0px, 0px);
|
shadow: sprite(0px, 0px, 0px, 0px);
|
||||||
padding: margins(11px, 12px, 11px, 12px);
|
padding: margins(11px, 12px, 11px, 12px);
|
||||||
|
|
||||||
border: 0;
|
border: 0px;
|
||||||
width: 182px;
|
width: 182px;
|
||||||
}
|
}
|
||||||
mvButton: iconedButton(btnDefIconed) {
|
mvButton: iconedButton(btnDefIconed) {
|
||||||
|
@ -2197,8 +2197,8 @@ mvButton: iconedButton(btnDefIconed) {
|
||||||
overBgColor: #505050;
|
overBgColor: #505050;
|
||||||
font: font(fsize);
|
font: font(fsize);
|
||||||
|
|
||||||
opacity: 1;
|
opacity: 1.;
|
||||||
overOpacity: 1;
|
overOpacity: 1.;
|
||||||
|
|
||||||
width: -32px;
|
width: -32px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
|
@ -2298,21 +2298,22 @@ overviewFileExtFont: font(18px semibold);
|
||||||
|
|
||||||
// Mac specific
|
// Mac specific
|
||||||
|
|
||||||
macAccessory: size(450, 90);
|
macAccessoryWidth: 450.;
|
||||||
|
macAccessoryHeight: 90.;
|
||||||
macEnableFilterAdd: 2;
|
macEnableFilterAdd: 2;
|
||||||
macEnableFilterTop: 5;
|
macEnableFilterTop: 5;
|
||||||
macSelectorTop: 6;
|
macSelectorTop: 6;
|
||||||
macAlwaysThisAppTop: 4;
|
macAlwaysThisAppTop: 4;
|
||||||
macAppHintTop: 8;
|
macAppHintTop: 8;
|
||||||
macCautionIconSize: size(16, 16);
|
macCautionIconSize: 16;
|
||||||
|
|
||||||
btnContext: iconedButton(btnDefIconed) {
|
btnContext: iconedButton(btnDefIconed) {
|
||||||
bgColor: white;
|
bgColor: white;
|
||||||
overBgColor: btnWhiteHover;
|
overBgColor: btnWhiteHover;
|
||||||
font: font(14px);
|
font: font(14px);
|
||||||
|
|
||||||
opacity: 1;
|
opacity: 1.;
|
||||||
overOpacity: 1;
|
overOpacity: 1.;
|
||||||
|
|
||||||
width: -32px;
|
width: -32px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
|
@ -2399,8 +2400,8 @@ passcodeSkip: 31px;
|
||||||
|
|
||||||
mentionHeight: 40px;
|
mentionHeight: 40px;
|
||||||
mentionScroll: flatScroll(scrollDef) {
|
mentionScroll: flatScroll(scrollDef) {
|
||||||
topsh: 0;
|
topsh: 0px;
|
||||||
bottomsh: 0;
|
bottomsh: 0px;
|
||||||
}
|
}
|
||||||
mentionPadding: margins(8px, 5px, 8px, 5px);
|
mentionPadding: margins(8px, 5px, 8px, 5px);
|
||||||
mentionTop: 11px;
|
mentionTop: 11px;
|
||||||
|
@ -2420,7 +2421,7 @@ sessionsHeight: 440px;
|
||||||
sessionHeight: 70px;
|
sessionHeight: 70px;
|
||||||
sessionCurrentPadding: margins(0px, 7px, 0px, 4px);
|
sessionCurrentPadding: margins(0px, 7px, 0px, 4px);
|
||||||
sessionCurrentHeight: 118px;
|
sessionCurrentHeight: 118px;
|
||||||
sessionPadding: margins(21px, 10px, 21px, 0);
|
sessionPadding: margins(21px, 10px, 21px, 0px);
|
||||||
sessionNameFont: msgNameFont;
|
sessionNameFont: msgNameFont;
|
||||||
sessionActiveFont: msgDateFont;
|
sessionActiveFont: msgDateFont;
|
||||||
sessionActiveColor: #aaa;
|
sessionActiveColor: #aaa;
|
||||||
|
|
|
@ -26,7 +26,7 @@ textStyle {
|
||||||
monoFg: color;
|
monoFg: color;
|
||||||
selectBg: color;
|
selectBg: color;
|
||||||
selectOverlay: color;
|
selectOverlay: color;
|
||||||
lineHeight: number;
|
lineHeight: pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
linkButton {
|
linkButton {
|
||||||
|
@ -42,7 +42,7 @@ sysButton {
|
||||||
img: sprite;
|
img: sprite;
|
||||||
color: color;
|
color: color;
|
||||||
overColor: color;
|
overColor: color;
|
||||||
duration: number;
|
duration: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
flatButton {
|
flatButton {
|
||||||
|
@ -54,16 +54,16 @@ flatButton {
|
||||||
overBgColor: color;
|
overBgColor: color;
|
||||||
downBgColor: color;
|
downBgColor: color;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
|
|
||||||
textTop: number;
|
textTop: pixels;
|
||||||
overTextTop: number;
|
overTextTop: pixels;
|
||||||
downTextTop: number;
|
downTextTop: pixels;
|
||||||
|
|
||||||
font: font;
|
font: font;
|
||||||
overFont: font;
|
overFont: font;
|
||||||
duration: number;
|
duration: int;
|
||||||
cursor: cursor;
|
cursor: cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,17 +76,17 @@ iconedButton {
|
||||||
color: color;
|
color: color;
|
||||||
bgColor: color;
|
bgColor: color;
|
||||||
overBgColor: color;
|
overBgColor: color;
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
font: font;
|
font: font;
|
||||||
|
|
||||||
opacity: number;
|
opacity: double;
|
||||||
overOpacity: number;
|
overOpacity: double;
|
||||||
|
|
||||||
textPos: point;
|
textPos: point;
|
||||||
downTextPos: point;
|
downTextPos: point;
|
||||||
|
|
||||||
duration: number;
|
duration: int;
|
||||||
cursor: cursor;
|
cursor: cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,12 +95,12 @@ flatCheckbox {
|
||||||
bgColor: color;
|
bgColor: color;
|
||||||
disColor: color;
|
disColor: color;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
textTop: number;
|
textTop: pixels;
|
||||||
textLeft: number;
|
textLeft: pixels;
|
||||||
font: font;
|
font: font;
|
||||||
duration: number;
|
duration: int;
|
||||||
bgFunc: transition;
|
bgFunc: transition;
|
||||||
cursor: cursor;
|
cursor: cursor;
|
||||||
|
|
||||||
|
@ -120,8 +120,8 @@ flatInput {
|
||||||
textColor: color;
|
textColor: color;
|
||||||
bgColor: color;
|
bgColor: color;
|
||||||
bgActive: color;
|
bgActive: color;
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
textMrg: margins;
|
textMrg: margins;
|
||||||
align: align;
|
align: align;
|
||||||
font: font;
|
font: font;
|
||||||
|
@ -130,7 +130,7 @@ flatInput {
|
||||||
imgRect: sprite;
|
imgRect: sprite;
|
||||||
imgPos: point;
|
imgPos: point;
|
||||||
|
|
||||||
borderWidth: number;
|
borderWidth: pixels;
|
||||||
borderColor: color;
|
borderColor: color;
|
||||||
borderActive: color;
|
borderActive: color;
|
||||||
borderError: color;
|
borderError: color;
|
||||||
|
@ -139,8 +139,8 @@ flatInput {
|
||||||
phFocusColor: color;
|
phFocusColor: color;
|
||||||
phPos: point;
|
phPos: point;
|
||||||
phAlign: align;
|
phAlign: align;
|
||||||
phShift: number;
|
phShift: pixels;
|
||||||
phDuration: number;
|
phDuration: int;
|
||||||
phLeftFunc: transition;
|
phLeftFunc: transition;
|
||||||
phAlphaFunc: transition;
|
phAlphaFunc: transition;
|
||||||
phColorFunc: transition;
|
phColorFunc: transition;
|
||||||
|
@ -149,7 +149,7 @@ flatInput {
|
||||||
flatTextarea {
|
flatTextarea {
|
||||||
textColor: color;
|
textColor: color;
|
||||||
bgColor: color;
|
bgColor: color;
|
||||||
width: number;
|
width: pixels;
|
||||||
textMrg: margins;
|
textMrg: margins;
|
||||||
align: align;
|
align: align;
|
||||||
font: font;
|
font: font;
|
||||||
|
@ -159,8 +159,8 @@ flatTextarea {
|
||||||
phFocusColor: color;
|
phFocusColor: color;
|
||||||
phPos: point;
|
phPos: point;
|
||||||
phAlign: align;
|
phAlign: align;
|
||||||
phShift: number;
|
phShift: pixels;
|
||||||
phDuration: number;
|
phDuration: int;
|
||||||
phLeftFunc: transition;
|
phLeftFunc: transition;
|
||||||
phAlphaFunc: transition;
|
phAlphaFunc: transition;
|
||||||
phColorFunc: transition;
|
phColorFunc: transition;
|
||||||
|
@ -172,26 +172,26 @@ flatScroll {
|
||||||
barOverColor: color;
|
barOverColor: color;
|
||||||
bgOverColor: color;
|
bgOverColor: color;
|
||||||
|
|
||||||
round: number;
|
round: pixels;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
minHeight: number;
|
minHeight: pixels;
|
||||||
deltax: number;
|
deltax: pixels;
|
||||||
deltat: number;
|
deltat: pixels;
|
||||||
deltab: number;
|
deltab: pixels;
|
||||||
|
|
||||||
topsh: number;
|
topsh: pixels;
|
||||||
bottomsh: number;
|
bottomsh: pixels;
|
||||||
shColor: color;
|
shColor: color;
|
||||||
|
|
||||||
duration: number;
|
duration: int;
|
||||||
hiding: number;
|
hiding: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
countryInput {
|
countryInput {
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
top: number;
|
top: pixels;
|
||||||
bgColor: color;
|
bgColor: color;
|
||||||
ptrSize: size;
|
ptrSize: size;
|
||||||
textMrg: margins;
|
textMrg: margins;
|
||||||
|
@ -201,53 +201,53 @@ countryInput {
|
||||||
|
|
||||||
slider {
|
slider {
|
||||||
color: color;
|
color: color;
|
||||||
thikness: number;
|
thikness: pixels;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
bar: sprite;
|
bar: sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
flatLabel {
|
flatLabel {
|
||||||
font: font;
|
font: font;
|
||||||
minWidth: number;
|
minWidth: pixels;
|
||||||
width: number;
|
width: pixels;
|
||||||
align: align;
|
align: align;
|
||||||
}
|
}
|
||||||
|
|
||||||
switcher {
|
switcher {
|
||||||
border: number;
|
border: pixels;
|
||||||
borderColor: color;
|
borderColor: color;
|
||||||
|
|
||||||
bgColor: color;
|
bgColor: color;
|
||||||
bgHovered: color;
|
bgHovered: color;
|
||||||
bgActive: color;
|
bgActive: color;
|
||||||
|
|
||||||
height: number;
|
height: pixels;
|
||||||
|
|
||||||
font: font;
|
font: font;
|
||||||
textColor: color;
|
textColor: color;
|
||||||
activeColor: color;
|
activeColor: color;
|
||||||
|
|
||||||
duration: number;
|
duration: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
dropdown {
|
dropdown {
|
||||||
border: number;
|
border: pixels;
|
||||||
borderColor: color;
|
borderColor: color;
|
||||||
|
|
||||||
padding: margins;
|
padding: margins;
|
||||||
shadow: sprite;
|
shadow: sprite;
|
||||||
shadowShift: number;
|
shadowShift: pixels;
|
||||||
|
|
||||||
duration: number;
|
duration: int;
|
||||||
width: number;
|
width: pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupMenu {
|
PopupMenu {
|
||||||
skip: number;
|
skip: pixels;
|
||||||
|
|
||||||
shadow: sprite;
|
shadow: sprite;
|
||||||
shadowShift: number;
|
shadowShift: pixels;
|
||||||
|
|
||||||
itemBg: color;
|
itemBg: color;
|
||||||
itemBgOver: color;
|
itemBgOver: color;
|
||||||
|
@ -261,15 +261,15 @@ PopupMenu {
|
||||||
itemFont: font;
|
itemFont: font;
|
||||||
|
|
||||||
separatorPadding: margins;
|
separatorPadding: margins;
|
||||||
separatorWidth: number;
|
separatorWidth: pixels;
|
||||||
separatorFg: color;
|
separatorFg: color;
|
||||||
|
|
||||||
arrow: sprite;
|
arrow: sprite;
|
||||||
|
|
||||||
duration: number;
|
duration: int;
|
||||||
|
|
||||||
widthMin: number;
|
widthMin: pixels;
|
||||||
widthMax: number;
|
widthMax: pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
Tooltip {
|
Tooltip {
|
||||||
|
@ -280,18 +280,18 @@ Tooltip {
|
||||||
textPadding: margins;
|
textPadding: margins;
|
||||||
|
|
||||||
shift: point;
|
shift: point;
|
||||||
skip: number;
|
skip: pixels;
|
||||||
|
|
||||||
widthMax: number;
|
widthMax: pixels;
|
||||||
linesMax: number;
|
linesMax: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
botKeyboardButton {
|
botKeyboardButton {
|
||||||
margin: number;
|
margin: pixels;
|
||||||
padding: number;
|
padding: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
textTop: number;
|
textTop: pixels;
|
||||||
downTextTop: number;
|
downTextTop: pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoxButton {
|
BoxButton {
|
||||||
|
@ -300,13 +300,13 @@ BoxButton {
|
||||||
textBg: color; // rect of textBg with rounded rect of textBgOver upon it
|
textBg: color; // rect of textBg with rounded rect of textBgOver upon it
|
||||||
textBgOver: color;
|
textBgOver: color;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
|
|
||||||
textTop: number;
|
textTop: pixels;
|
||||||
|
|
||||||
font: font;
|
font: font;
|
||||||
duration: number;
|
duration: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
Checkbox {
|
Checkbox {
|
||||||
|
@ -317,16 +317,16 @@ Checkbox {
|
||||||
checkFgOver: color;
|
checkFgOver: color;
|
||||||
checkFgActive: color;
|
checkFgActive: color;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
|
|
||||||
textPosition: point;
|
textPosition: point;
|
||||||
diameter: number;
|
diameter: pixels;
|
||||||
thickness: number;
|
thickness: pixels;
|
||||||
checkIcon: sprite;
|
checkIcon: sprite;
|
||||||
|
|
||||||
font: font;
|
font: font;
|
||||||
duration: number;
|
duration: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
Radiobutton {
|
Radiobutton {
|
||||||
|
@ -337,16 +337,16 @@ Radiobutton {
|
||||||
checkFgOver: color;
|
checkFgOver: color;
|
||||||
checkFgActive: color;
|
checkFgActive: color;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
|
|
||||||
textPosition: point;
|
textPosition: point;
|
||||||
diameter: number;
|
diameter: pixels;
|
||||||
thickness: number;
|
thickness: pixels;
|
||||||
checkSkip: number;
|
checkSkip: pixels;
|
||||||
|
|
||||||
font: font;
|
font: font;
|
||||||
duration: number;
|
duration: int;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputArea {
|
InputArea {
|
||||||
|
@ -357,23 +357,23 @@ InputArea {
|
||||||
placeholderFgActive: color;
|
placeholderFgActive: color;
|
||||||
placeholderMargins: margins;
|
placeholderMargins: margins;
|
||||||
placeholderAlign: align;
|
placeholderAlign: align;
|
||||||
placeholderShift: number;
|
placeholderShift: pixels;
|
||||||
|
|
||||||
duration: number;
|
duration: int;
|
||||||
|
|
||||||
borderFg: color;
|
borderFg: color;
|
||||||
borderFgActive: color;
|
borderFgActive: color;
|
||||||
borderFgError: color;
|
borderFgError: color;
|
||||||
|
|
||||||
border: number;
|
border: pixels;
|
||||||
borderActive: number;
|
borderActive: pixels;
|
||||||
borderError: number;
|
borderError: pixels;
|
||||||
|
|
||||||
font: font;
|
font: font;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
heightMin: number;
|
heightMin: pixels;
|
||||||
heightMax: number;
|
heightMax: pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputField {
|
InputField {
|
||||||
|
@ -385,28 +385,28 @@ InputField {
|
||||||
placeholderFgActive: color;
|
placeholderFgActive: color;
|
||||||
placeholderMargins: margins;
|
placeholderMargins: margins;
|
||||||
placeholderAlign: align;
|
placeholderAlign: align;
|
||||||
placeholderShift: number;
|
placeholderShift: pixels;
|
||||||
|
|
||||||
duration: number;
|
duration: int;
|
||||||
|
|
||||||
borderFg: color;
|
borderFg: color;
|
||||||
borderFgActive: color;
|
borderFgActive: color;
|
||||||
borderFgError: color;
|
borderFgError: color;
|
||||||
|
|
||||||
border: number;
|
border: pixels;
|
||||||
borderActive: number;
|
borderActive: pixels;
|
||||||
borderError: number;
|
borderError: pixels;
|
||||||
|
|
||||||
font: font;
|
font: font;
|
||||||
|
|
||||||
width: number;
|
width: pixels;
|
||||||
height: number;
|
height: pixels;
|
||||||
|
|
||||||
iconSprite: sprite;
|
iconSprite: sprite;
|
||||||
iconPosition: point;
|
iconPosition: point;
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerAvatarButton {
|
PeerAvatarButton {
|
||||||
size: number;
|
size: pixels;
|
||||||
photoSize: number;
|
photoSize: pixels;
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,6 +249,32 @@ void BasicTokenizedFile::skipWhitespaces() {
|
||||||
tokenStart_ = reader_.currentPtr();
|
tokenStart_ = reader_.currentPtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogStream operator<<(LogStream &&stream, BasicTokenizedFile::Token::Type type) {
|
||||||
|
const char *value = "'invalid'";
|
||||||
|
switch (type) {
|
||||||
|
case Type::Invalid: break;
|
||||||
|
case Type::Int: value = "'int'"; break;
|
||||||
|
case Type::Double: value = "'double'"; break;
|
||||||
|
case Type::String: value = "'string'"; break;
|
||||||
|
case Type::LeftParenthesis: value = "'('"; break;
|
||||||
|
case Type::RightParenthesis: value = "')'"; break;
|
||||||
|
case Type::LeftBrace: value = "'{'"; break;
|
||||||
|
case Type::RightBrace: value = "'}'"; break;
|
||||||
|
case Type::LeftBracket: value = "'['"; break;
|
||||||
|
case Type::RightBracket: value = "']'"; break;
|
||||||
|
case Type::Colon: value = "':'"; break;
|
||||||
|
case Type::Semicolon: value = "';'"; break;
|
||||||
|
case Type::Comma: value = "','"; break;
|
||||||
|
case Type::Dot: value = "'.'"; break;
|
||||||
|
case Type::Number: value = "'#'"; break;
|
||||||
|
case Type::Plus: value = "'+'"; break;
|
||||||
|
case Type::Minus: value = "'-'"; break;
|
||||||
|
case Type::Equals: value = "'='"; break;
|
||||||
|
case Type::Name: value = "'identifier'"; break;
|
||||||
|
}
|
||||||
|
return std::forward<LogStream>(stream) << value;
|
||||||
|
}
|
||||||
|
|
||||||
LogStream BasicTokenizedFile::logError(int code) const {
|
LogStream BasicTokenizedFile::logError(int code) const {
|
||||||
return reader_.logError(code, lineNumber_);
|
return reader_.logError(code, lineNumber_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,5 +147,11 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LogStream operator<<(LogStream &&stream, BasicTokenizedFile::Token::Type type);
|
||||||
|
template <>
|
||||||
|
LogStream operator<< <BasicTokenizedFile::Token::Type>(LogStream &&stream, BasicTokenizedFile::Token::Type &&value) = delete;
|
||||||
|
template <>
|
||||||
|
LogStream operator<< <const BasicTokenizedFile::Token::Type&>(LogStream &&stream, const BasicTokenizedFile::Token::Type &value) = delete;
|
||||||
|
|
||||||
} // namespace common
|
} // namespace common
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
}
|
}
|
||||||
explicit LogStream(std::ostream &stream) : stream_(&stream) {
|
explicit LogStream(std::ostream &stream) : stream_(&stream) {
|
||||||
}
|
}
|
||||||
LogStream(LogStream &&other) : stream_(other.stream_) {
|
LogStream(LogStream &&other) : stream_(other.stream_), final_(other.final_) {
|
||||||
other.final_ = false;
|
other.final_ = false;
|
||||||
}
|
}
|
||||||
std::ostream *stream() const {
|
std::ostream *stream() const {
|
||||||
|
|
|
@ -22,7 +22,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
//#include "codegen/common/qstringlist_safe.h"
|
|
||||||
#include "codegen/style/options.h"
|
#include "codegen/style/options.h"
|
||||||
|
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
|
|
|
@ -38,6 +38,8 @@ constexpr int kErrorInIncluded = 801;
|
||||||
constexpr int kErrorTypeMismatch = 802;
|
constexpr int kErrorTypeMismatch = 802;
|
||||||
constexpr int kErrorUnknownField = 803;
|
constexpr int kErrorUnknownField = 803;
|
||||||
constexpr int kErrorIdentifierNotFound = 804;
|
constexpr int kErrorIdentifierNotFound = 804;
|
||||||
|
constexpr int kErrorAlreadyDefined = 805;
|
||||||
|
constexpr int kErrorBadString = 806;
|
||||||
|
|
||||||
QString tokenValue(const BasicToken &token) {
|
QString tokenValue(const BasicToken &token) {
|
||||||
if (token.type == BasicType::String) {
|
if (token.type == BasicType::String) {
|
||||||
|
@ -54,13 +56,45 @@ bool isValidColor(const QString &str) {
|
||||||
|
|
||||||
for (auto ch : str) {
|
for (auto ch : str) {
|
||||||
auto code = ch.unicode();
|
auto code = ch.unicode();
|
||||||
if ((code < '0' || code > '9') && (code < 'a' || code > 'f') && (code < 'A' || code > 'F')) {
|
if ((code < '0' || code > '9') && (code < 'a' || code > 'f')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uchar readHexUchar(QChar ch) {
|
||||||
|
auto code = ch.unicode();
|
||||||
|
return (code >= '0' && code <= '9') ? ((code - '0') & 0xFF) : ((code - 'a') & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
uchar readHexUchar(QChar char1, QChar char2) {
|
||||||
|
return ((readHexUchar(char1) & 0x0F) << 4) | (readHexUchar(char2) & 0x0F);
|
||||||
|
}
|
||||||
|
|
||||||
|
structure::data::color convertWebColor(const QString &str) {
|
||||||
|
uchar r = 0, g = 0, b = 0, a = 255;
|
||||||
|
if (isValidColor(str)) {
|
||||||
|
auto len = str.size();
|
||||||
|
if (len == 3 || len == 4) {
|
||||||
|
r = readHexUchar(str.at(0), str.at(0));
|
||||||
|
g = readHexUchar(str.at(1), str.at(1));
|
||||||
|
b = readHexUchar(str.at(2), str.at(2));
|
||||||
|
if (len == 4) a = readHexUchar(str.at(3), str.at(3));
|
||||||
|
} else {
|
||||||
|
r = readHexUchar(str.at(0), str.at(1));
|
||||||
|
g = readHexUchar(str.at(2), str.at(3));
|
||||||
|
b = readHexUchar(str.at(4), str.at(5));
|
||||||
|
if (len == 8) a = readHexUchar(str.at(6), str.at(7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { r, g, b, a };
|
||||||
|
}
|
||||||
|
|
||||||
|
structure::data::color convertIntColor(int r, int g, int b, int a) {
|
||||||
|
return { uchar(r & 0xFF), uchar(g & 0xFF), uchar(b & 0xFF), uchar(a & 0xFF) };
|
||||||
|
}
|
||||||
|
|
||||||
std::string logFullName(const structure::FullName &name) {
|
std::string logFullName(const structure::FullName &name) {
|
||||||
return name.join('.').toStdString();
|
return name.join('.').toStdString();
|
||||||
}
|
}
|
||||||
|
@ -87,6 +121,31 @@ std::string logType(const structure::Type &type) {
|
||||||
return builtInTypes->value(type.tag, "invalid");
|
return builtInTypes->value(type.tag, "invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString fullNameKey(const structure::FullName &name) {
|
||||||
|
return name.join('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateAnsiString(const QString &value) {
|
||||||
|
for (auto ch : value) {
|
||||||
|
if (ch.unicode() > 127) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateTransitionString(const QString &value) {
|
||||||
|
return QRegularExpression("^[a-zA-Z_]+$").match(value).hasMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateCursorString(const QString &value) {
|
||||||
|
return QRegularExpression("^[a-z_]+$").match(value).hasMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateAlignString(const QString &value) {
|
||||||
|
return QRegularExpression("^[a-z_]+$").match(value).hasMatch();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ParsedFile::ParsedFile(const Options &options)
|
ParsedFile::ParsedFile(const Options &options)
|
||||||
|
@ -109,11 +168,21 @@ bool ParsedFile::read() {
|
||||||
}
|
}
|
||||||
} else if (auto braceOpen = file_.getToken(BasicType::LeftBrace)) {
|
} else if (auto braceOpen = file_.getToken(BasicType::LeftBrace)) {
|
||||||
if (auto structResult = readStruct(tokenValue(startToken))) {
|
if (auto structResult = readStruct(tokenValue(startToken))) {
|
||||||
|
if (findStruct(structResult.name)) {
|
||||||
|
logError(kErrorAlreadyDefined) << "struct '" << logFullName(structResult.name) << "' already defined";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result_.structsByName.insert(fullNameKey(structResult.name), result_.structs.size());
|
||||||
result_.structs.push_back(structResult);
|
result_.structs.push_back(structResult);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (auto colonToken = file_.getToken(BasicType::Colon)) {
|
} else if (auto colonToken = file_.getToken(BasicType::Colon)) {
|
||||||
if (auto variableResult = readVariable(tokenValue(startToken))) {
|
if (auto variableResult = readVariable(tokenValue(startToken))) {
|
||||||
|
if (findVariable(variableResult.name)) {
|
||||||
|
logError(kErrorAlreadyDefined) << "variable '" << logFullName(variableResult.name) << "' already defined";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result_.variablesByName.insert(fullNameKey(variableResult.name), result_.variables.size());
|
||||||
result_.variables.push_back(variableResult);
|
result_.variables.push_back(variableResult);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -139,19 +208,15 @@ common::LogStream ParsedFile::logErrorTypeMismatch() {
|
||||||
|
|
||||||
structure::Module ParsedFile::readIncluded() {
|
structure::Module ParsedFile::readIncluded() {
|
||||||
structure::Module result;
|
structure::Module result;
|
||||||
if (auto usingFile = file_.getToken(BasicType::String)) {
|
if (auto usingFile = assertNextToken(BasicType::String)) {
|
||||||
if (file_.getToken(BasicType::Semicolon)) {
|
if (assertNextToken(BasicType::Semicolon)) {
|
||||||
ParsedFile included(includedOptions(tokenValue(usingFile)));
|
ParsedFile included(includedOptions(tokenValue(usingFile)));
|
||||||
if (included.read()) {
|
if (included.read()) {
|
||||||
result = included.data();
|
result = included.data();
|
||||||
} else {
|
} else {
|
||||||
logError(kErrorInIncluded) << "error while parsing '" << tokenValue(usingFile).toStdString() << "'";
|
logError(kErrorInIncluded) << "error while parsing '" << tokenValue(usingFile).toStdString() << "'";
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "';'";
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "file path";
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -163,13 +228,11 @@ structure::Struct ParsedFile::readStruct(const QString &name) {
|
||||||
if (auto field = readStructField(tokenValue(fieldName))) {
|
if (auto field = readStructField(tokenValue(fieldName))) {
|
||||||
result.fields.push_back(field);
|
result.fields.push_back(field);
|
||||||
}
|
}
|
||||||
} else if (auto braceClose = file_.getToken(BasicType::RightBrace)) {
|
} else if (assertNextToken(BasicType::RightBrace)) {
|
||||||
if (result.fields.isEmpty()) {
|
if (result.fields.isEmpty()) {
|
||||||
logErrorUnexpectedToken() << "at least one field in struct";
|
logErrorUnexpectedToken() << "at least one field in struct";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "struct field name or '}'";
|
|
||||||
}
|
}
|
||||||
} while (!failed());
|
} while (!failed());
|
||||||
return result;
|
return result;
|
||||||
|
@ -179,8 +242,8 @@ structure::Variable ParsedFile::readVariable(const QString &name) {
|
||||||
structure::Variable result = { composeFullName(name) };
|
structure::Variable result = { composeFullName(name) };
|
||||||
if (auto value = readValue()) {
|
if (auto value = readValue()) {
|
||||||
result.value = value;
|
result.value = value;
|
||||||
if (!file_.getToken(BasicType::Semicolon)) {
|
if (value.type().tag != structure::TypeTag::Struct) {
|
||||||
logErrorUnexpectedToken() << "';'";
|
assertNextToken(BasicType::Semicolon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -188,31 +251,30 @@ structure::Variable ParsedFile::readVariable(const QString &name) {
|
||||||
|
|
||||||
structure::StructField ParsedFile::readStructField(const QString &name) {
|
structure::StructField ParsedFile::readStructField(const QString &name) {
|
||||||
structure::StructField result = { composeFullName(name) };
|
structure::StructField result = { composeFullName(name) };
|
||||||
if (auto colonToken = file_.getToken(BasicType::Colon)) {
|
if (auto colonToken = assertNextToken(BasicType::Colon)) {
|
||||||
if (auto type = readType()) {
|
if (auto type = readType()) {
|
||||||
result.type = type;
|
result.type = type;
|
||||||
if (!file_.getToken(BasicType::Semicolon)) {
|
assertNextToken(BasicType::Semicolon);
|
||||||
logErrorUnexpectedToken() << "';'";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "':'";
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Type ParsedFile::readType() {
|
structure::Type ParsedFile::readType() {
|
||||||
structure::Type result;
|
structure::Type result;
|
||||||
if (auto nameToken = file_.getToken(BasicType::Name)) {
|
if (auto nameToken = assertNextToken(BasicType::Name)) {
|
||||||
auto name = tokenValue(nameToken);
|
auto name = tokenValue(nameToken);
|
||||||
if (auto builtInType = typeNames_.value(name.toStdString())) {
|
if (auto builtInType = typeNames_.value(name.toStdString())) {
|
||||||
result = builtInType;
|
result = builtInType;
|
||||||
} else {
|
} else {
|
||||||
result.tag = structure::TypeTag::Struct;
|
auto fullName = composeFullName(name);
|
||||||
result.name = composeFullName(name);
|
if (findStruct(fullName)) {
|
||||||
|
result.tag = structure::TypeTag::Struct;
|
||||||
|
result.name = fullName;
|
||||||
|
} else {
|
||||||
|
logError(kErrorIdentifierNotFound) << "type name '" << logFullName(fullName) << "' not found";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "type name";
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -254,17 +316,12 @@ structure::Value ParsedFile::readStructValue() {
|
||||||
if (auto structName = file_.getToken(BasicType::Name)) {
|
if (auto structName = file_.getToken(BasicType::Name)) {
|
||||||
if (auto result = defaultConstructedStruct(composeFullName(tokenValue(structName)))) {
|
if (auto result = defaultConstructedStruct(composeFullName(tokenValue(structName)))) {
|
||||||
if (file_.getToken(BasicType::LeftParenthesis)) {
|
if (file_.getToken(BasicType::LeftParenthesis)) {
|
||||||
if (readStructParents(result)) {
|
if (!readStructParents(result)) {
|
||||||
if (file_.getToken(BasicType::LeftBrace)) {
|
return {};
|
||||||
readStructValueInner(result);
|
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "'{'";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (file_.getToken(BasicType::LeftBrace)) {
|
}
|
||||||
|
if (assertNextToken(BasicType::LeftBrace)) {
|
||||||
readStructValueInner(result);
|
readStructValueInner(result);
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "'(' or '{'";
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -274,71 +331,91 @@ structure::Value ParsedFile::readStructValue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::defaultConstructedStruct(const structure::FullName &structName) {
|
structure::Value ParsedFile::defaultConstructedStruct(const structure::FullName &structName) {
|
||||||
structure::Value result;
|
if (auto pattern = findStruct(structName)) {
|
||||||
for (const auto &structType : result_.structs) {
|
QList<structure::Variable> fields;
|
||||||
if (structType.name == structName) {
|
fields.reserve(pattern->fields.size());
|
||||||
result.fields.reserve(structType.fields.size());
|
for (const auto &fieldType : pattern->fields) {
|
||||||
for (const auto &fieldType : structType.fields) {
|
fields.push_back({ fieldType.name, { fieldType.type, Qt::Uninitialized } });
|
||||||
result.fields.push_back({ fieldType.name, fieldType.type });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return { structName, fields };
|
||||||
}
|
}
|
||||||
return result;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParsedFile::applyStructParent(structure::Value &result, const structure::FullName &parentName) {
|
void ParsedFile::applyStructParent(structure::Value &result, const structure::FullName &parentName) {
|
||||||
for (const auto &structValue : result_.variables) {
|
if (auto parent = findVariable(parentName)) {
|
||||||
if (structValue.name == parentName) {
|
if (parent->value.type() != result.type()) {
|
||||||
if (structValue.value.type == result.type) {
|
logErrorTypeMismatch() << "parent '" << logFullName(parentName) << "' has type '" << logType(parent->value.type()) << "' while child value has type " << logType(result.type());
|
||||||
const auto &srcFields(structValue.value.fields);
|
return;
|
||||||
auto &dstFields(result.fields);
|
|
||||||
logAssert(srcFields.size() == dstFields.size()) << "struct size check failed";
|
|
||||||
|
|
||||||
for (int i = 0, s = srcFields.size(); i != s; ++i) {
|
|
||||||
logAssert(srcFields.at(i).value.type == dstFields.at(i).value.type) << "struct field type check failed";
|
|
||||||
dstFields[i].value = srcFields.at(i).value;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logErrorTypeMismatch() << "parent '" << logFullName(parentName) << "' has type '" << logType(structValue.value.type) << "' while child value has type " << logType(result.type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto *srcFields(parent->value.Complex());
|
||||||
|
auto *dstFields(result.Complex());
|
||||||
|
if (!srcFields || !dstFields) {
|
||||||
|
logAssert(false) << "struct data check failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logAssert(srcFields->size() == dstFields->size()) << "struct size check failed";
|
||||||
|
for (int i = 0, s = srcFields->size(); i != s; ++i) {
|
||||||
|
const auto &srcValue(srcFields->at(i).value);
|
||||||
|
auto &dstValue((*dstFields)[i].value);
|
||||||
|
logAssert(srcValue.type() == dstValue.type()) << "struct field type check failed";
|
||||||
|
dstValue = srcValue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logError(kErrorIdentifierNotFound) << "parent '" << logFullName(parentName) << "' not found";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParsedFile::readStructValueInner(structure::Value &result) {
|
bool ParsedFile::readStructValueInner(structure::Value &result) {
|
||||||
do {
|
do {
|
||||||
if (auto fieldName = file_.getToken(BasicType::Name)) {
|
if (auto fieldName = file_.getToken(BasicType::Name)) {
|
||||||
if (auto field = readVariable(tokenValue(fieldName))) {
|
if (!assertNextToken(BasicType::Colon)) {
|
||||||
for (auto &already : result.fields) {
|
return false;
|
||||||
if (already.name == field.name) {
|
|
||||||
if (already.value.type == field.value.type) {
|
|
||||||
already.value = field.value;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
logErrorTypeMismatch() << "field '" << logFullName(already.name) << "' has type '" << logType(already.value.type) << "' while value has type " << logType(field.value.type);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
logError(kErrorUnknownField) << "field '" << logFullName(field.name) << "' was not found in struct of type '" << logType(result.type) << "'";
|
|
||||||
}
|
}
|
||||||
} else if (file_.getToken(BasicType::RightBrace)) {
|
|
||||||
|
if (auto field = readVariable(tokenValue(fieldName))) {
|
||||||
|
if (!assignStructField(result, field)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (assertNextToken(BasicType::RightBrace)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
logErrorUnexpectedToken() << "variable field name or '}'";
|
|
||||||
}
|
}
|
||||||
} while (!failed());
|
} while (!failed());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ParsedFile::assignStructField(structure::Value &result, const structure::Variable &field) {
|
||||||
|
auto *fields = result.Complex();
|
||||||
|
if (!fields) {
|
||||||
|
logAssert(false) << "struct data check failed";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (auto &already : *fields) {
|
||||||
|
if (already.name == field.name) {
|
||||||
|
if (already.value.type() == field.value.type()) {
|
||||||
|
already.value = field.value;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
logErrorTypeMismatch() << "field '" << logFullName(already.name) << "' has type '" << logType(already.value.type()) << "' while value has type '" << logType(field.value.type()) << "'";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logError(kErrorUnknownField) << "field '" << logFullName(field.name) << "' was not found in struct of type '" << logType(result.type()) << "'";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ParsedFile::readStructParents(structure::Value &result) {
|
bool ParsedFile::readStructParents(structure::Value &result) {
|
||||||
do {
|
do {
|
||||||
if (auto parentName = file_.getToken(BasicType::Name)) {
|
if (auto parentName = assertNextToken(BasicType::Name)) {
|
||||||
applyStructParent(result, composeFullName(tokenValue(parentName)));
|
applyStructParent(result, composeFullName(tokenValue(parentName)));
|
||||||
if (file_.getToken(BasicType::RightParenthesis)) {
|
if (file_.getToken(BasicType::RightParenthesis)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (!file_.getToken(BasicType::Comma)) {
|
} else {
|
||||||
logErrorUnexpectedToken() << "',' or ')'";
|
assertNextToken(BasicType::Comma);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logErrorUnexpectedToken() << "struct variable parent";
|
logErrorUnexpectedToken() << "struct variable parent";
|
||||||
|
@ -347,30 +424,17 @@ bool ParsedFile::readStructParents(structure::Value &result) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//ParsedFile::Token ParsedFile::readInVariableChild() {
|
|
||||||
// if (auto value = readValue()) {
|
|
||||||
// if (file_.getToken(BasicType::Semicolon)) {
|
|
||||||
// state_ = State::Default;
|
|
||||||
// return value;
|
|
||||||
// }
|
|
||||||
// logErrorUnexpectedToken(";");
|
|
||||||
// } else {
|
|
||||||
// logErrorUnexpectedToken("variable field value");
|
|
||||||
// }
|
|
||||||
// return invalidToken();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
structure::Value ParsedFile::readPositiveValue() {
|
structure::Value ParsedFile::readPositiveValue() {
|
||||||
auto numericToken = file_.getAnyToken();
|
auto numericToken = file_.getAnyToken();
|
||||||
if (numericToken.type == BasicType::Int) {
|
if (numericToken.type == BasicType::Int) {
|
||||||
return { { structure::TypeTag::Int }, tokenValue(numericToken) };
|
return { structure::TypeTag::Int, tokenValue(numericToken).toInt() };
|
||||||
} else if (numericToken.type == BasicType::Double) {
|
} else if (numericToken.type == BasicType::Double) {
|
||||||
return { { structure::TypeTag::Double }, tokenValue(numericToken) };
|
return { tokenValue(numericToken).toDouble() };
|
||||||
} else if (numericToken.type == BasicType::Name) {
|
} else if (numericToken.type == BasicType::Name) {
|
||||||
auto value = tokenValue(numericToken);
|
auto value = tokenValue(numericToken);
|
||||||
auto match = QRegularExpression("^\\d+px$").match(value);
|
auto match = QRegularExpression("^\\d+px$").match(value);
|
||||||
if (match.hasMatch()) {
|
if (match.hasMatch()) {
|
||||||
return { { structure::TypeTag::Pixels }, value.mid(0, value.size() - 2) };
|
return { structure::TypeTag::Pixels, value.mid(0, value.size() - 2).toInt() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_.putBack();
|
file_.putBack();
|
||||||
|
@ -382,7 +446,7 @@ structure::Value ParsedFile::readNumericValue() {
|
||||||
return value;
|
return value;
|
||||||
} else if (auto minusToken = file_.getToken(BasicType::Minus)) {
|
} else if (auto minusToken = file_.getToken(BasicType::Minus)) {
|
||||||
if (auto positiveValue = readNumericValue()) {
|
if (auto positiveValue = readNumericValue()) {
|
||||||
return { positiveValue.type, '-' + positiveValue.data };
|
return { positiveValue.type().tag, -positiveValue.Int() };
|
||||||
}
|
}
|
||||||
logErrorUnexpectedToken() << "numeric value";
|
logErrorUnexpectedToken() << "numeric value";
|
||||||
}
|
}
|
||||||
|
@ -391,7 +455,11 @@ structure::Value ParsedFile::readNumericValue() {
|
||||||
|
|
||||||
structure::Value ParsedFile::readStringValue() {
|
structure::Value ParsedFile::readStringValue() {
|
||||||
if (auto stringToken = file_.getToken(BasicType::String)) {
|
if (auto stringToken = file_.getToken(BasicType::String)) {
|
||||||
return { { structure::TypeTag::String }, stringToken.value };
|
auto value = tokenValue(stringToken);
|
||||||
|
if (validateAnsiString(value)) {
|
||||||
|
return { structure::TypeTag::String, stringToken.value.toStdString() };
|
||||||
|
}
|
||||||
|
logError(kErrorBadString) << "unicode symbols are not supported";
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -400,47 +468,92 @@ structure::Value ParsedFile::readColorValue() {
|
||||||
if (auto numberSign = file_.getToken(BasicType::Number)) {
|
if (auto numberSign = file_.getToken(BasicType::Number)) {
|
||||||
auto color = file_.getAnyToken();
|
auto color = file_.getAnyToken();
|
||||||
if (color.type == BasicType::Int || color.type == BasicType::Name) {
|
if (color.type == BasicType::Int || color.type == BasicType::Name) {
|
||||||
auto chars = tokenValue(color);
|
auto chars = tokenValue(color).toLower();
|
||||||
if (isValidColor(chars)) {
|
if (isValidColor(chars)) {
|
||||||
return { { structure::TypeTag::Color }, chars.toLower() };
|
return { convertWebColor(chars) };
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logErrorUnexpectedToken() << "color value in #ccc, #ccca, #cccccc or #ccccccaa format";
|
logErrorUnexpectedToken() << "color value in #ccc, #ccca, #cccccc or #ccccccaa format";
|
||||||
}
|
}
|
||||||
|
} else if (auto rgbaToken = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(rgbaToken) == "rgba") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto r = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto g = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto b = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto a = readNumericValue();
|
||||||
|
if (r.type().tag != structure::TypeTag::Int || r.Int() < 0 || r.Int() > 255 ||
|
||||||
|
g.type().tag != structure::TypeTag::Int || g.Int() < 0 || g.Int() > 255 ||
|
||||||
|
b.type().tag != structure::TypeTag::Int || b.Int() < 0 || b.Int() > 255 ||
|
||||||
|
a.type().tag != structure::TypeTag::Int || a.Int() < 0 || a.Int() > 255) {
|
||||||
|
logErrorTypeMismatch() << "expected four 0-255 values for the rgba color";
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
return { convertIntColor(r.Int(), g.Int(), b.Int(), a.Int()) };
|
||||||
|
} else if (tokenValue(rgbaToken) == "rgb") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto r = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto g = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto b = readNumericValue();
|
||||||
|
if (r.type().tag != structure::TypeTag::Int || r.Int() < 0 || r.Int() > 255 ||
|
||||||
|
g.type().tag != structure::TypeTag::Int || g.Int() < 0 || g.Int() > 255 ||
|
||||||
|
b.type().tag != structure::TypeTag::Int || b.Int() < 0 || b.Int() > 255) {
|
||||||
|
logErrorTypeMismatch() << "expected three int values for the rgb color";
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
return { convertIntColor(r.Int(), g.Int(), b.Int(), 255) };
|
||||||
|
}
|
||||||
|
file_.putBack();
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readPointValue() {
|
structure::Value ParsedFile::readPointValue() {
|
||||||
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(font) == "point") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto x = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto y = readNumericValue();
|
||||||
|
if (x.type().tag != structure::TypeTag::Pixels ||
|
||||||
|
y.type().tag != structure::TypeTag::Pixels) {
|
||||||
|
logErrorTypeMismatch() << "expected two px values for the point";
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
return { structure::data::point { x.Int(), y.Int() } };
|
||||||
|
}
|
||||||
|
file_.putBack();
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readSpriteValue() {
|
structure::Value ParsedFile::readSpriteValue() {
|
||||||
if (auto font = file_.getToken(BasicType::Name)) {
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
if (tokenValue(font) == "sprite") {
|
if (tokenValue(font) == "sprite") {
|
||||||
if (!file_.getToken(BasicType::LeftParenthesis)) {
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
logErrorUnexpectedToken() << "'(' and sprite definition";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto x = readNumericValue(); file_.getToken(BasicType::Comma);
|
auto x = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
auto y = readNumericValue(); file_.getToken(BasicType::Comma);
|
auto y = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
auto w = readNumericValue(); file_.getToken(BasicType::Comma);
|
auto w = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
auto h = readNumericValue();
|
auto h = readNumericValue();
|
||||||
if (x.type.tag != structure::TypeTag::Pixels ||
|
if (x.type().tag != structure::TypeTag::Pixels ||
|
||||||
y.type.tag != structure::TypeTag::Pixels ||
|
y.type().tag != structure::TypeTag::Pixels ||
|
||||||
w.type.tag != structure::TypeTag::Pixels ||
|
w.type().tag != structure::TypeTag::Pixels ||
|
||||||
h.type.tag != structure::TypeTag::Pixels) {
|
h.type().tag != structure::TypeTag::Pixels) {
|
||||||
logErrorTypeMismatch() << "px rect for the sprite expected";
|
logErrorTypeMismatch() << "expected four px values for the sprite";
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_.getToken(BasicType::RightParenthesis)) {
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
logErrorUnexpectedToken() << "')'";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return { { structure::TypeTag::Sprite }, x.data + ',' + y.data + ',' + w.data + ',' + h.data };
|
return { structure::data::sprite { x.Int(), y.Int(), w.Int(), h.Int() } };
|
||||||
}
|
}
|
||||||
file_.putBack();
|
file_.putBack();
|
||||||
}
|
}
|
||||||
|
@ -448,43 +561,138 @@ structure::Value ParsedFile::readSpriteValue() {
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readSizeValue() {
|
structure::Value ParsedFile::readSizeValue() {
|
||||||
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(font) == "size") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto w = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto h = readNumericValue();
|
||||||
|
if (w.type().tag != structure::TypeTag::Pixels ||
|
||||||
|
h.type().tag != structure::TypeTag::Pixels) {
|
||||||
|
logErrorTypeMismatch() << "expected two px values for the size";
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
return { structure::data::size { w.Int(), h.Int() } };
|
||||||
|
}
|
||||||
|
file_.putBack();
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readTransitionValue() {
|
structure::Value ParsedFile::readTransitionValue() {
|
||||||
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(font) == "transition") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto transition = tokenValue(assertNextToken(BasicType::Name));
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
if (validateTransitionString(transition)) {
|
||||||
|
return { structure::TypeTag::Transition, transition.toStdString() };
|
||||||
|
} else {
|
||||||
|
logError(kErrorBadString) << "bad transition value";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_.putBack();
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readCursorValue() {
|
structure::Value ParsedFile::readCursorValue() {
|
||||||
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(font) == "cursor") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto cursor = tokenValue(assertNextToken(BasicType::Name));
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
if (validateCursorString(cursor)) {
|
||||||
|
return { structure::TypeTag::Cursor, cursor.toStdString() };
|
||||||
|
} else {
|
||||||
|
logError(kErrorBadString) << "bad cursor string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_.putBack();
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readAlignValue() {
|
structure::Value ParsedFile::readAlignValue() {
|
||||||
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(font) == "align") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto align = tokenValue(assertNextToken(BasicType::Name));
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
if (validateAlignString(align)) {
|
||||||
|
return { structure::TypeTag::Align, align.toStdString() };
|
||||||
|
} else {
|
||||||
|
logError(kErrorBadString) << "bad align string";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_.putBack();
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readMarginsValue() {
|
structure::Value ParsedFile::readMarginsValue() {
|
||||||
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(font) == "margins") {
|
||||||
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
|
|
||||||
|
auto l = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto t = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto r = readNumericValue(); assertNextToken(BasicType::Comma);
|
||||||
|
auto b = readNumericValue();
|
||||||
|
if (l.type().tag != structure::TypeTag::Pixels ||
|
||||||
|
t.type().tag != structure::TypeTag::Pixels ||
|
||||||
|
r.type().tag != structure::TypeTag::Pixels ||
|
||||||
|
b.type().tag != structure::TypeTag::Pixels) {
|
||||||
|
logErrorTypeMismatch() << "expected four px values for the margins";
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNextToken(BasicType::RightParenthesis);
|
||||||
|
|
||||||
|
return { structure::data::margins { l.Int(), t.Int(), r.Int(), b.Int() } };
|
||||||
|
}
|
||||||
|
file_.putBack();
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
structure::Value ParsedFile::readFontValue() {
|
structure::Value ParsedFile::readFontValue() {
|
||||||
if (auto font = file_.getToken(BasicType::Name)) {
|
if (auto font = file_.getToken(BasicType::Name)) {
|
||||||
if (tokenValue(font) == "font") {
|
if (tokenValue(font) == "font") {
|
||||||
if (!file_.getToken(BasicType::LeftParenthesis)) {
|
assertNextToken(BasicType::LeftParenthesis);
|
||||||
logErrorUnexpectedToken() << "'(' and font definition";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int flags = 0;
|
||||||
structure::Value family, size;
|
structure::Value family, size;
|
||||||
do {
|
do {
|
||||||
|
if (auto formatToken = file_.getToken(BasicType::Name)) {
|
||||||
|
if (tokenValue(formatToken) == "bold") {
|
||||||
|
flags |= structure::data::font::Bold;
|
||||||
|
} else if (tokenValue(formatToken) == "italic") {
|
||||||
|
flags |= structure::data::font::Italic;
|
||||||
|
} else if (tokenValue(formatToken) == "underline") {
|
||||||
|
flags |= structure::data::font::Underline;
|
||||||
|
} else {
|
||||||
|
file_.putBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (auto familyValue = readStringValue()) {
|
if (auto familyValue = readStringValue()) {
|
||||||
family = familyValue;
|
family = familyValue;
|
||||||
} else if (auto sizeValue = readNumericValue()) {
|
} else if (auto sizeValue = readNumericValue()) {
|
||||||
size = sizeValue;
|
size = sizeValue;
|
||||||
} else if (auto copyValue = readCopyValue()) {
|
} else if (auto copyValue = readCopyValue()) {
|
||||||
if (copyValue.type.tag == structure::TypeTag::String) {
|
if (copyValue.type().tag == structure::TypeTag::String) {
|
||||||
family = copyValue;
|
family = copyValue;
|
||||||
} else if (copyValue.type.tag == structure::TypeTag::Pixels) {
|
} else if (copyValue.type().tag == structure::TypeTag::Pixels) {
|
||||||
size = copyValue;
|
size = copyValue;
|
||||||
} else {
|
} else {
|
||||||
logErrorUnexpectedToken() << "font family, font size or ')'";
|
logErrorUnexpectedToken() << "font family, font size or ')'";
|
||||||
|
@ -496,10 +704,10 @@ structure::Value ParsedFile::readFontValue() {
|
||||||
}
|
}
|
||||||
} while (!failed());
|
} while (!failed());
|
||||||
|
|
||||||
if (size.type.tag != structure::TypeTag::Pixels) {
|
if (size.type().tag != structure::TypeTag::Pixels) {
|
||||||
logErrorTypeMismatch() << "px value for the font size expected";
|
logErrorTypeMismatch() << "px value for the font size expected";
|
||||||
}
|
}
|
||||||
return { { structure::TypeTag::Font }, size.data + ',' + family.data };
|
return { structure::data::font { family.String(), size.Int(), flags } };
|
||||||
}
|
}
|
||||||
file_.putBack();
|
file_.putBack();
|
||||||
}
|
}
|
||||||
|
@ -509,18 +717,64 @@ structure::Value ParsedFile::readFontValue() {
|
||||||
structure::Value ParsedFile::readCopyValue() {
|
structure::Value ParsedFile::readCopyValue() {
|
||||||
if (auto copyName = file_.getToken(BasicType::Name)) {
|
if (auto copyName = file_.getToken(BasicType::Name)) {
|
||||||
structure::FullName name = { tokenValue(copyName) };
|
structure::FullName name = { tokenValue(copyName) };
|
||||||
for (const auto &variable : result_.variables) {
|
if (auto variable = findVariable(name)) {
|
||||||
if (variable.name == name) {
|
return variable->value.makeCopy(variable->name);
|
||||||
auto result = variable.value;
|
|
||||||
result.copy = variable.name;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
logError(kErrorIdentifierNotFound) << "identifier '" << logFullName(name) << "' not found";
|
logError(kErrorIdentifierNotFound) << "identifier '" << logFullName(name) << "' not found";
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns nullptr if there is no such struct in result_ or any of included modules.
|
||||||
|
const structure::Struct *ParsedFile::findStruct(const structure::FullName &name) {
|
||||||
|
if (auto result = findStructInModule(name, result_)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (const auto &included : result_.includes) {
|
||||||
|
if (auto result = findStructInModule(name, included)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const structure::Struct *ParsedFile::findStructInModule(const structure::FullName &name, const structure::Module &module) {
|
||||||
|
auto index = module.structsByName.value(fullNameKey(name), -1);
|
||||||
|
if (index < 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &module.structs.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns nullptr if there is no such variable in result_ or any of included modules.
|
||||||
|
const structure::Variable *ParsedFile::findVariable(const structure::FullName &name) {
|
||||||
|
if (auto result = findVariableInModule(name, result_)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (const auto &included : result_.includes) {
|
||||||
|
if (auto result = findVariableInModule(name, included)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const structure::Variable *ParsedFile::findVariableInModule(const structure::FullName &name, const structure::Module &module) {
|
||||||
|
auto index = module.variablesByName.value(fullNameKey(name), -1);
|
||||||
|
if (index < 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &module.variables.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicToken ParsedFile::assertNextToken(BasicToken::Type type) {
|
||||||
|
auto result = file_.getToken(type);
|
||||||
|
if (!result) {
|
||||||
|
logErrorUnexpectedToken() << type;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Options ParsedFile::includedOptions(const QString &filepath) {
|
Options ParsedFile::includedOptions(const QString &filepath) {
|
||||||
auto result = options_;
|
auto result = options_;
|
||||||
result.inputPath = filepath;
|
result.inputPath = filepath;
|
||||||
|
|
|
@ -78,6 +78,7 @@ private:
|
||||||
structure::Value defaultConstructedStruct(const structure::FullName &name);
|
structure::Value defaultConstructedStruct(const structure::FullName &name);
|
||||||
void applyStructParent(structure::Value &result, const structure::FullName &parentName);
|
void applyStructParent(structure::Value &result, const structure::FullName &parentName);
|
||||||
bool readStructValueInner(structure::Value &result);
|
bool readStructValueInner(structure::Value &result);
|
||||||
|
bool assignStructField(structure::Value &result, const structure::Variable &field);
|
||||||
bool readStructParents(structure::Value &result);
|
bool readStructParents(structure::Value &result);
|
||||||
|
|
||||||
// Simple methods for reading value types.
|
// Simple methods for reading value types.
|
||||||
|
@ -95,6 +96,18 @@ private:
|
||||||
structure::Value readFontValue();
|
structure::Value readFontValue();
|
||||||
structure::Value readCopyValue();
|
structure::Value readCopyValue();
|
||||||
|
|
||||||
|
// Returns nullptr if there is no such struct in result_ or any of included modules.
|
||||||
|
const structure::Struct *findStruct(const structure::FullName &name);
|
||||||
|
const structure::Struct *findStructInModule(const structure::FullName &name, const structure::Module &module);
|
||||||
|
|
||||||
|
// Returns nullptr if there is no such variable in result_ or any of included modules.
|
||||||
|
const structure::Variable *findVariable(const structure::FullName &name);
|
||||||
|
const structure::Variable *findVariableInModule(const structure::FullName &name, const structure::Module &module);
|
||||||
|
|
||||||
|
// Read next token and fire unexpected token error if it is not of "type".
|
||||||
|
using BasicToken = common::BasicTokenizedFile::Token;
|
||||||
|
BasicToken assertNextToken(BasicToken::Type type);
|
||||||
|
|
||||||
// Look through include directories in options_ and find absolute include path.
|
// Look through include directories in options_ and find absolute include path.
|
||||||
Options includedOptions(const QString &filepath);
|
Options includedOptions(const QString &filepath);
|
||||||
|
|
||||||
|
|
|
@ -21,60 +21,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include "codegen/style/structure_types.h"
|
||||||
|
|
||||||
namespace codegen {
|
namespace codegen {
|
||||||
namespace style {
|
namespace style {
|
||||||
namespace structure {
|
namespace structure {
|
||||||
|
|
||||||
// List of names, like overview.document.bg
|
|
||||||
using FullName = QStringList;
|
|
||||||
|
|
||||||
enum class TypeTag {
|
|
||||||
Invalid,
|
|
||||||
Int,
|
|
||||||
Double,
|
|
||||||
Pixels,
|
|
||||||
String,
|
|
||||||
Color,
|
|
||||||
Point,
|
|
||||||
Sprite,
|
|
||||||
Size,
|
|
||||||
Transition,
|
|
||||||
Cursor,
|
|
||||||
Align,
|
|
||||||
Margins,
|
|
||||||
Font,
|
|
||||||
Struct,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Type {
|
|
||||||
TypeTag tag;
|
|
||||||
FullName name; // only for type == ClassType::Struct
|
|
||||||
|
|
||||||
explicit operator bool() const {
|
|
||||||
return (tag != TypeTag::Invalid);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
inline bool operator==(const Type &a, const Type &b) {
|
|
||||||
return (a.tag == b.tag) && (a.name == b.name);
|
|
||||||
}
|
|
||||||
inline bool operator!=(const Type &a, const Type &b) {
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Variable;
|
|
||||||
struct Value {
|
|
||||||
Type type;
|
|
||||||
QString data; // for plain types
|
|
||||||
QList<Variable> fields; // for struct types
|
|
||||||
FullName copy; // for copies of existing named values
|
|
||||||
|
|
||||||
explicit operator bool() const {
|
|
||||||
return !data.isEmpty() || !fields.isEmpty() || !copy.isEmpty();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Variable {
|
struct Variable {
|
||||||
FullName name;
|
FullName name;
|
||||||
Value value;
|
Value value;
|
||||||
|
@ -107,6 +61,8 @@ struct Module {
|
||||||
QList<Module> includes;
|
QList<Module> includes;
|
||||||
QList<Struct> structs;
|
QList<Struct> structs;
|
||||||
QList<Variable> variables;
|
QList<Variable> variables;
|
||||||
|
QMap<QString, int> structsByName;
|
||||||
|
QMap<QString, int> variablesByName;
|
||||||
|
|
||||||
explicit operator bool() const {
|
explicit operator bool() const {
|
||||||
return !fullpath.isEmpty();
|
return !fullpath.isEmpty();
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
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/structure_types.h"
|
||||||
|
|
||||||
|
#include "codegen/style/structure.h"
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace style {
|
||||||
|
namespace structure {
|
||||||
|
|
||||||
|
struct Value::DataTypes {
|
||||||
|
class TInt : public DataBase {
|
||||||
|
public:
|
||||||
|
TInt(int value) : value_(value) {
|
||||||
|
}
|
||||||
|
int Int() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TDouble : public DataBase {
|
||||||
|
public:
|
||||||
|
TDouble(double value) : value_(value) {
|
||||||
|
}
|
||||||
|
double Double() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
double value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TString : public DataBase {
|
||||||
|
public:
|
||||||
|
TString(std::string value) : value_(value) {
|
||||||
|
}
|
||||||
|
std::string String() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TPoint : public DataBase {
|
||||||
|
public:
|
||||||
|
TPoint(data::point value) : value_(value) {
|
||||||
|
}
|
||||||
|
data::point Point() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
data::point value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TSprite : public DataBase {
|
||||||
|
public:
|
||||||
|
TSprite(data::sprite value) : value_(value) {
|
||||||
|
}
|
||||||
|
data::sprite Sprite() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
data::sprite value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TSize : public DataBase {
|
||||||
|
public:
|
||||||
|
TSize(data::size value) : value_(value) {
|
||||||
|
}
|
||||||
|
data::size Size() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
data::size value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TColor : public DataBase {
|
||||||
|
public:
|
||||||
|
TColor(data::color value) : value_(value) {
|
||||||
|
}
|
||||||
|
data::color Color() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
data::color value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TMargins : public DataBase {
|
||||||
|
public:
|
||||||
|
TMargins(data::margins value) : value_(value) {
|
||||||
|
}
|
||||||
|
data::margins Margins() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
data::margins value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TFont : public DataBase {
|
||||||
|
public:
|
||||||
|
TFont(data::font value) : value_(value) {
|
||||||
|
}
|
||||||
|
data::font Font() const override { return value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
data::font value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class TComplex : public DataBase {
|
||||||
|
public:
|
||||||
|
TComplex(data::complex value) : value_(value) {
|
||||||
|
}
|
||||||
|
const data::complex *Complex() const override { return &value_; }
|
||||||
|
data::complex *Complex() override { return &value_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
data::complex value_;
|
||||||
|
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
Value::Value() : Value(TypeTag::Invalid, std::make_shared<DataBase>()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(double value) : Value(TypeTag::Double, std::make_shared<DataTypes::TDouble>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(data::point value) : Value(TypeTag::Point, std::make_shared<DataTypes::TPoint>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(data::sprite value) : Value(TypeTag::Sprite, std::make_shared<DataTypes::TSprite>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(data::size value) : Value(TypeTag::Size, std::make_shared<DataTypes::TSize>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(data::color value) : Value(TypeTag::Color, std::make_shared<DataTypes::TColor>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(data::margins value) : Value(TypeTag::Margins, std::make_shared<DataTypes::TMargins>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(data::font value) : Value(TypeTag::Font, std::make_shared<DataTypes::TFont>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(const FullName &type, data::complex value)
|
||||||
|
: type_ { TypeTag::Struct, type }
|
||||||
|
, data_(std::make_shared<DataTypes::TComplex>(value)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(TypeTag type, int value) : Value(type, std::make_shared<DataTypes::TInt>(value)) {
|
||||||
|
if (type_.tag != TypeTag::Int && type_.tag != TypeTag::Pixels) {
|
||||||
|
type_.tag = TypeTag::Invalid;
|
||||||
|
data_ = std::make_shared<DataBase>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(TypeTag type, std::string value) : Value(type, std::make_shared<DataTypes::TString>(value)) {
|
||||||
|
if (type_.tag != TypeTag::String &&
|
||||||
|
type_.tag != TypeTag::Transition &&
|
||||||
|
type_.tag != TypeTag::Cursor &&
|
||||||
|
type_.tag != TypeTag::Align) {
|
||||||
|
type_.tag = TypeTag::Invalid;
|
||||||
|
data_ = std::make_shared<DataBase>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(Type type, Qt::Initialization) : type_(type) {
|
||||||
|
switch (type_.tag) {
|
||||||
|
case TypeTag::Invalid: data_ = std::make_shared<DataBase>(); break;
|
||||||
|
case TypeTag::Int: data_ = std::make_shared<DataTypes::TInt>(0); break;
|
||||||
|
case TypeTag::Double: data_ = std::make_shared<DataTypes::TDouble>(0.); break;
|
||||||
|
case TypeTag::Pixels: data_ = std::make_shared<DataTypes::TInt>(0); break;
|
||||||
|
case TypeTag::String: data_ = std::make_shared<DataTypes::TString>(""); break;
|
||||||
|
case TypeTag::Color: data_ = std::make_shared<DataTypes::TColor>(data::color { 0, 0, 0, 255 }); break;
|
||||||
|
case TypeTag::Point: data_ = std::make_shared<DataTypes::TPoint>(data::point { 0, 0 }); break;
|
||||||
|
case TypeTag::Sprite: data_ = std::make_shared<DataTypes::TSprite>(data::sprite { 0, 0, 0, 0 }); break;
|
||||||
|
case TypeTag::Size: data_ = std::make_shared<DataTypes::TSize>(data::size { 0, 0 }); break;
|
||||||
|
case TypeTag::Transition: data_ = std::make_shared<DataTypes::TString>("linear"); break;
|
||||||
|
case TypeTag::Cursor: data_ = std::make_shared<DataTypes::TString>("default"); break;
|
||||||
|
case TypeTag::Align: data_ = std::make_shared<DataTypes::TString>("left"); break;
|
||||||
|
case TypeTag::Margins: data_ = std::make_shared<DataTypes::TMargins>(data::margins { 0, 0, 0, 0 }); break;
|
||||||
|
case TypeTag::Font: data_ = std::make_shared<DataTypes::TFont>(data::font { "", 13, 0 }); break;
|
||||||
|
case TypeTag::Struct: data_ = std::make_shared<DataTypes::TComplex>(data::complex {}); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value::Value(TypeTag type, std::shared_ptr<DataBase> &&data) : type_ { type }, data_(std::move(data)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace structure
|
||||||
|
} // namespace style
|
||||||
|
} // namespace codegen
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
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/QStringList>
|
||||||
|
|
||||||
|
namespace codegen {
|
||||||
|
namespace style {
|
||||||
|
namespace structure {
|
||||||
|
|
||||||
|
// List of names, like overview.document.bg
|
||||||
|
using FullName = QStringList;
|
||||||
|
|
||||||
|
struct Variable;
|
||||||
|
|
||||||
|
enum class TypeTag {
|
||||||
|
Invalid,
|
||||||
|
Int,
|
||||||
|
Double,
|
||||||
|
Pixels,
|
||||||
|
String,
|
||||||
|
Color,
|
||||||
|
Point,
|
||||||
|
Sprite,
|
||||||
|
Size,
|
||||||
|
Transition,
|
||||||
|
Cursor,
|
||||||
|
Align,
|
||||||
|
Margins,
|
||||||
|
Font,
|
||||||
|
Struct,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Type {
|
||||||
|
TypeTag tag;
|
||||||
|
FullName name; // only for type == ClassType::Struct
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return (tag != TypeTag::Invalid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
inline bool operator==(const Type &a, const Type &b) {
|
||||||
|
return (a.tag == b.tag) && (a.name == b.name);
|
||||||
|
}
|
||||||
|
inline bool operator!=(const Type &a, const Type &b) {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace data {
|
||||||
|
|
||||||
|
struct point {
|
||||||
|
int x, y;
|
||||||
|
};
|
||||||
|
struct sprite {
|
||||||
|
int left, top, width, height;
|
||||||
|
};
|
||||||
|
struct size {
|
||||||
|
int width, height;
|
||||||
|
};
|
||||||
|
struct color {
|
||||||
|
uchar red, green, blue, alpha;
|
||||||
|
};
|
||||||
|
struct margins {
|
||||||
|
int left, top, right, bottom;
|
||||||
|
};
|
||||||
|
struct font {
|
||||||
|
enum Flag {
|
||||||
|
Bold = 0x01,
|
||||||
|
Italic = 0x02,
|
||||||
|
Underline = 0x04,
|
||||||
|
};
|
||||||
|
std::string family;
|
||||||
|
int size;
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
using complex = QList<Variable>;
|
||||||
|
|
||||||
|
} // namespace data
|
||||||
|
|
||||||
|
class Value {
|
||||||
|
public:
|
||||||
|
Value();
|
||||||
|
Value(double value);
|
||||||
|
Value(data::point value);
|
||||||
|
Value(data::sprite value);
|
||||||
|
Value(data::size value);
|
||||||
|
Value(data::color value);
|
||||||
|
Value(data::margins value);
|
||||||
|
Value(data::font value);
|
||||||
|
Value(const FullName &type, data::complex value);
|
||||||
|
|
||||||
|
// Can be int / pixels.
|
||||||
|
Value(TypeTag type, int value);
|
||||||
|
|
||||||
|
// Can be string / transition / cursor / align.
|
||||||
|
Value(TypeTag type, std::string value);
|
||||||
|
|
||||||
|
// Default constructed value (uninitialized).
|
||||||
|
Value(Type type, Qt::Initialization);
|
||||||
|
|
||||||
|
Type type() const { return type_; }
|
||||||
|
int Int() const { return data_->Int(); }
|
||||||
|
double Double() const { return data_->Double(); }
|
||||||
|
std::string String() const { return data_->String(); }
|
||||||
|
data::point Point() const { return data_->Point(); }
|
||||||
|
data::sprite Sprite() const { return data_->Sprite(); };
|
||||||
|
data::size Size() const { return data_->Size(); };
|
||||||
|
data::color Color() const { return data_->Color(); };
|
||||||
|
data::margins Margins() const { return data_->Margins(); };
|
||||||
|
data::font Font() const { return data_->Font(); };
|
||||||
|
const data::complex *Complex() const { return data_->Complex(); };
|
||||||
|
data::complex *Complex() { return data_->Complex(); };
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return type_.tag != TypeTag::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value makeCopy(const FullName ©Of) const {
|
||||||
|
Value result(*this);
|
||||||
|
result.copyOf_ = copyOf;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
class DataBase {
|
||||||
|
public:
|
||||||
|
virtual int Int() const { return 0; }
|
||||||
|
virtual double Double() const { return 0.; }
|
||||||
|
virtual std::string String() const { return std::string(); }
|
||||||
|
virtual data::point Point() const { return {}; };
|
||||||
|
virtual data::sprite Sprite() const { return {}; };
|
||||||
|
virtual data::size Size() const { return {}; };
|
||||||
|
virtual data::color Color() const { return {}; };
|
||||||
|
virtual data::margins Margins() const { return {}; };
|
||||||
|
virtual data::font Font() const { return {}; };
|
||||||
|
virtual const data::complex *Complex() const { return nullptr; };
|
||||||
|
virtual data::complex *Complex() { return nullptr; };
|
||||||
|
virtual ~DataBase() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct DataTypes;
|
||||||
|
|
||||||
|
Value(TypeTag type, std::shared_ptr<DataBase> &&data);
|
||||||
|
|
||||||
|
Type type_;
|
||||||
|
std::shared_ptr<DataBase> data_;
|
||||||
|
|
||||||
|
FullName copyOf_; // for copies of existing named values
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace structure
|
||||||
|
} // namespace style
|
||||||
|
} // namespace codegen
|
|
@ -794,7 +794,7 @@ void objc_openFile(const QString &f, bool openwith) {
|
||||||
|
|
||||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||||
|
|
||||||
NSRect fullRect = { { 0., 0. }, { st::macAccessory.width() * 1., st::macAccessory.height() * 1. } };
|
NSRect fullRect = { { 0., 0. }, { st::macAccessoryWidth, st::macAccessoryHeight } };
|
||||||
NSView *accessory = [[NSView alloc] initWithFrame:fullRect];
|
NSView *accessory = [[NSView alloc] initWithFrame:fullRect];
|
||||||
|
|
||||||
[accessory setAutoresizesSubviews:YES];
|
[accessory setAutoresizesSubviews:YES];
|
||||||
|
@ -861,7 +861,7 @@ void objc_openFile(const QString &f, bool openwith) {
|
||||||
NSImageView *badIcon = [[NSImageView alloc] init];
|
NSImageView *badIcon = [[NSImageView alloc] init];
|
||||||
NSImage *badImage = [NSImage imageNamed:NSImageNameCaution];
|
NSImage *badImage = [NSImage imageNamed:NSImageNameCaution];
|
||||||
[badIcon setImage:badImage];
|
[badIcon setImage:badImage];
|
||||||
[badIcon setFrame:NSMakeRect(0, 0, st::macCautionIconSize.width(), st::macCautionIconSize.height())];
|
[badIcon setFrame:NSMakeRect(0, 0, st::macCautionIconSize, st::macCautionIconSize)];
|
||||||
|
|
||||||
NSRect badFrame = [badLabel frame], badIconFrame = [badIcon frame];
|
NSRect badFrame = [badLabel frame], badIconFrame = [badIcon frame];
|
||||||
badFrame.origin.x = (fullRect.size.width - badFrame.size.width + badIconFrame.size.width) / 2.;
|
badFrame.origin.x = (fullRect.size.width - badFrame.size.width + badIconFrame.size.width) / 2.;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
<ClCompile Include="..\..\..\SourceFiles\codegen\style\options.cpp" />
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\options.cpp" />
|
||||||
<ClCompile Include="..\..\..\SourceFiles\codegen\style\parsed_file.cpp" />
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\parsed_file.cpp" />
|
||||||
<ClCompile Include="..\..\..\SourceFiles\codegen\style\main.cpp" />
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\main.cpp" />
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\structure_types.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\SourceFiles\codegen\common\checked_utf8_string.h" />
|
<ClInclude Include="..\..\..\SourceFiles\codegen\common\checked_utf8_string.h" />
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
<ClInclude Include="..\..\..\SourceFiles\codegen\style\options.h" />
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\options.h" />
|
||||||
<ClInclude Include="..\..\..\SourceFiles\codegen\style\structure.h" />
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\structure.h" />
|
||||||
<ClInclude Include="..\..\..\SourceFiles\codegen\style\parsed_file.h" />
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\parsed_file.h" />
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\structure_types.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>{E4DF8176-4DEF-4859-962F-B497E3E7A323}</ProjectGuid>
|
<ProjectGuid>{E4DF8176-4DEF-4859-962F-B497E3E7A323}</ProjectGuid>
|
||||||
|
|
|
@ -37,6 +37,9 @@
|
||||||
<ClCompile Include="..\..\..\SourceFiles\codegen\style\parsed_file.cpp">
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\parsed_file.cpp">
|
||||||
<Filter>src\style</Filter>
|
<Filter>src\style</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\SourceFiles\codegen\style\structure_types.cpp">
|
||||||
|
<Filter>src\style</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\..\SourceFiles\codegen\style\generator.h">
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\generator.h">
|
||||||
|
@ -69,5 +72,8 @@
|
||||||
<ClInclude Include="..\..\..\SourceFiles\codegen\style\parsed_file.h">
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\parsed_file.h">
|
||||||
<Filter>src\style</Filter>
|
<Filter>src\style</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\..\SourceFiles\codegen\style\structure_types.h">
|
||||||
|
<Filter>src\style</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue