[llvm] r314478 - [llvm-rc] Add user-defined resources parsing ability. [8/8]
Marek Sokolowski via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 28 17:14:18 PDT 2017
Author: mnbvmar
Date: Thu Sep 28 17:14:18 2017
New Revision: 314478
URL: http://llvm.org/viewvc/llvm-project?rev=314478&view=rev
Log:
[llvm-rc] Add user-defined resources parsing ability. [8/8]
This allows llvm-rc to parse user-defined resources (ref:
msdn.microsoft.com/en-us/library/windows/desktop/aa381054.aspx).
These statements either import files, or put the specified raw data in
the resulting resource file.
Thanks to Nico Weber for his original work in this area.
Differential Revision: https://reviews.llvm.org/D37033
Added:
llvm/trunk/test/tools/llvm-rc/Inputs/parser-user-invalid-contents.rc
Modified:
llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc
llvm/trunk/test/tools/llvm-rc/parser.test
llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp
llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
Modified: llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc?rev=314478&r1=314477&r2=314478&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc (original)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc Thu Sep 28 17:14:18 2017
@@ -111,3 +111,13 @@ BEGIN
END
END
+
+MYNAME MYTYPE "filename"
+
+500 600 "other filename"
+
+HELLO INTEGERS {1, 2, 3, 4}
+
+HELLO STRINGS {"1", "2", "3", "4"}
+
+4 MIXED {1, "2", 3, "4"}
Added: llvm/trunk/test/tools/llvm-rc/Inputs/parser-user-invalid-contents.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/parser-user-invalid-contents.rc?rev=314478&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/parser-user-invalid-contents.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-user-invalid-contents.rc Thu Sep 28 17:14:18 2017
@@ -0,0 +1,4 @@
+MYNAME MYTYPE
+BEGIN
+ 1, 2, InvalidToken
+END
Modified: llvm/trunk/test/tools/llvm-rc/parser.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/parser.test?rev=314478&r1=314477&r2=314478&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/parser.test (original)
+++ llvm/trunk/test/tools/llvm-rc/parser.test Thu Sep 28 17:14:18 2017
@@ -91,6 +91,12 @@
; PGOOD-NEXT: "Translation" => 1033 1252
; PGOOD-NEXT: End of block
; PGOOD-NEXT: End of block
+; PGOOD-NEXT: User-defined (type: MYTYPE, name: MYNAME): "filename"
+; PGOOD-NEXT: User-defined (type: 600, name: 500): "other filename"
+; PGOOD-NEXT: User-defined (type: INTEGERS, name: HELLO): data = 1 2 3 4
+; PGOOD-NEXT: User-defined (type: STRINGS, name: HELLO): data = "1" "2" "3" "4"
+; PGOOD-NEXT: User-defined (type: MIXED, name: 4): data = 1 "2" 3 "4"
+
@@ -121,7 +127,7 @@
; RUN: not llvm-rc /V %p/Inputs/parser-nonsense-type.rc 2>&1 | FileCheck %s --check-prefix PNONSENSE2
-; PNONSENSE2: llvm-rc: Error parsing file: expected resource type, got WORLD
+; PNONSENSE2: llvm-rc: Error parsing file: expected filename, '{' or BEGIN, got <EOF>
; RUN: not llvm-rc /V %p/Inputs/parser-nonsense-type-eof.rc 2>&1 | FileCheck %s --check-prefix PNONSENSE3
@@ -242,3 +248,8 @@
; RUN: not llvm-rc /V %p/Inputs/parser-versioninfo-repeated-fixed.rc 2>&1 | FileCheck %s --check-prefix PVERSIONINFO6
; PVERSIONINFO6: llvm-rc: Error parsing file: expected yet unread fixed VERSIONINFO statement type, got FILEVERSION
+
+
+; RUN: not llvm-rc /V %p/Inputs/parser-user-invalid-contents.rc 2>&1 | FileCheck %s --check-prefix PUSER1
+
+; PUSER1: llvm-rc: Error parsing file: expected int or string, got InvalidToken
Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp?rev=314478&r1=314477&r2=314478&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp Thu Sep 28 17:14:18 2017
@@ -80,7 +80,7 @@ RCParser::ParseType RCParser::parseSingl
else if (TypeToken->equalsLower("VERSIONINFO"))
Result = parseVersionInfoResource();
else
- return getExpectedError("resource type", /* IsAlreadyRead = */ true);
+ Result = parseUserDefinedResource(*TypeToken);
if (Result)
(*Result)->setName(*NameToken);
@@ -416,6 +416,31 @@ RCParser::ParseType RCParser::parseDialo
return std::move(Dialog);
}
+RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) {
+ if (isEof())
+ return getExpectedError("filename, '{' or BEGIN");
+
+ // Check if this is a file resource.
+ if (look().kind() == Kind::String)
+ return make_unique<UserDefinedResource>(Type, read().value());
+
+ RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
+ std::vector<IntOrString> Data;
+
+ // Consume comma before each consecutive token except the first one.
+ bool ConsumeComma = false;
+ while (!consumeOptionalType(Kind::BlockEnd)) {
+ if (ConsumeComma)
+ RETURN_IF_ERROR(consumeType(Kind::Comma));
+ ConsumeComma = true;
+
+ ASSIGN_OR_RETURN(Item, readIntOrString());
+ Data.push_back(*Item);
+ }
+
+ return make_unique<UserDefinedResource>(Type, std::move(Data));
+}
+
RCParser::ParseType RCParser::parseVersionInfoResource() {
ASSIGN_OR_RETURN(FixedResult, parseVersionInfoFixed());
ASSIGN_OR_RETURN(BlockResult, parseVersionInfoBlockContents(StringRef()));
Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.h?rev=314478&r1=314477&r2=314478&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.h Thu Sep 28 17:14:18 2017
@@ -139,6 +139,7 @@ private:
ParseType parseHTMLResource();
ParseType parseMenuResource();
ParseType parseStringTableResource();
+ ParseType parseUserDefinedResource(IntOrString Type);
ParseType parseVersionInfoResource();
// Helper DIALOG parser - a single control.
Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp?rev=314478&r1=314477&r2=314478&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp Thu Sep 28 17:14:18 2017
@@ -214,6 +214,16 @@ raw_ostream &VersionInfoResource::log(ra
return MainBlock.log(OS);
}
+raw_ostream &UserDefinedResource::log(raw_ostream &OS) const {
+ OS << "User-defined (type: " << Type << ", name: " << ResName << "): ";
+ if (IsFileResource)
+ return OS << FileLoc << "\n";
+ OS << "data = ";
+ for (auto &Item : Contents)
+ OS << Item << " ";
+ return OS << "\n";
+}
+
raw_ostream &CharacteristicsStmt::log(raw_ostream &OS) const {
return OS << "Characteristics: " << Value << "\n";
}
Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h?rev=314478&r1=314477&r2=314478&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h Thu Sep 28 17:14:18 2017
@@ -319,6 +319,24 @@ public:
raw_ostream &log(raw_ostream &) const override;
};
+// User-defined resource. It is either:
+// * a link to the file, e.g. NAME TYPE "filename",
+// * or contains a list of integers and strings, e.g. NAME TYPE {1, "a", 2}.
+class UserDefinedResource : public RCResource {
+ IntOrString Type;
+ StringRef FileLoc;
+ std::vector<IntOrString> Contents;
+ bool IsFileResource;
+
+public:
+ UserDefinedResource(IntOrString ResourceType, StringRef FileLocation)
+ : Type(ResourceType), FileLoc(FileLocation), IsFileResource(true) {}
+ UserDefinedResource(IntOrString ResourceType, std::vector<IntOrString> &&Data)
+ : Type(ResourceType), Contents(std::move(Data)), IsFileResource(false) {}
+
+ raw_ostream &log(raw_ostream &) const override;
+};
+
// -- VERSIONINFO resource and its helper classes --
//
// This resource lists the version information on the executable/library.
More information about the llvm-commits
mailing list