[llvm] r314578 - [llvm-rc] Serialize DIALOG(EX) to .res files (serialization, pt 4).

Marek Sokolowski via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 29 17:38:53 PDT 2017


Author: mnbvmar
Date: Fri Sep 29 17:38:52 2017
New Revision: 314578

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

This is now able to serialize DIALOG and DIALOGEX resources to .res
files. It still can't parse dialog-specific CAPTION, FONT, and STYLE
optional statement - these will be added in the following patch.

A limited set of controls is included. However, more can be easily added
by extending SupportedCtls map defined in ResourceScriptStmt.cpp.

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

Added:
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord-neg.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-id.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-ref-id.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-size.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-negative-size.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord-neg.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-size.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-negative-size.rc
    llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog.rc
    llvm/trunk/test/tools/llvm-rc/tag-dialog.test
Modified:
    llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
    llvm/trunk/tools/llvm-rc/ResourceFileWriter.h
    llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
    llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp
    llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
    llvm/trunk/tools/llvm-rc/ResourceVisitor.h

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord-neg.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord-neg.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord-neg.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord-neg.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1,3 @@
+1 DIALOG 1, 1, 1, 1 {
+  LTEXT "u", 1, 5, -32769, 5, 5
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-coord.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1,3 @@
+1 DIALOGEX 1, 1, 1, 1 {
+  LTEXT "a", 1, 44444, 5, 6, 7
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-id.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-id.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-id.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-id.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1,3 @@
+5 DIALOG 1, 2, 3, 4 {
+  RTEXT "Too large ID", 100000, 1, 2, 3, 4
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-ref-id.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-ref-id.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-ref-id.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-ref-id.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1,3 @@
+1 DIALOGEX 1, 2, 3, 4 {
+  CTEXT 65536, 42, 1, 1, 1, 1
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-size.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-size.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-size.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-large-size.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1,3 @@
+1 DIALOGEX 1, 2, 3, 4 {
+  LTEXT "L", 1, 15, 15, 40000, 15
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-negative-size.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-negative-size.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-negative-size.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-ctl-negative-size.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1,3 @@
+1 DIALOG 1, 1, 1, 1 {
+  LTEXT "u", 1, 5, 5, 5, -700
+}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord-neg.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord-neg.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord-neg.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord-neg.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1 @@
+1 DIALOG 1, -40000, 14, 15 {}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-coord.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1 @@
+1 DIALOGEX 50000, 654321, 100, 100 {}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-size.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-size.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-size.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-large-size.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1 @@
+1 DIALOGEX 100, 100, 12345, 32768 {}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-negative-size.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-negative-size.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-negative-size.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog-negative-size.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1 @@
+1 DIALOGEX 100, 100, -50, 13 {}

Added: llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog.rc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog.rc?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog.rc (added)
+++ llvm/trunk/test/tools/llvm-rc/Inputs/tag-dialog.rc Fri Sep 29 17:38:52 2017
@@ -0,0 +1,44 @@
+Empty DIALOGEX 2, 3, 4, 5 {}
+
+Args DIALOGEX 2, 3, 4, 5 {
+  LTEXT "Left text", 1, 0, 0, 50, 10
+  RTEXT "Right text", 2, 12, 0, 50, 10, 42
+  LTEXT "Left text 2", 3, 24, 0, 50, 10, 0xBADCAFE, 0xBAD00BAD
+  RTEXT "Right text 2", 4, 36, 0, 50, 10, 1, 2, 0x12345678
+
+  EDITTEXT 16, 100, 0, 60, 10
+  EDITTEXT 17, 100, 16, 60, 10, 0xAABB0000
+  EDITTEXT 18, 100, 32, 60, 10, 0xA000000B, 0xCC0000DD
+  EDITTEXT 19, 100, 32, 60, 10, 0, 0, 3456789012
+
+  PUSHBUTTON "Push 1", 32, 200, 0, 54, 11
+  PUSHBUTTON "Push 2", 33, 201, 15, 54, 11, 12345
+  PUSHBUTTON "Push 3", 34, 202, 30, 54, 11, 0xA, 0xC0000042
+  PUSHBUTTON "Push 4", 35, 200, 45, 54, 11, 0, 1, 2
+}
+    
+Types DIALOGEX 12345, -11215, 0x1234, 0x1EED, 0x51525354 {
+  LTEXT "L", 1, 2, 3, 4, 5
+  CTEXT "C", 6, 7, 8, 9, 10
+  RTEXT "R", 11, 12, 13, 14, 15
+
+  PUSHBUTTON "PB", 1001, 1002, 1003, 1004, 1005
+  DEFPUSHBUTTON "DPB", 1006, 1007, 1008, 1009, 1010
+
+  EDITTEXT 2001, 2002, 2003, 2004, 2005
+
+  LTEXT 65535, 3001, 3002, 3003, 3004, 3005
+}
+
+EmptyOld DIALOG 1, 2, 3, 4 {}
+
+ArgsOld DIALOG 1, 2, 3, 4 {
+  LTEXT "L", 1, 2, 3, 4, 5
+  LTEXT "L2", 6, 7, 8, 9, 10, 11
+  LTEXT "L3", 12, 13, 14, 15, 16, 17, 18
+
+  EDITTEXT 19, 20, 21, 22, 23
+  EDITTEXT 24, 25, 26, 27, 28, 29
+  EDITTEXT 30, 31, 32, 33, 34, 35, 36
+}
+

Added: llvm/trunk/test/tools/llvm-rc/tag-dialog.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-rc/tag-dialog.test?rev=314578&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-rc/tag-dialog.test (added)
+++ llvm/trunk/test/tools/llvm-rc/tag-dialog.test Fri Sep 29 17:38:52 2017
@@ -0,0 +1,199 @@
+; RUN: llvm-rc /FO %t %p/Inputs/tag-dialog.rc
+; RUN: llvm-readobj %t | FileCheck %s --check-prefix=DIALOG
+
+; DIALOG: Resource type (int): 5
+; DIALOG-NEXT: Resource name (string): EMPTY
+; DIALOG-NEXT: Data version: 0
+; DIALOG-NEXT: Memory flags: 0x1030
+; DIALOG-NEXT: Language ID: 1033
+; DIALOG-NEXT: Version (major): 0
+; DIALOG-NEXT: Version (minor): 0
+; DIALOG-NEXT: Characteristics: 0
+; DIALOG-NEXT: Data size: 32
+; DIALOG-NEXT: Data: (
+; DIALOG-NEXT:   0000: 0100FFFF 00000000 00000000 00008880  |................|
+; DIALOG-NEXT:   0010: 00000200 03000400 05000000 00000000  |................|
+; DIALOG-NEXT: )
+
+; DIALOG-DAG: Resource type (int): 5
+; DIALOG-NEXT: Resource name (string): ARGS
+; DIALOG-NEXT: Data version: 0
+; DIALOG-NEXT: Memory flags: 0x1030
+; DIALOG-NEXT: Language ID: 1033
+; DIALOG-NEXT: Version (major): 0
+; DIALOG-NEXT: Version (minor): 0
+; DIALOG-NEXT: Characteristics: 0
+; DIALOG-NEXT: Data size: 552
+; DIALOG-NEXT: Data: (
+; DIALOG-NEXT:   0000: 0100FFFF 00000000 00000000 00008880  |................|
+; DIALOG-NEXT:   0010: 0C000200 03000400 05000000 00000000  |................|
+; DIALOG-NEXT:   0020: 00000000 00000000 00000250 00000000  |...........P....|
+; DIALOG-NEXT:   0030: 32000A00 01000000 FFFF8200 4C006500  |2...........L.e.|
+; DIALOG-NEXT:   0040: 66007400 20007400 65007800 74000000  |f.t. .t.e.x.t...|
+; DIALOG-NEXT:   0050: 00000000 00000000 00000000 2A000250  |............*..P|
+; DIALOG-NEXT:   0060: 0C000000 32000A00 02000000 FFFF8200  |....2...........|
+; DIALOG-NEXT:   0070: 52006900 67006800 74002000 74006500  |R.i.g.h.t. .t.e.|
+; DIALOG-NEXT:   0080: 78007400 00000000 00000000 AD0BD0BA  |x.t.............|
+; DIALOG-NEXT:   0090: FECAAF5B 18000000 32000A00 03000000  |...[....2.......|
+; DIALOG-NEXT:   00A0: FFFF8200 4C006500 66007400 20007400  |....L.e.f.t. .t.|
+; DIALOG-NEXT:   00B0: 65007800 74002000 32000000 00000000  |e.x.t. .2.......|
+; DIALOG-NEXT:   00C0: 78563412 02000000 03000250 24000000  |xV4........P$...|
+; DIALOG-NEXT:   00D0: 32000A00 04000000 FFFF8200 52006900  |2...........R.i.|
+; DIALOG-NEXT:   00E0: 67006800 74002000 74006500 78007400  |g.h.t. .t.e.x.t.|
+; DIALOG-NEXT:   00F0: 20003200 00000000 00000000 00000000  | .2.............|
+; DIALOG-NEXT:   0100: 00008150 64000000 3C000A00 10000000  |...Pd...<.......|
+; DIALOG-NEXT:   0110: FFFF8100 00000000 00000000 00000000  |................|
+; DIALOG-NEXT:   0120: 0000BBFA 64001000 3C000A00 11000000  |....d...<.......|
+; DIALOG-NEXT:   0130: FFFF8100 00000000 00000000 DD0000CC  |................|
+; DIALOG-NEXT:   0140: 0B0081F0 64002000 3C000A00 12000000  |....d. .<.......|
+; DIALOG-NEXT:   0150: FFFF8100 00000000 146A0ACE 00000000  |.........j......|
+; DIALOG-NEXT:   0160: 00008150 64002000 3C000A00 13000000  |...Pd. .<.......|
+; DIALOG-NEXT:   0170: FFFF8100 00000000 00000000 00000000  |................|
+; DIALOG-NEXT:   0180: 00000150 C8000000 36000B00 20000000  |...P....6... ...|
+; DIALOG-NEXT:   0190: FFFF8000 50007500 73006800 20003100  |....P.u.s.h. .1.|
+; DIALOG-NEXT:   01A0: 00000000 00000000 00000000 39300150  |............90.P|
+; DIALOG-NEXT:   01B0: C9000F00 36000B00 21000000 FFFF8000  |....6...!.......|
+; DIALOG-NEXT:   01C0: 50007500 73006800 20003200 00000000  |P.u.s.h. .2.....|
+; DIALOG-NEXT:   01D0: 00000000 420000C0 0A000150 CA001E00  |....B......P....|
+; DIALOG-NEXT:   01E0: 36000B00 22000000 FFFF8000 50007500  |6...".......P.u.|
+; DIALOG-NEXT:   01F0: 73006800 20003300 00000000 02000000  |s.h. .3.........|
+; DIALOG-NEXT:   0200: 01000000 00000150 C8002D00 36000B00  |.......P..-.6...|
+; DIALOG-NEXT:   0210: 23000000 FFFF8000 50007500 73006800  |#.......P.u.s.h.|
+; DIALOG-NEXT:   0220: 20003400 00000000                    | .4.....|
+; DIALOG-NEXT: )
+
+; DIALOG-DAG: Resource type (int): 5
+; DIALOG-NEXT: Resource name (string): TYPES
+; DIALOG-NEXT: Data version: 0
+; DIALOG-NEXT: Memory flags: 0x1030
+; DIALOG-NEXT: Language ID: 1033
+; DIALOG-NEXT: Version (major): 0
+; DIALOG-NEXT: Version (minor): 0
+; DIALOG-NEXT: Characteristics: 0
+; DIALOG-NEXT: Data size: 282
+; DIALOG-NEXT: Data: (
+; DIALOG-NEXT:   0000: 0100FFFF 54535251 00000000 00008880  |....TSRQ........|
+; DIALOG-NEXT:   0010: 07003930 31D43412 ED1E0000 00000000  |..901.4.........|
+; DIALOG-NEXT:   0020: 00000000 00000000 00000250 02000300  |...........P....|
+; DIALOG-NEXT:   0030: 04000500 01000000 FFFF8200 4C000000  |............L...|
+; DIALOG-NEXT:   0040: 00000000 00000000 00000000 01000250  |...............P|
+; DIALOG-NEXT:   0050: 07000800 09000A00 06000000 FFFF8200  |................|
+; DIALOG-NEXT:   0060: 43000000 00000000 00000000 00000000  |C...............|
+; DIALOG-NEXT:   0070: 02000250 0C000D00 0E000F00 0B000000  |...P............|
+; DIALOG-NEXT:   0080: FFFF8200 52000000 00000000 00000000  |....R...........|
+; DIALOG-NEXT:   0090: 00000000 00000150 EA03EB03 EC03ED03  |.......P........|
+; DIALOG-NEXT:   00A0: E9030000 FFFF8000 50004200 00000000  |........P.B.....|
+; DIALOG-NEXT:   00B0: 00000000 00000000 01000150 EF03F003  |...........P....|
+; DIALOG-NEXT:   00C0: F103F203 EE030000 FFFF8000 44005000  |............D.P.|
+; DIALOG-NEXT:   00D0: 42000000 00000000 00000000 00000000  |B...............|
+; DIALOG-NEXT:   00E0: 00008150 D207D307 D407D507 D1070000  |...P............|
+; DIALOG-NEXT:   00F0: FFFF8100 00000000 00000000 00000000  |................|
+; DIALOG-NEXT:   0100: 00000250 BA0BBB0B BC0BBD0B B90B0000  |...P............|
+; DIALOG-NEXT:   0110: FFFF8200 FFFFFFFF 0000               |..........|
+; DIALOG-NEXT: )
+
+; DIALOG-DAG: Resource type (int): 5
+; DIALOG-NEXT: Resource name (string): EMPTYOLD
+; DIALOG-NEXT: Data version: 0
+; DIALOG-NEXT: Memory flags: 0x1030
+; DIALOG-NEXT: Language ID: 1033
+; DIALOG-NEXT: Version (major): 0
+; DIALOG-NEXT: Version (minor): 0
+; DIALOG-NEXT: Characteristics: 0
+; DIALOG-NEXT: Data size: 24
+; DIALOG-NEXT: Data: (
+; DIALOG-NEXT:   0000: 00008880 00000000 00000100 02000300  |................|
+; DIALOG-NEXT:   0010: 04000000 00000000                    |........|
+; DIALOG-NEXT: )
+
+; DIALOG-DAG: Resource type (int): 5
+; DIALOG-NEXT: Resource name (string): ARGSOLD
+; DIALOG-NEXT: Data version: 0
+; DIALOG-NEXT: Memory flags: 0x1030
+; DIALOG-NEXT: Language ID: 1033
+; DIALOG-NEXT: Version (major): 0
+; DIALOG-NEXT: Version (minor): 0
+; DIALOG-NEXT: Characteristics: 0
+; DIALOG-NEXT: Data size: 198
+; DIALOG-NEXT: Data: (
+; DIALOG-NEXT:   0000: 00008880 00000000 06000100 02000300  |................|
+; DIALOG-NEXT:   0010: 04000000 00000000 00000250 00000000  |...........P....|
+; DIALOG-NEXT:   0020: 02000300 04000500 0100FFFF 82004C00  |..............L.|
+; DIALOG-NEXT:   0030: 00000000 0B000250 00000000 07000800  |.......P........|
+; DIALOG-NEXT:   0040: 09000A00 0600FFFF 82004C00 32000000  |..........L.2...|
+; DIALOG-NEXT:   0050: 00000000 11000250 12000000 0D000E00  |.......P........|
+; DIALOG-NEXT:   0060: 0F001000 0C00FFFF 82004C00 33000000  |..........L.3...|
+; DIALOG-NEXT:   0070: 00000000 00008150 00000000 14001500  |.......P........|
+; DIALOG-NEXT:   0080: 16001700 1300FFFF 81000000 00000000  |................|
+; DIALOG-NEXT:   0090: 1D008150 00000000 19001A00 1B001C00  |...P............|
+; DIALOG-NEXT:   00A0: 1800FFFF 81000000 00000000 23008150  |............#..P|
+; DIALOG-NEXT:   00B0: 24000000 1F002000 21002200 1E00FFFF  |$..... .!.".....|
+; DIALOG-NEXT:   00C0: 81000000 0000                        |......|
+; DIALOG-NEXT: )
+
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-large-coord.rc 2>&1 | FileCheck %s --check-prefix COORD1
+
+; COORD1: llvm-rc: Error in DIALOGEX statement (ID 1):
+; COORD1-NEXT: Dialog x-coordinate (50000) does not fit in 16-bit signed integer type.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-large-coord-neg.rc 2>&1 | FileCheck %s --check-prefix COORD2
+
+; COORD2: llvm-rc: Error in DIALOG statement (ID 1):
+; COORD2-NEXT: Dialog y-coordinate (-40000) does not fit in 16-bit signed integer type.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-large-size.rc 2>&1 | FileCheck %s --check-prefix COORD3
+
+; COORD3: llvm-rc: Error in DIALOGEX statement (ID 1):
+; COORD3-NEXT: Dialog height (32768) does not fit in 16-bit signed integer type.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-negative-size.rc 2>&1 | FileCheck %s --check-prefix COORD4
+
+; COORD4: llvm-rc: Error in DIALOGEX statement (ID 1):
+; COORD4-NEXT: Dialog width (-50) cannot be negative.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-ctl-large-coord.rc 2>&1 | FileCheck %s --check-prefix CTL-COORD1
+
+; CTL-COORD1: llvm-rc: Error in DIALOGEX statement (ID 1):
+; CTL-COORD1-NEXT: Error in LTEXT control (ID 1):
+; CTL-COORD1-NEXT: Dialog control x-coordinate (44444) does not fit in 16-bit signed integer type.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-ctl-large-coord-neg.rc 2>&1 | FileCheck %s --check-prefix CTL-COORD2
+
+; CTL-COORD2: llvm-rc: Error in DIALOG statement (ID 1):
+; CTL-COORD2-NEXT: Error in LTEXT control (ID 1):
+; CTL-COORD2-NEXT: Dialog control y-coordinate (-32769) does not fit in 16-bit signed integer type.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-ctl-large-size.rc 2>&1 | FileCheck %s --check-prefix CTL-COORD3
+
+; CTL-COORD3: llvm-rc: Error in DIALOGEX statement (ID 1):
+; CTL-COORD3-NEXT: Error in LTEXT control (ID 1):
+; CTL-COORD3-NEXT: Dialog control width (40000) does not fit in 16-bit signed integer type.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-ctl-negative-size.rc 2>&1 | FileCheck %s --check-prefix CTL-COORD4
+
+; CTL-COORD4: llvm-rc: Error in DIALOG statement (ID 1):
+; CTL-COORD4-NEXT: Error in LTEXT control (ID 1):
+; CTL-COORD4-NEXT: Dialog control height (-700) cannot be negative.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-ctl-large-id.rc 2>&1 | FileCheck %s --check-prefix CTL-ID
+
+; CTL-ID: llvm-rc: Error in DIALOG statement (ID 5):
+; CTL-ID-NEXT: Error in RTEXT control (ID 100000):
+; CTL-ID-NEXT: Control ID in simple DIALOG resource (100000) does not fit in 16 bits.
+
+
+; RUN: not llvm-rc /FO %t %p/Inputs/tag-dialog-ctl-large-ref-id.rc 2>&1 | FileCheck %s --check-prefix CTL-REF-ID
+
+; CTL-REF-ID: llvm-rc: Error in DIALOGEX statement (ID 1):
+; CTL-REF-ID-NEXT: Error in CTEXT control (ID 42):
+; CTL-REF-ID-NEXT: Control reference ID (65536) does not fit in 16 bits.

Modified: llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp?rev=314578&r1=314577&r2=314578&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.cpp Fri Sep 29 17:38:52 2017
@@ -60,6 +60,25 @@ static Error checkNumberFits(uint32_t Nu
   return checkNumberFits(Number, sizeof(FitType) * 8, FieldName);
 }
 
+// A similar function for signed integers.
+template <typename FitType>
+static Error checkSignedNumberFits(uint32_t Number, Twine FieldName,
+                                   bool CanBeNegative) {
+  int32_t SignedNum = Number;
+  if (SignedNum < std::numeric_limits<FitType>::min() ||
+      SignedNum > std::numeric_limits<FitType>::max())
+    return createError(FieldName + " (" + Twine(SignedNum) +
+                           ") does not fit in " + Twine(sizeof(FitType) * 8) +
+                           "-bit signed integer type.",
+                       std::errc::value_too_large);
+
+  if (!CanBeNegative && SignedNum < 0)
+    return createError(FieldName + " (" + Twine(SignedNum) +
+                       ") cannot be negative.");
+
+  return Error::success();
+}
+
 static Error checkIntOrString(IntOrString Value, Twine FieldName) {
   if (!Value.isInt())
     return Error::success();
@@ -201,6 +220,10 @@ Error ResourceFileWriter::visitAccelerat
   return writeResource(Res, &ResourceFileWriter::writeAcceleratorsBody);
 }
 
+Error ResourceFileWriter::visitDialogResource(const RCResource *Res) {
+  return writeResource(Res, &ResourceFileWriter::writeDialogBody);
+}
+
 Error ResourceFileWriter::visitHTMLResource(const RCResource *Res) {
   return writeResource(Res, &ResourceFileWriter::writeHTMLBody);
 }
@@ -379,8 +402,152 @@ Error ResourceFileWriter::writeAccelerat
   return Error::success();
 }
 
-// --- HTMLResource helpers. --- //
+// --- DialogResource helpers. --- //
+
+Error ResourceFileWriter::writeSingleDialogControl(const Control &Ctl,
+                                                   bool IsExtended) {
+  // Each control should be aligned to DWORD.
+  padStream(sizeof(uint32_t));
 
+  auto TypeInfo = Control::SupportedCtls.lookup(Ctl.Type);
+  uint32_t CtlStyle = TypeInfo.Style | Ctl.Style.getValueOr(0);
+  uint32_t CtlExtStyle = Ctl.ExtStyle.getValueOr(0);
+
+  // DIALOG(EX) item header prefix.
+  if (!IsExtended) {
+    struct {
+      ulittle32_t Style;
+      ulittle32_t ExtStyle;
+    } Prefix{ulittle32_t(CtlStyle), ulittle32_t(CtlExtStyle)};
+    writeObject(Prefix);
+  } else {
+    struct {
+      ulittle32_t HelpID;
+      ulittle32_t ExtStyle;
+      ulittle32_t Style;
+    } Prefix{ulittle32_t(Ctl.HelpID.getValueOr(0)), ulittle32_t(CtlExtStyle),
+             ulittle32_t(CtlStyle)};
+    writeObject(Prefix);
+  }
+
+  // Common fixed-length part.
+  RETURN_IF_ERROR(checkSignedNumberFits<int16_t>(
+      Ctl.X, "Dialog control x-coordinate", true));
+  RETURN_IF_ERROR(checkSignedNumberFits<int16_t>(
+      Ctl.Y, "Dialog control y-coordinate", true));
+  RETURN_IF_ERROR(
+      checkSignedNumberFits<int16_t>(Ctl.Width, "Dialog control width", false));
+  RETURN_IF_ERROR(checkSignedNumberFits<int16_t>(
+      Ctl.Height, "Dialog control height", false));
+  struct {
+    ulittle16_t X;
+    ulittle16_t Y;
+    ulittle16_t Width;
+    ulittle16_t Height;
+  } Middle{ulittle16_t(Ctl.X), ulittle16_t(Ctl.Y), ulittle16_t(Ctl.Width),
+           ulittle16_t(Ctl.Height)};
+  writeObject(Middle);
+
+  // ID; it's 16-bit in DIALOG and 32-bit in DIALOGEX.
+  if (!IsExtended) {
+    RETURN_IF_ERROR(checkNumberFits<uint16_t>(
+        Ctl.ID, "Control ID in simple DIALOG resource"));
+    writeInt<uint16_t>(Ctl.ID);
+  } else {
+    writeInt<uint32_t>(Ctl.ID);
+  }
+
+  // Window class - either 0xFFFF + 16-bit integer or a string.
+  RETURN_IF_ERROR(writeIntOrString(IntOrString(TypeInfo.CtlClass)));
+
+  // Element caption/reference ID. ID is preceded by 0xFFFF.
+  RETURN_IF_ERROR(checkIntOrString(Ctl.Title, "Control reference ID"));
+  RETURN_IF_ERROR(writeIntOrString(Ctl.Title));
+
+  // # bytes of extra creation data count. Don't pass any.
+  writeInt<uint16_t>(0);
+
+  return Error::success();
+}
+
+Error ResourceFileWriter::writeDialogBody(const RCResource *Base) {
+  auto *Res = cast<DialogResource>(Base);
+
+  // Default style: WS_POPUP | WS_BORDER | WS_SYSMENU.
+  const uint32_t UsedStyle = 0x80880000;
+
+  // Write DIALOG(EX) header prefix. These are pretty different.
+  if (!Res->IsExtended) {
+    struct {
+      ulittle32_t Style;
+      ulittle32_t ExtStyle;
+    } Prefix{ulittle32_t(UsedStyle),
+             ulittle32_t(0)}; // As of now, we don't keep EXSTYLE.
+
+    writeObject(Prefix);
+  } else {
+    const uint16_t DialogExMagic = 0xFFFF;
+
+    struct {
+      ulittle16_t Version;
+      ulittle16_t Magic;
+      ulittle32_t HelpID;
+      ulittle32_t ExtStyle;
+      ulittle32_t Style;
+    } Prefix{ulittle16_t(1), ulittle16_t(DialogExMagic),
+             ulittle32_t(Res->HelpID), ulittle32_t(0), ulittle32_t(UsedStyle)};
+
+    writeObject(Prefix);
+  }
+
+  // Now, a common part. First, fixed-length fields.
+  RETURN_IF_ERROR(checkNumberFits<uint16_t>(Res->Controls.size(),
+                                            "Number of dialog controls"));
+  RETURN_IF_ERROR(
+      checkSignedNumberFits<int16_t>(Res->X, "Dialog x-coordinate", true));
+  RETURN_IF_ERROR(
+      checkSignedNumberFits<int16_t>(Res->Y, "Dialog y-coordinate", true));
+  RETURN_IF_ERROR(
+      checkSignedNumberFits<int16_t>(Res->Width, "Dialog width", false));
+  RETURN_IF_ERROR(
+      checkSignedNumberFits<int16_t>(Res->Height, "Dialog height", false));
+  struct {
+    ulittle16_t Count;
+    ulittle16_t PosX;
+    ulittle16_t PosY;
+    ulittle16_t DialogWidth;
+    ulittle16_t DialogHeight;
+  } Middle{ulittle16_t(Res->Controls.size()), ulittle16_t(Res->X),
+           ulittle16_t(Res->Y), ulittle16_t(Res->Width),
+           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);
+
+  // Window CLASS field. Not kept here.
+  writeInt<uint16_t>(0);
+
+  // Window title. There is no title for now, so all we output is '\0'.
+  writeInt<uint16_t>(0);
+
+  auto handleCtlError = [&](Error &&Err, const Control &Ctl) -> Error {
+    if (!Err)
+      return Error::success();
+    return joinErrors(createError("Error in " + Twine(Ctl.Type) +
+                                  " control  (ID " + Twine(Ctl.ID) + "):"),
+                      std::move(Err));
+  };
+
+  for (auto &Ctl : Res->Controls)
+    RETURN_IF_ERROR(
+        handleCtlError(writeSingleDialogControl(Ctl, Res->IsExtended), Ctl));
+
+  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=314578&r1=314577&r2=314578&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceFileWriter.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceFileWriter.h Fri Sep 29 17:38:52 2017
@@ -31,6 +31,7 @@ public:
 
   Error visitNullResource(const RCResource *) override;
   Error visitAcceleratorsResource(const RCResource *) override;
+  Error visitDialogResource(const RCResource *) override;
   Error visitHTMLResource(const RCResource *) override;
   Error visitMenuResource(const RCResource *) override;
 
@@ -61,6 +62,10 @@ private:
                                bool IsLastItem);
   Error writeAcceleratorsBody(const RCResource *);
 
+  // DialogResource
+  Error writeSingleDialogControl(const Control &, bool IsExtended);
+  Error writeDialogBody(const RCResource *);
+
   // HTMLResource
   Error writeHTMLBody(const RCResource *);
 

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp?rev=314578&r1=314577&r2=314578&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptParser.cpp Fri Sep 29 17:38:52 2017
@@ -458,15 +458,17 @@ Expected<Control> RCParser::parseControl
   //  [class] text, id, x, y, width, height [, style] [, exstyle] [, helpID]
   //  [class]       id, x, y, width, height [, style] [, exstyle] [, helpID]
   // Note that control ids must be integers.
+  // Text might be either a string or an integer pointing to resource ID.
   ASSIGN_OR_RETURN(ClassResult, readIdentifier());
   std::string ClassUpper = ClassResult->upper();
-  if (Control::SupportedCtls.find(ClassUpper) == Control::SupportedCtls.end())
+  auto CtlInfo = Control::SupportedCtls.find(ClassUpper);
+  if (CtlInfo == Control::SupportedCtls.end())
     return getExpectedError("control type, END or '}'", true);
 
   // Read caption if necessary.
-  StringRef Caption;
-  if (Control::CtlsWithTitle.find(ClassUpper) != Control::CtlsWithTitle.end()) {
-    ASSIGN_OR_RETURN(CaptionResult, readString());
+  IntOrString Caption{StringRef()};
+  if (CtlInfo->getValue().HasTitle) {
+    ASSIGN_OR_RETURN(CaptionResult, readIntOrString());
     RETURN_IF_ERROR(consumeType(Kind::Comma));
     Caption = *CaptionResult;
   }

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp?rev=314578&r1=314577&r2=314578&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.cpp Fri Sep 29 17:38:52 2017
@@ -120,11 +120,14 @@ raw_ostream &StringTableResource::log(ra
   return OS;
 }
 
-const StringSet<> Control::SupportedCtls = {
-    "LTEXT", "RTEXT", "CTEXT", "PUSHBUTTON", "DEFPUSHBUTTON", "EDITTEXT"};
-
-const StringSet<> Control::CtlsWithTitle = {"LTEXT", "RTEXT", "CTEXT",
-                                            "PUSHBUTTON", "DEFPUSHBUTTON"};
+const StringMap<Control::CtlInfo> Control::SupportedCtls = {
+    {"LTEXT", CtlInfo{0x50020000, ClsStatic, true}},
+    {"CTEXT", CtlInfo{0x50020001, ClsStatic, true}},
+    {"RTEXT", CtlInfo{0x50020002, ClsStatic, true}},
+    {"PUSHBUTTON", CtlInfo{0x50010000, ClsButton, true}},
+    {"DEFPUSHBUTTON", CtlInfo{0x50010001, ClsButton, true}},
+    {"EDITTEXT", CtlInfo{0x50810000, ClsEdit, false}},
+};
 
 raw_ostream &Control::log(raw_ostream &OS) const {
   OS << "  Control (" << ID << "): " << Type << ", title: " << Title

Modified: llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h?rev=314578&r1=314577&r2=314578&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceScriptStmt.h Fri Sep 29 17:38:52 2017
@@ -439,21 +439,40 @@ public:
 
 // Single control definition.
 class Control {
-  StringRef Type, Title;
+public:
+  StringRef Type;
+  IntOrString Title;
   uint32_t ID, X, Y, Width, Height;
   Optional<uint32_t> Style, ExtStyle, HelpID;
 
-public:
-  Control(StringRef CtlType, StringRef CtlTitle, uint32_t CtlID, uint32_t PosX,
-          uint32_t PosY, uint32_t ItemWidth, uint32_t ItemHeight,
+  // Control classes as described in DLGITEMTEMPLATEEX documentation.
+  //
+  // Ref: msdn.microsoft.com/en-us/library/windows/desktop/ms645389.aspx
+  enum CtlClasses {
+    ClsButton = 0x80,
+    ClsEdit = 0x81,
+    ClsStatic = 0x82,
+    ClsListBox = 0x83,
+    ClsScrollBar = 0x84,
+    ClsComboBox = 0x85
+  };
+
+  // Simple information about a single control type.
+  struct CtlInfo {
+    uint32_t Style;
+    uint16_t CtlClass;
+    bool HasTitle;
+  };
+
+  Control(StringRef CtlType, IntOrString CtlTitle, uint32_t CtlID,
+          uint32_t PosX, uint32_t PosY, uint32_t ItemWidth, uint32_t ItemHeight,
           Optional<uint32_t> ItemStyle, Optional<uint32_t> ExtItemStyle,
           Optional<uint32_t> CtlHelpID)
       : Type(CtlType), Title(CtlTitle), ID(CtlID), X(PosX), Y(PosY),
         Width(ItemWidth), Height(ItemHeight), Style(ItemStyle),
         ExtStyle(ExtItemStyle), HelpID(CtlHelpID) {}
 
-  static const StringSet<> SupportedCtls;
-  static const StringSet<> CtlsWithTitle;
+  static const StringMap<CtlInfo> SupportedCtls;
 
   raw_ostream &log(raw_ostream &) const;
 };
@@ -462,11 +481,11 @@ public:
 // DIALOGEX because of their being too similar to each other. We only have a
 // flag determining the type of the dialog box.
 class DialogResource : public OptStatementsRCResource {
+public:
   uint32_t X, Y, Width, Height, HelpID;
   std::vector<Control> Controls;
   bool IsExtended;
 
-public:
   DialogResource(uint32_t PosX, uint32_t PosY, uint32_t DlgWidth,
                  uint32_t DlgHeight, uint32_t DlgHelpID,
                  OptionalStmtList &&OptStmts, bool IsDialogEx)
@@ -477,6 +496,21 @@ public:
   void addControl(Control &&Ctl) { Controls.push_back(std::move(Ctl)); }
 
   raw_ostream &log(raw_ostream &) const override;
+
+  // It was a weird design decision to assign the same resource type number
+  // both for DIALOG and DIALOGEX (and the same structure version number).
+  // It makes it possible for DIALOG to be mistaken for DIALOGEX.
+  IntOrString getResourceType() const override { return RkDialog; }
+  Twine getResourceTypeName() const override {
+    return "DIALOG" + Twine(IsExtended ? "EX" : "");
+  }
+  Error visit(Visitor *V) const override {
+    return V->visitDialogResource(this);
+  }
+  ResourceKind getKind() const override { return RkDialog; }
+  static bool classof(const RCResource *Res) {
+    return Res->getKind() == RkDialog;
+  }
 };
 
 // User-defined resource. It is either:

Modified: llvm/trunk/tools/llvm-rc/ResourceVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rc/ResourceVisitor.h?rev=314578&r1=314577&r2=314578&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rc/ResourceVisitor.h (original)
+++ llvm/trunk/tools/llvm-rc/ResourceVisitor.h Fri Sep 29 17:38:52 2017
@@ -29,6 +29,7 @@ class Visitor {
 public:
   virtual Error visitNullResource(const RCResource *) = 0;
   virtual Error visitAcceleratorsResource(const RCResource *) = 0;
+  virtual Error visitDialogResource(const RCResource *) = 0;
   virtual Error visitHTMLResource(const RCResource *) = 0;
   virtual Error visitMenuResource(const RCResource *) = 0;
 




More information about the llvm-commits mailing list