Skip to content

llvm-rc: add support for MENU in DIALOG(EX) #89409

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions llvm/test/tools/llvm-rc/Inputs/dialog-with-menu.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
101 DIALOG 0, 0, 362, 246
STYLE 0x40l | 0x0004l | 0x0008l | 0x0800l | 0x00020000l |
0x00010000l | 0x80000000l | 0x10000000l | 0x02000000l | 0x00C00000l |
0x00080000l | 0x00040000l
CAPTION "MakeNSISW"
MENU 104
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "",202,"RichEdit20A",0x0004l | 0x0040l |
0x0100l | 0x0800l | 0x00008000 |
0x00010000l | 0x00800000l | 0x00200000l,7,22,348,190
CONTROL "",-1,"Static",0x00000010l,7,220,346,1
LTEXT "",200,7,230,200,12,0x08000000l
DEFPUSHBUTTON "Test &Installer",203,230,226,60,15,0x08000000l | 0x00010000l
PUSHBUTTON "&Close",2,296,226,49,15,0x00010000l
END
32 changes: 32 additions & 0 deletions llvm/test/tools/llvm-rc/dialog-with-menu.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
; RUN: llvm-rc -no-preprocess /FO %t -- %p/Inputs/dialog-with-menu.rc
; RUN: llvm-readobj %t | FileCheck %s

CHECK: Resource type (int): DIALOG (ID 5)
CHECK-NEXT: Resource name (int): 101
CHECK-NEXT: Data version: 0
CHECK-NEXT: Memory flags: 0x1030
CHECK-NEXT: Language ID: 1033
CHECK-NEXT: Version (major): 0
CHECK-NEXT: Version (minor): 0
CHECK-NEXT: Characteristics: 0
CHECK-NEXT: Data size: 278
CHECK-NEXT: Data: (
CHECK-NEXT: 0000: 4C08CF92 00000000 05000000 00006A01 |L.............j.|
CHECK-NEXT: 0010: F600FFFF 68000000 4D006100 6B006500 |....h...M.a.k.e.|
CHECK-NEXT: 0020: 4E005300 49005300 57000000 08004D00 |N.S.I.S.W.....M.|
CHECK-NEXT: 0030: 53002000 53006800 65006C00 6C002000 |S. .S.h.e.l.l. .|
CHECK-NEXT: 0040: 44006C00 67000000 4489A150 00000000 |D.l.g...D..P....|
CHECK-NEXT: 0050: 07001600 5C01BE00 CA005200 69006300 |....\.....R.i.c.|
CHECK-NEXT: 0060: 68004500 64006900 74003200 30004100 |h.E.d.i.t.2.0.A.|
CHECK-NEXT: 0070: 00000000 00000000 10000050 00000000 |...........P....|
CHECK-NEXT: 0080: 0700DC00 5A010100 FFFF5300 74006100 |....Z.....S.t.a.|
CHECK-NEXT: 0090: 74006900 63000000 00000000 00000258 |t.i.c..........X|
CHECK-NEXT: 00A0: 00000000 0700E600 C8000C00 C800FFFF |................|
CHECK-NEXT: 00B0: 82000000 00000000 01000158 00000000 |...........X....|
CHECK-NEXT: 00C0: E600E200 3C000F00 CB00FFFF 80005400 |....<.........T.|
CHECK-NEXT: 00D0: 65007300 74002000 26004900 6E007300 |e.s.t. .&.I.n.s.|
CHECK-NEXT: 00E0: 74006100 6C006C00 65007200 00000000 |t.a.l.l.e.r.....|
CHECK-NEXT: 00F0: 00000150 00000000 2801E200 31000F00 |...P....(...1...|
CHECK-NEXT: 0100: 0200FFFF 80002600 43006C00 6F007300 |......&.C.l.o.s.|
CHECK-NEXT: 0110: 65000000 0000 |e.....|
CHECK-NEXT: )
10 changes: 7 additions & 3 deletions llvm/tools/llvm-rc/ResourceFileWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,11 @@ Error ResourceFileWriter::visitVersionStmt(const VersionStmt *Stmt) {
return Error::success();
}

Error ResourceFileWriter::visitMenuStmt(const MenuStmt *Stmt) {
ObjectData.Menu = Stmt->Value;
return Error::success();
}

Error ResourceFileWriter::writeResource(
const RCResource *Res,
Error (ResourceFileWriter::*BodyWriter)(const RCResource *)) {
Expand Down Expand Up @@ -1132,9 +1137,8 @@ Error ResourceFileWriter::writeDialogBody(const RCResource *Base) {
ulittle16_t(Res->Height)};
writeObject(Middle);

// MENU field. As of now, we don't keep them in the state and can peacefully
// think there is no menu attached to the dialog.
writeInt<uint16_t>(0);
// MENU field.
RETURN_IF_ERROR(writeIntOrString(ObjectData.Menu));

// Window CLASS field.
RETURN_IF_ERROR(writeIntOrString(ObjectData.Class));
Expand Down
5 changes: 4 additions & 1 deletion llvm/tools/llvm-rc/ResourceFileWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "ResourceScriptStmt.h"
#include "ResourceVisitor.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Endian.h"

namespace llvm {
Expand Down Expand Up @@ -68,6 +69,7 @@ class ResourceFileWriter : public Visitor {
Error visitLanguageStmt(const LanguageResource *) override;
Error visitStyleStmt(const StyleStmt *) override;
Error visitVersionStmt(const VersionStmt *) override;
Error visitMenuStmt(const MenuStmt *) override;

// Stringtables are output at the end of .res file. We need a separate
// function to do it.
Expand All @@ -92,10 +94,11 @@ class ResourceFileWriter : public Visitor {
};
std::optional<FontInfo> Font;
IntOrString Class;
IntOrString Menu;

ObjectInfo()
: LanguageInfo(0), Characteristics(0), VersionInfo(0),
Class(StringRef()) {}
Class(StringRef()), Menu(StringRef()) {}
} ObjectData;

struct StringTableInfo {
Expand Down
7 changes: 7 additions & 0 deletions llvm/tools/llvm-rc/ResourceScriptParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ RCParser::parseSingleOptionalStatement(OptStmtType StmtsType) {
return parseFontStmt(StmtsType);
if (TypeToken->equals_insensitive("STYLE"))
return parseStyleStmt();
if (TypeToken->equals_insensitive("MENU"))
return parseMenuStmt();
}

return getExpectedError("optional statement type, BEGIN or '{'",
Expand Down Expand Up @@ -965,6 +967,11 @@ RCParser::ParseOptionType RCParser::parseExStyleStmt() {
return std::make_unique<ExStyleStmt>(*Arg);
}

RCParser::ParseOptionType RCParser::parseMenuStmt() {
ASSIGN_OR_RETURN(Arg, readIntOrString());
return std::make_unique<MenuStmt>(*Arg);
}

Error RCParser::getExpectedError(const Twine &Message, bool IsAlreadyRead) {
return make_error<ParserError>(
Message, IsAlreadyRead ? std::prev(CurLoc) : CurLoc, End);
Expand Down
1 change: 1 addition & 0 deletions llvm/tools/llvm-rc/ResourceScriptParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class RCParser {
ParseOptionType parseExStyleStmt();
ParseOptionType parseFontStmt(OptStmtType DialogType);
ParseOptionType parseStyleStmt();
ParseOptionType parseMenuStmt();

// 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
Expand Down
4 changes: 4 additions & 0 deletions llvm/tools/llvm-rc/ResourceScriptStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,5 +309,9 @@ raw_ostream &ExStyleStmt::log(raw_ostream &OS) const {
return OS << "ExStyle: " << Value << "\n";
}

raw_ostream &MenuStmt::log(raw_ostream &OS) const {
return OS << "Menu: " << Value << "\n";
}

} // namespace rc
} // namespace llvm
13 changes: 13 additions & 0 deletions llvm/tools/llvm-rc/ResourceScriptStmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,19 @@ class ExStyleStmt : public OptionalStmt {
Error visit(Visitor *V) const override { return V->visitExStyleStmt(this); }
};

// MENU optional statement.
//
// Ref: https://learn.microsoft.com/en-us/windows/win32/menurc/menu-statement
class MenuStmt : public OptionalStmt {
public:
IntOrString Value;

MenuStmt(IntOrString NameOrId) : Value(NameOrId) {}
raw_ostream &log(raw_ostream &) const override;
Twine getResourceTypeName() const override { return "MENU"; }
Error visit(Visitor *V) const override { return V->visitMenuStmt(this); }
};

// CLASS optional statement.
//
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380883(v=vs.85).aspx
Expand Down
2 changes: 2 additions & 0 deletions llvm/tools/llvm-rc/ResourceVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class FontStmt;
class LanguageResource;
class StyleStmt;
class VersionStmt;
class MenuStmt;

class Visitor {
public:
Expand All @@ -52,6 +53,7 @@ class Visitor {
virtual Error visitLanguageStmt(const LanguageResource *) = 0;
virtual Error visitStyleStmt(const StyleStmt *) = 0;
virtual Error visitVersionStmt(const VersionStmt *) = 0;
virtual Error visitMenuStmt(const MenuStmt *) = 0;

virtual ~Visitor() {}
};
Expand Down