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
&MenuExItem::log(raw_ostream
&OS
) const {
106 OS
<< " MenuExItem (" << Name
<< "), ID = " << Id
;
107 OS
<< ", type: " << Type
<< ", state: " << State
;
111 raw_ostream
&PopupItem::log(raw_ostream
&OS
) const {
112 OS
<< " Popup (" << Name
<< ")";
115 return SubItems
.log(OS
);
118 raw_ostream
&PopupExItem::log(raw_ostream
&OS
) const {
119 OS
<< " Popup (" << Name
<< ")";
120 OS
<< ", type: " << Type
<< ", state: " << State
<< ", help ID: " << HelpId
;
122 return SubItems
.log(OS
);
125 raw_ostream
&MenuResource::log(raw_ostream
&OS
) const {
126 OS
<< "Menu (" << ResName
<< "):\n";
127 OptStatements
->log(OS
);
128 return Elements
.log(OS
);
131 raw_ostream
&MenuExResource::log(raw_ostream
&OS
) const {
132 OS
<< "MenuEx (" << ResName
<< "):\n";
133 OptStatements
->log(OS
);
134 return Elements
.log(OS
);
137 raw_ostream
&StringTableResource::log(raw_ostream
&OS
) const {
138 OS
<< "StringTable:\n";
139 OptStatements
->log(OS
);
140 for (const auto &String
: Table
) {
141 OS
<< " " << String
.first
<< " =>";
142 for (const auto &S
: String
.second
)
149 const StringMap
<Control::CtlInfo
> Control::SupportedCtls
= {
150 {"LTEXT", CtlInfo
{0x50020000, ClsStatic
, true}},
151 {"CTEXT", CtlInfo
{0x50020001, ClsStatic
, true}},
152 {"RTEXT", CtlInfo
{0x50020002, ClsStatic
, true}},
153 {"ICON", CtlInfo
{0x50000003, ClsStatic
, true}},
154 {"PUSHBUTTON", CtlInfo
{0x50010000, ClsButton
, true}},
155 {"DEFPUSHBUTTON", CtlInfo
{0x50010001, ClsButton
, true}},
156 {"AUTO3STATE", CtlInfo
{0x50010006, ClsButton
, true}},
157 {"AUTOCHECKBOX", CtlInfo
{0x50010003, ClsButton
, true}},
158 {"AUTORADIOBUTTON", CtlInfo
{0x50000009, ClsButton
, true}},
159 {"CHECKBOX", CtlInfo
{0x50010002, ClsButton
, true}},
160 {"GROUPBOX", CtlInfo
{0x50000007, ClsButton
, true}},
161 {"RADIOBUTTON", CtlInfo
{0x50000004, ClsButton
, true}},
162 {"STATE3", CtlInfo
{0x50010005, ClsButton
, true}},
163 {"PUSHBOX", CtlInfo
{0x5001000A, ClsButton
, true}},
164 {"EDITTEXT", CtlInfo
{0x50810000, ClsEdit
, false}},
165 {"COMBOBOX", CtlInfo
{0x50000000, ClsComboBox
, false}},
166 {"LISTBOX", CtlInfo
{0x50800001, ClsListBox
, false}},
167 {"SCROLLBAR", CtlInfo
{0x50000000, ClsScrollBar
, false}},
168 {"CONTROL", CtlInfo
{0x50000000, 0, true}},
171 raw_ostream
&Control::log(raw_ostream
&OS
) const {
172 OS
<< " Control (" << ID
<< "): " << Type
<< ", title: " << Title
173 << ", loc: (" << X
<< ", " << Y
<< "), size: [" << Width
<< ", " << Height
176 OS
<< ", style: " << (*Style
).getValue();
178 OS
<< ", ext. style: " << *ExtStyle
;
180 OS
<< ", help ID: " << *HelpID
;
184 raw_ostream
&DialogResource::log(raw_ostream
&OS
) const {
185 OS
<< "Dialog" << (IsExtended
? "Ex" : "") << " (" << ResName
<< "): loc: ("
186 << X
<< ", " << Y
<< "), size: [" << Width
<< ", " << Height
187 << "], help ID: " << HelpID
<< "\n";
188 OptStatements
->log(OS
);
189 for (auto &Ctl
: Controls
)
194 raw_ostream
&VersionInfoBlock::log(raw_ostream
&OS
) const {
195 OS
<< " Start of block (name: " << Name
<< ")\n";
196 for (auto &Stmt
: Stmts
)
198 return OS
<< " End of block\n";
201 raw_ostream
&VersionInfoValue::log(raw_ostream
&OS
) const {
202 OS
<< " " << Key
<< " =>";
203 size_t NumValues
= Values
.size();
204 for (size_t Id
= 0; Id
< NumValues
; ++Id
) {
205 if (Id
> 0 && HasPrecedingComma
[Id
])
207 OS
<< " " << Values
[Id
];
212 using VersionInfoFixed
= VersionInfoResource::VersionInfoFixed
;
213 using VersionInfoFixedType
= VersionInfoFixed::VersionInfoFixedType
;
216 VersionInfoFixed::FixedFieldsNames
[VersionInfoFixed::FtNumTypes
] = {
217 "", "FILEVERSION", "PRODUCTVERSION", "FILEFLAGSMASK",
218 "FILEFLAGS", "FILEOS", "FILETYPE", "FILESUBTYPE"};
220 const StringMap
<VersionInfoFixedType
> VersionInfoFixed::FixedFieldsInfoMap
= {
221 {FixedFieldsNames
[FtFileVersion
], FtFileVersion
},
222 {FixedFieldsNames
[FtProductVersion
], FtProductVersion
},
223 {FixedFieldsNames
[FtFileFlagsMask
], FtFileFlagsMask
},
224 {FixedFieldsNames
[FtFileFlags
], FtFileFlags
},
225 {FixedFieldsNames
[FtFileOS
], FtFileOS
},
226 {FixedFieldsNames
[FtFileType
], FtFileType
},
227 {FixedFieldsNames
[FtFileSubtype
], FtFileSubtype
}};
229 VersionInfoFixedType
VersionInfoFixed::getFixedType(StringRef Type
) {
230 auto UpperType
= Type
.upper();
231 auto Iter
= FixedFieldsInfoMap
.find(UpperType
);
232 if (Iter
!= FixedFieldsInfoMap
.end())
233 return Iter
->getValue();
237 bool VersionInfoFixed::isTypeSupported(VersionInfoFixedType Type
) {
238 return FtUnknown
< Type
&& Type
< FtNumTypes
;
241 bool VersionInfoFixed::isVersionType(VersionInfoFixedType Type
) {
244 case FtProductVersion
:
252 raw_ostream
&VersionInfoFixed::log(raw_ostream
&OS
) const {
253 for (int Type
= FtUnknown
; Type
< FtNumTypes
; ++Type
) {
254 if (!isTypeSupported((VersionInfoFixedType
)Type
))
256 OS
<< " Fixed: " << FixedFieldsNames
[Type
] << ":";
257 for (uint32_t Val
: FixedInfo
[Type
])
264 raw_ostream
&VersionInfoResource::log(raw_ostream
&OS
) const {
265 OS
<< "VersionInfo (" << ResName
<< "):\n";
267 return MainBlock
.log(OS
);
270 raw_ostream
&UserDefinedResource::log(raw_ostream
&OS
) const {
271 OS
<< "User-defined (type: " << Type
<< ", name: " << ResName
<< "): ";
273 return OS
<< FileLoc
<< "\n";
275 for (auto &Item
: Contents
)
280 raw_ostream
&CharacteristicsStmt::log(raw_ostream
&OS
) const {
281 return OS
<< "Characteristics: " << Value
<< "\n";
284 raw_ostream
&VersionStmt::log(raw_ostream
&OS
) const {
285 return OS
<< "Version: " << Value
<< "\n";
288 raw_ostream
&CaptionStmt::log(raw_ostream
&OS
) const {
289 return OS
<< "Caption: " << Value
<< "\n";
292 raw_ostream
&ClassStmt::log(raw_ostream
&OS
) const {
293 return OS
<< "Class: " << Value
<< "\n";
296 raw_ostream
&FontStmt::log(raw_ostream
&OS
) const {
297 OS
<< "Font: size = " << Size
<< ", face = " << Name
298 << ", weight = " << Weight
;
301 return OS
<< ", charset = " << Charset
<< "\n";
304 raw_ostream
&StyleStmt::log(raw_ostream
&OS
) const {
305 return OS
<< "Style: " << Value
<< "\n";
308 raw_ostream
&ExStyleStmt::log(raw_ostream
&OS
) const {
309 return OS
<< "ExStyle: " << Value
<< "\n";