blob: 95890fe66693bbd499cc595f0308d336f6491758 [file] [log] [blame]
Marek Sokolowski5cd3d5c2017-08-18 18:24:17 +00001//===-- ResourceScriptStmt.h ------------------------------------*- C++-*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9//
10// This lists all the resource and statement types occurring in RC scripts.
11//
12//===---------------------------------------------------------------------===//
13
14#ifndef LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H
15#define LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H
16
17#include "ResourceScriptToken.h"
18
Marek Sokolowski4ac54d92017-08-29 16:49:59 +000019#include "llvm/ADT/StringSet.h"
20
Marek Sokolowski5cd3d5c2017-08-18 18:24:17 +000021namespace llvm {
22namespace rc {
23
24// A class holding a name - either an integer or a reference to the string.
25class IntOrString {
26private:
27 union Data {
28 uint32_t Int;
29 StringRef String;
30 Data(uint32_t Value) : Int(Value) {}
31 Data(const StringRef Value) : String(Value) {}
Marek Sokolowski7f110522017-08-28 22:58:31 +000032 Data(const RCToken &Token) {
33 if (Token.kind() == RCToken::Kind::Int)
34 Int = Token.intValue();
35 else
36 String = Token.value();
37 }
Marek Sokolowski5cd3d5c2017-08-18 18:24:17 +000038 } Data;
39 bool IsInt;
40
41public:
42 IntOrString() : IntOrString(0) {}
43 IntOrString(uint32_t Value) : Data(Value), IsInt(1) {}
44 IntOrString(StringRef Value) : Data(Value), IsInt(0) {}
45 IntOrString(const RCToken &Token)
46 : Data(Token), IsInt(Token.kind() == RCToken::Kind::Int) {}
47
48 bool equalsLower(const char *Str) {
49 return !IsInt && Data.String.equals_lower(Str);
50 }
51
52 friend raw_ostream &operator<<(raw_ostream &, const IntOrString &);
53};
54
55// Base resource. All the resources should derive from this base.
56class RCResource {
57protected:
58 IntOrString ResName;
59
60public:
61 RCResource() = default;
62 RCResource(RCResource &&) = default;
63 void setName(const IntOrString &Name) { ResName = Name; }
64 virtual raw_ostream &log(raw_ostream &OS) const {
65 return OS << "Base statement\n";
66 };
67 virtual ~RCResource() {}
68};
69
70// Optional statement base. All such statements should derive from this base.
71class OptionalStmt : public RCResource {};
72
73class OptionalStmtList : public OptionalStmt {
74 std::vector<std::unique_ptr<OptionalStmt>> Statements;
75
76public:
77 OptionalStmtList() {}
78 virtual raw_ostream &log(raw_ostream &OS) const;
79
80 void addStmt(std::unique_ptr<OptionalStmt> Stmt) {
81 Statements.push_back(std::move(Stmt));
82 }
83};
84
85// LANGUAGE statement. It can occur both as a top-level statement (in such
86// a situation, it changes the default language until the end of the file)
87// and as an optional resource statement (then it changes the language
88// of a single resource).
89//
90// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381019(v=vs.85).aspx
91class LanguageResource : public OptionalStmt {
92 uint32_t Lang, SubLang;
93
94public:
95 LanguageResource(uint32_t LangId, uint32_t SubLangId)
96 : Lang(LangId), SubLang(SubLangId) {}
97 raw_ostream &log(raw_ostream &) const override;
98};
99
Marek Sokolowski7f110522017-08-28 22:58:31 +0000100// ACCELERATORS resource. Defines a named table of accelerators for the app.
101//
102// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380610(v=vs.85).aspx
103class AcceleratorsResource : public RCResource {
104public:
105 class Accelerator {
106 public:
107 IntOrString Event;
108 uint32_t Id;
109 uint8_t Flags;
110
111 enum Options {
112 ASCII = (1 << 0),
113 VIRTKEY = (1 << 1),
114 NOINVERT = (1 << 2),
115 ALT = (1 << 3),
116 SHIFT = (1 << 4),
117 CONTROL = (1 << 5)
118 };
119
120 static constexpr size_t NumFlags = 6;
121 static StringRef OptionsStr[NumFlags];
122 };
123
124 AcceleratorsResource(OptionalStmtList &&OptStmts)
125 : OptStatements(std::move(OptStmts)) {}
126 void addAccelerator(IntOrString Event, uint32_t Id, uint8_t Flags) {
127 Accelerators.push_back(Accelerator{Event, Id, Flags});
128 }
129 raw_ostream &log(raw_ostream &) const override;
130
131private:
132 std::vector<Accelerator> Accelerators;
133 OptionalStmtList OptStatements;
134};
135
Marek Sokolowski72aa9372017-08-28 21:59:54 +0000136// CURSOR resource. Represents a single cursor (".cur") file.
137//
138// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380920(v=vs.85).aspx
139class CursorResource : public RCResource {
140 StringRef CursorLoc;
141
142public:
143 CursorResource(StringRef Location) : CursorLoc(Location) {}
144 raw_ostream &log(raw_ostream &) const override;
145};
146
Marek Sokolowski5cd3d5c2017-08-18 18:24:17 +0000147// ICON resource. Represents a single ".ico" file containing a group of icons.
148//
149// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381018(v=vs.85).aspx
150class IconResource : public RCResource {
151 StringRef IconLoc;
152
153public:
154 IconResource(StringRef Location) : IconLoc(Location) {}
155 raw_ostream &log(raw_ostream &) const override;
156};
157
Marek Sokolowski72aa9372017-08-28 21:59:54 +0000158// HTML resource. Represents a local webpage that is to be embedded into the
159// resulting resource file. It embeds a file only - no additional resources
160// (images etc.) are included with this resource.
161//
162// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa966018(v=vs.85).aspx
163class HTMLResource : public RCResource {
164 StringRef HTMLLoc;
165
166public:
167 HTMLResource(StringRef Location) : HTMLLoc(Location) {}
168 raw_ostream &log(raw_ostream &) const override;
169};
170
Marek Sokolowski99ecb0e2017-08-28 23:46:30 +0000171// -- MENU resource and its helper classes --
172// This resource describes the contents of an application menu
173// (usually located in the upper part of the dialog.)
174//
175// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381025(v=vs.85).aspx
176
177// Description of a single submenu item.
178class MenuDefinition {
179public:
180 enum Options {
181 CHECKED = (1 << 0),
182 GRAYED = (1 << 1),
183 HELP = (1 << 2),
184 INACTIVE = (1 << 3),
185 MENUBARBREAK = (1 << 4),
186 MENUBREAK = (1 << 5)
187 };
188
189 static constexpr size_t NumFlags = 6;
190 static StringRef OptionsStr[NumFlags];
191 static raw_ostream &logFlags(raw_ostream &, uint8_t Flags);
192 virtual raw_ostream &log(raw_ostream &OS) const {
193 return OS << "Base menu definition\n";
194 }
195 virtual ~MenuDefinition() {}
196};
197
198// Recursive description of a whole submenu.
199class MenuDefinitionList : public MenuDefinition {
200 std::vector<std::unique_ptr<MenuDefinition>> Definitions;
201
202public:
203 void addDefinition(std::unique_ptr<MenuDefinition> Def) {
204 Definitions.push_back(std::move(Def));
205 }
206 raw_ostream &log(raw_ostream &) const override;
207};
208
209// Separator in MENU definition (MENUITEM SEPARATOR).
210//
211// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381024(v=vs.85).aspx
212class MenuSeparator : public MenuDefinition {
213public:
214 raw_ostream &log(raw_ostream &) const override;
215};
216
217// MENUITEM statement definition.
218//
219// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381024(v=vs.85).aspx
220class MenuItem : public MenuDefinition {
221 StringRef Name;
222 uint32_t Id;
223 uint8_t Flags;
224
225public:
226 MenuItem(StringRef Caption, uint32_t ItemId, uint8_t ItemFlags)
227 : Name(Caption), Id(ItemId), Flags(ItemFlags) {}
228 raw_ostream &log(raw_ostream &) const override;
229};
230
231// POPUP statement definition.
232//
233// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381030(v=vs.85).aspx
234class PopupItem : public MenuDefinition {
235 StringRef Name;
236 uint8_t Flags;
237 MenuDefinitionList SubItems;
238
239public:
240 PopupItem(StringRef Caption, uint8_t ItemFlags,
241 MenuDefinitionList &&SubItemsList)
242 : Name(Caption), Flags(ItemFlags), SubItems(std::move(SubItemsList)) {}
243 raw_ostream &log(raw_ostream &) const override;
244};
245
246// Menu resource definition.
247class MenuResource : public RCResource {
248 OptionalStmtList OptStatements;
249 MenuDefinitionList Elements;
250
251public:
252 MenuResource(OptionalStmtList &&OptStmts, MenuDefinitionList &&Items)
253 : OptStatements(std::move(OptStmts)), Elements(std::move(Items)) {}
254 raw_ostream &log(raw_ostream &) const override;
255};
256
Marek Sokolowski5cd3d5c2017-08-18 18:24:17 +0000257// STRINGTABLE resource. Contains a list of strings, each having its unique ID.
258//
259// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381050(v=vs.85).aspx
260class StringTableResource : public RCResource {
261 OptionalStmtList OptStatements;
262 std::vector<std::pair<uint32_t, StringRef>> Table;
263
264public:
265 StringTableResource(OptionalStmtList &&OptStmts)
266 : OptStatements(std::move(OptStmts)) {}
267 void addString(uint32_t ID, StringRef String) {
268 Table.emplace_back(ID, String);
269 }
270 raw_ostream &log(raw_ostream &) const override;
271};
272
Marek Sokolowski4ac54d92017-08-29 16:49:59 +0000273// -- DIALOG(EX) resource and its helper classes --
274//
275// This resource describes dialog boxes and controls residing inside them.
276//
277// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381003(v=vs.85).aspx
278// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381002(v=vs.85).aspx
279
280// Single control definition.
281class Control {
282 StringRef Type, Title;
283 uint32_t ID, X, Y, Width, Height;
284 Optional<uint32_t> Style, ExtStyle, HelpID;
285
286public:
287 Control(StringRef CtlType, StringRef CtlTitle, uint32_t CtlID, uint32_t PosX,
288 uint32_t PosY, uint32_t ItemWidth, uint32_t ItemHeight,
289 Optional<uint32_t> ItemStyle, Optional<uint32_t> ExtItemStyle,
290 Optional<uint32_t> CtlHelpID)
291 : Type(CtlType), Title(CtlTitle), ID(CtlID), X(PosX), Y(PosY),
292 Width(ItemWidth), Height(ItemHeight), Style(ItemStyle),
293 ExtStyle(ExtItemStyle), HelpID(CtlHelpID) {}
294
295 static const StringSet<> SupportedCtls;
296 static const StringSet<> CtlsWithTitle;
297
298 raw_ostream &log(raw_ostream &) const;
299};
300
301// Single dialog definition. We don't create distinct classes for DIALOG and
302// DIALOGEX because of their being too similar to each other. We only have a
303// flag determining the type of the dialog box.
304class DialogResource : public RCResource {
305 uint32_t X, Y, Width, Height, HelpID;
306 OptionalStmtList OptStatements;
307 std::vector<Control> Controls;
308 bool IsExtended;
309
310public:
311 DialogResource(uint32_t PosX, uint32_t PosY, uint32_t DlgWidth,
312 uint32_t DlgHeight, uint32_t DlgHelpID,
313 OptionalStmtList &&OptStmts, bool IsDialogEx)
314 : X(PosX), Y(PosY), Width(DlgWidth), Height(DlgHeight), HelpID(DlgHelpID),
315 OptStatements(std::move(OptStmts)), IsExtended(IsDialogEx) {}
316
317 void addControl(Control &&Ctl) { Controls.push_back(std::move(Ctl)); }
318
319 raw_ostream &log(raw_ostream &) const override;
320};
321
Marek Sokolowskib5f39a02017-09-29 00:14:18 +0000322// User-defined resource. It is either:
323// * a link to the file, e.g. NAME TYPE "filename",
324// * or contains a list of integers and strings, e.g. NAME TYPE {1, "a", 2}.
325class UserDefinedResource : public RCResource {
326 IntOrString Type;
327 StringRef FileLoc;
328 std::vector<IntOrString> Contents;
329 bool IsFileResource;
330
331public:
332 UserDefinedResource(IntOrString ResourceType, StringRef FileLocation)
333 : Type(ResourceType), FileLoc(FileLocation), IsFileResource(true) {}
334 UserDefinedResource(IntOrString ResourceType, std::vector<IntOrString> &&Data)
335 : Type(ResourceType), Contents(std::move(Data)), IsFileResource(false) {}
336
337 raw_ostream &log(raw_ostream &) const override;
338};
339
Marek Sokolowskifb74cb12017-09-28 22:41:38 +0000340// -- VERSIONINFO resource and its helper classes --
341//
342// This resource lists the version information on the executable/library.
343// The declaration consists of the following items:
344// * A number of fixed optional version statements (e.g. FILEVERSION, FILEOS)
345// * BEGIN
346// * A number of BLOCK and/or VALUE statements. BLOCK recursively defines
347// another block of version information, whereas VALUE defines a
348// key -> value correspondence. There might be more than one value
349// corresponding to the single key.
350// * END
351//
352// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381058(v=vs.85).aspx
353
354// A single VERSIONINFO statement;
355class VersionInfoStmt {
356public:
357 virtual raw_ostream &log(raw_ostream &OS) const { return OS << "VI stmt\n"; }
358 virtual ~VersionInfoStmt() {}
359};
360
361// BLOCK definition; also the main VERSIONINFO declaration is considered a
362// BLOCK, although it has no name.
363// The correct top-level blocks are "VarFileInfo" and "StringFileInfo". We don't
364// care about them at the parsing phase.
365class VersionInfoBlock : public VersionInfoStmt {
366 std::vector<std::unique_ptr<VersionInfoStmt>> Stmts;
367 StringRef Name;
368
369public:
370 VersionInfoBlock(StringRef BlockName) : Name(BlockName) {}
371 void addStmt(std::unique_ptr<VersionInfoStmt> Stmt) {
372 Stmts.push_back(std::move(Stmt));
373 }
374 raw_ostream &log(raw_ostream &) const override;
375};
376
377class VersionInfoValue : public VersionInfoStmt {
378 StringRef Key;
379 std::vector<IntOrString> Values;
380
381public:
382 VersionInfoValue(StringRef InfoKey, std::vector<IntOrString> &&Vals)
383 : Key(InfoKey), Values(std::move(Vals)) {}
384 raw_ostream &log(raw_ostream &) const override;
385};
386
387class VersionInfoResource : public RCResource {
388public:
389 // A class listing fixed VERSIONINFO statements (occuring before main BEGIN).
390 // If any of these is not specified, it is assumed by the original tool to
391 // be equal to 0.
392 class VersionInfoFixed {
393 public:
394 enum VersionInfoFixedType {
395 FtUnknown,
396 FtFileVersion,
397 FtProductVersion,
398 FtFileFlagsMask,
399 FtFileFlags,
400 FtFileOS,
401 FtFileType,
402 FtFileSubtype,
403 FtNumTypes
404 };
405
406 private:
407 static const StringMap<VersionInfoFixedType> FixedFieldsInfoMap;
408 static const StringRef FixedFieldsNames[FtNumTypes];
409
410 public:
411 SmallVector<uint32_t, 4> FixedInfo[FtNumTypes];
412 SmallVector<bool, FtNumTypes> IsTypePresent;
413
414 static VersionInfoFixedType getFixedType(StringRef Type);
415 static bool isTypeSupported(VersionInfoFixedType Type);
416 static bool isVersionType(VersionInfoFixedType Type);
417
418 VersionInfoFixed() : IsTypePresent(FtNumTypes, false) {}
419
420 void setValue(VersionInfoFixedType Type, ArrayRef<uint32_t> Value) {
421 FixedInfo[Type] = SmallVector<uint32_t, 4>(Value.begin(), Value.end());
422 IsTypePresent[Type] = true;
423 }
424
425 raw_ostream &log(raw_ostream &) const;
426 };
427
428private:
429 VersionInfoBlock MainBlock;
430 VersionInfoFixed FixedData;
431
432public:
433 VersionInfoResource(VersionInfoBlock &&TopLevelBlock,
434 VersionInfoFixed &&FixedInfo)
435 : MainBlock(std::move(TopLevelBlock)), FixedData(std::move(FixedInfo)) {}
436
437 raw_ostream &log(raw_ostream &) const override;
438};
439
Marek Sokolowski5cd3d5c2017-08-18 18:24:17 +0000440// CHARACTERISTICS optional statement.
441//
442// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx
443class CharacteristicsStmt : public OptionalStmt {
444 uint32_t Value;
445
446public:
447 CharacteristicsStmt(uint32_t Characteristic) : Value(Characteristic) {}
448 raw_ostream &log(raw_ostream &) const override;
449};
450
451// VERSION optional statement.
452//
453// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381059(v=vs.85).aspx
454class VersionStmt : public OptionalStmt {
455 uint32_t Value;
456
457public:
458 VersionStmt(uint32_t Version) : Value(Version) {}
459 raw_ostream &log(raw_ostream &) const override;
460};
461
Marek Sokolowski4ac54d92017-08-29 16:49:59 +0000462// CAPTION optional statement.
463//
464// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380778(v=vs.85).aspx
465class CaptionStmt : public OptionalStmt {
466 StringRef Value;
467
468public:
469 CaptionStmt(StringRef Caption) : Value(Caption) {}
470 raw_ostream &log(raw_ostream &) const override;
471};
472
473// FONT optional statement.
474// Note that the documentation is inaccurate: it expects five arguments to be
475// given, however the example provides only two. In fact, the original tool
476// expects two arguments - point size and name of the typeface.
477//
478// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381013(v=vs.85).aspx
479class FontStmt : public OptionalStmt {
480 uint32_t Size;
481 StringRef Typeface;
482
483public:
484 FontStmt(uint32_t FontSize, StringRef FontName)
485 : Size(FontSize), Typeface(FontName) {}
486 raw_ostream &log(raw_ostream &) const override;
487};
488
489// STYLE optional statement.
490//
491// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381051(v=vs.85).aspx
492class StyleStmt : public OptionalStmt {
493 uint32_t Value;
494
495public:
496 StyleStmt(uint32_t Style) : Value(Style) {}
497 raw_ostream &log(raw_ostream &) const override;
498};
499
Marek Sokolowski5cd3d5c2017-08-18 18:24:17 +0000500} // namespace rc
501} // namespace llvm
502
503#endif