Index: llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc =================================================================== --- llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc +++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-correct-everything.rc @@ -13,3 +13,6 @@ 2 "world" } STRINGTABLE BEGIN END + +500 HTML "index.html" +Name Cursor "hello.ico" Index: llvm/trunk/test/tools/llvm-rc/Inputs/parser-html-bad-string.rc =================================================================== --- llvm/trunk/test/tools/llvm-rc/Inputs/parser-html-bad-string.rc +++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-html-bad-string.rc @@ -0,0 +1 @@ +200 HTML ThisPassesInTheOriginalToolButDocSaysItShouldBeQuoted Index: llvm/trunk/test/tools/llvm-rc/Inputs/parser-html-extra-comma.rc =================================================================== --- llvm/trunk/test/tools/llvm-rc/Inputs/parser-html-extra-comma.rc +++ llvm/trunk/test/tools/llvm-rc/Inputs/parser-html-extra-comma.rc @@ -0,0 +1 @@ +1 HTML, "index.html" Index: llvm/trunk/test/tools/llvm-rc/parser.test =================================================================== --- llvm/trunk/test/tools/llvm-rc/parser.test +++ llvm/trunk/test/tools/llvm-rc/parser.test @@ -11,57 +11,60 @@ ; PGOOD-NEXT: 1 => "hello" ; PGOOD-NEXT: 2 => "world" ; PGOOD-NEXT: StringTable: +; PGOOD-NEXT: HTML (500): "index.html" +; PGOOD-NEXT: Cursor (Name): "hello.ico" -; RUN: not llvm-rc /V %p/Inputs/parser-stringtable-no-string.rc 2> %t2 -; RUN: FileCheck %s --check-prefix PSTRINGTABLE1 --input-file %t2 +; RUN: not llvm-rc /V %p/Inputs/parser-stringtable-no-string.rc 2>&1 | FileCheck %s --check-prefix PSTRINGTABLE1 ; PSTRINGTABLE1: llvm-rc: Error parsing file: expected string, got } -; RUN: not llvm-rc /V %p/Inputs/parser-stringtable-weird-option.rc 2> %t3 -; RUN: FileCheck %s --check-prefix PSTRINGTABLE2 --input-file %t3 +; RUN: not llvm-rc /V %p/Inputs/parser-stringtable-weird-option.rc 2>&1 | FileCheck %s --check-prefix PSTRINGTABLE2 ; PSTRINGTABLE2: llvm-rc: Error parsing file: expected optional statement type, BEGIN or '{', got NONSENSETYPE -; RUN: not llvm-rc /V %p/Inputs/parser-eof.rc 2> %t4 -; RUN: FileCheck %s --check-prefix PEOF --input-file %t4 +; RUN: not llvm-rc /V %p/Inputs/parser-eof.rc 2>&1 | FileCheck %s --check-prefix PEOF ; PEOF: llvm-rc: Error parsing file: expected integer, got -; RUN: not llvm-rc /V %p/Inputs/parser-no-characteristics-arg.rc 2> %t5 -; RUN: FileCheck %s --check-prefix PCHARACTERISTICS1 --input-file %t5 +; RUN: not llvm-rc /V %p/Inputs/parser-no-characteristics-arg.rc 2>&1 | FileCheck %s --check-prefix PCHARACTERISTICS1 ; PCHARACTERISTICS1: llvm-rc: Error parsing file: expected integer, got BEGIN -; RUN: not llvm-rc /V %p/Inputs/parser-nonsense-token.rc 2> %t6 -; RUN: FileCheck %s --check-prefix PNONSENSE1 --input-file %t6 +; RUN: not llvm-rc /V %p/Inputs/parser-nonsense-token.rc 2>&1 | FileCheck %s --check-prefix PNONSENSE1 ; PNONSENSE1: llvm-rc: Error parsing file: expected int or identifier, got & -; RUN: not llvm-rc /V %p/Inputs/parser-nonsense-type.rc 2> %t7 -; RUN: FileCheck %s --check-prefix PNONSENSE2 --input-file %t7 +; 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 -; RUN: not llvm-rc /V %p/Inputs/parser-nonsense-type-eof.rc 2> %t8 -; RUN: FileCheck %s --check-prefix PNONSENSE3 --input-file %t8 +; RUN: not llvm-rc /V %p/Inputs/parser-nonsense-type-eof.rc 2>&1 | FileCheck %s --check-prefix PNONSENSE3 ; PNONSENSE3: llvm-rc: Error parsing file: expected int or identifier, got -; RUN: not llvm-rc /V %p/Inputs/parser-language-no-comma.rc 2> %t9 -; RUN: FileCheck %s --check-prefix PLANGUAGE1 --input-file %t9 +; RUN: not llvm-rc /V %p/Inputs/parser-language-no-comma.rc 2>&1 | FileCheck %s --check-prefix PLANGUAGE1 ; PLANGUAGE1: llvm-rc: Error parsing file: expected ',', got 7 -; RUN: not llvm-rc /V %p/Inputs/parser-language-too-many-commas.rc 2> %t10 -; RUN: FileCheck %s --check-prefix PLANGUAGE2 --input-file %t10 +; RUN: not llvm-rc /V %p/Inputs/parser-language-too-many-commas.rc 2>&1 | FileCheck %s --check-prefix PLANGUAGE2 ; PLANGUAGE2: llvm-rc: Error parsing file: expected integer, got , + + +; RUN: not llvm-rc /V %p/Inputs/parser-html-bad-string.rc 2>&1 | FileCheck %s --check-prefix PHTML1 + +; PHTML1: llvm-rc: Error parsing file: expected string, got ThisPassesInTheOriginalToolButDocSaysItShouldBeQuoted + + +; RUN: not llvm-rc /V %p/Inputs/parser-html-extra-comma.rc 2>&1 | FileCheck %s --check-prefix PHTML2 + +; PHTML2: llvm-rc: Error parsing file: expected string, got , Index: llvm/trunk/tools/llvm-rc/ResourceScriptParser.h =================================================================== --- llvm/trunk/tools/llvm-rc/ResourceScriptParser.h +++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.h @@ -118,7 +118,9 @@ // Top-level resource parsers. ParseType parseLanguageResource(); + ParseType parseCursorResource(); ParseType parseIconResource(); + ParseType parseHTMLResource(); ParseType parseStringTableResource(); // Optional statement parsers. Index: llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp =================================================================== --- llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp +++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp @@ -63,8 +63,12 @@ ParseType Result = std::unique_ptr(); (void)!Result; - if (TypeToken->equalsLower("ICON")) + if (TypeToken->equalsLower("CURSOR")) + Result = parseCursorResource(); + else if (TypeToken->equalsLower("ICON")) Result = parseIconResource(); + else if (TypeToken->equalsLower("HTML")) + Result = parseHTMLResource(); else return getExpectedError("resource type", /* IsAlreadyRead = */ true); @@ -219,11 +223,21 @@ return parseLanguageStmt(); } +RCParser::ParseType RCParser::parseCursorResource() { + ASSIGN_OR_RETURN(Arg, readString()); + return make_unique(*Arg); +} + RCParser::ParseType RCParser::parseIconResource() { ASSIGN_OR_RETURN(Arg, readString()); return make_unique(*Arg); } +RCParser::ParseType RCParser::parseHTMLResource() { + ASSIGN_OR_RETURN(Arg, readString()); + return make_unique(*Arg); +} + RCParser::ParseType RCParser::parseStringTableResource() { ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements()); RETURN_IF_ERROR(consumeType(Kind::BlockBegin)); Index: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h =================================================================== --- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h +++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h @@ -90,6 +90,17 @@ raw_ostream &log(raw_ostream &) const override; }; +// CURSOR resource. Represents a single cursor (".cur") file. +// +// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380920(v=vs.85).aspx +class CursorResource : public RCResource { + StringRef CursorLoc; + +public: + CursorResource(StringRef Location) : CursorLoc(Location) {} + raw_ostream &log(raw_ostream &) const override; +}; + // ICON resource. Represents a single ".ico" file containing a group of icons. // // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381018(v=vs.85).aspx @@ -101,6 +112,19 @@ raw_ostream &log(raw_ostream &) const override; }; +// HTML resource. Represents a local webpage that is to be embedded into the +// resulting resource file. It embeds a file only - no additional resources +// (images etc.) are included with this resource. +// +// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa966018(v=vs.85).aspx +class HTMLResource : public RCResource { + StringRef HTMLLoc; + +public: + HTMLResource(StringRef Location) : HTMLLoc(Location) {} + raw_ostream &log(raw_ostream &) const override; +}; + // STRINGTABLE resource. Contains a list of strings, each having its unique ID. // // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381050(v=vs.85).aspx Index: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp =================================================================== --- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp +++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp @@ -36,10 +36,18 @@ return OS << "Language: " << Lang << ", Sublanguage: " << SubLang << "\n"; } +raw_ostream &CursorResource::log(raw_ostream &OS) const { + return OS << "Cursor (" << ResName << "): " << CursorLoc << "\n"; +} + raw_ostream &IconResource::log(raw_ostream &OS) const { return OS << "Icon (" << ResName << "): " << IconLoc << "\n"; } +raw_ostream &HTMLResource::log(raw_ostream &OS) const { + return OS << "HTML (" << ResName << "): " << HTMLLoc << "\n"; +} + raw_ostream &StringTableResource::log(raw_ostream &OS) const { OS << "StringTable:\n"; OptStatements.log(OS);