summaryrefslogtreecommitdiff
path: root/tools/llvm-rc
diff options
context:
space:
mode:
authorMarek Sokolowski <mnbvmar@gmail.com>2017-08-18 17:25:55 +0000
committerMarek Sokolowski <mnbvmar@gmail.com>2017-08-18 17:25:55 +0000
commit43ca59772e9abd04b1c672fcae67a60101991b7e (patch)
tree1d49e20a83bda90498ef303817ff97d781acabd7 /tools/llvm-rc
parenta8f3cf28e07becd256c1e8b25cf2a745077c135d (diff)
Revert "[llvm-rc] Add basic RC scripts parsing ability."
This reverts commit r311175. This failed some buildbots compilation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311177 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-rc')
-rw-r--r--tools/llvm-rc/CMakeLists.txt2
-rw-r--r--tools/llvm-rc/ResourceScriptParser.cpp265
-rw-r--r--tools/llvm-rc/ResourceScriptParser.h143
-rw-r--r--tools/llvm-rc/ResourceScriptStmt.cpp60
-rw-r--r--tools/llvm-rc/ResourceScriptStmt.h145
-rw-r--r--tools/llvm-rc/llvm-rc.cpp8
6 files changed, 0 insertions, 623 deletions
diff --git a/tools/llvm-rc/CMakeLists.txt b/tools/llvm-rc/CMakeLists.txt
index dce6cbb1121..0e254516d74 100644
--- a/tools/llvm-rc/CMakeLists.txt
+++ b/tools/llvm-rc/CMakeLists.txt
@@ -10,7 +10,5 @@ add_public_tablegen_target(RcTableGen)
add_llvm_tool(llvm-rc
llvm-rc.cpp
- ResourceScriptParser.cpp
- ResourceScriptStmt.cpp
ResourceScriptToken.cpp
)
diff --git a/tools/llvm-rc/ResourceScriptParser.cpp b/tools/llvm-rc/ResourceScriptParser.cpp
deleted file mode 100644
index f284551cddc..00000000000
--- a/tools/llvm-rc/ResourceScriptParser.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-//===-- ResourceScriptParser.cpp --------------------------------*- C++-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-//
-// This implements the parser defined in ResourceScriptParser.h.
-//
-//===---------------------------------------------------------------------===//
-
-#include "ResourceScriptParser.h"
-
-// Take an expression returning llvm::Error and forward the error if it exists.
-#define RETURN_IF_ERROR(Expr) \
- if (auto Err = (Expr)) \
- return std::move(Err);
-
-// Take an expression returning llvm::Expected<T> and assign it to Var or
-// forward the error out of the function.
-#define ASSIGN_OR_RETURN(Var, Expr) \
- auto Var = (Expr); \
- if (!Var) \
- return Var.takeError();
-
-namespace llvm {
-namespace rc {
-
-RCParser::ParserError::ParserError(const Twine Expected, const LocIter CurLoc,
- const LocIter End)
- : ErrorLoc(CurLoc), FileEnd(End) {
- CurMessage = "Error parsing file: expected " + Expected.str() + ", got " +
- (CurLoc == End ? "<EOF>" : CurLoc->value()).str();
-}
-
-char RCParser::ParserError::ID = 0;
-
-RCParser::RCParser(const std::vector<RCToken> &TokenList)
- : Tokens(TokenList), CurLoc(Tokens.begin()), End(Tokens.end()) {}
-
-RCParser::RCParser(std::vector<RCToken> &&TokenList)
- : Tokens(std::move(TokenList)), CurLoc(Tokens.begin()), End(Tokens.end()) {}
-
-bool RCParser::isEof() const { return CurLoc == End; }
-
-RCParser::ParseType RCParser::parseSingleResource() {
- // The first thing we read is usually a resource's name. However, in some
- // cases (LANGUAGE and STRINGTABLE) the resources don't have their names
- // and the first token to be read is the type.
- ASSIGN_OR_RETURN(NameToken, readTypeOrName());
-
- if (NameToken->equalsLower("LANGUAGE"))
- return parseLanguageResource();
- else if (NameToken->equalsLower("STRINGTABLE"))
- return parseStringTableResource();
-
- // If it's not an unnamed resource, what we've just read is a name. Now,
- // read resource type;
- ASSIGN_OR_RETURN(TypeToken, readTypeOrName());
-
- ParseType Result = std::unique_ptr<RCResource>();
- (void)!Result;
-
- if (TypeToken->equalsLower("ICON"))
- Result = parseIconResource();
- else
- return getExpectedError("resource type", /* IsAlreadyRead = */ true);
-
- if (Result)
- (*Result)->setName(*NameToken);
-
- return Result;
-}
-
-bool RCParser::isNextTokenKind(Kind TokenKind) const {
- return !isEof() && look().kind() == TokenKind;
-}
-
-const RCToken &RCParser::look() const {
- assert(!isEof());
- return *CurLoc;
-}
-
-const RCToken &RCParser::read() {
- assert(!isEof());
- return *CurLoc++;
-}
-
-void RCParser::consume() {
- assert(!isEof());
- CurLoc++;
-}
-
-Expected<uint32_t> RCParser::readInt() {
- if (!isNextTokenKind(Kind::Int))
- return getExpectedError("integer");
- return read().intValue();
-}
-
-Expected<StringRef> RCParser::readString() {
- if (!isNextTokenKind(Kind::String))
- return getExpectedError("string");
- return read().value();
-}
-
-Expected<StringRef> RCParser::readIdentifier() {
- if (!isNextTokenKind(Kind::Identifier))
- return getExpectedError("identifier");
- return read().value();
-}
-
-Expected<IntOrString> RCParser::readTypeOrName() {
- // We suggest that the correct resource name or type should be either an
- // identifier or an integer. The original RC tool is much more liberal.
- if (!isNextTokenKind(Kind::Identifier) && !isNextTokenKind(Kind::Int))
- return getExpectedError("int or identifier");
-
- const RCToken &Tok = read();
- if (Tok.kind() == Kind::Int)
- return IntOrString(Tok.intValue());
- else
- return IntOrString(Tok.value());
-}
-
-Error RCParser::consumeType(Kind TokenKind) {
- if (isNextTokenKind(TokenKind)) {
- consume();
- return Error::success();
- }
-
- switch (TokenKind) {
-#define TOKEN(TokenName) \
- case Kind::TokenName: \
- return getExpectedError(#TokenName);
-#define SHORT_TOKEN(TokenName, TokenCh) \
- case Kind::TokenName: \
- return getExpectedError(#TokenCh);
-#include "ResourceScriptTokenList.h"
-#undef SHORT_TOKEN
-#undef TOKEN
- }
-}
-
-bool RCParser::consumeOptionalType(Kind TokenKind) {
- if (isNextTokenKind(TokenKind)) {
- consume();
- return true;
- }
-
- return false;
-}
-
-Expected<SmallVector<uint32_t, 8>>
-RCParser::readIntsWithCommas(size_t MinCount, size_t MaxCount) {
- assert(MinCount <= MaxCount);
-
- SmallVector<uint32_t, 8> Result;
-
- auto FailureHandler =
- [&](llvm::Error Err) -> Expected<SmallVector<uint32_t, 8>> {
- if (Result.size() < MinCount)
- return std::move(Err);
- consumeError(std::move(Err));
- return Result;
- };
-
- for (size_t i = 0; i < MaxCount; ++i) {
- // Try to read a comma unless we read the first token.
- // Sometimes RC tool requires them and sometimes not. We decide to
- // always require them.
- if (i >= 1) {
- if (auto CommaError = consumeType(Kind::Comma))
- return FailureHandler(std::move(CommaError));
- }
-
- if (auto IntResult = readInt())
- Result.push_back(*IntResult);
- else
- return FailureHandler(IntResult.takeError());
- }
-
- return Result;
-}
-
-// As for now, we ignore the extended set of statements.
-Expected<OptionalStmtList> RCParser::parseOptionalStatements(bool IsExtended) {
- OptionalStmtList Result;
-
- // The last statement is always followed by the start of the block.
- while (!isNextTokenKind(Kind::BlockBegin)) {
- ASSIGN_OR_RETURN(SingleParse, parseSingleOptionalStatement(IsExtended));
- Result.addStmt(std::move(*SingleParse));
- }
-
- return Result;
-}
-
-Expected<std::unique_ptr<OptionalStmt>>
-RCParser::parseSingleOptionalStatement(bool) {
- ASSIGN_OR_RETURN(TypeToken, readIdentifier());
- if (TypeToken->equals_lower("CHARACTERISTICS"))
- return parseCharacteristicsStmt();
- else if (TypeToken->equals_lower("LANGUAGE"))
- return parseLanguageStmt();
- else if (TypeToken->equals_lower("VERSION"))
- return parseVersionStmt();
- else
- return getExpectedError("optional statement type, BEGIN or '{'",
- /* IsAlreadyRead = */ true);
-}
-
-RCParser::ParseType RCParser::parseLanguageResource() {
- // Read LANGUAGE as an optional statement. If it's read correctly, we can
- // upcast it to RCResource.
- return parseLanguageStmt();
-}
-
-RCParser::ParseType RCParser::parseIconResource() {
- ASSIGN_OR_RETURN(Arg, readString());
- return make_unique<IconResource>(*Arg);
-}
-
-RCParser::ParseType RCParser::parseStringTableResource() {
- ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
- RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
-
- auto Table = make_unique<StringTableResource>(std::move(*OptStatements));
-
- // Read strings until we reach the end of the block.
- while (!consumeOptionalType(Kind::BlockEnd)) {
- // Each definition consists of string's ID (an integer) and a string.
- // Some examples in documentation suggest that there might be a comma in
- // between, however we strictly adhere to the single statement definition.
- ASSIGN_OR_RETURN(IDResult, readInt());
- ASSIGN_OR_RETURN(StrResult, readString());
- Table->addString(*IDResult, *StrResult);
- }
-
- return Table;
-}
-
-RCParser::ParseOptionType RCParser::parseLanguageStmt() {
- ASSIGN_OR_RETURN(Args, readIntsWithCommas(/* min = */ 2, /* max = */ 2));
- return make_unique<LanguageResource>((*Args)[0], (*Args)[1]);
-}
-
-RCParser::ParseOptionType RCParser::parseCharacteristicsStmt() {
- ASSIGN_OR_RETURN(Arg, readInt());
- return make_unique<CharacteristicsStmt>(*Arg);
-}
-
-RCParser::ParseOptionType RCParser::parseVersionStmt() {
- ASSIGN_OR_RETURN(Arg, readInt());
- return make_unique<VersionStmt>(*Arg);
-}
-
-Error RCParser::getExpectedError(const Twine Message, bool IsAlreadyRead) {
- return make_error<ParserError>(
- Message, IsAlreadyRead ? std::prev(CurLoc) : CurLoc, End);
-}
-
-} // namespace rc
-} // namespace llvm
diff --git a/tools/llvm-rc/ResourceScriptParser.h b/tools/llvm-rc/ResourceScriptParser.h
deleted file mode 100644
index 017e22f273d..00000000000
--- a/tools/llvm-rc/ResourceScriptParser.h
+++ /dev/null
@@ -1,143 +0,0 @@
-//===-- ResourceScriptParser.h ----------------------------------*- C++-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-//
-// This defines the RC scripts parser. It takes a sequence of RC tokens
-// and then provides the method to parse the resources one by one.
-//
-//===---------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_LLVMRC_RESOURCESCRIPTPARSER_H
-#define LLVM_TOOLS_LLVMRC_RESOURCESCRIPTPARSER_H
-
-#include "ResourceScriptStmt.h"
-#include "ResourceScriptToken.h"
-
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <system_error>
-#include <vector>
-
-namespace llvm {
-namespace rc {
-
-class RCParser {
-public:
- using LocIter = std::vector<RCToken>::iterator;
- using ParseType = Expected<std::unique_ptr<RCResource>>;
- using ParseOptionType = Expected<std::unique_ptr<OptionalStmt>>;
-
- // Class describing a single failure of parser.
- class ParserError : public ErrorInfo<ParserError> {
- public:
- ParserError(Twine Expected, const LocIter CurLoc, const LocIter End);
-
- void log(raw_ostream &OS) const override { OS << CurMessage; }
- std::error_code convertToErrorCode() const override {
- return std::make_error_code(std::errc::invalid_argument);
- }
- const std::string &getMessage() const { return CurMessage; }
-
- static char ID; // Keep llvm::Error happy.
-
- private:
- std::string CurMessage;
- LocIter ErrorLoc, FileEnd;
- };
-
- RCParser(const std::vector<RCToken> &TokenList);
- RCParser(std::vector<RCToken> &&TokenList);
-
- // Reads and returns a single resource definition, or error message if any
- // occurred.
- ParseType parseSingleResource();
-
- bool isEof() const;
-
-private:
- using Kind = RCToken::Kind;
-
- // Checks if the current parser state points to the token of type TokenKind.
- bool isNextTokenKind(Kind TokenKind) const;
-
- // These methods assume that the parser is not in EOF state.
-
- // Take a look at the current token. Do not fetch it.
- const RCToken &look() const;
- // Read the current token and advance the state by one token.
- const RCToken &read();
- // Advance the state by one token, discarding the current token.
- void consume();
-
- // The following methods try to read a single token, check if it has the
- // correct type and then parse it.
- Expected<uint32_t> readInt(); // Parse an integer.
- Expected<StringRef> readString(); // Parse a string.
- Expected<StringRef> readIdentifier(); // Parse an identifier.
- Expected<IntOrString> readTypeOrName(); // Parse an integer or an identifier.
-
- // Advance the state by one, discarding the current token.
- // If the discarded token had an incorrect type, fail.
- Error consumeType(Kind TokenKind);
-
- // Check the current token type. If it's TokenKind, discard it.
- // Return true if the parser consumed this token successfully.
- bool consumeOptionalType(Kind TokenKind);
-
- // Read at least MinCount, and at most MaxCount integers separated by
- // commas. The parser stops reading after fetching MaxCount integers
- // or after an error occurs. Whenever the parser reads a comma, it
- // expects an integer to follow.
- Expected<SmallVector<uint32_t, 8>> readIntsWithCommas(size_t MinCount,
- size_t MaxCount);
-
- // Reads a set of optional statements. These can change the behavior of
- // a number of resource types (e.g. STRINGTABLE, MENU or DIALOG) if provided
- // before the main block with the contents of the resource.
- // Usually, resources use a basic set of optional statements:
- // CHARACTERISTICS, LANGUAGE, VERSION
- // However, DIALOG and DIALOGEX extend this list by the following items:
- // CAPTION, CLASS, EXSTYLE, FONT, MENU, STYLE
- // UseExtendedStatements flag (off by default) allows the parser to read
- // the additional types of statements.
- //
- // Ref (to the list of all optional statements):
- // msdn.microsoft.com/en-us/library/windows/desktop/aa381002(v=vs.85).aspx
- Expected<OptionalStmtList>
- parseOptionalStatements(bool UseExtendedStatements = false);
-
- // Read a single optional statement.
- Expected<std::unique_ptr<OptionalStmt>>
- parseSingleOptionalStatement(bool UseExtendedStatements = false);
-
- // Top-level resource parsers.
- ParseType parseLanguageResource();
- ParseType parseIconResource();
- ParseType parseStringTableResource();
-
- // Optional statement parsers.
- ParseOptionType parseLanguageStmt();
- ParseOptionType parseCharacteristicsStmt();
- ParseOptionType parseVersionStmt();
-
- // Raises an error. If IsAlreadyRead = false (default), this complains about
- // the token that couldn't be parsed. If the flag is on, this complains about
- // the correctly read token that makes no sense (that is, the current parser
- // state is beyond the erroneous token.)
- Error getExpectedError(const Twine Message, bool IsAlreadyRead = false);
-
- std::vector<RCToken> Tokens;
- LocIter CurLoc;
- const LocIter End;
-};
-
-} // namespace rc
-} // namespace llvm
-
-#endif
diff --git a/tools/llvm-rc/ResourceScriptStmt.cpp b/tools/llvm-rc/ResourceScriptStmt.cpp
deleted file mode 100644
index af62e532225..00000000000
--- a/tools/llvm-rc/ResourceScriptStmt.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-//
-// This implements methods defined in ResourceScriptStmt.h.
-//
-// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380599(v=vs.85).aspx
-//
-//===---------------------------------------------------------------------===//
-
-#include "ResourceScriptStmt.h"
-
-namespace llvm {
-namespace rc {
-
-raw_ostream &operator<<(raw_ostream &OS, const IntOrString &Item) {
- if (Item.IsInt)
- return OS << Item.Data.Int;
- else
- return OS << Item.Data.String;
-}
-
-raw_ostream &OptionalStmtList::log(raw_ostream &OS) const {
- for (const auto &Stmt : Statements) {
- OS << " Option: ";
- Stmt->log(OS);
- }
- return OS;
-}
-
-raw_ostream &LanguageResource::log(raw_ostream &OS) const {
- return OS << "Language: " << Lang << ", Sublanguage: " << SubLang << "\n";
-}
-
-raw_ostream &IconResource::log(raw_ostream &OS) const {
- return OS << "Icon (" << ResName << "): " << IconLoc << "\n";
-}
-
-raw_ostream &StringTableResource::log(raw_ostream &OS) const {
- OS << "StringTable:\n";
- OptStatements.log(OS);
- for (const auto &String : Table)
- OS << " " << String.first << " => " << String.second << "\n";
- return OS;
-}
-
-raw_ostream &CharacteristicsStmt::log(raw_ostream &OS) const {
- return OS << "Characteristics: " << Value << "\n";
-}
-
-raw_ostream &VersionStmt::log(raw_ostream &OS) const {
- return OS << "Version: " << Value << "\n";
-}
-
-} // namespace rc
-} // namespace llvm
diff --git a/tools/llvm-rc/ResourceScriptStmt.h b/tools/llvm-rc/ResourceScriptStmt.h
deleted file mode 100644
index 3ee0962cfed..00000000000
--- a/tools/llvm-rc/ResourceScriptStmt.h
+++ /dev/null
@@ -1,145 +0,0 @@
-//===-- ResourceScriptStmt.h ------------------------------------*- C++-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-//
-// This lists all the resource and statement types occurring in RC scripts.
-//
-//===---------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H
-#define LLVM_TOOLS_LLVMRC_RESOURCESCRIPTSTMT_H
-
-#include "ResourceScriptToken.h"
-
-namespace llvm {
-namespace rc {
-
-// A class holding a name - either an integer or a reference to the string.
-class IntOrString {
-private:
- union Data {
- uint32_t Int;
- StringRef String;
- Data(uint32_t Value) : Int(Value) {}
- Data(const StringRef Value) : String(Value) {}
- Data(const RCToken &Token);
- } Data;
- bool IsInt;
-
-public:
- IntOrString() : IntOrString(0) {}
- IntOrString(uint32_t Value) : Data(Value), IsInt(1) {}
- IntOrString(StringRef Value) : Data(Value), IsInt(0) {}
- IntOrString(const RCToken &Token)
- : Data(Token), IsInt(Token.kind() == RCToken::Kind::Int) {}
-
- bool equalsLower(const char *Str) {
- return !IsInt && Data.String.equals_lower(Str);
- }
-
- friend raw_ostream &operator<<(raw_ostream &, const IntOrString &);
-};
-
-// Base resource. All the resources should derive from this base.
-class RCResource {
-protected:
- IntOrString ResName;
-
-public:
- RCResource() = default;
- RCResource(RCResource &&) = default;
- void setName(const IntOrString &Name) { ResName = Name; }
- virtual raw_ostream &log(raw_ostream &OS) const {
- return OS << "Base statement\n";
- };
- virtual ~RCResource() {}
-};
-
-// Optional statement base. All such statements should derive from this base.
-class OptionalStmt : public RCResource {};
-
-class OptionalStmtList : public OptionalStmt {
- std::vector<std::unique_ptr<OptionalStmt>> Statements;
-
-public:
- OptionalStmtList() {}
- virtual raw_ostream &log(raw_ostream &OS) const;
-
- void addStmt(std::unique_ptr<OptionalStmt> Stmt) {
- Statements.push_back(std::move(Stmt));
- }
-};
-
-// LANGUAGE statement. It can occur both as a top-level statement (in such
-// a situation, it changes the default language until the end of the file)
-// and as an optional resource statement (then it changes the language
-// of a single resource).
-//
-// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381019(v=vs.85).aspx
-class LanguageResource : public OptionalStmt {
- uint32_t Lang, SubLang;
-
-public:
- LanguageResource(uint32_t LangId, uint32_t SubLangId)
- : Lang(LangId), SubLang(SubLangId) {}
- 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
-class IconResource : public RCResource {
- StringRef IconLoc;
-
-public:
- IconResource(StringRef Location) : IconLoc(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
-class StringTableResource : public RCResource {
- OptionalStmtList OptStatements;
- std::vector<std::pair<uint32_t, StringRef>> Table;
-
-public:
- StringTableResource(OptionalStmtList &&OptStmts)
- : OptStatements(std::move(OptStmts)) {}
- void addString(uint32_t ID, StringRef String) {
- Table.emplace_back(ID, String);
- }
- raw_ostream &log(raw_ostream &) const override;
-};
-
-// CHARACTERISTICS optional statement.
-//
-// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx
-class CharacteristicsStmt : public OptionalStmt {
- uint32_t Value;
-
-public:
- CharacteristicsStmt(uint32_t Characteristic) : Value(Characteristic) {}
- raw_ostream &log(raw_ostream &) const override;
-};
-
-// VERSION optional statement.
-//
-// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381059(v=vs.85).aspx
-class VersionStmt : public OptionalStmt {
- uint32_t Value;
-
-public:
- VersionStmt(uint32_t Version) : Value(Version) {}
- raw_ostream &log(raw_ostream &) const override;
-};
-
-} // namespace rc
-} // namespace llvm
-
-#endif
diff --git a/tools/llvm-rc/llvm-rc.cpp b/tools/llvm-rc/llvm-rc.cpp
index 9446b11a507..098daba14e2 100644
--- a/tools/llvm-rc/llvm-rc.cpp
+++ b/tools/llvm-rc/llvm-rc.cpp
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "ResourceScriptToken.h"
-#include "ResourceScriptParser.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
@@ -134,12 +133,5 @@ int main(int argc_, const char *argv_[]) {
}
}
- rc::RCParser Parser{std::move(Tokens)};
- while (!Parser.isEof()) {
- auto Resource = ExitOnErr(Parser.parseSingleResource());
- if (BeVerbose)
- Resource->log(outs());
- }
-
return 0;
}