ekaranto-rubywmq 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +4 -0
- data/LICENSE.txt +201 -0
- data/README.md +408 -0
- data/Rakefile +87 -0
- data/examples/each_a.rb +16 -0
- data/examples/each_b.rb +25 -0
- data/examples/each_header.rb +22 -0
- data/examples/files_to_q.cfg +24 -0
- data/examples/files_to_q.rb +31 -0
- data/examples/get_a.rb +19 -0
- data/examples/get_client.rb +35 -0
- data/examples/put1_a.rb +9 -0
- data/examples/put1_b.rb +17 -0
- data/examples/put1_c.rb +16 -0
- data/examples/put_a.rb +19 -0
- data/examples/put_b.rb +27 -0
- data/examples/put_dlh.rb +25 -0
- data/examples/put_dynamic_q.rb +22 -0
- data/examples/put_group_a.rb +35 -0
- data/examples/put_group_b.rb +37 -0
- data/examples/put_rfh.rb +51 -0
- data/examples/put_rfh2_a.rb +27 -0
- data/examples/put_rfh2_b.rb +27 -0
- data/examples/put_xmit_q.rb +17 -0
- data/examples/q_to_files.cfg +17 -0
- data/examples/q_to_files.rb +32 -0
- data/examples/request.rb +44 -0
- data/examples/server.rb +81 -0
- data/ext/decode_rfh.c +348 -0
- data/ext/decode_rfh.h +45 -0
- data/ext/extconf.rb +30 -0
- data/ext/extconf_client.rb +24 -0
- data/ext/generate/generate_const.rb +140 -0
- data/ext/generate/generate_reason.rb +233 -0
- data/ext/generate/generate_structs.rb +82 -0
- data/ext/generate/wmq_structs.erb +341 -0
- data/ext/wmq.c +90 -0
- data/ext/wmq.h +371 -0
- data/ext/wmq_message.c +671 -0
- data/ext/wmq_mq_load.c +217 -0
- data/ext/wmq_queue.c +1411 -0
- data/ext/wmq_queue_manager.c +1570 -0
- data/lib/rubywmq.rb +1 -0
- data/lib/wmq/message.rb +70 -0
- data/lib/wmq/queue_manager.rb +110 -0
- data/lib/wmq/version.rb +3 -0
- data/lib/wmq.rb +16 -0
- data/nbproject/project.properties +11 -0
- data/nbproject/project.xml +17 -0
- data/tests/test.rb +318 -0
- metadata +115 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
# Extract Constants from the WebSphere MQ header files
|
2
|
+
class GenerateConst
|
3
|
+
|
4
|
+
# Extract Constants from Header files
|
5
|
+
def GenerateConst.extract_const(filename, const_prefix, start_exp=nil, end_exp=nil)
|
6
|
+
@constants = []
|
7
|
+
active = if start_exp then false else true end # Sure there is a better way
|
8
|
+
File.open(filename) do |file|
|
9
|
+
file.each do |line|
|
10
|
+
line.rstrip!
|
11
|
+
if line.length > 0 # Skip empty lines
|
12
|
+
if active
|
13
|
+
break if start_exp && line.match(end_exp)
|
14
|
+
# Skip Comment lines, then check for a match
|
15
|
+
if (line !~ /^\s*\/\*/) && (match = /\s*#define\s+(#{const_prefix}\w+)[\(\s]+([-\\\w\dx\'\"\s]+)/.match(line))
|
16
|
+
@constants << [match[1], match[2]]
|
17
|
+
end
|
18
|
+
else
|
19
|
+
next unless line.match(start_exp)
|
20
|
+
active = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@constants
|
26
|
+
end
|
27
|
+
|
28
|
+
# Extract MQ Constants from Header files
|
29
|
+
def GenerateConst.rb_const(filename, const_prefix, exclude_exp=nil)
|
30
|
+
str = ''
|
31
|
+
GenerateConst.extract_const(filename, const_prefix).each do |item|
|
32
|
+
const, val = item
|
33
|
+
next if const.include?('_STRUC_ID')
|
34
|
+
next if exclude_exp && const.match(exclude_exp)
|
35
|
+
if val.include?('"') || val.include?("'")
|
36
|
+
if match = val.match(/(\w+)/)
|
37
|
+
val = "'#{match[0]}'"
|
38
|
+
else
|
39
|
+
val = "''"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
str << " %-30s = #{val}\n" % const
|
43
|
+
end
|
44
|
+
str
|
45
|
+
end
|
46
|
+
|
47
|
+
def GenerateConst.config(filename, prefix)
|
48
|
+
str = "# WMQ::QueueManager execute commands\n"
|
49
|
+
str << "execute_commands:\n"
|
50
|
+
GenerateConst.extract_const(filename,prefix).each do |item|
|
51
|
+
name = item[0].gsub(prefix,'').downcase
|
52
|
+
str << " :%-26s " % "#{name}:"
|
53
|
+
match = name.match(/\w+?_([\w_]+)/)
|
54
|
+
str << ":#{match[1]}" if match
|
55
|
+
str << "\n"
|
56
|
+
end
|
57
|
+
str
|
58
|
+
end
|
59
|
+
|
60
|
+
def GenerateConst.wmq_const(path)
|
61
|
+
str = <<END_OF_STRING
|
62
|
+
################################################################################
|
63
|
+
#
|
64
|
+
# WARNING: DO NOT MODIFY THIS FILE
|
65
|
+
#
|
66
|
+
# This file was generated by generate_const.rb.
|
67
|
+
#
|
68
|
+
################################################################################
|
69
|
+
module WMQ
|
70
|
+
END_OF_STRING
|
71
|
+
[ ['Connect Options','cmqc.h','MQCNO_',/(VERSION)|(CONN_TAG)|(HANDLE_SHARE)|(_LENGTH)/],
|
72
|
+
['Open Options', 'cmqc.h','MQOO_' ],
|
73
|
+
['Close Options', 'cmqc.h','MQCO_'],
|
74
|
+
['Match Options', 'cmqc.h','MQMO_'],
|
75
|
+
['Message Format Options', 'cmqc.h','MQFMT_',/(_ARRAY)/],
|
76
|
+
['Get Message Options', 'cmqc.h','MQGMO_',/(VERSION)|(LENGTH)|(MQGMO_BROWSE_HANDLE)|(MQGMO_BROWSE_CO_OP)/],
|
77
|
+
['Transport Types', 'cmqxc.h','MQXPT_'] ,
|
78
|
+
['Report Options', 'cmqc.h', 'MQRO_'],
|
79
|
+
['Message Types', 'cmqc.h', 'MQMT_'],
|
80
|
+
['Expiry', 'cmqc.h', 'MQEI_'],
|
81
|
+
['Feedback Values', 'cmqc.h', 'MQFB_'],
|
82
|
+
['Encoding Values', 'cmqc.h', 'MQENC_',/(MQENC_NORMAL)|(MQENC_REVERSED)|(MQENC_S390)|(MQENC_TNS)/],
|
83
|
+
['Coded Character Set Identifiers', 'cmqc.h', 'MQCCSI_'],
|
84
|
+
['Priority', 'cmqc.h', 'MQPRI_'],
|
85
|
+
['Persistence', 'cmqc.h', 'MQPER_'],
|
86
|
+
['Put Application Types', 'cmqc.h', 'MQAT_'],
|
87
|
+
['Message Flags', 'cmqc.h', 'MQMF_'],
|
88
|
+
['Original Length', 'cmqc.h', 'MQOL_'],
|
89
|
+
['Put Message Options', 'cmqc.h', 'MQPMO_',/(VERSION)|(LENGTH)/],
|
90
|
+
['Put Message Record Fields', 'cmqc.h', 'MQPMRF_',/(VERSION)|(LENGTH)/],
|
91
|
+
['Reason Codes', 'cmqc.h','MQRC_'],
|
92
|
+
].each do |item|
|
93
|
+
str << "\n# #{item[0]}\n"
|
94
|
+
str << GenerateConst.rb_const("#{path}/#{item[1]}", item[2], item[3])
|
95
|
+
end
|
96
|
+
str << "end\n"
|
97
|
+
end
|
98
|
+
|
99
|
+
def GenerateConst.admin_consts(path)
|
100
|
+
str = <<END_OF_STRING
|
101
|
+
################################################################################
|
102
|
+
#
|
103
|
+
# WARNING: DO NOT MODIFY THIS FILE
|
104
|
+
#
|
105
|
+
# This file was generated by generate_const.rb.
|
106
|
+
#
|
107
|
+
################################################################################
|
108
|
+
module WMQ
|
109
|
+
END_OF_STRING
|
110
|
+
str << "# Admin constants from cmqc.h\n"
|
111
|
+
[ ['Object Types', 'cmqc.h', 'MQOT_'],
|
112
|
+
['Security Identifier Types', 'cmqc.h', 'MQSIDT_'],
|
113
|
+
['Channel Types', 'cmqxc.h', 'MQCHT_'],
|
114
|
+
].each do |item|
|
115
|
+
str << "\n# #{item[0]}\n"
|
116
|
+
str << GenerateConst.rb_const("#{path}/#{item[1]}", item[2], item[3])
|
117
|
+
end
|
118
|
+
GenerateConst.extract_const(path+'cmqc.h', 'MQ', /Queue\s+Attributes/, /General\s+Constants/).each do |item|
|
119
|
+
str << " %-30s = #{item[1]}\n" % item[0]
|
120
|
+
end
|
121
|
+
str << "# Admin constants from cmqcfc.h\n"
|
122
|
+
GenerateConst.extract_const(path+'cmqcfc.h', 'MQ', /Parameter\s+Values/, /typedef\s+struct/).each do |item|
|
123
|
+
str << " %-30s = #{item[1]}\n" % item[0]
|
124
|
+
end
|
125
|
+
str << "end\n"
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.generate(path, target_path='')
|
129
|
+
File.open(File.join(target_path,'constants_admin.rb'), 'w') {|file| file.write(GenerateConst.admin_consts(path))}
|
130
|
+
puts 'Generated wmq_const_admin.rb'
|
131
|
+
File.open(File.join(target_path,'constants.rb'), 'w') {|file| file.write(GenerateConst.wmq_const(path))}
|
132
|
+
puts 'Generated wmq_const.rb'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
if $0 == __FILE__
|
137
|
+
path = ARGV[0] || raise("Mandatory parameter: 'WebSphere MQ Include path' is missing")
|
138
|
+
path = path + '/'
|
139
|
+
GenerateConst.generate(path)
|
140
|
+
end
|
@@ -0,0 +1,233 @@
|
|
1
|
+
class GenerateReason
|
2
|
+
|
3
|
+
# Extract Error Code Constants from Header files
|
4
|
+
def GenerateReason.extract_const(filename, const_prefix)
|
5
|
+
@constants = []
|
6
|
+
File.open(filename) do |file|
|
7
|
+
file.each do |line|
|
8
|
+
line.rstrip!
|
9
|
+
# Skip empty and comment lines
|
10
|
+
if line.length > 0 && line !~ /^\s*\/\*/
|
11
|
+
if match = /\s*#define\s+(#{const_prefix}\w+)[\(\s]+([-\dx]+)/.match(line)
|
12
|
+
@constants << [match[1], match[2]]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@constants
|
18
|
+
end
|
19
|
+
|
20
|
+
# Extract Error Code Constants from Header files
|
21
|
+
# Uses lazy print to collect duplicate values
|
22
|
+
def GenerateReason.reason_case(filename, prefix)
|
23
|
+
last_rc = nil
|
24
|
+
last_reason = nil
|
25
|
+
str = ''
|
26
|
+
GenerateReason.extract_const(filename,prefix).each do |item|
|
27
|
+
if last_rc == item[1]
|
28
|
+
str << " case %-30s: return \"#{item[0]} or #{last_reason}[#{item[1]}]\";\n" % item[0]
|
29
|
+
last_rc = nil
|
30
|
+
last_reason = nil
|
31
|
+
else
|
32
|
+
str << " case %-30s: return \"#{last_reason}[#{last_rc}]\";\n" % last_reason if last_rc
|
33
|
+
last_rc = item[1]
|
34
|
+
last_reason = item[0]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
str
|
38
|
+
end
|
39
|
+
|
40
|
+
# The WebSphere MQ header files have several duplicate values,
|
41
|
+
# so need to exclude duplicates.
|
42
|
+
def GenerateReason.selector_case(filename, prefix, excludes=nil, &block)
|
43
|
+
GenerateReason.extract_const(filename,prefix).each do |item|
|
44
|
+
next if item[0].include?('FIRST') || item[0].include?('LAST')
|
45
|
+
next if excludes && excludes.include?(item[0])
|
46
|
+
block.call item
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def GenerateReason.wmq_reason(path)
|
51
|
+
str = <<END_OF_STRING
|
52
|
+
/* --------------------------------------------------------------------------
|
53
|
+
*
|
54
|
+
* WARNING: DO NOT MODIFY THIS FILE
|
55
|
+
*
|
56
|
+
* This file was generated by generate_reason.rb.
|
57
|
+
*
|
58
|
+
* --------------------------------------------------------------------------*/
|
59
|
+
|
60
|
+
#include "wmq.h"
|
61
|
+
|
62
|
+
char* wmq_reason(MQLONG reason_code)
|
63
|
+
{
|
64
|
+
switch (reason_code)
|
65
|
+
{
|
66
|
+
END_OF_STRING
|
67
|
+
|
68
|
+
[['cmqc.h', 'MQRC_'],
|
69
|
+
['cmqcfc.h', 'MQRCCF_']].each do |item|
|
70
|
+
str << GenerateReason.reason_case(path+item[0], item[1])
|
71
|
+
end
|
72
|
+
str << <<END_OF_STRING
|
73
|
+
}
|
74
|
+
printf("WMQ::wmq_reason Unknown Reason code:%ld\\n",(long)reason_code);
|
75
|
+
return "Unknown reason code";
|
76
|
+
}
|
77
|
+
|
78
|
+
END_OF_STRING
|
79
|
+
|
80
|
+
str_switch = ''
|
81
|
+
str_id_init = ''
|
82
|
+
# Integer Selectors for Object Attributes
|
83
|
+
[['cmqc.h', 'MQIA_'],
|
84
|
+
['cmqcfc.h', 'MQIACF_', ['MQIACF_ERROR_ID',
|
85
|
+
'MQIACF_QUIESCE']],
|
86
|
+
['cmqcfc.h', 'MQIACH_', ['MQIACH_CURRENT_SEQ_NUMBER',
|
87
|
+
'MQIACH_BYTES_RCVD',
|
88
|
+
'MQIACH_BUFFERS_RCVD',
|
89
|
+
'MQIACH_MSGS_RCVD']],
|
90
|
+
['cmqcfc.h', 'MQIAMO_'],
|
91
|
+
['cmqcfc.h', 'MQIAMO64_', ['MQIAMO64_AVG_Q_TIME',
|
92
|
+
'MQIAMO64_Q_TIME_AVG',
|
93
|
+
'MQIAMO64_Q_TIME_MAX',
|
94
|
+
'MQIAMO64_Q_TIME_MIN']],
|
95
|
+
# Integer System Selectors
|
96
|
+
['cmqbc.h', 'MQIASY_'],
|
97
|
+
# Character Selectors for Object Attributes
|
98
|
+
['cmqc.h', 'MQCA_',['MQCA_BASE_OBJECT_NAME']],
|
99
|
+
['cmqcfc.h', 'MQCACF_'],
|
100
|
+
['cmqcfc.h', 'MQCACH_'],
|
101
|
+
['cmqcfc.h', 'MQCAMO_'],
|
102
|
+
# Byte String Selectors for Object Attributes
|
103
|
+
['cmqc.h', 'MQBA_'],
|
104
|
+
['cmqcfc.h', 'MQBACF_'],
|
105
|
+
# Group Selectors for Object Attributes
|
106
|
+
['cmqcfc.h', 'MQGACF_'] ].each do |item|
|
107
|
+
str << "/* Constants #{item[1]}* from #{item[0]} */\n"
|
108
|
+
str_switch << " /* Constants #{item[1]}* from #{item[0]} */\n"
|
109
|
+
str_id_init << " /* Constants #{item[1]}* from #{item[0]} */\n"
|
110
|
+
GenerateReason.selector_case(path+item[0], item[1], item[2]) do |const|
|
111
|
+
id = const[0].gsub(item[1],'').downcase
|
112
|
+
str_switch << " case %-30s: return ID_#{id};\n" % const[0]
|
113
|
+
str_id_init << " ID_%-25s = rb_intern(\"#{id}\");\n" % id
|
114
|
+
str << "static ID ID_#{id};\n"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
str << <<END_OF_STRING
|
119
|
+
|
120
|
+
void QueueManager_selector_id_init()
|
121
|
+
{
|
122
|
+
#{str_id_init}
|
123
|
+
}
|
124
|
+
|
125
|
+
ID wmq_selector_id(MQLONG selector)
|
126
|
+
{
|
127
|
+
switch (selector)
|
128
|
+
{
|
129
|
+
#{str_switch}
|
130
|
+
}
|
131
|
+
printf("WMQ::wmq_select_text Unknown Selector:%ld\\n",(long)selector);
|
132
|
+
return rb_intern("unknown_selector_code");
|
133
|
+
}
|
134
|
+
|
135
|
+
void wmq_selector(ID selector_id, PMQLONG selector_type, PMQLONG selector)
|
136
|
+
{
|
137
|
+
*selector_type = MQIT_INTEGER;
|
138
|
+
END_OF_STRING
|
139
|
+
first = true
|
140
|
+
str_if = ''
|
141
|
+
str_id_init = ''
|
142
|
+
# Integer Selectors for Object Attributes
|
143
|
+
[['cmqc.h', 'MQIA_'],
|
144
|
+
['cmqcfc.h', 'MQIACF_', ['MQIACF_ERROR_ID',
|
145
|
+
'MQIACF_QUIESCE']],
|
146
|
+
['cmqcfc.h', 'MQIACH_', ['MQIACH_CURRENT_SEQ_NUMBER',
|
147
|
+
'MQIACH_BYTES_RCVD',
|
148
|
+
'MQIACH_BUFFERS_RCVD']],
|
149
|
+
['cmqcfc.h', 'MQIAMO_'],
|
150
|
+
['cmqcfc.h', 'MQIAMO64_', ['MQIAMO64_AVG_Q_TIME',
|
151
|
+
'MQIAMO64_Q_TIME_AVG',
|
152
|
+
'MQIAMO64_Q_TIME_MAX',
|
153
|
+
'MQIAMO64_Q_TIME_MIN']],
|
154
|
+
# Integer System Selectors
|
155
|
+
# ['cmqbc.h', 'MQIASY_'],
|
156
|
+
].each do |item|
|
157
|
+
str << " /* Consteants #{item[1]}* from #{item[0]} */\n"
|
158
|
+
GenerateReason.selector_case(path+item[0], item[1], item[2]) do |const|
|
159
|
+
str << " if(selector_id == %-32s{ *selector = #{const[0]}; return;}\n" % "ID_#{const[0].gsub(item[1],'').downcase})"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
str << "\n *selector_type = MQIT_STRING;\n\n"
|
163
|
+
# Character Selectors for Object Attributes
|
164
|
+
[['cmqc.h', 'MQCA_',['MQCA_BASE_OBJECT_NAME']],
|
165
|
+
['cmqcfc.h', 'MQCACF_'],
|
166
|
+
['cmqcfc.h', 'MQCACH_'],
|
167
|
+
['cmqcfc.h', 'MQCAMO_'],
|
168
|
+
# Byte String Selectors for Object Attributes
|
169
|
+
# ['cmqc.h', 'MQBA_'],
|
170
|
+
# ['cmqcfc.h', 'MQBACF_'],
|
171
|
+
# Group Selectors for Object Attributes
|
172
|
+
# ['cmqcfc.h', 'MQGACF_']
|
173
|
+
].each do |item|
|
174
|
+
str << " /* Constants #{item[1]}* from #{item[0]} */\n"
|
175
|
+
GenerateReason.selector_case(path+item[0], item[1], item[2]) do |const|
|
176
|
+
str << " if(selector_id == %-32s{ *selector = #{const[0]}; return;}\n" % "ID_#{const[0].gsub(item[1],'').downcase})"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
str << <<END_OF_STRING
|
181
|
+
|
182
|
+
rb_raise(rb_eArgError, "WMQ::QueueManager#execute [wmq_selector] Unknown selector supplied");
|
183
|
+
}
|
184
|
+
|
185
|
+
END_OF_STRING
|
186
|
+
first = true
|
187
|
+
str_if = ''
|
188
|
+
str_id_init = ''
|
189
|
+
GenerateReason.selector_case(path+'cmqcfc.h', 'MQCMD_') do |const|
|
190
|
+
if first
|
191
|
+
first = false
|
192
|
+
str_if << " "
|
193
|
+
else
|
194
|
+
str_if << " else "
|
195
|
+
end
|
196
|
+
id = const[0].gsub('MQCMD_','').downcase
|
197
|
+
str_id_init << " ID_%-25s = rb_intern(\"#{id}\");\n" % id
|
198
|
+
str_if << "if(command_id == %-28s{ command = #{const[0]}; }\n" % "ID_#{const[0].gsub('MQCMD_','').downcase})"
|
199
|
+
str << "static ID ID_#{id};\n"
|
200
|
+
end
|
201
|
+
str << <<END_OF_STRING
|
202
|
+
|
203
|
+
void QueueManager_command_id_init()
|
204
|
+
{
|
205
|
+
#{str_id_init}
|
206
|
+
}
|
207
|
+
|
208
|
+
MQLONG wmq_command_lookup(ID command_id)
|
209
|
+
{
|
210
|
+
MQLONG command = 0;
|
211
|
+
#{str_if}
|
212
|
+
else
|
213
|
+
{
|
214
|
+
rb_raise(rb_eArgError, "WMQ::QueueManager#execute [wmq_command_lookup] Unknown command supplied");
|
215
|
+
}
|
216
|
+
|
217
|
+
return command;
|
218
|
+
}
|
219
|
+
END_OF_STRING
|
220
|
+
str
|
221
|
+
end
|
222
|
+
|
223
|
+
def self.generate(path)
|
224
|
+
File.open('wmq_reason.c', 'w') {|file| file.write(GenerateReason.wmq_reason(path))}
|
225
|
+
puts 'Generated wmq_reason.c'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
if $0 == __FILE__
|
230
|
+
path = ARGV[0] || raise("Mandatory parameter: 'WebSphere MQ Include path' is missing")
|
231
|
+
path = path + '/'
|
232
|
+
GenerateReason.generate(path)
|
233
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
class GenerateStructs
|
4
|
+
|
5
|
+
@@field_ignore_list = [ 'StrucId', 'Version' , 'StrucLength']
|
6
|
+
|
7
|
+
# Store path to WebSphere MQ Structures
|
8
|
+
def initialize(wmq_includepath, templates_path='.')
|
9
|
+
@path = wmq_includepath
|
10
|
+
@templates_path = templates_path
|
11
|
+
end
|
12
|
+
|
13
|
+
def extract_struct (filename, struct_name)
|
14
|
+
properties_list = []
|
15
|
+
line_number = 0
|
16
|
+
found = false
|
17
|
+
File.open(filename) do |file|
|
18
|
+
file.each do |line|
|
19
|
+
line_number += 1
|
20
|
+
line.rstrip!
|
21
|
+
# Skip empty and comment lines
|
22
|
+
if line.length > 0 && line !~ /^\s*\/\*/
|
23
|
+
if !found
|
24
|
+
found = true if line =~ /^\s*struct\s*tag#{struct_name}/
|
25
|
+
else
|
26
|
+
return(properties_list) if line =~ /^\s*\};/
|
27
|
+
match = /\s*(MQ\w+)\s+(\w+);/.match(line)
|
28
|
+
if match
|
29
|
+
type = match[1]
|
30
|
+
element = match[2]
|
31
|
+
properties_list.push([type, element])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
properties_list
|
38
|
+
end
|
39
|
+
|
40
|
+
def rubyize_name(name)
|
41
|
+
name.gsub(/::/, '/').
|
42
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
43
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
44
|
+
tr("-", "_").
|
45
|
+
downcase
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.test_rubyize_name
|
49
|
+
test = self.new
|
50
|
+
[['a', 'a'],
|
51
|
+
['A', 'a'],
|
52
|
+
['Aa', 'aa'],
|
53
|
+
['AA', 'aa'],
|
54
|
+
['AaA', 'aa_a'],
|
55
|
+
['MyFieldName', 'my_field_name'],
|
56
|
+
['MMyFieldNName', 'm_my_field_n_name'],
|
57
|
+
['ABCdefGHIjKlMnOPQrSTuvwxYz', 'ab_cdef_gh_ij_kl_mn_op_qr_s_tuvwx_yz']
|
58
|
+
].each do |item|
|
59
|
+
str = test.rubyize_name(item[0])
|
60
|
+
raise("rubyize_name('#{item[0]}') == #{str} != '#{item[1]})") if str != item[1]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_structs(erb)
|
65
|
+
erb.result(binding)
|
66
|
+
end
|
67
|
+
|
68
|
+
def generate(target_filename = 'wmq_structs.c')
|
69
|
+
erb = nil
|
70
|
+
File.open(@templates_path+'/wmq_structs.erb') { |file| erb = ERB.new(file.read) }
|
71
|
+
File.open(target_filename, 'w') {|file| file.write(generate_structs(erb)) }
|
72
|
+
puts "Generated #{target_filename}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# TODO Auto Daisy-Chain Headers: Format, CodedCharSetId, Encoding
|
77
|
+
# TODO During Deblock validate that data size left at least matches struct size
|
78
|
+
if $0 == __FILE__
|
79
|
+
path = ARGV[0] || raise("Mandatory parameter: 'WebSphere MQ Include path' is missing")
|
80
|
+
path = path + '/'
|
81
|
+
GenerateStructs.new(path, 'generate').generate
|
82
|
+
end
|