summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-rc/ResourceScriptParser.cpp
diff options
context:
space:
mode:
authorMarek Sokolowski <mnbvmar@gmail.com>2017-08-28 23:46:30 +0000
committerMarek Sokolowski <mnbvmar@gmail.com>2017-08-28 23:46:30 +0000
commit99ecb0ebcaa4b953fcc5e9fbf49b233ef1b9b294 (patch)
treed9bb28e179e99e08584bd940da9d4b21cf16f707 /llvm/tools/llvm-rc/ResourceScriptParser.cpp
parent873a0746f124c47413407a7f767c906db17828db (diff)
downloadbcm5719-llvm-99ecb0ebcaa4b953fcc5e9fbf49b233ef1b9b294.tar.gz
bcm5719-llvm-99ecb0ebcaa4b953fcc5e9fbf49b233ef1b9b294.zip
[llvm-rc] Add MENU parsing ability (parser, pt 4/8).
This extends llvm-rc parsing tool by MENU resource (msdn.microsoft.com/en-us/library/windows/desktop/aa381025(v=vs.85).aspx). As for now, MENUEX (msdn.microsoft.com/en-us/library/windows/desktop/aa381023(v=vs.85).aspx) seems unnecessary. Thanks for Nico Weber for his original work in this area. Differential Revision: https://reviews.llvm.org/D36898 llvm-svn: 311956
Diffstat (limited to 'llvm/tools/llvm-rc/ResourceScriptParser.cpp')
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptParser.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index 8d08396e615..5cc171c49af 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -71,6 +71,8 @@ RCParser::ParseType RCParser::parseSingleResource() {
Result = parseIconResource();
else if (TypeToken->equalsLower("HTML"))
Result = parseHTMLResource();
+ else if (TypeToken->equalsLower("MENU"))
+ Result = parseMenuResource();
else
return getExpectedError("resource type", /* IsAlreadyRead = */ true);
@@ -285,6 +287,71 @@ RCParser::ParseType RCParser::parseHTMLResource() {
return make_unique<HTMLResource>(*Arg);
}
+RCParser::ParseType RCParser::parseMenuResource() {
+ ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
+ ASSIGN_OR_RETURN(Items, parseMenuItemsList());
+ return make_unique<MenuResource>(std::move(*OptStatements),
+ std::move(*Items));
+}
+
+Expected<MenuDefinitionList> RCParser::parseMenuItemsList() {
+ RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
+
+ MenuDefinitionList List;
+
+ // Read a set of items. Each item is of one of three kinds:
+ // MENUITEM SEPARATOR
+ // MENUITEM caption:String, result:Int [, menu flags]...
+ // POPUP caption:String [, menu flags]... { items... }
+ while (!consumeOptionalType(Kind::BlockEnd)) {
+ ASSIGN_OR_RETURN(ItemTypeResult, readIdentifier());
+
+ bool IsMenuItem = ItemTypeResult->equals_lower("MENUITEM");
+ bool IsPopup = ItemTypeResult->equals_lower("POPUP");
+ if (!IsMenuItem && !IsPopup)
+ return getExpectedError("MENUITEM, POPUP, END or '}'", true);
+
+ if (IsMenuItem && isNextTokenKind(Kind::Identifier)) {
+ // Now, expecting SEPARATOR.
+ ASSIGN_OR_RETURN(SeparatorResult, readIdentifier());
+ if (SeparatorResult->equals_lower("SEPARATOR")) {
+ List.addDefinition(make_unique<MenuSeparator>());
+ continue;
+ }
+
+ return getExpectedError("SEPARATOR or string", true);
+ }
+
+ // Not a separator. Read the caption.
+ ASSIGN_OR_RETURN(CaptionResult, readString());
+
+ // If MENUITEM, expect also a comma and an integer.
+ uint32_t MenuResult = -1;
+
+ if (IsMenuItem) {
+ RETURN_IF_ERROR(consumeType(Kind::Comma));
+ ASSIGN_OR_RETURN(IntResult, readInt());
+ MenuResult = *IntResult;
+ }
+
+ ASSIGN_OR_RETURN(FlagsResult, parseFlags(MenuDefinition::OptionsStr));
+
+ if (IsPopup) {
+ // If POPUP, read submenu items recursively.
+ ASSIGN_OR_RETURN(SubMenuResult, parseMenuItemsList());
+ List.addDefinition(make_unique<PopupItem>(*CaptionResult, *FlagsResult,
+ std::move(*SubMenuResult)));
+ continue;
+ }
+
+ assert(IsMenuItem);
+ List.addDefinition(
+ make_unique<MenuItem>(*CaptionResult, MenuResult, *FlagsResult));
+ }
+
+ return std::move(List);
+}
+
RCParser::ParseType RCParser::parseStringTableResource() {
ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
OpenPOWER on IntegriCloud