2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //===---------------------------------------------------------------------===//
8 // This implements methods defined in ResourceScriptStmt.h.
10 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380599(v=vs.85).aspx
12 //===---------------------------------------------------------------------===//
14 #include "ResourceScriptStmt.h"
19 raw_ostream
&operator<<(raw_ostream
&OS
, const IntOrString
&Item
) {
21 return OS
<< Item
.Data
.Int
;
23 return OS
<< Item
.Data
.String
;
26 raw_ostream
&OptionalStmtList::log(raw_ostream
&OS
) const {
27 for (const auto &Stmt
: Statements
) {
34 raw_ostream
&LanguageResource::log(raw_ostream
&OS
) const {
35 return OS
<< "Language: " << Lang
<< ", Sublanguage: " << SubLang
<< "\n";
38 StringRef
AcceleratorsResource::Accelerator::OptionsStr
39 [AcceleratorsResource::Accelerator::NumFlags
] = {
40 "ASCII", "VIRTKEY", "NOINVERT", "ALT", "SHIFT", "CONTROL"};
42 uint32_t AcceleratorsResource::Accelerator::OptionsFlags
43 [AcceleratorsResource::Accelerator::NumFlags
] = {ASCII
, VIRTKEY
, NOINVERT
,
46 raw_ostream
&AcceleratorsResource::log(raw_ostream
&OS
) const {
47 OS
<< "Accelerators (" << ResName
<< "): \n";
48 OptStatements
->log(OS
);
49 for (const auto &Acc
: Accelerators
) {
50 OS
<< " Accelerator: " << Acc
.Event
<< " " << Acc
.Id
;
51 for (size_t i
= 0; i
< Accelerator::NumFlags
; ++i
)
52 if (Acc
.Flags
& Accelerator::OptionsFlags
[i
])
53 OS
<< " " << Accelerator::OptionsStr
[i
];
59 raw_ostream
&BitmapResource::log(raw_ostream
&OS
) const {
60 return OS
<< "Bitmap (" << ResName
<< "): " << BitmapLoc
<< "\n";
63 raw_ostream
&CursorResource::log(raw_ostream
&OS
) const {
64 return OS
<< "Cursor (" << ResName
<< "): " << CursorLoc
<< "\n";
67 raw_ostream
&IconResource::log(raw_ostream
&OS
) const {
68 return OS
<< "Icon (" << ResName
<< "): " << IconLoc
<< "\n";
71 raw_ostream
&HTMLResource::log(raw_ostream
&OS
) const {
72 return OS
<< "HTML (" << ResName
<< "): " << HTMLLoc
<< "\n";
75 StringRef
MenuDefinition::OptionsStr
[MenuDefinition::NumFlags
] = {
76 "CHECKED", "GRAYED", "HELP", "INACTIVE", "MENUBARBREAK", "MENUBREAK"};
78 uint32_t MenuDefinition::OptionsFlags
[MenuDefinition::NumFlags
] = {
79 CHECKED
, GRAYED
, HELP
, INACTIVE
, MENUBARBREAK
, MENUBREAK
};
81 raw_ostream
&MenuDefinition::logFlags(raw_ostream
&OS
, uint16_t Flags
) {
82 for (size_t i
= 0; i
< NumFlags
; ++i
)
83 if (Flags
& OptionsFlags
[i
])
84 OS
<< " " << OptionsStr
[i
];
88 raw_ostream
&MenuDefinitionList::log(raw_ostream
&OS
) const {
89 OS
<< " Menu list starts\n";
90 for (auto &Item
: Definitions
)
92 return OS
<< " Menu list ends\n";
95 raw_ostream
&MenuItem::log(raw_ostream
&OS
) const {
96 OS
<< " MenuItem (" << Name
<< "), ID = " << Id
;
101 raw_ostream
&MenuSeparator::log(raw_ostream
&OS
) const {
102 return OS
<< " Menu separator\n";
105 raw_ostream
&PopupItem::log(raw_ostream
&OS
) const {
106 OS
<< " Popup (" << Name
<< ")";
109 return SubItems
.log(OS
);
112 raw_ostream
&MenuResource::log(raw_ostream
&OS
) const {
113 OS
<< "Menu (" << ResName
<< "):\n";
114 OptStatements
->log(OS
);
115 return Elements
.log(OS
);
118 raw_ostream
&StringTableResource::log(raw_ostream
&OS
) const {
119 OS
<< "StringTable:\n";
120 OptStatements
->log(OS
);
121 for (const auto &String
: Table
)
122 OS
<< " " << String
.first
<< " => " << String
.second
<< "\n";
126 const StringMap
<Control::CtlInfo
> Control::SupportedCtls
= {
127 {"LTEXT", CtlInfo
{0x50020000, ClsStatic
, true}},
128 {"CTEXT", CtlInfo
{0x50020001, ClsStatic
, true}},
129 {"RTEXT", CtlInfo
{0x50020002, ClsStatic
, true}},
130 {"ICON", CtlInfo
{0x50000003, ClsStatic
, true}},
131 {"PUSHBUTTON", CtlInfo
{0x50010000, ClsButton
, true}},
132 {"DEFPUSHBUTTON", CtlInfo
{0x50010001, ClsButton
, true}},
133 {"AUTO3STATE", CtlInfo
{0x50010006, ClsButton
, true}},
134 {"AUTOCHECKBOX", CtlInfo
{0x50010003, ClsButton
, true}},
135 {"AUTORADIOBUTTON", CtlInfo
{0x50000009, ClsButton
, true}},
136 {"CHECKBOX", CtlInfo
{0x50010002, ClsButton
, true}},
137 {"GROUPBOX", CtlInfo
{0x50000007, ClsButton
, true}},
138 {"RADIOBUTTON", CtlInfo
{0x50000004, ClsButton
, true}},
139 {"STATE3", CtlInfo
{0x50010005, ClsButton
, true}},
140 {"PUSHBOX", CtlInfo
{0x5001000A, ClsButton
, true}},
141 {"EDITTEXT", CtlInfo
{0x50810000, ClsEdit
, false}},
142 {"COMBOBOX", CtlInfo
{0x50000000, ClsComboBox
, false}},
143 {"LISTBOX", CtlInfo
{0x50800001, ClsListBox
, false}},
144 {"SCROLLBAR", CtlInfo
{0x50000000, ClsScrollBar
, false}},
145 {"CONTROL", CtlInfo
{0x50000000, 0, true}},
148 raw_ostream
&Control::log(raw_ostream
&OS
) const {
149 OS
<< " Control (" << ID
<< "): " << Type
<< ", title: " << Title
150 << ", loc: (" << X
<< ", " << Y
<< "), size: [" << Width
<< ", " << Height
153 OS
<< ", style: " << (*Style
).getValue();
155 OS
<< ", ext. style: " << *ExtStyle
;
157 OS
<< ", help ID: " << *HelpID
;
161 raw_ostream
&DialogResource::log(raw_ostream
&OS
) const {
162 OS
<< "Dialog" << (IsExtended
? "Ex" : "") << " (" << ResName
<< "): loc: ("
163 << X
<< ", " << Y
<< "), size: [" << Width
<< ", " << Height
164 << "], help ID: " << HelpID
<< "\n";
165 OptStatements
->log(OS
);
166 for (auto &Ctl
: Controls
)
171 raw_ostream
&VersionInfoBlock::log(raw_ostream
&OS
) const {
172 OS
<< " Start of block (name: " << Name
<< ")\n";
173 for (auto &Stmt
: Stmts
)
175 return OS
<< " End of block\n";
178 raw_ostream
&VersionInfoValue::log(raw_ostream
&OS
) const {
179 OS
<< " " << Key
<< " =>";
180 size_t NumValues
= Values
.size();
181 for (size_t Id
= 0; Id
< NumValues
; ++Id
) {
182 if (Id
> 0 && HasPrecedingComma
[Id
])
184 OS
<< " " << Values
[Id
];
189 using VersionInfoFixed
= VersionInfoResource::VersionInfoFixed
;
190 using VersionInfoFixedType
= VersionInfoFixed::VersionInfoFixedType
;
193 VersionInfoFixed::FixedFieldsNames
[VersionInfoFixed::FtNumTypes
] = {
194 "", "FILEVERSION", "PRODUCTVERSION", "FILEFLAGSMASK",
195 "FILEFLAGS", "FILEOS", "FILETYPE", "FILESUBTYPE"};
197 const StringMap
<VersionInfoFixedType
> VersionInfoFixed::FixedFieldsInfoMap
= {
198 {FixedFieldsNames
[FtFileVersion
], FtFileVersion
},
199 {FixedFieldsNames
[FtProductVersion
], FtProductVersion
},
200 {FixedFieldsNames
[FtFileFlagsMask
], FtFileFlagsMask
},
201 {FixedFieldsNames
[FtFileFlags
], FtFileFlags
},
202 {FixedFieldsNames
[FtFileOS
], FtFileOS
},
203 {FixedFieldsNames
[FtFileType
], FtFileType
},
204 {FixedFieldsNames
[FtFileSubtype
], FtFileSubtype
}};
206 VersionInfoFixedType
VersionInfoFixed::getFixedType(StringRef Type
) {
207 auto UpperType
= Type
.upper();
208 auto Iter
= FixedFieldsInfoMap
.find(UpperType
);
209 if (Iter
!= FixedFieldsInfoMap
.end())
210 return Iter
->getValue();
214 bool VersionInfoFixed::isTypeSupported(VersionInfoFixedType Type
) {
215 return FtUnknown
< Type
&& Type
< FtNumTypes
;
218 bool VersionInfoFixed::isVersionType(VersionInfoFixedType Type
) {
221 case FtProductVersion
:
229 raw_ostream
&VersionInfoFixed::log(raw_ostream
&OS
) const {
230 for (int Type
= FtUnknown
; Type
< FtNumTypes
; ++Type
) {
231 if (!isTypeSupported((VersionInfoFixedType
)Type
))
233 OS
<< " Fixed: " << FixedFieldsNames
[Type
] << ":";
234 for (uint32_t Val
: FixedInfo
[Type
])
241 raw_ostream
&VersionInfoResource::log(raw_ostream
&OS
) const {
242 OS
<< "VersionInfo (" << ResName
<< "):\n";
244 return MainBlock
.log(OS
);
247 raw_ostream
&UserDefinedResource::log(raw_ostream
&OS
) const {
248 OS
<< "User-defined (type: " << Type
<< ", name: " << ResName
<< "): ";
250 return OS
<< FileLoc
<< "\n";
252 for (auto &Item
: Contents
)
257 raw_ostream
&CharacteristicsStmt::log(raw_ostream
&OS
) const {
258 return OS
<< "Characteristics: " << Value
<< "\n";
261 raw_ostream
&VersionStmt::log(raw_ostream
&OS
) const {
262 return OS
<< "Version: " << Value
<< "\n";
265 raw_ostream
&CaptionStmt::log(raw_ostream
&OS
) const {
266 return OS
<< "Caption: " << Value
<< "\n";
269 raw_ostream
&ClassStmt::log(raw_ostream
&OS
) const {
270 return OS
<< "Class: " << Value
<< "\n";
273 raw_ostream
&FontStmt::log(raw_ostream
&OS
) const {
274 OS
<< "Font: size = " << Size
<< ", face = " << Name
275 << ", weight = " << Weight
;
278 return OS
<< ", charset = " << Charset
<< "\n";
281 raw_ostream
&StyleStmt::log(raw_ostream
&OS
) const {
282 return OS
<< "Style: " << Value
<< "\n";
285 raw_ostream
&ExStyleStmt::log(raw_ostream
&OS
) const {
286 return OS
<< "ExStyle: " << Value
<< "\n";