[llvm] r314549 - [llvm-rc] Serialize ACCELERATORS to .res files (serialization, pt 2).

Marek Sokolowski via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 29 12:07:44 PDT 2017


Author: mnbvmar
Date: Fri Sep 29 12:07:44 2017
New Revision: 314549

URL: http://llvm.org/viewvc/llvm-project?rev=314549&view=rev
Log:
[llvm-rc] Serialize ACCELERATORS to .res files (serialization, pt 2).

This allows llvm-rc to serialize ACCELERATORS resources.

Additionally, as this is the first type of resource to support basic
optional resource statements (LANGUAGE, CHARACTERISTICS, VERSION),

ACCELERATORS statement documentation:
msdn.microsoft.com/en-us/library/windows/desktop/aa380610.aspx
Accelerator table structure documentation:
msdn.microsoft.com/en-us/library/windows/desktop/ms648010.aspx
Optional resource statement fields are described in:
msdn.microsoft.com/en-us/library/windows/desktop/ms648027.aspx

Thanks for Nico Weber for his original work in this area.

Differential Revision: https://reviews.llvm.org/D37824

Added:
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-alt.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-control.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-shift.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-virtkey.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-id.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-key-id.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-control-nonalpha.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-long-virtkey.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-caret.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-type.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-only-caret.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-long.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-short.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-virtual-nonalpha.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators.rc
    llvm/trunk/test/tools/llvm-rc/tag-accelerators.test
Modified:
    llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
    llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
    llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
    llvm/trunk/tools/llvm-rc/ResourceVisitor.h

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-alt.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-alt.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-alt.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-alt.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+2 ACCELERATORS {
+  "A", 15, ASCII, ALT
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-control.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-control.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-control.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-control.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+2 ACCELERATORS {
+  "A", 15, ASCII, CONTROL
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-shift.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-shift.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-shift.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-shift.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+2 ACCELERATORS {
+  "A", 15, ASCII, SHIFT
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-virtkey.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-virtkey.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-virtkey.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-ascii-virtkey.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+2 ACCELERATORS {
+  "A", 15, ASCII, VIRTKEY
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-id.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-id.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-id.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-id.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+1 ACCELERATORS {
+  "A", 1234567, VIRTKEY
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-key-id.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-key-id.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-key-id.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-bad-key-id.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,3 @@
+9 ACCELERATORS {
+  1234567, 0, VIRTKEY
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-control-nonalpha.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-control-nonalpha.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-control-nonalpha.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-control-nonalpha.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+100 ACCELERATORS {
+  "^5", 1, ASCII
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-long-virtkey.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-long-virtkey.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-long-virtkey.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-long-virtkey.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+100 ACCELERATORS {
+  "^X", 10, VIRTKEY
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-caret.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-caret.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-caret.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-caret.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+50 ACCELERATORS {
+  "XY", 1, ASCII
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-type.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-type.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-type.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-no-type.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+5 ACCELERATORS {
+  10, 42
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-only-caret.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-only-caret.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-only-caret.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-only-caret.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+555 ACCELERATORS {
+  "^", 100
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-long.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-long.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-long.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-long.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+12 ACCELERATORS {
+  "Hello", 5, ASCII
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-short.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-short.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-short.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-too-short.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+10 ACCELERATORS {
+  "", 12, VIRTKEY
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-virtual-nonalpha.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-virtual-nonalpha.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-virtual-nonalpha.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators-virtual-nonalpha.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,4 @@
+42 ACCELERATORS {
+  "]", 1, VIRTKEY
+}
+

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators.rc?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-accelerators.rc Fri Sep 29 12:07:44 2017
@@ -0,0 +1,114 @@
+1 ACCELERATORS
+VERSION 700
+LANGUAGE 5, 1
+{
+  "a", 3
+  "a", 4, ASCII
+  "a", 5, VIRTKEY
+  "A", 6
+  "A", 7, ASCII
+  "A", 8, VIRTKEY
+  "1", 9
+  "1", 10, ASCII
+  "1", 11, VIRTKEY
+  "$", 12
+  "$", 13, ASCII
+  "]", 15
+  "]", 16, ASCII
+  "^a", 18
+  "^a", 19, ASCII
+  0, 37, ASCII
+  0, 38, VIRTKEY
+  1, 40, ASCII
+  1, 41, VIRTKEY
+  127, 43, ASCII
+  127, 44, VIRTKEY
+  128, 46, ASCII
+  128, 47, VIRTKEY
+  255, 49, ASCII
+  255, 50, VIRTKEY
+  256, 52, ASCII
+  256, 53, VIRTKEY
+  "^A", 66
+  "^A", 67, ASCII
+  54321, 70, ASCII
+  54321, 71, VIRTKEY
+}
+
+2 ACCELERATORS {
+  42, 0, ASCII
+  42, 1, VIRTKEY
+  42, 2, ASCII, NOINVERT
+  42, 3, VIRTKEY, NOINVERT
+  42, 4, VIRTKEY, CONTROL
+  42, 5, VIRTKEY, SHIFT
+  42, 6, VIRTKEY, ALT
+  42, 7, VIRTKEY, NOINVERT, CONTROL
+  42, 8, VIRTKEY, NOINVERT, SHIFT
+  42, 9, VIRTKEY, NOINVERT, ALT
+  42, 10, VIRTKEY, CONTROL, SHIFT
+  42, 11, VIRTKEY, CONTROL, ALT
+  42, 12, VIRTKEY, SHIFT, ALT
+  42, 13, VIRTKEY, NOINVERT, CONTROL, SHIFT
+  42, 14, VIRTKEY, NOINVERT, CONTROL, ALT
+  42, 15, VIRTKEY, NOINVERT, SHIFT, ALT
+  42, 16, VIRTKEY, CONTROL, SHIFT, ALT
+  42, 17, VIRTKEY, NOINVERT, CONTROL, SHIFT, ALT
+  "f", 18, ASCII
+  "f", 19, VIRTKEY
+  "f", 20, ASCII, NOINVERT
+  "f", 21, VIRTKEY, NOINVERT
+  "f", 22, VIRTKEY, CONTROL
+  "f", 23, VIRTKEY, SHIFT
+  "f", 24, VIRTKEY, ALT
+  "f", 25, VIRTKEY, NOINVERT, CONTROL
+  "f", 26, VIRTKEY, NOINVERT, SHIFT
+  "f", 27, VIRTKEY, NOINVERT, ALT
+  "f", 28, VIRTKEY, CONTROL, SHIFT
+  "f", 29, VIRTKEY, CONTROL, ALT
+  "f", 30, VIRTKEY, SHIFT, ALT
+  "f", 31, VIRTKEY, NOINVERT, CONTROL, SHIFT
+  "f", 32, VIRTKEY, NOINVERT, CONTROL, ALT
+  "f", 33, VIRTKEY, NOINVERT, SHIFT, ALT
+  "f", 34, VIRTKEY, CONTROL, SHIFT, ALT
+  "f", 35, VIRTKEY, NOINVERT, CONTROL, SHIFT, ALT
+  "U", 36, ASCII
+  "U", 37, VIRTKEY
+  "U", 38, ASCII, NOINVERT
+  "U", 39, VIRTKEY, NOINVERT
+  "U", 40, VIRTKEY, CONTROL
+  "U", 41, VIRTKEY, SHIFT
+  "U", 42, VIRTKEY, ALT
+  "U", 43, VIRTKEY, NOINVERT, CONTROL
+  "U", 44, VIRTKEY, NOINVERT, SHIFT
+  "U", 45, VIRTKEY, NOINVERT, ALT
+  "U", 46, VIRTKEY, CONTROL, SHIFT
+  "U", 47, VIRTKEY, CONTROL, ALT
+  "U", 48, VIRTKEY, SHIFT, ALT
+  "U", 49, VIRTKEY, NOINVERT, CONTROL, SHIFT
+  "U", 50, VIRTKEY, NOINVERT, CONTROL, ALT
+  "U", 51, VIRTKEY, NOINVERT, SHIFT, ALT
+  "U", 52, VIRTKEY, CONTROL, SHIFT, ALT
+  "U", 53, VIRTKEY, NOINVERT, CONTROL, SHIFT, ALT
+  "7", 54, ASCII
+  "7", 55, VIRTKEY
+  "7", 56, ASCII, NOINVERT
+  "7", 57, VIRTKEY, NOINVERT
+  "7", 58, VIRTKEY, CONTROL
+  "7", 59, VIRTKEY, SHIFT
+  "7", 60, VIRTKEY, ALT
+  "7", 61, VIRTKEY, NOINVERT, CONTROL
+  "7", 62, VIRTKEY, NOINVERT, SHIFT
+  "7", 63, VIRTKEY, NOINVERT, ALT
+  "7", 64, VIRTKEY, CONTROL, SHIFT
+  "7", 65, VIRTKEY, CONTROL, ALT
+  "7", 66, VIRTKEY, SHIFT, ALT
+  "7", 67, VIRTKEY, NOINVERT, CONTROL, SHIFT
+  "7", 68, VIRTKEY, NOINVERT, CONTROL, ALT
+  "7", 69, VIRTKEY, NOINVERT, SHIFT, ALT
+  "7", 70, VIRTKEY, CONTROL, SHIFT, ALT
+  "7", 71, VIRTKEY, NOINVERT, CONTROL, SHIFT, ALT
+  "^j", 72, ASCII
+  "^j", 73, ASCII, NOINVERT
+}
+

Added: llvm/trunk/test/tools/llvm-rc/tag-accelerators.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/tag-accelerators.test?rev=314549&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/tag-accelerators.test (added)
+++ llvm/trunk/test/tools/llvm-rc/tag-accelerators.test Fri Sep 29 12:07:44 2017
@@ -0,0 +1,157 @@
+; RUN: llvm-rc /FO %t %p/Inputs/tag-accelerators.rc
+; RUN: llvm-readobj %t | FileCheck %s --check-prefix=ACCELERATORS
+
+; ACCELERATORS: Resource type (int): 9
+; ACCELERATORS-NEXT: Resource name (int): 1
+; ACCELERATORS-NEXT: Data version: 0
+; ACCELERATORS-NEXT: Memory flags: 0x30
+; ACCELERATORS-NEXT: Language ID: 1029
+; ACCELERATORS-NEXT: Version (major): 0
+; ACCELERATORS-NEXT: Version (minor): 700
+; ACCELERATORS-NEXT: Characteristics: 0
+; ACCELERATORS-NEXT: Data size: 248
+; ACCELERATORS-NEXT: Data: (
+; ACCELERATORS-NEXT:   0000: 00006100 03000000 00006100 04000000  |..a.......a.....|
+; ACCELERATORS-NEXT:   0010: 01004100 05000000 00004100 06000000  |..A.......A.....|
+; ACCELERATORS-NEXT:   0020: 00004100 07000000 01004100 08000000  |..A.......A.....|
+; ACCELERATORS-NEXT:   0030: 00003100 09000000 00003100 0A000000  |..1.......1.....|
+; ACCELERATORS-NEXT:   0040: 01003100 0B000000 00002400 0C000000  |..1.......$.....|
+; ACCELERATORS-NEXT:   0050: 00002400 0D000000 00005D00 0F000000  |..$.......].....|
+; ACCELERATORS-NEXT:   0060: 00005D00 10000000 00000100 12000000  |..].............|
+; ACCELERATORS-NEXT:   0070: 00000100 13000000 00000000 25000000  |............%...|
+; ACCELERATORS-NEXT:   0080: 01000000 26000000 00000100 28000000  |....&.......(...|
+; ACCELERATORS-NEXT:   0090: 01000100 29000000 00007F00 2B000000  |....).......+...|
+; ACCELERATORS-NEXT:   00A0: 01007F00 2C000000 00008000 2E000000  |....,...........|
+; ACCELERATORS-NEXT:   00B0: 01008000 2F000000 0000FF00 31000000  |..../.......1...|
+; ACCELERATORS-NEXT:   00C0: 0100FF00 32000000 00000001 34000000  |....2.......4...|
+; ACCELERATORS-NEXT:   00D0: 01000001 35000000 00000100 42000000  |....5.......B...|
+; ACCELERATORS-NEXT:   00E0: 00000100 43000000 000031D4 46000000  |....C.....1.F...|
+; ACCELERATORS-NEXT:   00F0: 810031D4 47000000                    |..1.G...|
+; ACCELERATORS-NEXT: )
+
+; ACCELERATORS-DAG: Resource type (int): 9
+; ACCELERATORS-NEXT: Resource name (int): 2
+; ACCELERATORS-NEXT: Data version: 0
+; ACCELERATORS-NEXT: Memory flags: 0x30
+; ACCELERATORS-NEXT: Language ID: 1033
+; ACCELERATORS-NEXT: Version (major): 0
+; ACCELERATORS-NEXT: Version (minor): 0
+; ACCELERATORS-NEXT: Characteristics: 0
+; ACCELERATORS-NEXT: Data size: 592
+; ACCELERATORS-NEXT: Data: (
+; ACCELERATORS-NEXT:   0000: 00002A00 00000000 01002A00 01000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0010: 02002A00 02000000 03002A00 03000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0020: 09002A00 04000000 05002A00 05000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0030: 11002A00 06000000 0B002A00 07000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0040: 07002A00 08000000 13002A00 09000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0050: 0D002A00 0A000000 19002A00 0B000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0060: 15002A00 0C000000 0F002A00 0D000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0070: 1B002A00 0E000000 17002A00 0F000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0080: 1D002A00 10000000 1F002A00 11000000  |..*.......*.....|
+; ACCELERATORS-NEXT:   0090: 00006600 12000000 01004600 13000000  |..f.......F.....|
+; ACCELERATORS-NEXT:   00A0: 02006600 14000000 03004600 15000000  |..f.......F.....|
+; ACCELERATORS-NEXT:   00B0: 09004600 16000000 05004600 17000000  |..F.......F.....|
+; ACCELERATORS-NEXT:   00C0: 11004600 18000000 0B004600 19000000  |..F.......F.....|
+; ACCELERATORS-NEXT:   00D0: 07004600 1A000000 13004600 1B000000  |..F.......F.....|
+; ACCELERATORS-NEXT:   00E0: 0D004600 1C000000 19004600 1D000000  |..F.......F.....|
+; ACCELERATORS-NEXT:   00F0: 15004600 1E000000 0F004600 1F000000  |..F.......F.....|
+; ACCELERATORS-NEXT:   0100: 1B004600 20000000 17004600 21000000  |..F. .....F.!...|
+; ACCELERATORS-NEXT:   0110: 1D004600 22000000 1F004600 23000000  |..F.".....F.#...|
+; ACCELERATORS-NEXT:   0120: 00005500 24000000 01005500 25000000  |..U.$.....U.%...|
+; ACCELERATORS-NEXT:   0130: 02005500 26000000 03005500 27000000  |..U.&.....U.'...|
+; ACCELERATORS-NEXT:   0140: 09005500 28000000 05005500 29000000  |..U.(.....U.)...|
+; ACCELERATORS-NEXT:   0150: 11005500 2A000000 0B005500 2B000000  |..U.*.....U.+...|
+; ACCELERATORS-NEXT:   0160: 07005500 2C000000 13005500 2D000000  |..U.,.....U.-...|
+; ACCELERATORS-NEXT:   0170: 0D005500 2E000000 19005500 2F000000  |..U.......U./...|
+; ACCELERATORS-NEXT:   0180: 15005500 30000000 0F005500 31000000  |..U.0.....U.1...|
+; ACCELERATORS-NEXT:   0190: 1B005500 32000000 17005500 33000000  |..U.2.....U.3...|
+; ACCELERATORS-NEXT:   01A0: 1D005500 34000000 1F005500 35000000  |..U.4.....U.5...|
+; ACCELERATORS-NEXT:   01B0: 00003700 36000000 01003700 37000000  |..7.6.....7.7...|
+; ACCELERATORS-NEXT:   01C0: 02003700 38000000 03003700 39000000  |..7.8.....7.9...|
+; ACCELERATORS-NEXT:   01D0: 09003700 3A000000 05003700 3B000000  |..7.:.....7.;...|
+; ACCELERATORS-NEXT:   01E0: 11003700 3C000000 0B003700 3D000000  |..7.<.....7.=...|
+; ACCELERATORS-NEXT:   01F0: 07003700 3E000000 13003700 3F000000  |..7.>.....7.?...|
+; ACCELERATORS-NEXT:   0200: 0D003700 40000000 19003700 41000000  |..7. at .....7.A...|
+; ACCELERATORS-NEXT:   0210: 15003700 42000000 0F003700 43000000  |..7.B.....7.C...|
+; ACCELERATORS-NEXT:   0220: 1B003700 44000000 17003700 45000000  |..7.D.....7.E...|
+; ACCELERATORS-NEXT:   0230: 1D003700 46000000 1F003700 47000000  |..7.F.....7.G...|
+; ACCELERATORS-NEXT:   0240: 00000A00 48000000 82000A00 49000000  |....H.......I...|
+; ACCELERATORS-NEXT: )
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-bad-id.rc 2>&1 | FileCheck %s --check-prefix BADID
+
+; BADID: llvm-rc: Error in ACCELERATORS statement (ID 1):
+; BADID-NEXT: ACCELERATORS entry ID (1234567) does not fit in 16 bits.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-ascii-virtkey.rc 2>&1 | FileCheck %s --check-prefix ASCII1
+
+; ASCII1: llvm-rc: Error in ACCELERATORS statement (ID 2):
+; ASCII1-NEXT: Accelerator ID 15: Accelerator can't be both ASCII and VIRTKEY
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-ascii-control.rc 2>&1 | FileCheck %s --check-prefix ASCII2
+
+; ASCII2: llvm-rc: Error in ACCELERATORS statement (ID 2):
+; ASCII2-NEXT: Accelerator ID 15: Can only apply ALT, SHIFT or CONTROL to VIRTKEY accelerators
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-ascii-shift.rc 2>&1 | FileCheck %s --check-prefix ASCII3
+
+; ASCII3: llvm-rc: Error in ACCELERATORS statement (ID 2):
+; ASCII3-NEXT: Accelerator ID 15: Can only apply ALT, SHIFT or CONTROL to VIRTKEY accelerators
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-ascii-alt.rc 2>&1 | FileCheck %s --check-prefix ASCII4
+
+; ASCII4: llvm-rc: Error in ACCELERATORS statement (ID 2):
+; ASCII4-NEXT: Accelerator ID 15: Can only apply ALT, SHIFT or CONTROL to VIRTKEY accelerators
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-bad-key-id.rc 2>&1 | FileCheck %s --check-prefix BADKEYID
+
+; BADKEYID: llvm-rc: Error in ACCELERATORS statement (ID 9):
+; BADKEYID-NEXT: Numeric event key ID (1234567) does not fit in 16 bits.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-too-short.rc 2>&1 | FileCheck %s --check-prefix LENGTH1
+
+; LENGTH1: llvm-rc: Error in ACCELERATORS statement (ID 10):
+; LENGTH1-NEXT: Accelerator ID 12: Accelerator string events should have length 1 or 2
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-too-long.rc 2>&1 | FileCheck %s --check-prefix LENGTH2
+
+; LENGTH2: llvm-rc: Error in ACCELERATORS statement (ID 12):
+; LENGTH2-NEXT: Accelerator ID 5: Accelerator string events should have length 1 or 2
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-only-caret.rc 2>&1 | FileCheck %s --check-prefix CARET1
+
+; CARET1: llvm-rc: Error in ACCELERATORS statement (ID 555):
+; CARET1-NEXT: Accelerator ID 100: No character following '^' in accelerator event
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-no-caret.rc 2>&1 | FileCheck %s --check-prefix CARET2
+
+; CARET2: llvm-rc: Error in ACCELERATORS statement (ID 50):
+; CARET2-NEXT: Accelerator ID 1: Event string should be one-character, possibly preceded by '^'
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-long-virtkey.rc 2>&1 | FileCheck %s --check-prefix CARET3
+
+; CARET3: llvm-rc: Error in ACCELERATORS statement (ID 100):
+; CARET3-NEXT: Accelerator ID 10: VIRTKEY accelerator events can't be preceded by '^'
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-control-nonalpha.rc 2>&1 | FileCheck %s --check-prefix NONALPHA1
+
+; NONALPHA1: llvm-rc: Error in ACCELERATORS statement (ID 100):
+; NONALPHA1-NEXT: Accelerator ID 1: Control character accelerator event should be alphabetic
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-accelerators-virtual-nonalpha.rc 2>&1 | FileCheck %s --check-prefix NONALPHA2
+
+; NONALPHA2: llvm-rc: Error in ACCELERATORS statement (ID 42):
+; NONALPHA2-NEXT: Accelerator ID 1: Non-alphanumeric characters cannot describe virtual keys

Modified: llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp?rev=314549&r1=314548&r2=314549&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp Fri Sep 29 12:07:44 2017
@@ -28,6 +28,19 @@ using namespace llvm::support;
 namespace llvm {
 namespace rc {
 
+// Class that employs RAII to save the current serializator object state
+// and revert to it as soon as we leave the scope. This is useful if resources
+// declare their own resource-local statements.
+class ContextKeeper {
+  ResourceFileWriter *FileWriter;
+  ResourceFileWriter::ObjectInfo SavedInfo;
+
+public:
+  ContextKeeper(ResourceFileWriter *V)
+      : FileWriter(V), SavedInfo(V->ObjectData) {}
+  ~ContextKeeper() { FileWriter->ObjectData = SavedInfo; }
+};
+
 static Error createError(Twine Message,
                          std::errc Type = std::errc::invalid_argument) {
   return make_error<StringError>(Message, std::make_error_code(Type));
@@ -184,10 +197,20 @@ Error ResourceFileWriter::visitNullResou
   return writeResource(Res, &ResourceFileWriter::writeNullBody);
 }
 
+Error ResourceFileWriter::visitAcceleratorsResource(const RCResource *Res) {
+  return writeResource(Res, &ResourceFileWriter::writeAcceleratorsBody);
+}
+
 Error ResourceFileWriter::visitHTMLResource(const RCResource *Res) {
   return writeResource(Res, &ResourceFileWriter::writeHTMLBody);
 }
 
+Error ResourceFileWriter::visitCharacteristicsStmt(
+    const CharacteristicsStmt *Stmt) {
+  ObjectData.Characteristics = Stmt->Value;
+  return Error::success();
+}
+
 Error ResourceFileWriter::visitLanguageStmt(const LanguageResource *Stmt) {
   RETURN_IF_ERROR(checkNumberFits(Stmt->Lang, 10, "Primary language ID"));
   RETURN_IF_ERROR(checkNumberFits(Stmt->SubLang, 6, "Sublanguage ID"));
@@ -195,6 +218,11 @@ Error ResourceFileWriter::visitLanguageS
   return Error::success();
 }
 
+Error ResourceFileWriter::visitVersionStmt(const VersionStmt *Stmt) {
+  ObjectData.VersionInfo = Stmt->Value;
+  return Error::success();
+}
+
 Error ResourceFileWriter::writeResource(
     const RCResource *Res,
     Error (ResourceFileWriter::*BodyWriter)(const RCResource *)) {
@@ -208,12 +236,16 @@ Error ResourceFileWriter::writeResource(
   RETURN_IF_ERROR(handleError(writeIdentifier(ResType), Res));
   RETURN_IF_ERROR(handleError(writeIdentifier(Res->ResName), Res));
 
+  // Apply the resource-local optional statements.
+  ContextKeeper RAII(this);
+  RETURN_IF_ERROR(handleError(Res->applyStmts(this), Res));
+
   padStream(sizeof(uint32_t));
   object::WinResHeaderSuffix HeaderSuffix{
       ulittle32_t(0), // DataVersion; seems to always be 0
       ulittle16_t(Res->getMemoryFlags()), ulittle16_t(ObjectData.LanguageInfo),
-      ulittle32_t(0),  // VersionInfo
-      ulittle32_t(0)}; // Characteristics
+      ulittle32_t(ObjectData.VersionInfo),
+      ulittle32_t(ObjectData.Characteristics)};
   writeObject(HeaderSuffix);
 
   uint64_t DataLoc = tell();
@@ -229,10 +261,123 @@ Error ResourceFileWriter::writeResource(
   return Error::success();
 }
 
+// --- NullResource helpers. --- //
+
 Error ResourceFileWriter::writeNullBody(const RCResource *) {
   return Error::success();
 }
 
+// --- AcceleratorsResource helpers. --- //
+
+Error ResourceFileWriter::writeSingleAccelerator(
+    const AcceleratorsResource::Accelerator &Obj, bool IsLastItem) {
+  using Accelerator = AcceleratorsResource::Accelerator;
+  using Opt = Accelerator::Options;
+
+  struct AccelTableEntry {
+    ulittle16_t Flags;
+    ulittle16_t ANSICode;
+    ulittle16_t Id;
+    uint16_t Padding;
+  } Entry{ulittle16_t(0), ulittle16_t(0), ulittle16_t(0), 0};
+
+  bool IsASCII = Obj.Flags & Opt::ASCII, IsVirtKey = Obj.Flags & Opt::VIRTKEY;
+
+  // Remove ASCII flags (which doesn't occur in .res files).
+  Entry.Flags = Obj.Flags & ~Opt::ASCII;
+
+  if (IsLastItem)
+    Entry.Flags |= 0x80;
+
+  RETURN_IF_ERROR(checkNumberFits<uint16_t>(Obj.Id, "ACCELERATORS entry ID"));
+  Entry.Id = ulittle16_t(Obj.Id);
+
+  auto createAccError = [&Obj](const char *Msg) {
+    return createError("Accelerator ID " + Twine(Obj.Id) + ": " + Msg);
+  };
+
+  if (IsASCII && IsVirtKey)
+    return createAccError("Accelerator can't be both ASCII and VIRTKEY");
+
+  if (!IsVirtKey && (Obj.Flags & (Opt::ALT | Opt::SHIFT | Opt::CONTROL)))
+    return createAccError("Can only apply ALT, SHIFT or CONTROL to VIRTKEY"
+                          " accelerators");
+
+  if (Obj.Event.isInt()) {
+    if (!IsASCII && !IsVirtKey)
+      return createAccError(
+          "Accelerator with a numeric event must be either ASCII"
+          " or VIRTKEY");
+
+    uint32_t EventVal = Obj.Event.getInt();
+    RETURN_IF_ERROR(
+        checkNumberFits<uint16_t>(EventVal, "Numeric event key ID"));
+    Entry.ANSICode = ulittle16_t(EventVal);
+    writeObject(Entry);
+    return Error::success();
+  }
+
+  StringRef Str = Obj.Event.getString();
+  bool IsWide;
+  stripQuotes(Str, IsWide);
+
+  if (Str.size() == 0 || Str.size() > 2)
+    return createAccError(
+        "Accelerator string events should have length 1 or 2");
+
+  if (Str[0] == '^') {
+    if (Str.size() == 1)
+      return createAccError("No character following '^' in accelerator event");
+    if (IsVirtKey)
+      return createAccError(
+          "VIRTKEY accelerator events can't be preceded by '^'");
+
+    char Ch = Str[1];
+    if (Ch >= 'a' && Ch <= 'z')
+      Entry.ANSICode = ulittle16_t(Ch - 'a' + 1);
+    else if (Ch >= 'A' && Ch <= 'Z')
+      Entry.ANSICode = ulittle16_t(Ch - 'A' + 1);
+    else
+      return createAccError("Control character accelerator event should be"
+                            " alphabetic");
+
+    writeObject(Entry);
+    return Error::success();
+  }
+
+  if (Str.size() == 2)
+    return createAccError("Event string should be one-character, possibly"
+                          " preceded by '^'");
+
+  uint8_t EventCh = Str[0];
+  // The original tool just warns in this situation. We chose to fail.
+  if (IsVirtKey && !isalnum(EventCh))
+    return createAccError("Non-alphanumeric characters cannot describe virtual"
+                          " keys");
+  if (EventCh > 0x7F)
+    return createAccError("Non-ASCII description of accelerator");
+
+  if (IsVirtKey)
+    EventCh = toupper(EventCh);
+  Entry.ANSICode = ulittle16_t(EventCh);
+  writeObject(Entry);
+  return Error::success();
+}
+
+Error ResourceFileWriter::writeAcceleratorsBody(const RCResource *Base) {
+  auto *Res = cast<AcceleratorsResource>(Base);
+  size_t AcceleratorId = 0;
+  for (auto &Acc : Res->Accelerators) {
+    ++AcceleratorId;
+    RETURN_IF_ERROR(
+        writeSingleAccelerator(Acc, AcceleratorId == Res->Accelerators.size()));
+  }
+  return Error::success();
+}
+
+// --- HTMLResource helpers. --- //
+
+
 Error ResourceFileWriter::writeHTMLBody(const RCResource *Base) {
   return appendFile(cast<HTMLResource>(Base)->HTMLLoc);
 }

Modified: llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceFileWriter.h?rev=314549&r1=314548&r2=314549&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.h Fri Sep 29 12:07:44 2017
@@ -30,14 +30,19 @@ public:
   }
 
   Error visitNullResource(const RCResource *) override;
+  Error visitAcceleratorsResource(const RCResource *) override;
   Error visitHTMLResource(const RCResource *) override;
 
+  Error visitCharacteristicsStmt(const CharacteristicsStmt *) override;
   Error visitLanguageStmt(const LanguageResource *) override;
+  Error visitVersionStmt(const VersionStmt *) override;
 
   struct ObjectInfo {
     uint16_t LanguageInfo;
+    uint32_t Characteristics;
+    uint32_t VersionInfo;
 
-    ObjectInfo() : LanguageInfo(0) {}
+    ObjectInfo() : LanguageInfo(0), Characteristics(0), VersionInfo(0) {}
   } ObjectData;
 
 private:
@@ -47,7 +52,15 @@ private:
   writeResource(const RCResource *Res,
                 Error (ResourceFileWriter::*BodyWriter)(const RCResource *));
 
+  // NullResource
   Error writeNullBody(const RCResource *);
+
+  // AcceleratorsResource
+  Error writeSingleAccelerator(const AcceleratorsResource::Accelerator &,
+                               bool IsLastItem);
+  Error writeAcceleratorsBody(const RCResource *);
+
+  // HTMLResource
   Error writeHTMLBody(const RCResource *);
 
   // Output stream handling.

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h?rev=314549&r1=314548&r2=314549&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h Fri Sep 29 12:07:44 2017
@@ -104,9 +104,6 @@ enum MemoryFlags {
 class RCResource {
 public:
   IntOrString ResName;
-
-  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";
@@ -117,6 +114,10 @@ public:
     llvm_unreachable("This is unable to call methods from Visitor base");
   }
 
+  // Apply the statements attached to this resource. Generic resources
+  // don't have any.
+  virtual Error applyStmts(Visitor *) const { return Error::success(); }
+
   // By default, memory flags are DISCARDABLE | PURE | MOVEABLE.
   virtual uint16_t getMemoryFlags() const {
     return MfDiscardable | MfPure | MfMoveable;
@@ -153,11 +154,18 @@ class OptionalStmtList : public Optional
 
 public:
   OptionalStmtList() {}
-  virtual raw_ostream &log(raw_ostream &OS) const;
+  raw_ostream &log(raw_ostream &OS) const override;
 
   void addStmt(std::unique_ptr<OptionalStmt> Stmt) {
     Statements.push_back(std::move(Stmt));
   }
+
+  Error visit(Visitor *V) const override {
+    for (auto &StmtPtr : Statements)
+      if (auto Err = StmtPtr->visit(V))
+        return Err;
+    return Error::success();
+  }
 };
 
 class OptStatementsRCResource : public RCResource {
@@ -166,6 +174,8 @@ public:
 
   OptStatementsRCResource(OptionalStmtList &&Stmts)
       : OptStatements(llvm::make_unique<OptionalStmtList>(std::move(Stmts))) {}
+
+  virtual Error applyStmts(Visitor *V) const { return OptStatements->visit(V); }
 };
 
 // LANGUAGE statement. It can occur both as a top-level statement (in such
@@ -218,14 +228,27 @@ public:
     static uint32_t OptionsFlags[NumFlags];
   };
 
+  std::vector<Accelerator> Accelerators;
+
   using OptStatementsRCResource::OptStatementsRCResource;
   void addAccelerator(IntOrString Event, uint32_t Id, uint16_t Flags) {
     Accelerators.push_back(Accelerator{Event, Id, Flags});
   }
   raw_ostream &log(raw_ostream &) const override;
 
-private:
-  std::vector<Accelerator> Accelerators;
+  IntOrString getResourceType() const override { return RkAccelerators; }
+  uint16_t getMemoryFlags() const override {
+    return MfPure | MfMoveable;
+  }
+  Twine getResourceTypeName() const override { return "ACCELERATORS"; }
+
+  Error visit(Visitor *V) const override {
+    return V->visitAcceleratorsResource(this);
+  }
+  ResourceKind getKind() const override { return RkAccelerators; }
+  static bool classof(const RCResource *Res) {
+    return Res->getKind() == RkAccelerators;
+  }
 };
 
 // CURSOR resource. Represents a single cursor (".cur") file.
@@ -546,22 +569,30 @@ public:
 //
 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx
 class CharacteristicsStmt : public OptionalStmt {
+public:
   uint32_t Value;
 
-public:
   CharacteristicsStmt(uint32_t Characteristic) : Value(Characteristic) {}
   raw_ostream &log(raw_ostream &) const override;
+
+  Twine getResourceTypeName() const override { return "CHARACTERISTICS"; }
+  Error visit(Visitor *V) const override {
+    return V->visitCharacteristicsStmt(this);
+  }
 };
 
 // VERSION optional statement.
 //
 // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381059(v=vs.85).aspx
 class VersionStmt : public OptionalStmt {
+public:
   uint32_t Value;
 
-public:
   VersionStmt(uint32_t Version) : Value(Version) {}
   raw_ostream &log(raw_ostream &) const override;
+
+  Twine getResourceTypeName() const override { return "VERSION"; }
+  Error visit(Visitor *V) const override { return V->visitVersionStmt(this); }
 };
 
 // CAPTION optional statement.

Modified: llvm/trunk/tools/llvm-rc/ResourceVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceVisitor.h?rev=314549&r1=314548&r2=314549&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceVisitor.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceVisitor.h Fri Sep 29 12:07:44 2017
@@ -21,14 +21,19 @@ namespace rc {
 
 class RCResource;
 
+class CharacteristicsStmt;
 class LanguageResource;
+class VersionStmt;
 
 class Visitor {
 public:
   virtual Error visitNullResource(const RCResource *) = 0;
+  virtual Error visitAcceleratorsResource(const RCResource *) = 0;
   virtual Error visitHTMLResource(const RCResource *) = 0;
 
+  virtual Error visitCharacteristicsStmt(const CharacteristicsStmt *) = 0;
   virtual Error visitLanguageStmt(const LanguageResource *) = 0;
+  virtual Error visitVersionStmt(const VersionStmt *) = 0;
 
   virtual ~Visitor() {}
 };




More information about the llvm-commits mailing list