diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 |
commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /tools/llvm-rc/ResourceScriptParser.cpp | |
parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) |
Notes
Diffstat (limited to 'tools/llvm-rc/ResourceScriptParser.cpp')
-rw-r--r-- | tools/llvm-rc/ResourceScriptParser.cpp | 164 |
1 files changed, 138 insertions, 26 deletions
diff --git a/tools/llvm-rc/ResourceScriptParser.cpp b/tools/llvm-rc/ResourceScriptParser.cpp index cf1579ee2a11..8cc0b50933c2 100644 --- a/tools/llvm-rc/ResourceScriptParser.cpp +++ b/tools/llvm-rc/ResourceScriptParser.cpp @@ -66,18 +66,22 @@ RCParser::ParseType RCParser::parseSingleResource() { if (TypeToken->equalsLower("ACCELERATORS")) Result = parseAcceleratorsResource(); + else if (TypeToken->equalsLower("BITMAP")) + Result = parseBitmapResource(); else if (TypeToken->equalsLower("CURSOR")) Result = parseCursorResource(); else if (TypeToken->equalsLower("DIALOG")) Result = parseDialogResource(false); else if (TypeToken->equalsLower("DIALOGEX")) Result = parseDialogResource(true); - else if (TypeToken->equalsLower("ICON")) - Result = parseIconResource(); else if (TypeToken->equalsLower("HTML")) Result = parseHTMLResource(); + else if (TypeToken->equalsLower("ICON")) + Result = parseIconResource(); else if (TypeToken->equalsLower("MENU")) Result = parseMenuResource(); + else if (TypeToken->equalsLower("RCDATA")) + Result = parseUserDefinedResource(RkRcData); else if (TypeToken->equalsLower("VERSIONINFO")) Result = parseVersionInfoResource(); else @@ -212,6 +216,12 @@ Expected<StringRef> RCParser::readString() { return read().value(); } +Expected<StringRef> RCParser::readFilename() { + if (!isNextTokenKind(Kind::String) && !isNextTokenKind(Kind::Identifier)) + return getExpectedError("string"); + return read().value(); +} + Expected<StringRef> RCParser::readIdentifier() { if (!isNextTokenKind(Kind::Identifier)) return getExpectedError("identifier"); @@ -319,6 +329,37 @@ Expected<uint32_t> RCParser::parseFlags(ArrayRef<StringRef> FlagDesc, return Result; } +uint16_t RCParser::parseMemoryFlags(uint16_t Flags) { + while (!isEof()) { + const RCToken &Token = look(); + if (Token.kind() != Kind::Identifier) + return Flags; + const StringRef Ident = Token.value(); + if (Ident.equals_lower("PRELOAD")) + Flags |= MfPreload; + else if (Ident.equals_lower("LOADONCALL")) + Flags &= ~MfPreload; + else if (Ident.equals_lower("FIXED")) + Flags &= ~(MfMoveable | MfDiscardable); + else if (Ident.equals_lower("MOVEABLE")) + Flags |= MfMoveable; + else if (Ident.equals_lower("DISCARDABLE")) + Flags |= MfDiscardable | MfMoveable | MfPure; + else if (Ident.equals_lower("PURE")) + Flags |= MfPure; + else if (Ident.equals_lower("IMPURE")) + Flags &= ~(MfPure | MfDiscardable); + else if (Ident.equals_lower("SHARED")) + Flags |= MfPure; + else if (Ident.equals_lower("NONSHARED")) + Flags &= ~(MfPure | MfDiscardable); + else + return Flags; + consume(); + } + return Flags; +} + Expected<OptionalStmtList> RCParser::parseOptionalStatements(OptStmtType StmtsType) { OptionalStmtList Result; @@ -345,6 +386,8 @@ RCParser::parseSingleOptionalStatement(OptStmtType StmtsType) { if (StmtsType != OptStmtType::BasicStmt) { if (TypeToken->equals_lower("CAPTION")) return parseCaptionStmt(); + if (TypeToken->equals_lower("CLASS")) + return parseClassStmt(); if (TypeToken->equals_lower("FONT")) return parseFontStmt(StmtsType); if (TypeToken->equals_lower("STYLE")) @@ -362,11 +405,13 @@ RCParser::ParseType RCParser::parseLanguageResource() { } RCParser::ParseType RCParser::parseAcceleratorsResource() { + uint16_t MemoryFlags = + parseMemoryFlags(AcceleratorsResource::getDefaultMemoryFlags()); ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements()); RETURN_IF_ERROR(consumeType(Kind::BlockBegin)); - auto Accels = - llvm::make_unique<AcceleratorsResource>(std::move(*OptStatements)); + auto Accels = llvm::make_unique<AcceleratorsResource>( + std::move(*OptStatements), MemoryFlags); while (!consumeOptionalType(Kind::BlockEnd)) { ASSIGN_OR_RETURN(EventResult, readIntOrString()); @@ -383,11 +428,15 @@ RCParser::ParseType RCParser::parseAcceleratorsResource() { } RCParser::ParseType RCParser::parseCursorResource() { - ASSIGN_OR_RETURN(Arg, readString()); - return llvm::make_unique<CursorResource>(*Arg); + uint16_t MemoryFlags = + parseMemoryFlags(CursorResource::getDefaultMemoryFlags()); + ASSIGN_OR_RETURN(Arg, readFilename()); + return llvm::make_unique<CursorResource>(*Arg, MemoryFlags); } RCParser::ParseType RCParser::parseDialogResource(bool IsExtended) { + uint16_t MemoryFlags = + parseMemoryFlags(DialogResource::getDefaultMemoryFlags()); // Dialog resources have the following format of the arguments: // DIALOG: x, y, width, height [opt stmts...] {controls...} // DIALOGEX: x, y, width, height [, helpID] [opt stmts...] {controls...} @@ -410,7 +459,7 @@ RCParser::ParseType RCParser::parseDialogResource(bool IsExtended) { auto Dialog = llvm::make_unique<DialogResource>( (*LocResult)[0], (*LocResult)[1], (*LocResult)[2], (*LocResult)[3], - HelpID, std::move(*OptStatements), IsExtended); + HelpID, std::move(*OptStatements), IsExtended, MemoryFlags); while (!consumeOptionalType(Kind::BlockEnd)) { ASSIGN_OR_RETURN(ControlDefResult, parseControl()); @@ -421,12 +470,20 @@ RCParser::ParseType RCParser::parseDialogResource(bool IsExtended) { } RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) { + uint16_t MemoryFlags = + parseMemoryFlags(UserDefinedResource::getDefaultMemoryFlags()); if (isEof()) return getExpectedError("filename, '{' or BEGIN"); // Check if this is a file resource. - if (look().kind() == Kind::String) - return llvm::make_unique<UserDefinedResource>(Type, read().value()); + switch (look().kind()) { + case Kind::String: + case Kind::Identifier: + return llvm::make_unique<UserDefinedResource>(Type, read().value(), + MemoryFlags); + default: + break; + } RETURN_IF_ERROR(consumeType(Kind::BlockBegin)); std::vector<IntOrString> Data; @@ -442,14 +499,17 @@ RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) { Data.push_back(*Item); } - return llvm::make_unique<UserDefinedResource>(Type, std::move(Data)); + return llvm::make_unique<UserDefinedResource>(Type, std::move(Data), + MemoryFlags); } RCParser::ParseType RCParser::parseVersionInfoResource() { + uint16_t MemoryFlags = + parseMemoryFlags(VersionInfoResource::getDefaultMemoryFlags()); ASSIGN_OR_RETURN(FixedResult, parseVersionInfoFixed()); ASSIGN_OR_RETURN(BlockResult, parseVersionInfoBlockContents(StringRef())); - return llvm::make_unique<VersionInfoResource>(std::move(**BlockResult), - std::move(*FixedResult)); + return llvm::make_unique<VersionInfoResource>( + std::move(**BlockResult), std::move(*FixedResult), MemoryFlags); } Expected<Control> RCParser::parseControl() { @@ -473,32 +533,76 @@ Expected<Control> RCParser::parseControl() { Caption = *CaptionResult; } - ASSIGN_OR_RETURN(Args, readIntsWithCommas(5, 8)); + ASSIGN_OR_RETURN(ID, readInt()); + RETURN_IF_ERROR(consumeType(Kind::Comma)); + + IntOrString Class; + Optional<uint32_t> Style; + if (ClassUpper == "CONTROL") { + // CONTROL text, id, class, style, x, y, width, height [, exstyle] [, helpID] + ASSIGN_OR_RETURN(ClassStr, readString()); + RETURN_IF_ERROR(consumeType(Kind::Comma)); + Class = *ClassStr; + ASSIGN_OR_RETURN(StyleVal, readInt()); + RETURN_IF_ERROR(consumeType(Kind::Comma)); + Style = *StyleVal; + } else { + Class = CtlInfo->getValue().CtlClass; + } + + // x, y, width, height + ASSIGN_OR_RETURN(Args, readIntsWithCommas(4, 4)); - auto TakeOptArg = [&Args](size_t Id) -> Optional<uint32_t> { - return Args->size() > Id ? (uint32_t)(*Args)[Id] : Optional<uint32_t>(); - }; + if (ClassUpper != "CONTROL") { + if (consumeOptionalType(Kind::Comma)) { + ASSIGN_OR_RETURN(Val, readInt()); + Style = *Val; + } + } - return Control(*ClassResult, Caption, (*Args)[0], (*Args)[1], (*Args)[2], - (*Args)[3], (*Args)[4], TakeOptArg(5), TakeOptArg(6), - TakeOptArg(7)); + Optional<uint32_t> ExStyle; + if (consumeOptionalType(Kind::Comma)) { + ASSIGN_OR_RETURN(Val, readInt()); + ExStyle = *Val; + } + Optional<uint32_t> HelpID; + if (consumeOptionalType(Kind::Comma)) { + ASSIGN_OR_RETURN(Val, readInt()); + HelpID = *Val; + } + + return Control(*ClassResult, Caption, *ID, (*Args)[0], (*Args)[1], + (*Args)[2], (*Args)[3], Style, ExStyle, HelpID, Class); +} + +RCParser::ParseType RCParser::parseBitmapResource() { + uint16_t MemoryFlags = + parseMemoryFlags(BitmapResource::getDefaultMemoryFlags()); + ASSIGN_OR_RETURN(Arg, readFilename()); + return llvm::make_unique<BitmapResource>(*Arg, MemoryFlags); } RCParser::ParseType RCParser::parseIconResource() { - ASSIGN_OR_RETURN(Arg, readString()); - return llvm::make_unique<IconResource>(*Arg); + uint16_t MemoryFlags = + parseMemoryFlags(IconResource::getDefaultMemoryFlags()); + ASSIGN_OR_RETURN(Arg, readFilename()); + return llvm::make_unique<IconResource>(*Arg, MemoryFlags); } RCParser::ParseType RCParser::parseHTMLResource() { - ASSIGN_OR_RETURN(Arg, readString()); - return llvm::make_unique<HTMLResource>(*Arg); + uint16_t MemoryFlags = + parseMemoryFlags(HTMLResource::getDefaultMemoryFlags()); + ASSIGN_OR_RETURN(Arg, readFilename()); + return llvm::make_unique<HTMLResource>(*Arg, MemoryFlags); } RCParser::ParseType RCParser::parseMenuResource() { + uint16_t MemoryFlags = + parseMemoryFlags(MenuResource::getDefaultMemoryFlags()); ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements()); ASSIGN_OR_RETURN(Items, parseMenuItemsList()); return llvm::make_unique<MenuResource>(std::move(*OptStatements), - std::move(*Items)); + std::move(*Items), MemoryFlags); } Expected<MenuDefinitionList> RCParser::parseMenuItemsList() { @@ -561,11 +665,13 @@ Expected<MenuDefinitionList> RCParser::parseMenuItemsList() { } RCParser::ParseType RCParser::parseStringTableResource() { + uint16_t MemoryFlags = + parseMemoryFlags(StringTableResource::getDefaultMemoryFlags()); ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements()); RETURN_IF_ERROR(consumeType(Kind::BlockBegin)); - auto Table = - llvm::make_unique<StringTableResource>(std::move(*OptStatements)); + auto Table = llvm::make_unique<StringTableResource>(std::move(*OptStatements), + MemoryFlags); // Read strings until we reach the end of the block. while (!consumeOptionalType(Kind::BlockEnd)) { @@ -573,6 +679,7 @@ RCParser::ParseType RCParser::parseStringTableResource() { // 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()); + consumeOptionalType(Kind::Comma); ASSIGN_OR_RETURN(StrResult, readString()); Table->addString(*IDResult, *StrResult); } @@ -674,6 +781,11 @@ RCParser::ParseOptionType RCParser::parseCaptionStmt() { return llvm::make_unique<CaptionStmt>(*Arg); } +RCParser::ParseOptionType RCParser::parseClassStmt() { + ASSIGN_OR_RETURN(Arg, readIntOrString()); + return llvm::make_unique<ClassStmt>(*Arg); +} + RCParser::ParseOptionType RCParser::parseFontStmt(OptStmtType DialogType) { assert(DialogType != OptStmtType::BasicStmt); |