rubywmq 0.3.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.
@@ -0,0 +1,3 @@
1
+ call "C:\Program Files\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"
2
+ ruby extconf.rb --with-mqm-include="C:\Program Files\IBM\WebSphere MQ\Tools\c\include"
3
+ nmake
@@ -0,0 +1,5 @@
1
+ ruby extconf.rb --with-mqm-include=/opt/mqm/inc --with-mqm-lib=/opt/mqm/lib
2
+ make
3
+ # Uncomment the following lines for platforms other than Solaris, Windows and Linux
4
+ #ruby extconf_client.rb --with-mqm-include=/opt/mqm/inc --with-mqm-lib=/opt/mqm/lib
5
+ #make
@@ -0,0 +1,348 @@
1
+ /*
2
+ * Copyright 2007 Edwin M. Fine, Fine Computer Consultants, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0
5
+ * (the "License"); you may not use this file except
6
+ * in compliance with the License. You may obtain a copy
7
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ * Unless required by applicable law or agreed to in writing,
9
+ * software distributed under the License is distributed on an
10
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ * either express or implied. See the License for the specific
12
+ * language governing permissions and limitations under the License.
13
+ */
14
+
15
+ /*
16
+ * This function decodes an RFH NameValueString into separate
17
+ * name/value strings and invokes a callback function for each
18
+ * name/value pair. The callback function prototype is
19
+ *
20
+ * void cbfunc(const char *name, const char *value);
21
+ *
22
+ * Strings are expected to be null-terminated and not contain any
23
+ * null characters.
24
+ *
25
+ * This is the specification for NameValueString:
26
+ *
27
+ * NameValueString (MQCHARn)
28
+ *
29
+ * String containing name/value pairs.
30
+ *
31
+ * This is a variable-length character string containing name/value
32
+ * pairs in the form:
33
+ *
34
+ * name1 value1 name2 value2 name3 value3 ...
35
+ *
36
+ * Each name or value must be separated from the adjacent name
37
+ * or value by one or more blank characters; these blanks are
38
+ * not significant. A name or value can contain significant
39
+ * blanks by prefixing and suffixing the name or value with the
40
+ * double-quote character; all characters between the open
41
+ * double-quote and the matching close double-quote are treated
42
+ * as significant. In the following example, the name is
43
+ * FAMOUS_WORDS, and the value is Hello World:
44
+ *
45
+ * FAMOUS_WORDS "Hello World"
46
+ *
47
+ * A name or value can contain any characters other than the
48
+ * null character (which acts as a delimiter for
49
+ * NameValueString). However, to assist interoperability, an
50
+ * application might prefer to restrict names to the following
51
+ * characters:
52
+ *
53
+ * * First character: upper case or lower case alphabetic (A
54
+ * through Z, or a through z), or underscore.
55
+ *
56
+ * * Second character: upper case or lower case alphabetic,
57
+ * decimal digit (0 through 9), underscore, hyphen, or
58
+ * dot.
59
+ *
60
+ * If a name or value contains one or more double-quote
61
+ * characters, the name or value must be enclosed in double
62
+ * quotes, and each double quote within the string must be
63
+ * doubled, for example:
64
+ *
65
+ * Famous_Words "The program displayed ""Hello World"""
66
+ *
67
+ * Names and values are case sensitive, that is, lowercase
68
+ * letters are not considered to be the same as uppercase
69
+ * letters. For example, FAMOUS_WORDS and Famous_Words are two
70
+ * different names. / The length in bytes of NameValueString is
71
+ * equal to StrucLength minus MQRFH_STRUC_LENGTH_FIXED. To avoid
72
+ * problems with data conversion of the user data in some
73
+ * environments, make sure that this length is a multiple of
74
+ * four. NameValueString must be padded with blanks to this
75
+ * length, or terminated earlier by placing a null character
76
+ * following the last value in the string. The null and bytes
77
+ * following it, up to the specified length of NameValueString,
78
+ * are ignored.
79
+ */
80
+
81
+ #include "decode_rfh.h"
82
+ #include <stdio.h>
83
+
84
+ #define MAX_TOK_LEN 1024 /* This is pretty generous */
85
+ #define EOS -1 /* End of input string */
86
+ #define QUOTE '"'
87
+
88
+ #define IS_SEPARATOR(ch) ((ch) == ' ' || (ch) == '\0')
89
+ #define IS_VALID_ID_CHAR(ch) (!IS_SEPARATOR(ch))
90
+ #define IS_UNQUOTED_ID_CHAR(ch) (!IS_SEPARATOR(ch) && ch != QUOTE)
91
+ #define GETCHAR(charp, endp) ((charp) < (endp) ? (int)*charp++ : EOS)
92
+ #define LOOKAHEAD(charp, endp) (charp < endp - 1 ? (int)*charp : EOS)
93
+ #define PUSHBACK(ch, charp) (*--charp = (char)ch)
94
+
95
+ #define SKIP_SEPARATORS(charp, endp) \
96
+ while (charp < endp && IS_SEPARATOR(*charp)) ++charp
97
+
98
+ typedef enum {
99
+ ST_INITIAL,
100
+ ST_IN_QUOTED_ID,
101
+ ST_IN_UNQUOTED_ID,
102
+ ST_END,
103
+ } state_t;
104
+
105
+ static int debug_mode = 0;
106
+
107
+ int rfh_in_debug_mode(void)
108
+ {
109
+ return debug_mode;
110
+ }
111
+
112
+ void rfh_set_debug_mode(int on_if_true)
113
+ {
114
+ debug_mode = on_if_true;
115
+ }
116
+
117
+ #define ENUM_TUPLE(enum_val) { enum_val, #enum_val }
118
+ #define NUM_ELEMS(arr) (sizeof(arr) / sizeof(*arr))
119
+
120
+ static const char *rfh_state_to_s(state_t state)
121
+ {
122
+ static struct
123
+ {
124
+ state_t state;
125
+ const char *str;
126
+ } state_map[] =
127
+ {
128
+ ENUM_TUPLE(ST_INITIAL),
129
+ ENUM_TUPLE(ST_IN_QUOTED_ID),
130
+ ENUM_TUPLE(ST_IN_UNQUOTED_ID),
131
+ ENUM_TUPLE(ST_END),
132
+ };
133
+
134
+ size_t i;
135
+
136
+ for (i = 0; i < NUM_ELEMS(state_map); ++i)
137
+ if (state_map[i].state == state)
138
+ return state_map[i].str;
139
+
140
+ return "";
141
+ }
142
+
143
+ const char *rfh_toktype_to_s(rfh_toktype_t toktype)
144
+ {
145
+ static struct
146
+ {
147
+ rfh_toktype_t toktype;
148
+ const char *str;
149
+ } toktype_map[] =
150
+ {
151
+ ENUM_TUPLE(TT_TOKEN),
152
+ ENUM_TUPLE(TT_UNESCAPED_QUOTE),
153
+ ENUM_TUPLE(TT_ILLEGAL_QUOTE),
154
+ ENUM_TUPLE(TT_UNEXPECTED_EOS),
155
+ ENUM_TUPLE(TT_TOKEN_TRUNCATED),
156
+ ENUM_TUPLE(TT_INTERNAL_ERROR),
157
+ ENUM_TUPLE(TT_ALLOC_FAILURE),
158
+ ENUM_TUPLE(TT_END),
159
+ };
160
+
161
+ size_t i;
162
+
163
+ for (i = 0; i < NUM_ELEMS(toktype_map); ++i)
164
+ if (toktype_map[i].toktype == toktype)
165
+ return toktype_map[i].str;
166
+
167
+ return "";
168
+ }
169
+
170
+ static rfh_toktype_t get_token(const char **charpp, const char *endp, char *token, char *end_token)
171
+ {
172
+ const char *charp = *charpp;
173
+ char *tokp = token;
174
+ int ch;
175
+ state_t state = ST_INITIAL;
176
+ rfh_toktype_t toktype = TT_TOKEN;
177
+
178
+ SKIP_SEPARATORS(charp, endp);
179
+
180
+ while (state != ST_END && tokp < end_token)
181
+ {
182
+ ch = GETCHAR(charp, endp);
183
+
184
+ if (debug_mode)
185
+ fprintf(stderr, "state = %s, char = %c [%d]\n", rfh_state_to_s(state), (char)ch, ch);
186
+
187
+ switch (state)
188
+ {
189
+ case ST_INITIAL:
190
+ if (ch == EOS)
191
+ {
192
+ *tokp = '\0';
193
+ toktype = TT_END;
194
+ state = ST_END;
195
+ if (debug_mode)
196
+ fprintf(stderr, "new state = %s, toktype = %s\n",
197
+ rfh_state_to_s(state), rfh_toktype_to_s(toktype));
198
+ }
199
+ else if (IS_UNQUOTED_ID_CHAR(ch))
200
+ {
201
+ *tokp++ = (char)ch;
202
+ state = ST_IN_UNQUOTED_ID;
203
+ if (debug_mode)
204
+ fprintf(stderr, "new state = %s\n", rfh_state_to_s(state));
205
+ }
206
+ else if (ch == QUOTE)
207
+ {
208
+ state = ST_IN_QUOTED_ID;
209
+ if (debug_mode)
210
+ fprintf(stderr, "new state = %s\n", rfh_state_to_s(state));
211
+ }
212
+ break;
213
+
214
+ case ST_IN_UNQUOTED_ID:
215
+ if (IS_SEPARATOR(ch) || ch == EOS)
216
+ {
217
+ *tokp = '\0';
218
+ state = ST_END;
219
+ if (debug_mode)
220
+ fprintf(stderr, "new state = %s\n", rfh_state_to_s(state));
221
+ }
222
+ else if (ch == QUOTE) /* Not allowed in unquoted string */
223
+ {
224
+ toktype = TT_ILLEGAL_QUOTE;
225
+ state = ST_END;
226
+ if (debug_mode)
227
+ fprintf(stderr, "new state = %s, toktype = %s\n",
228
+ rfh_state_to_s(state), rfh_toktype_to_s(toktype));
229
+ }
230
+ else
231
+ *tokp++ = (char)ch;
232
+ break;
233
+
234
+ case ST_IN_QUOTED_ID:
235
+ if (ch == QUOTE) /* Could be end of token, or first char of "" */
236
+ {
237
+ int lookahead_ch = LOOKAHEAD(charp, endp);
238
+ if (lookahead_ch == QUOTE) /* Found escaped quote */
239
+ {
240
+ *tokp++ = QUOTE;
241
+ ++charp; /* Skip second quote */
242
+ }
243
+ else if (IS_SEPARATOR(lookahead_ch) || lookahead_ch == EOS) /* End of token */
244
+ {
245
+ *tokp = '\0';
246
+ state = ST_END;
247
+ if (debug_mode)
248
+ fprintf(stderr, "new state = %s\n", rfh_state_to_s(state));
249
+ }
250
+ else /* Error: Unescaped quote */
251
+ {
252
+ toktype = TT_UNESCAPED_QUOTE;
253
+ state = ST_END;
254
+ if (debug_mode)
255
+ fprintf(stderr, "new state = %s, toktype = %s\n",
256
+ rfh_state_to_s(state), rfh_toktype_to_s(toktype));
257
+ }
258
+ }
259
+ else if (ch == EOS) /* Error */
260
+ {
261
+ toktype = TT_UNEXPECTED_EOS;
262
+ state = ST_END;
263
+ if (debug_mode)
264
+ fprintf(stderr, "new state = %s, toktype = %s\n",
265
+ rfh_state_to_s(state), rfh_toktype_to_s(toktype));
266
+ }
267
+ else
268
+ *tokp++ = (char)ch;
269
+ break;
270
+
271
+ default:
272
+ toktype = TT_INTERNAL_ERROR;
273
+ state = ST_END;
274
+ if (debug_mode)
275
+ fprintf(stderr, "new state = %s, toktype = %s\n",
276
+ rfh_state_to_s(state), rfh_toktype_to_s(toktype));
277
+ break;
278
+ } /* switch */
279
+ } /* while */
280
+
281
+ /* If state is not ST_END, an error may have occurred */
282
+ if (state != ST_END && toktype == TT_TOKEN)
283
+ {
284
+ if (tokp >= end_token)
285
+ toktype = TT_TOKEN_TRUNCATED;
286
+ else
287
+ toktype = TT_UNEXPECTED_EOS;
288
+
289
+ if (debug_mode)
290
+ fprintf(stderr, "end state = %s, toktype = %s\n",
291
+ rfh_state_to_s(state), rfh_toktype_to_s(toktype));
292
+ }
293
+
294
+ *charpp = charp;
295
+
296
+ if (debug_mode)
297
+ fprintf(stderr, "-- leaving; end state = %s, returned toktype = %s, returned token = [%s]\n",
298
+ rfh_state_to_s(state), rfh_toktype_to_s(toktype), token);
299
+
300
+ return toktype;
301
+ }
302
+
303
+ rfh_toktype_t rfh_decode_name_val_str(const char *nvstr, size_t len, CALLBACK_FN callback, void *user_data)
304
+ {
305
+ #if defined(USE_FIXED_BUFFERS)
306
+ char name[MAX_TOK_LEN + 1];
307
+ char value[MAX_TOK_LEN + 1];
308
+ size_t name_len = sizeof(name);
309
+ size_t value_len = sizeof(value);
310
+ #else
311
+ size_t name_len = len + 1;
312
+ size_t value_len = len + 1;
313
+ char *buf = (char *)malloc(len * 2 * sizeof(char) + 2);
314
+ char *name = buf;
315
+ char *value = buf + len + 1;
316
+ #endif
317
+
318
+ const char *charp = nvstr, *endp = nvstr + len;
319
+ rfh_toktype_t toktype;
320
+
321
+ #if !defined(USE_FIXED_BUFFERS)
322
+ if (buf == NULL) /* Out of mem */
323
+ return TT_ALLOC_FAILURE;
324
+ #endif
325
+
326
+ for (;;)
327
+ {
328
+ if ((toktype = get_token(&charp, endp, name, name + name_len)) != TT_TOKEN)
329
+ {
330
+ break;
331
+ }
332
+
333
+ if ((toktype = get_token(&charp, endp, value, value + value_len)) != TT_TOKEN)
334
+ {
335
+ if (toktype == TT_END) /* Expected a value! */
336
+ toktype = TT_UNEXPECTED_EOS;
337
+ break;
338
+ }
339
+
340
+ callback(name, value, user_data);
341
+ }
342
+
343
+ #if !defined(USE_FIXED_BUFFERS)
344
+ free(buf);
345
+ #endif
346
+
347
+ return toktype;
348
+ }
@@ -0,0 +1,45 @@
1
+ /*
2
+ * Copyright 2007 Edwin M. Fine, Fine Computer Consultants, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0
5
+ * (the "License"); you may not use this file except
6
+ * in compliance with the License. You may obtain a copy
7
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ * Unless required by applicable law or agreed to in writing,
9
+ * software distributed under the License is distributed on an
10
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11
+ * either express or implied. See the License for the specific
12
+ * language governing permissions and limitations under the License.
13
+ */
14
+ #if !defined(DECODE_RFH_INCLUDED)
15
+ #define DECODE_RFH_INCLUDED
16
+
17
+ #include <stdlib.h> /* For size_t */
18
+
19
+ typedef void (*CALLBACK_FN)(const char *name, const char *value, void *user_data);
20
+
21
+ typedef enum {
22
+ TT_TOKEN,
23
+ TT_UNESCAPED_QUOTE, /* '"' not followed by '"' in quoted string */
24
+ TT_ILLEGAL_QUOTE, /* '"' in unquoted string */
25
+ TT_UNEXPECTED_EOS,
26
+ TT_TOKEN_TRUNCATED, /* Token buffer too short to receive full token */
27
+ TT_INTERNAL_ERROR,
28
+ TT_ALLOC_FAILURE,
29
+ TT_END
30
+ } rfh_toktype_t;
31
+
32
+ /* Returns TT_END on success, other on error */
33
+ rfh_toktype_t
34
+ rfh_decode_name_val_str(const char *nvstr,
35
+ size_t len,
36
+ CALLBACK_FN callback,
37
+ void *user_data);
38
+
39
+ /* Translates toktype_t to string */
40
+ const char *rfh_toktype_to_s(rfh_toktype_t toktype);
41
+
42
+ int rfh_in_debug_mode(void);
43
+ void rfh_set_debug_mode(int on_if_true);
44
+
45
+ #endif
@@ -0,0 +1,44 @@
1
+ ################################################################################
2
+ # Copyright 2006 J. Reid Morrison. Dimension Solutions, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ ################################################################################
16
+
17
+ require 'mkmf'
18
+ require 'generate/generate_reason'
19
+ require 'generate/generate_const'
20
+ require 'generate/generate_structs'
21
+
22
+ include_path = ''
23
+ if RUBY_PLATFORM =~ /mswin32/
24
+ include_path = 'C:\Program Files\IBM\WebSphere MQ\Tools\c\include'
25
+ dir_config('mqm', include_path, '.')
26
+ else
27
+ include_path = '/opt/mqm/inc'
28
+ dir_config('mqm', include_path, '/opt/mqm/lib')
29
+ end
30
+
31
+ have_header('cmqc.h')
32
+
33
+ # Check for WebSphere MQ Server library
34
+ unless (RUBY_PLATFORM =~ /win/i) || (RUBY_PLATFORM =~ /solaris/i) || (RUBY_PLATFORM =~ /linux/i)
35
+ have_library('mqm')
36
+ end
37
+
38
+ # Generate Source Files
39
+ GenerateReason.generate(include_path+'/')
40
+ GenerateConst.generate(include_path+'/', 'lib')
41
+ GenerateStructs.new(include_path+'/', 'generate').generate
42
+
43
+ # Generate Makefile
44
+ create_makefile('wmq/wmq')