[llvm] llvm-rc: add support for MENU in DIALOG(EX) (PR #89409)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 19 09:21:02 PDT 2024
https://github.com/oltolm created https://github.com/llvm/llvm-project/pull/89409
Adds support for `MENU` in `DIALOG(EX)` to `llvm-rc`. Fixes #49559.
>From c99c888be7c72671d4e030d7d4c528e73e39ea3d Mon Sep 17 00:00:00 2001
From: oltolm <oleg.tolmatcev at gmail.com>
Date: Fri, 19 Apr 2024 18:12:18 +0200
Subject: [PATCH] llvm-rc: add support for MENU in DIALOG(EX)
---
.../tools/llvm-rc/Inputs/dialog-with-menu.rc | 16 ++++++++++
llvm/test/tools/llvm-rc/dialog-with-menu.test | 32 +++++++++++++++++++
llvm/tools/llvm-rc/ResourceFileWriter.cpp | 10 ++++--
llvm/tools/llvm-rc/ResourceFileWriter.h | 5 ++-
llvm/tools/llvm-rc/ResourceScriptParser.cpp | 29 ++++++++++-------
llvm/tools/llvm-rc/ResourceScriptParser.h | 1 +
llvm/tools/llvm-rc/ResourceScriptStmt.cpp | 4 +++
llvm/tools/llvm-rc/ResourceScriptStmt.h | 13 ++++++++
llvm/tools/llvm-rc/ResourceVisitor.h | 2 ++
9 files changed, 96 insertions(+), 16 deletions(-)
create mode 100644 llvm/test/tools/llvm-rc/Inputs/dialog-with-menu.rc
create mode 100644 llvm/test/tools/llvm-rc/dialog-with-menu.test
diff --git a/llvm/test/tools/llvm-rc/Inputs/dialog-with-menu.rc b/llvm/test/tools/llvm-rc/Inputs/dialog-with-menu.rc
new file mode 100644
index 00000000000000..bb79dca399c219
--- /dev/null
+++ b/llvm/test/tools/llvm-rc/Inputs/dialog-with-menu.rc
@@ -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
diff --git a/llvm/test/tools/llvm-rc/dialog-with-menu.test b/llvm/test/tools/llvm-rc/dialog-with-menu.test
new file mode 100644
index 00000000000000..2529e9c1722be4
--- /dev/null
+++ b/llvm/test/tools/llvm-rc/dialog-with-menu.test
@@ -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: )
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.cpp b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
index d507525970ec84..85b59532bb83b2 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.cpp
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.cpp
@@ -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 *)) {
@@ -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));
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.h b/llvm/tools/llvm-rc/ResourceFileWriter.h
index 9413a0eecdace5..82d3e3b9e9e8bd 100644
--- a/llvm/tools/llvm-rc/ResourceFileWriter.h
+++ b/llvm/tools/llvm-rc/ResourceFileWriter.h
@@ -16,6 +16,7 @@
#include "ResourceScriptStmt.h"
#include "ResourceVisitor.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Endian.h"
namespace llvm {
@@ -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.
@@ -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 {
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.cpp b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
index 4f02fa502d24fd..3666201f624d73 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.cpp
@@ -419,18 +419,18 @@ RCParser::parseSingleOptionalStatement(OptStmtType StmtsType) {
if (TypeToken->equals_insensitive("VERSION"))
return parseVersionStmt();
- if (StmtsType != OptStmtType::BasicStmt) {
- if (TypeToken->equals_insensitive("CAPTION"))
- return parseCaptionStmt();
- if (TypeToken->equals_insensitive("CLASS"))
- return parseClassStmt();
- if (TypeToken->equals_insensitive("EXSTYLE"))
- return parseExStyleStmt();
- if (TypeToken->equals_insensitive("FONT"))
- return parseFontStmt(StmtsType);
- if (TypeToken->equals_insensitive("STYLE"))
- return parseStyleStmt();
- }
+ if (TypeToken->equals_insensitive("CAPTION"))
+ return parseCaptionStmt();
+ if (TypeToken->equals_insensitive("CLASS"))
+ return parseClassStmt();
+ if (TypeToken->equals_insensitive("EXSTYLE"))
+ return parseExStyleStmt();
+ if (TypeToken->equals_insensitive("FONT"))
+ return parseFontStmt(StmtsType);
+ if (TypeToken->equals_insensitive("STYLE"))
+ return parseStyleStmt();
+ if (TypeToken->equals_insensitive("MENU"))
+ return parseMenuStmt();
return getExpectedError("optional statement type, BEGIN or '{'",
/* IsAlreadyRead = */ true);
@@ -965,6 +965,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);
diff --git a/llvm/tools/llvm-rc/ResourceScriptParser.h b/llvm/tools/llvm-rc/ResourceScriptParser.h
index 603afd8d73fb1a..aa7f847187c495 100644
--- a/llvm/tools/llvm-rc/ResourceScriptParser.h
+++ b/llvm/tools/llvm-rc/ResourceScriptParser.h
@@ -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
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
index 62df7999252fe1..a7f3df0863e74b 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.cpp
@@ -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
diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h
index 70e7cec9cb84d2..05865e5828592d 100644
--- a/llvm/tools/llvm-rc/ResourceScriptStmt.h
+++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h
@@ -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
diff --git a/llvm/tools/llvm-rc/ResourceVisitor.h b/llvm/tools/llvm-rc/ResourceVisitor.h
index a950cd7555ecdf..a121a0a507c277 100644
--- a/llvm/tools/llvm-rc/ResourceVisitor.h
+++ b/llvm/tools/llvm-rc/ResourceVisitor.h
@@ -28,6 +28,7 @@ class FontStmt;
class LanguageResource;
class StyleStmt;
class VersionStmt;
+class MenuStmt;
class Visitor {
public:
@@ -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() {}
};
More information about the llvm-commits
mailing list