This repository has been archived by the owner on Jan 30, 2020. It is now read-only.
/
generate_reason.rb
231 lines (210 loc) · 7.07 KB
/
generate_reason.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
class GenerateReason
# Extract Error Code Constants from Header files
def GenerateReason.extract_const(filename, const_prefix)
constants = []
File.open(filename) do |file|
file.each do |line|
line.rstrip!
# Skip empty and comment lines
if line.length > 0 && line !~ /^\s*\/\*/
if match = /\s*#define\s+(#{const_prefix}\w+)[\(\s]+([-\dx]+)/.match(line)
constants << [match[1], match[2]]
end
end
end
end
constants
end
# Extract Error Code Constants from Header files
# Uses lazy print to collect duplicate values
def GenerateReason.reason_case(filename, prefix)
last_rc = nil
last_reason = nil
str = ''
GenerateReason.extract_const(filename, prefix).each do |item|
if last_rc == item[1]
str << " case %-30s: return \"#{item[0]} or #{last_reason}[#{item[1]}]\";\n" % item[0]
last_rc = nil
last_reason = nil
else
str << " case %-30s: return \"#{last_reason}[#{last_rc}]\";\n" % last_reason if last_rc
last_rc = item[1]
last_reason = item[0]
end
end
str
end
# The WebSphere MQ header files have several duplicate values,
# so need to exclude duplicates.
def GenerateReason.selector_case(filename, prefix, excludes=nil, &block)
GenerateReason.extract_const(filename, prefix).each do |item|
next if item[0].include?('FIRST') || item[0].include?('LAST')
next if excludes && excludes.include?(item[0])
block.call item
end
end
def GenerateReason.wmq_reason(path)
str = <<END_OF_STRING
/* --------------------------------------------------------------------------
*
* WARNING: DO NOT MODIFY THIS FILE
*
* This file was generated by generate_reason.rb.
*
* --------------------------------------------------------------------------*/
#include "wmq.h"
char* wmq_reason(MQLONG reason_code)
{
switch (reason_code)
{
END_OF_STRING
[
['cmqc.h', 'MQRC_'],
['cmqcfc.h', 'MQRCCF_']
].each do |item|
str << GenerateReason.reason_case(path+item[0], item[1])
end
str << <<END_OF_STRING
}
printf("WMQ::wmq_reason Unknown Reason code:%ld\\n",(long)reason_code);
return "Unknown reason code";
}
END_OF_STRING
str_switch = ''
str_id_init = ''
values = []
# Integer Selectors for Object Attributes
[
['cmqc.h', 'MQIA_'],
['cmqcfc.h', 'MQIACF_', ['MQIACF_ERROR_ID', 'MQIACF_QUIESCE']],
['cmqcfc.h', 'MQIACH_', ['MQIACH_CURRENT_SEQ_NUMBER', 'MQIACH_BYTES_RCVD', 'MQIACH_BUFFERS_RCVD', 'MQIACH_MSGS_RCVD']],
['cmqcfc.h', 'MQIAMO_'],
['cmqcfc.h', 'MQIAMO64_', ['MQIAMO64_AVG_Q_TIME', 'MQIAMO64_Q_TIME_AVG', 'MQIAMO64_Q_TIME_MAX', 'MQIAMO64_Q_TIME_MIN']],
# Integer System Selectors
['cmqbc.h', 'MQIASY_'],
# Character Selectors for Object Attributes
['cmqc.h', 'MQCA_', ['MQCA_BASE_OBJECT_NAME']],
['cmqcfc.h', 'MQCACF_'],
['cmqcfc.h', 'MQCACH_'],
['cmqcfc.h', 'MQCAMO_'],
# Byte String Selectors for Object Attributes
['cmqc.h', 'MQBA_'],
['cmqcfc.h', 'MQBACF_'],
# Group Selectors for Object Attributes
['cmqcfc.h', 'MQGACF_']
].each do |item|
str << "/* Constants #{item[1]}* from #{item[0]} */\n"
str_switch << " /* Constants #{item[1]}* from #{item[0]} */\n"
str_id_init << " /* Constants #{item[1]}* from #{item[0]} */\n"
GenerateReason.selector_case(path+item[0], item[1], item[2]) do |const|
id = const[0].gsub(item[1], '').downcase
# Ignore duplicate values
unless values.include?(const[1])
str_switch << " case %-30s: return ID_#{id};\n" % const[0]
values << const[1]
end
str_id_init << " ID_%-25s = rb_intern(\"#{id}\");\n" % id
str << "static ID ID_#{id};\n"
end
end
str << <<END_OF_STRING
void QueueManager_selector_id_init()
{
#{str_id_init}
}
ID wmq_selector_id(MQLONG selector)
{
switch (selector)
{
#{str_switch}
}
printf("WMQ::wmq_select_text Unknown Selector:%ld\\n",(long)selector);
return rb_intern("unknown_selector_code");
}
void wmq_selector(ID selector_id, PMQLONG selector_type, PMQLONG selector)
{
*selector_type = MQIT_INTEGER;
END_OF_STRING
first = true
str_if = ''
str_id_init = ''
# Integer Selectors for Object Attributes
[
['cmqc.h', 'MQIA_'],
['cmqcfc.h', 'MQIACF_', ['MQIACF_ERROR_ID', 'MQIACF_QUIESCE']],
['cmqcfc.h', 'MQIACH_', ['MQIACH_CURRENT_SEQ_NUMBER', 'MQIACH_BYTES_RCVD', 'MQIACH_BUFFERS_RCVD']],
['cmqcfc.h', 'MQIAMO_'],
['cmqcfc.h', 'MQIAMO64_', ['MQIAMO64_AVG_Q_TIME', 'MQIAMO64_Q_TIME_AVG', 'MQIAMO64_Q_TIME_MAX', 'MQIAMO64_Q_TIME_MIN']],
# Integer System Selectors
# ['cmqbc.h', 'MQIASY_'],
].each do |item|
str << " /* Constants #{item[1]}* from #{item[0]} */\n"
GenerateReason.selector_case(path+item[0], item[1], item[2]) do |const|
str << " if(selector_id == %-32s{ *selector = #{const[0]}; return;}\n" % "ID_#{const[0].gsub(item[1], '').downcase})"
end
end
str << "\n *selector_type = MQIT_STRING;\n\n"
# Character Selectors for Object Attributes
[
['cmqc.h', 'MQCA_', ['MQCA_BASE_OBJECT_NAME']],
['cmqcfc.h', 'MQCACF_'],
['cmqcfc.h', 'MQCACH_'],
['cmqcfc.h', 'MQCAMO_'],
# Byte String Selectors for Object Attributes
# ['cmqc.h', 'MQBA_'],
# ['cmqcfc.h', 'MQBACF_'],
# Group Selectors for Object Attributes
# ['cmqcfc.h', 'MQGACF_']
].each do |item|
str << " /* Constants #{item[1]}* from #{item[0]} */\n"
GenerateReason.selector_case(path+item[0], item[1], item[2]) do |const|
str << " if(selector_id == %-32s{ *selector = #{const[0]}; return;}\n" % "ID_#{const[0].gsub(item[1], '').downcase})"
end
end
str << <<END_OF_STRING
rb_raise(rb_eArgError, "WMQ::QueueManager#execute [wmq_selector] Unknown selector supplied");
}
END_OF_STRING
first = true
str_if = ''
str_id_init = ''
GenerateReason.selector_case(path+'cmqcfc.h', 'MQCMD_') do |const|
if first
first = false
str_if << ' '
else
str_if << ' else '
end
id = const[0].gsub('MQCMD_', '').downcase
str_id_init << " ID_%-25s = rb_intern(\"#{id}\");\n" % id
str_if << "if(command_id == %-28s{ command = #{const[0]}; }\n" % "ID_#{const[0].gsub('MQCMD_', '').downcase})"
str << "static ID ID_#{id};\n"
end
str << <<END_OF_STRING
void QueueManager_command_id_init()
{
#{str_id_init}
}
MQLONG wmq_command_lookup(ID command_id)
{
MQLONG command = 0;
#{str_if}
else
{
rb_raise(rb_eArgError, "WMQ::QueueManager#execute [wmq_command_lookup] Unknown command supplied");
}
return command;
}
END_OF_STRING
str
end
def self.generate(path)
File.open('wmq_reason.c', 'w') { |file| file.write(GenerateReason.wmq_reason(path)) }
puts 'Generated wmq_reason.c'
end
end
if $0 == __FILE__
path = ARGV[0] || raise("Mandatory parameter: 'WebSphere MQ Include path' is missing")
path = path + '/'
GenerateReason.generate(path)
end