[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