rubywmq 2.0.2 → 2.1.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.
- checksums.yaml +4 -4
- data/Gemfile +10 -0
- data/Gemfile.lock +37 -0
- data/LICENSE.txt +1 -1
- data/README.md +29 -47
- data/Rakefile +12 -76
- data/examples/each_a.rb +2 -3
- data/examples/each_b.rb +4 -5
- data/examples/each_header.rb +5 -6
- data/examples/files_to_q.rb +7 -8
- data/examples/get_a.rb +3 -5
- data/examples/get_client.rb +9 -10
- data/examples/put1_a.rb +2 -3
- data/examples/put1_b.rb +4 -7
- data/examples/put1_c.rb +6 -6
- data/examples/put_a.rb +0 -2
- data/examples/put_b.rb +5 -7
- data/examples/put_dlh.rb +11 -12
- data/examples/put_dynamic_q.rb +7 -7
- data/examples/put_group_a.rb +3 -4
- data/examples/put_group_b.rb +7 -7
- data/examples/put_rfh.rb +13 -11
- data/examples/put_rfh2_a.rb +9 -10
- data/examples/put_rfh2_b.rb +9 -9
- data/examples/put_xmit_q.rb +63 -8
- data/examples/q_to_files.rb +6 -7
- data/examples/request.rb +20 -18
- data/examples/server.rb +19 -16
- data/ext/extconf.rb +2 -1
- data/ext/extconf_client.rb +3 -3
- data/ext/generate/generate_const.rb +30 -23
- data/ext/generate/generate_reason.rb +70 -72
- data/ext/generate/generate_structs.rb +20 -19
- data/ext/generate/wmq_structs.erb +67 -67
- data/ext/wmq.c +0 -16
- data/ext/wmq.h +0 -16
- data/ext/wmq_message.c +8 -24
- data/ext/wmq_mq_load.c +5 -17
- data/ext/wmq_queue.c +73 -90
- data/ext/wmq_queue_manager.c +115 -108
- data/lib/wmq/message.rb +36 -34
- data/lib/wmq/queue_manager.rb +22 -19
- data/lib/wmq/version.rb +1 -1
- data/rubywmq.gemspec +38 -0
- data/test/queue_manager_test.rb +334 -0
- data/test/test_helper.rb +14 -0
- metadata +16 -26
- data/tests/test.rb +0 -318
    
        data/examples/q_to_files.rb
    CHANGED
    
    | @@ -1,7 +1,6 @@ | |
| 1 1 | 
             
            #
         | 
| 2 2 | 
             
            # Example: q_to_files:  Copy all messages in a queue to separate files in a directory
         | 
| 3 3 | 
             
            #
         | 
| 4 | 
            -
            require 'rubygems'
         | 
| 5 4 | 
             
            require 'find'
         | 
| 6 5 | 
             
            require 'yaml'
         | 
| 7 6 | 
             
            require 'wmq'
         | 
| @@ -9,22 +8,22 @@ require 'fileutils' | |
| 9 8 |  | 
| 10 9 | 
             
            # Call program passing environment name as first parameter
         | 
| 11 10 | 
             
            #   The environment corresponds to an entry in the config file
         | 
| 12 | 
            -
            env | 
| 11 | 
            +
            env    = ARGV[0] || raise("Command line argument 'environment' is required")
         | 
| 13 12 | 
             
            config = YAML::load_file('q_to_files.cfg')[env]
         | 
| 14 13 |  | 
| 15 14 | 
             
            # Create supplied path if it does not exist
         | 
| 16 | 
            -
            path | 
| 15 | 
            +
            path   = config['target_directory']
         | 
| 17 16 | 
             
            FileUtils.mkdir_p(path)
         | 
| 18 17 |  | 
| 19 | 
            -
            message | 
| 18 | 
            +
            message            = WMQ::Message.new
         | 
| 20 19 | 
             
            message.descriptor = config['descriptor'] || {}
         | 
| 21 | 
            -
            tstart | 
| 22 | 
            -
            counter | 
| 20 | 
            +
            tstart             = Time.now
         | 
| 21 | 
            +
            counter            = 0
         | 
| 23 22 | 
             
            WMQ::QueueManager.connect(config['qmgr_options']) do |qmgr|
         | 
| 24 23 | 
             
              qmgr.open_queue(config['input_queue']) do |queue|
         | 
| 25 24 | 
             
                queue.each do |message|
         | 
| 26 25 | 
             
                  counter = counter + 1
         | 
| 27 | 
            -
                  File.open(File.join(path, "message_%03d" % counter), 'w') {|file| file.write(message.data) }
         | 
| 26 | 
            +
                  File.open(File.join(path, "message_%03d" % counter), 'w') { |file| file.write(message.data) }
         | 
| 28 27 | 
             
                end
         | 
| 29 28 | 
             
              end
         | 
| 30 29 | 
             
            end
         | 
    
        data/examples/request.rb
    CHANGED
    
    | @@ -6,39 +6,41 @@ | |
| 6 6 | 
             
            #
         | 
| 7 7 | 
             
            #          A temporary Dynamic Reply To Queue is used with non-persistent messaging
         | 
| 8 8 | 
             
            #
         | 
| 9 | 
            -
            require 'rubygems'
         | 
| 10 9 | 
             
            require 'wmq'
         | 
| 11 10 |  | 
| 12 11 | 
             
            wait_seconds = 30
         | 
| 13 12 |  | 
| 14 | 
            -
            WMQ::QueueManager.connect(: | 
| 15 | 
            -
              qmgr.open_queue( | 
| 16 | 
            -
             | 
| 17 | 
            -
             | 
| 18 | 
            -
             | 
| 13 | 
            +
            WMQ::QueueManager.connect(q_mgr_name: 'REID') do |qmgr|
         | 
| 14 | 
            +
              qmgr.open_queue(
         | 
| 15 | 
            +
                q_name:         'SYSTEM.DEFAULT.MODEL.QUEUE',
         | 
| 16 | 
            +
                dynamic_q_name: 'REQUEST.*',
         | 
| 17 | 
            +
                mode:           :input
         | 
| 18 | 
            +
              ) do |reply_queue|
         | 
| 19 19 |  | 
| 20 | 
            -
                message | 
| 21 | 
            -
                message.descriptor = { | 
| 22 | 
            -
             | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
             | 
| 20 | 
            +
                message            = WMQ::Message.new()
         | 
| 21 | 
            +
                message.descriptor = {
         | 
| 22 | 
            +
                  msg_type:       WMQ::MQMT_REQUEST,
         | 
| 23 | 
            +
                  reply_to_q:     reply_queue.name,
         | 
| 24 | 
            +
                  reply_to_q_mgr: qmgr.name,
         | 
| 25 | 
            +
                  format:         WMQ::MQFMT_STRING,
         | 
| 26 | 
            +
                  expiry:         wait_seconds*10 # Measured in tenths of a second
         | 
| 27 | 
            +
                }
         | 
| 28 | 
            +
                message.data       = 'Hello World'
         | 
| 27 29 |  | 
| 28 30 | 
             
                # Send request message
         | 
| 29 | 
            -
                qmgr.put(: | 
| 31 | 
            +
                qmgr.put(q_name: 'TEST.QUEUE', message: message)
         | 
| 30 32 |  | 
| 31 33 | 
             
                # Copy outgoing Message id to correlation id
         | 
| 32 | 
            -
                message.descriptor[:correl_id]=message.descriptor[:msg_id]
         | 
| 34 | 
            +
                message.descriptor[:correl_id] = message.descriptor[:msg_id]
         | 
| 33 35 |  | 
| 34 36 | 
             
                # Wait for reply
         | 
| 35 37 | 
             
                #   Only get the message that matches the correlation id set above
         | 
| 36 | 
            -
                if reply_queue.get(: | 
| 37 | 
            -
                  puts  | 
| 38 | 
            +
                if reply_queue.get(wait: wait_seconds * 1000, message: message, match: WMQ::MQMO_MATCH_CORREL_ID)
         | 
| 39 | 
            +
                  puts 'Received:'
         | 
| 38 40 | 
             
                  puts message.data
         | 
| 39 41 | 
             
                else
         | 
| 40 42 | 
             
                  # get returns false when no message received. Also: message.data = nil
         | 
| 41 | 
            -
                  puts  | 
| 43 | 
            +
                  puts 'Timed Out waiting for a reply from the server'
         | 
| 42 44 | 
             
                end
         | 
| 43 45 | 
             
              end
         | 
| 44 46 | 
             
            end
         | 
    
        data/examples/server.rb
    CHANGED
    
    | @@ -3,12 +3,12 @@ | |
| 3 3 | 
             
            #
         | 
| 4 4 | 
             
            #     This server times out after 60 seconds, but could be modified to
         | 
| 5 5 | 
             
            #     run forever. Example:
         | 
| 6 | 
            -
            #         queue.each(: | 
| 6 | 
            +
            #         queue.each(wait: -1) do |message|
         | 
| 7 7 | 
             
            #
         | 
| 8 8 | 
             
            #     Note: - All calls are being performed under synchpoint control to
         | 
| 9 9 | 
             
            #             prevent messages being if the program terminates unexpectedly
         | 
| 10 10 | 
             
            #             or an error occurrs.
         | 
| 11 | 
            -
            #             Uses:  : | 
| 11 | 
            +
            #             Uses:  sync: true
         | 
| 12 12 | 
             
            #           - Queue#each will backout any message changes if an excecption is raised
         | 
| 13 13 | 
             
            #             but not handled within the each block
         | 
| 14 14 | 
             
            #
         | 
| @@ -46,31 +46,34 @@ | |
| 46 46 | 
             
            #                 - E.g. Database, File etc..
         | 
| 47 47 | 
             
            #             - etc....
         | 
| 48 48 | 
             
            #
         | 
| 49 | 
            -
            require 'rubygems'
         | 
| 50 49 | 
             
            require 'wmq'
         | 
| 51 50 |  | 
| 52 | 
            -
            WMQ::QueueManager.connect(: | 
| 53 | 
            -
              qmgr.open_queue(: | 
| 54 | 
            -
                queue.each(: | 
| 55 | 
            -
                  puts  | 
| 51 | 
            +
            WMQ::QueueManager.connect(q_mgr_name: 'REID') do |qmgr|
         | 
| 52 | 
            +
              qmgr.open_queue(q_name: 'TEST.QUEUE', mode: :input) do |queue|
         | 
| 53 | 
            +
                queue.each(wait: 60000, sync: true, convert: true) do |request|
         | 
| 54 | 
            +
                  puts 'Data Received:'
         | 
| 56 55 | 
             
                  puts request.data
         | 
| 57 56 |  | 
| 58 57 | 
             
                  begin
         | 
| 59 | 
            -
                    reply | 
| 58 | 
            +
                    reply      = WMQ::Message.new
         | 
| 60 59 | 
             
                    reply.data = 'Echo back:'+request.data
         | 
| 61 60 |  | 
| 62 | 
            -
                    qmgr.put_to_reply_q( | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 61 | 
            +
                    qmgr.put_to_reply_q(
         | 
| 62 | 
            +
                      message:         reply,
         | 
| 63 | 
            +
                      request_message: request, # Only replies if message type is request
         | 
| 64 | 
            +
                      sync:            true
         | 
| 65 | 
            +
                    )
         | 
| 65 66 |  | 
| 66 67 | 
             
                  rescue WMQ::WMQException => exc
         | 
| 67 68 | 
             
                    # Failed to send reply, put message to the Dead Letter Queue and add a dead letter header
         | 
| 68 69 | 
             
                    p exc
         | 
| 69 | 
            -
                    puts  | 
| 70 | 
            -
                    qmgr.put_to_dead_letter_q( | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 70 | 
            +
                    puts 'Failed to reply to sender, Put to dead letter queue'
         | 
| 71 | 
            +
                    qmgr.put_to_dead_letter_q(
         | 
| 72 | 
            +
                      message: request,
         | 
| 73 | 
            +
                      reason:  WMQ::MQRC_UNKNOWN_REMOTE_Q_MGR,
         | 
| 74 | 
            +
                      q_name:  queue.name,
         | 
| 75 | 
            +
                      sync:    true
         | 
| 76 | 
            +
                    )
         | 
| 74 77 | 
             
                    # If it fails to put to the dead letter queue, this program will terminate and
         | 
| 75 78 | 
             
                    # the changes will be "backed out". E.g. Queue Full, ...
         | 
| 76 79 | 
             
                  end
         | 
    
        data/ext/extconf.rb
    CHANGED
    
    | @@ -7,7 +7,8 @@ require 'generate_structs' | |
| 7 7 |  | 
| 8 8 | 
             
            include_path = ''
         | 
| 9 9 | 
             
            if RUBY_PLATFORM =~ /win|mingw/i
         | 
| 10 | 
            -
               | 
| 10 | 
            +
              x86_path     = 'C:\Program Files (x86)\IBM\WebSphere MQ\tools\c\include'
         | 
| 11 | 
            +
              include_path = File.directory?(x86_path) ? x86_path : 'C:\Program Files\IBM\WebSphere MQ\tools\c\include'
         | 
| 11 12 | 
             
              dir_config('mqm', include_path, '.')
         | 
| 12 13 | 
             
            else
         | 
| 13 14 | 
             
              include_path = '/opt/mqm/inc'
         | 
    
        data/ext/extconf_client.rb
    CHANGED
    
    | @@ -4,9 +4,9 @@ | |
| 4 4 | 
             
            #        Windows, Solaris and Linux
         | 
| 5 5 | 
             
            #
         | 
| 6 6 | 
             
            require 'mkmf'
         | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 7 | 
            +
            require_relative '../../generate/generate_reason'
         | 
| 8 | 
            +
            require_relative '../../generate/generate_const'
         | 
| 9 | 
            +
            require_relative '../../generate/generate_structs'
         | 
| 10 10 |  | 
| 11 11 | 
             
            include_path = ''
         | 
| 12 12 | 
             
            unless (RUBY_PLATFORM =~ /win/i) || (RUBY_PLATFORM =~ /solaris/i) || (RUBY_PLATFORM =~ /linux/i)
         | 
| @@ -3,17 +3,22 @@ class GenerateConst | |
| 3 3 |  | 
| 4 4 | 
             
              # Extract Constants from Header files
         | 
| 5 5 | 
             
              def GenerateConst.extract_const(filename, const_prefix, start_exp=nil, end_exp=nil)
         | 
| 6 | 
            -
                 | 
| 7 | 
            -
                active | 
| 6 | 
            +
                constants = []
         | 
| 7 | 
            +
                active     =
         | 
| 8 | 
            +
                  if start_exp then
         | 
| 9 | 
            +
                    false
         | 
| 10 | 
            +
                  else
         | 
| 11 | 
            +
                    true
         | 
| 12 | 
            +
                  end # Sure there is a better way
         | 
| 8 13 | 
             
                File.open(filename) do |file|
         | 
| 9 14 | 
             
                  file.each do |line|
         | 
| 10 15 | 
             
                    line.rstrip!
         | 
| 11 | 
            -
                    if line.length > 0 | 
| 16 | 
            +
                    if line.length > 0 # Skip empty lines
         | 
| 12 17 | 
             
                      if active
         | 
| 13 18 | 
             
                        break if start_exp && line.match(end_exp)
         | 
| 14 19 | 
             
                        # Skip Comment lines, then check for a match
         | 
| 15 20 | 
             
                        if (line !~ /^\s*\/\*/) && (match = /\s*#define\s+(#{const_prefix}\w+)[\(\s]+([-\\\w\dx\'\"\s]+)/.match(line))
         | 
| 16 | 
            -
                           | 
| 21 | 
            +
                          constants << [match[1], match[2]]
         | 
| 17 22 | 
             
                        end
         | 
| 18 23 | 
             
                      else
         | 
| 19 24 | 
             
                        next unless line.match(start_exp)
         | 
| @@ -22,7 +27,7 @@ class GenerateConst | |
| 22 27 | 
             
                    end
         | 
| 23 28 | 
             
                  end
         | 
| 24 29 | 
             
                end
         | 
| 25 | 
            -
                 | 
| 30 | 
            +
                constants
         | 
| 26 31 | 
             
              end
         | 
| 27 32 |  | 
| 28 33 | 
             
              # Extract MQ Constants from Header files
         | 
| @@ -47,8 +52,8 @@ class GenerateConst | |
| 47 52 | 
             
              def GenerateConst.config(filename, prefix)
         | 
| 48 53 | 
             
                str = "# WMQ::QueueManager execute commands\n"
         | 
| 49 54 | 
             
                str << "execute_commands:\n"
         | 
| 50 | 
            -
                GenerateConst.extract_const(filename,prefix).each do |item|
         | 
| 51 | 
            -
                  name = item[0].gsub(prefix,'').downcase
         | 
| 55 | 
            +
                GenerateConst.extract_const(filename, prefix).each do |item|
         | 
| 56 | 
            +
                  name = item[0].gsub(prefix, '').downcase
         | 
| 52 57 | 
             
                  str << "  :%-26s " % "#{name}:"
         | 
| 53 58 | 
             
                  match = name.match(/\w+?_([\w_]+)/)
         | 
| 54 59 | 
             
                  str << ":#{match[1]}" if match
         | 
| @@ -68,28 +73,29 @@ class GenerateConst | |
| 68 73 | 
             
            ################################################################################
         | 
| 69 74 | 
             
            module WMQ
         | 
| 70 75 | 
             
            END_OF_STRING
         | 
| 71 | 
            -
                [ | 
| 72 | 
            -
                  [' | 
| 73 | 
            -
                  [' | 
| 74 | 
            -
                  [' | 
| 75 | 
            -
                  [' | 
| 76 | 
            -
                  [' | 
| 77 | 
            -
                  [' | 
| 76 | 
            +
                [
         | 
| 77 | 
            +
                  ['Connect Options', 'cmqc.h', 'MQCNO_', /(VERSION)|(CONN_TAG)|(HANDLE_SHARE)|(_LENGTH)/],
         | 
| 78 | 
            +
                  ['Open Options', 'cmqc.h', 'MQOO_'],
         | 
| 79 | 
            +
                  ['Close Options', 'cmqc.h', 'MQCO_'],
         | 
| 80 | 
            +
                  ['Match Options', 'cmqc.h', 'MQMO_'],
         | 
| 81 | 
            +
                  ['Message Format Options', 'cmqc.h', 'MQFMT_', /(_ARRAY)/],
         | 
| 82 | 
            +
                  ['Get Message Options', 'cmqc.h', 'MQGMO_', /(VERSION)|(LENGTH)|(MQGMO_BROWSE_HANDLE)|(MQGMO_BROWSE_CO_OP)/],
         | 
| 83 | 
            +
                  ['Transport Types', 'cmqxc.h', 'MQXPT_'],
         | 
| 78 84 | 
             
                  ['Report Options', 'cmqc.h', 'MQRO_'],
         | 
| 79 85 | 
             
                  ['Message Types', 'cmqc.h', 'MQMT_'],
         | 
| 80 86 | 
             
                  ['Expiry', 'cmqc.h', 'MQEI_'],
         | 
| 81 87 | 
             
                  ['Feedback Values', 'cmqc.h', 'MQFB_'],
         | 
| 82 | 
            -
                  ['Encoding Values', 'cmqc.h', 'MQENC_' | 
| 88 | 
            +
                  ['Encoding Values', 'cmqc.h', 'MQENC_', /(MQENC_NORMAL)|(MQENC_REVERSED)|(MQENC_S390)|(MQENC_TNS)/],
         | 
| 83 89 | 
             
                  ['Coded Character Set Identifiers', 'cmqc.h', 'MQCCSI_'],
         | 
| 84 90 | 
             
                  ['Priority', 'cmqc.h', 'MQPRI_'],
         | 
| 85 91 | 
             
                  ['Persistence', 'cmqc.h', 'MQPER_'],
         | 
| 86 92 | 
             
                  ['Put Application Types', 'cmqc.h', 'MQAT_'],
         | 
| 87 93 | 
             
                  ['Message Flags', 'cmqc.h', 'MQMF_'],
         | 
| 88 94 | 
             
                  ['Original Length', 'cmqc.h', 'MQOL_'],
         | 
| 89 | 
            -
                  ['Put Message Options', 'cmqc.h', 'MQPMO_' | 
| 90 | 
            -
                  ['Put Message Record Fields', 'cmqc.h', 'MQPMRF_' | 
| 91 | 
            -
                  ['Reason Codes', 'cmqc.h','MQRC_'],
         | 
| 92 | 
            -
             | 
| 95 | 
            +
                  ['Put Message Options', 'cmqc.h', 'MQPMO_', /(VERSION)|(LENGTH)/],
         | 
| 96 | 
            +
                  ['Put Message Record Fields', 'cmqc.h', 'MQPMRF_', /(VERSION)|(LENGTH)/],
         | 
| 97 | 
            +
                  ['Reason Codes', 'cmqc.h', 'MQRC_'],
         | 
| 98 | 
            +
                ].each do |item|
         | 
| 93 99 | 
             
                  str << "\n# #{item[0]}\n"
         | 
| 94 100 | 
             
                  str << GenerateConst.rb_const("#{path}/#{item[1]}", item[2], item[3])
         | 
| 95 101 | 
             
                end
         | 
| @@ -108,10 +114,11 @@ END_OF_STRING | |
| 108 114 | 
             
            module WMQ
         | 
| 109 115 | 
             
            END_OF_STRING
         | 
| 110 116 | 
             
                str << "# Admin constants from cmqc.h\n"
         | 
| 111 | 
            -
                [ | 
| 117 | 
            +
                [
         | 
| 118 | 
            +
                  ['Object Types', 'cmqc.h', 'MQOT_'],
         | 
| 112 119 | 
             
                  ['Security Identifier Types', 'cmqc.h', 'MQSIDT_'],
         | 
| 113 120 | 
             
                  ['Channel Types', 'cmqxc.h', 'MQCHT_'],
         | 
| 114 | 
            -
             | 
| 121 | 
            +
                ].each do |item|
         | 
| 115 122 | 
             
                  str << "\n# #{item[0]}\n"
         | 
| 116 123 | 
             
                  str << GenerateConst.rb_const("#{path}/#{item[1]}", item[2], item[3])
         | 
| 117 124 | 
             
                end
         | 
| @@ -126,9 +133,9 @@ END_OF_STRING | |
| 126 133 | 
             
              end
         | 
| 127 134 |  | 
| 128 135 | 
             
              def self.generate(path, target_path='')
         | 
| 129 | 
            -
                File.open(File.join(target_path,'constants_admin.rb'), 'w') {|file| file.write(GenerateConst.admin_consts(path))}
         | 
| 136 | 
            +
                File.open(File.join(target_path, 'constants_admin.rb'), 'w') { |file| file.write(GenerateConst.admin_consts(path)) }
         | 
| 130 137 | 
             
                puts 'Generated wmq_const_admin.rb'
         | 
| 131 | 
            -
                File.open(File.join(target_path,'constants.rb'), 'w') {|file| file.write(GenerateConst.wmq_const(path))}
         | 
| 138 | 
            +
                File.open(File.join(target_path, 'constants.rb'), 'w') { |file| file.write(GenerateConst.wmq_const(path)) }
         | 
| 132 139 | 
             
                puts 'Generated wmq_const.rb'
         | 
| 133 140 | 
             
              end
         | 
| 134 141 | 
             
            end
         | 
| @@ -2,45 +2,45 @@ class GenerateReason | |
| 2 2 |  | 
| 3 3 | 
             
              # Extract Error Code Constants from Header files
         | 
| 4 4 | 
             
              def GenerateReason.extract_const(filename, const_prefix)
         | 
| 5 | 
            -
                 | 
| 5 | 
            +
                constants = []
         | 
| 6 6 | 
             
                File.open(filename) do |file|
         | 
| 7 7 | 
             
                  file.each do |line|
         | 
| 8 8 | 
             
                    line.rstrip!
         | 
| 9 9 | 
             
                    # Skip empty and comment lines
         | 
| 10 10 | 
             
                    if line.length > 0 && line !~ /^\s*\/\*/
         | 
| 11 11 | 
             
                      if match = /\s*#define\s+(#{const_prefix}\w+)[\(\s]+([-\dx]+)/.match(line)
         | 
| 12 | 
            -
                         | 
| 12 | 
            +
                        constants << [match[1], match[2]]
         | 
| 13 13 | 
             
                      end
         | 
| 14 14 | 
             
                    end
         | 
| 15 15 | 
             
                  end
         | 
| 16 16 | 
             
                end
         | 
| 17 | 
            -
                 | 
| 17 | 
            +
                constants
         | 
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| 20 20 | 
             
              # Extract Error Code Constants from Header files
         | 
| 21 21 | 
             
              # Uses lazy print to collect duplicate values
         | 
| 22 22 | 
             
              def GenerateReason.reason_case(filename, prefix)
         | 
| 23 | 
            -
                last_rc | 
| 23 | 
            +
                last_rc     = nil
         | 
| 24 24 | 
             
                last_reason = nil
         | 
| 25 | 
            -
                str | 
| 26 | 
            -
                GenerateReason.extract_const(filename,prefix).each do |item|
         | 
| 25 | 
            +
                str         = ''
         | 
| 26 | 
            +
                GenerateReason.extract_const(filename, prefix).each do |item|
         | 
| 27 27 | 
             
                  if last_rc == item[1]
         | 
| 28 28 | 
             
                    str << "        case %-30s: return \"#{item[0]} or #{last_reason}[#{item[1]}]\";\n" % item[0]
         | 
| 29 | 
            -
                    last_rc | 
| 29 | 
            +
                    last_rc     = nil
         | 
| 30 30 | 
             
                    last_reason = nil
         | 
| 31 31 | 
             
                  else
         | 
| 32 32 | 
             
                    str << "        case %-30s: return \"#{last_reason}[#{last_rc}]\";\n" % last_reason if last_rc
         | 
| 33 | 
            -
                    last_rc | 
| 33 | 
            +
                    last_rc     = item[1]
         | 
| 34 34 | 
             
                    last_reason = item[0]
         | 
| 35 35 | 
             
                  end
         | 
| 36 36 | 
             
                end
         | 
| 37 37 | 
             
                str
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| 40 | 
            -
            # The WebSphere MQ header files have several duplicate values,
         | 
| 41 | 
            -
            # so need to exclude duplicates.
         | 
| 40 | 
            +
              # The WebSphere MQ header files have several duplicate values,
         | 
| 41 | 
            +
              # so need to exclude duplicates.
         | 
| 42 42 | 
             
              def GenerateReason.selector_case(filename, prefix, excludes=nil, &block)
         | 
| 43 | 
            -
                GenerateReason.extract_const(filename,prefix).each do |item|
         | 
| 43 | 
            +
                GenerateReason.extract_const(filename, prefix).each do |item|
         | 
| 44 44 | 
             
                  next if item[0].include?('FIRST') || item[0].include?('LAST')
         | 
| 45 45 | 
             
                  next if excludes && excludes.include?(item[0])
         | 
| 46 46 | 
             
                  block.call item
         | 
| @@ -65,8 +65,10 @@ char* wmq_reason(MQLONG reason_code) | |
| 65 65 | 
             
                {
         | 
| 66 66 | 
             
            END_OF_STRING
         | 
| 67 67 |  | 
| 68 | 
            -
                [ | 
| 69 | 
            -
             | 
| 68 | 
            +
                [
         | 
| 69 | 
            +
                  ['cmqc.h', 'MQRC_'],
         | 
| 70 | 
            +
                  ['cmqcfc.h', 'MQRCCF_']
         | 
| 71 | 
            +
                ].each do |item|
         | 
| 70 72 | 
             
                  str << GenerateReason.reason_case(path+item[0], item[1])
         | 
| 71 73 | 
             
                end
         | 
| 72 74 | 
             
                str << <<END_OF_STRING
         | 
| @@ -77,39 +79,39 @@ END_OF_STRING | |
| 77 79 |  | 
| 78 80 | 
             
            END_OF_STRING
         | 
| 79 81 |  | 
| 80 | 
            -
                str_switch | 
| 82 | 
            +
                str_switch  = ''
         | 
| 81 83 | 
             
                str_id_init = ''
         | 
| 84 | 
            +
                values = []
         | 
| 82 85 | 
             
            # Integer Selectors for Object Attributes
         | 
| 83 | 
            -
                [ | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 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']],
         | 
| 86 | 
            +
                [
         | 
| 87 | 
            +
                  ['cmqc.h', 'MQIA_'],
         | 
| 88 | 
            +
                  ['cmqcfc.h', 'MQIACF_', ['MQIACF_ERROR_ID', 'MQIACF_QUIESCE']],
         | 
| 89 | 
            +
                  ['cmqcfc.h', 'MQIACH_', ['MQIACH_CURRENT_SEQ_NUMBER', 'MQIACH_BYTES_RCVD', 'MQIACH_BUFFERS_RCVD', 'MQIACH_MSGS_RCVD']],
         | 
| 90 | 
            +
                  ['cmqcfc.h', 'MQIAMO_'],
         | 
| 91 | 
            +
                  ['cmqcfc.h', 'MQIAMO64_', ['MQIAMO64_AVG_Q_TIME', 'MQIAMO64_Q_TIME_AVG', 'MQIAMO64_Q_TIME_MAX', 'MQIAMO64_Q_TIME_MIN']],
         | 
| 95 92 | 
             
            # Integer System Selectors
         | 
| 96 | 
            -
             | 
| 93 | 
            +
                  ['cmqbc.h', 'MQIASY_'],
         | 
| 97 94 | 
             
            # Character Selectors for Object Attributes
         | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 95 | 
            +
                  ['cmqc.h', 'MQCA_', ['MQCA_BASE_OBJECT_NAME']],
         | 
| 96 | 
            +
                  ['cmqcfc.h', 'MQCACF_'],
         | 
| 97 | 
            +
                  ['cmqcfc.h', 'MQCACH_'],
         | 
| 98 | 
            +
                  ['cmqcfc.h', 'MQCAMO_'],
         | 
| 102 99 | 
             
            # Byte String Selectors for Object Attributes
         | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 100 | 
            +
                  ['cmqc.h', 'MQBA_'],
         | 
| 101 | 
            +
                  ['cmqcfc.h', 'MQBACF_'],
         | 
| 105 102 | 
             
            # Group Selectors for Object Attributes
         | 
| 106 | 
            -
             | 
| 103 | 
            +
                  ['cmqcfc.h', 'MQGACF_']
         | 
| 104 | 
            +
                ].each do |item|
         | 
| 107 105 | 
             
                  str << "/* Constants #{item[1]}* from #{item[0]} */\n"
         | 
| 108 106 | 
             
                  str_switch << "        /* Constants #{item[1]}* from #{item[0]} */\n"
         | 
| 109 107 | 
             
                  str_id_init << "    /* Constants #{item[1]}* from #{item[0]} */\n"
         | 
| 110 108 | 
             
                  GenerateReason.selector_case(path+item[0], item[1], item[2]) do |const|
         | 
| 111 | 
            -
                    id = const[0].gsub(item[1],'').downcase
         | 
| 112 | 
            -
                     | 
| 109 | 
            +
                    id = const[0].gsub(item[1], '').downcase
         | 
| 110 | 
            +
                    # Ignore duplicate values
         | 
| 111 | 
            +
                    unless values.include?(const[1])
         | 
| 112 | 
            +
                      str_switch << "        case %-30s: return ID_#{id};\n" % const[0]
         | 
| 113 | 
            +
                      values << const[1]
         | 
| 114 | 
            +
                    end
         | 
| 113 115 | 
             
                    str_id_init << "    ID_%-25s = rb_intern(\"#{id}\");\n" % id
         | 
| 114 116 | 
             
                    str << "static ID ID_#{id};\n"
         | 
| 115 117 | 
             
                  end
         | 
| @@ -136,35 +138,31 @@ void wmq_selector(ID selector_id, PMQLONG selector_type, PMQLONG selector) | |
| 136 138 | 
             
            {
         | 
| 137 139 | 
             
                *selector_type = MQIT_INTEGER;
         | 
| 138 140 | 
             
            END_OF_STRING
         | 
| 139 | 
            -
                first | 
| 140 | 
            -
                str_if | 
| 141 | 
            +
                first       = true
         | 
| 142 | 
            +
                str_if      = ''
         | 
| 141 143 | 
             
                str_id_init = ''
         | 
| 142 144 | 
             
            # Integer Selectors for Object Attributes
         | 
| 143 | 
            -
                [ | 
| 144 | 
            -
             | 
| 145 | 
            -
             | 
| 146 | 
            -
             | 
| 147 | 
            -
             | 
| 148 | 
            -
             | 
| 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']],
         | 
| 145 | 
            +
                [
         | 
| 146 | 
            +
                  ['cmqc.h', 'MQIA_'],
         | 
| 147 | 
            +
                  ['cmqcfc.h', 'MQIACF_', ['MQIACF_ERROR_ID', 'MQIACF_QUIESCE']],
         | 
| 148 | 
            +
                  ['cmqcfc.h', 'MQIACH_', ['MQIACH_CURRENT_SEQ_NUMBER', 'MQIACH_BYTES_RCVD', 'MQIACH_BUFFERS_RCVD']],
         | 
| 149 | 
            +
                  ['cmqcfc.h', 'MQIAMO_'],
         | 
| 150 | 
            +
                  ['cmqcfc.h', 'MQIAMO64_', ['MQIAMO64_AVG_Q_TIME', 'MQIAMO64_Q_TIME_AVG', 'MQIAMO64_Q_TIME_MAX', 'MQIAMO64_Q_TIME_MIN']],
         | 
| 154 151 | 
             
            # Integer System Selectors
         | 
| 155 152 | 
             
            #     ['cmqbc.h', 'MQIASY_'],
         | 
| 156 153 | 
             
                ].each do |item|
         | 
| 157 | 
            -
                  str << "    /*  | 
| 154 | 
            +
                  str << "    /* Constants #{item[1]}* from #{item[0]} */\n"
         | 
| 158 155 | 
             
                  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})"
         | 
| 156 | 
            +
                    str << "    if(selector_id == %-32s{ *selector = #{const[0]}; return;}\n" % "ID_#{const[0].gsub(item[1], '').downcase})"
         | 
| 160 157 | 
             
                  end
         | 
| 161 158 | 
             
                end
         | 
| 162 159 | 
             
                str << "\n    *selector_type = MQIT_STRING;\n\n"
         | 
| 163 160 | 
             
            # Character Selectors for Object Attributes
         | 
| 164 | 
            -
             | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
             | 
| 161 | 
            +
                [
         | 
| 162 | 
            +
                  ['cmqc.h', 'MQCA_', ['MQCA_BASE_OBJECT_NAME']],
         | 
| 163 | 
            +
                  ['cmqcfc.h', 'MQCACF_'],
         | 
| 164 | 
            +
                  ['cmqcfc.h', 'MQCACH_'],
         | 
| 165 | 
            +
                  ['cmqcfc.h', 'MQCAMO_'],
         | 
| 168 166 | 
             
            # Byte String Selectors for Object Attributes
         | 
| 169 167 | 
             
            #     ['cmqc.h', 'MQBA_'],
         | 
| 170 168 | 
             
            #     ['cmqcfc.h', 'MQBACF_'],
         | 
| @@ -173,7 +171,7 @@ END_OF_STRING | |
| 173 171 | 
             
                ].each do |item|
         | 
| 174 172 | 
             
                  str << "    /* Constants #{item[1]}* from #{item[0]} */\n"
         | 
| 175 173 | 
             
                  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})"
         | 
| 174 | 
            +
                    str << "    if(selector_id == %-32s{ *selector = #{const[0]}; return;}\n" % "ID_#{const[0].gsub(item[1], '').downcase})"
         | 
| 177 175 | 
             
                  end
         | 
| 178 176 | 
             
                end
         | 
| 179 177 |  | 
| @@ -183,21 +181,21 @@ END_OF_STRING | |
| 183 181 | 
             
            }
         | 
| 184 182 |  | 
| 185 183 | 
             
            END_OF_STRING
         | 
| 186 | 
            -
             | 
| 187 | 
            -
                   | 
| 188 | 
            -
             | 
| 189 | 
            -
             | 
| 190 | 
            -
             | 
| 191 | 
            -
             | 
| 192 | 
            -
             | 
| 193 | 
            -
             | 
| 194 | 
            -
             | 
| 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"
         | 
| 184 | 
            +
                first       = true
         | 
| 185 | 
            +
                str_if      = ''
         | 
| 186 | 
            +
                str_id_init = ''
         | 
| 187 | 
            +
                GenerateReason.selector_case(path+'cmqcfc.h', 'MQCMD_') do |const|
         | 
| 188 | 
            +
                  if first
         | 
| 189 | 
            +
                    first = false
         | 
| 190 | 
            +
                    str_if << '    '
         | 
| 191 | 
            +
                  else
         | 
| 192 | 
            +
                    str_if << '    else '
         | 
| 200 193 | 
             
                  end
         | 
| 194 | 
            +
                  id = const[0].gsub('MQCMD_', '').downcase
         | 
| 195 | 
            +
                  str_id_init << "    ID_%-25s = rb_intern(\"#{id}\");\n" % id
         | 
| 196 | 
            +
                  str_if << "if(command_id == %-28s{ command = #{const[0]}; }\n" % "ID_#{const[0].gsub('MQCMD_', '').downcase})"
         | 
| 197 | 
            +
                  str << "static ID ID_#{id};\n"
         | 
| 198 | 
            +
                end
         | 
| 201 199 | 
             
                str << <<END_OF_STRING
         | 
| 202 200 |  | 
| 203 201 | 
             
            void QueueManager_command_id_init()
         | 
| @@ -217,11 +215,11 @@ MQLONG wmq_command_lookup(ID command_id) | |
| 217 215 | 
             
                return command;
         | 
| 218 216 | 
             
            }
         | 
| 219 217 | 
             
            END_OF_STRING
         | 
| 220 | 
            -
             | 
| 218 | 
            +
                str
         | 
| 221 219 | 
             
              end
         | 
| 222 220 |  | 
| 223 221 | 
             
              def self.generate(path)
         | 
| 224 | 
            -
                File.open('wmq_reason.c', 'w') {|file| file.write(GenerateReason.wmq_reason(path))}
         | 
| 222 | 
            +
                File.open('wmq_reason.c', 'w') { |file| file.write(GenerateReason.wmq_reason(path)) }
         | 
| 225 223 | 
             
                puts 'Generated wmq_reason.c'
         | 
| 226 224 | 
             
              end
         | 
| 227 225 | 
             
            end
         |