Module: Dfhmdf

Included in:
ConvertDfhmdf
Defined in:
lib/dfhmdf.rb,
lib/dfhmdf/version.rb

Constant Summary collapse

VERSION =
"0.0.2"

Instance Method Summary collapse

Instance Method Details

#clearObject

Clear variables to prepare for parsing a DFHMDF macro.



9
10
11
12
# File 'lib/dfhmdf.rb', line 9

def clear
  @field_label, @parameter_hash, @parameters, @tokens = nil
  @dfhmdf = false
end

#column_positionObject

Return the column position of the field as specified in the POS=(row, column) operand of DFHMDF. Increment the value by 1 to bypass the attribute byte. If the value has not been set, return zero.



130
131
132
# File 'lib/dfhmdf.rb', line 130

def column_position 
  (@operands_hash != nil && @operands_hash[:pos] && @operands_hash[:pos][1].to_i + 1) || 0
end

#dfhmdf?Boolean

True if we are looking at a DFHMDF macro in the input.

Returns:

  • (Boolean)


152
153
154
# File 'lib/dfhmdf.rb', line 152

def dfhmdf?
  @dfhmdf
end

#field_labelObject

Return the field label (name) as specified on the DFHMDF macro. When no label is coded on the macro, build a name based on the X and Y coordinates, like x20y5 or x9y32.



146
147
148
# File 'lib/dfhmdf.rb', line 146

def field_label
  (@field_label == nil && "x#{line_position}y#{column_position}") || @field_label
end

#field_lengthObject

Return the length of the field. This may be specified in the LENGTH= operand of DFHMDF or derived from the PICOUT= or INTIAL= operand.



137
138
139
140
141
# File 'lib/dfhmdf.rb', line 137

def field_length
  (@operands_hash != nil && @operands_hash[:length] && @operands_hash[:length].to_i) ||
  (@operands_hash != nil && @operands_hash[:initial] && @operands_hash[:initial].length) ||
  (@operands_hash != nil && @operands_hash[:picout] && @operands_hash[:picout].length) || 0
end

#line_positionObject

Return the line position of the field as specified in the POS=(line, column) operand of DFHMDF. If the position has not been set, return zero.



122
123
124
# File 'lib/dfhmdf.rb', line 122

def line_position
  (@operands_hash != nil && @operands_hash[:pos] && @operands_hash[:pos][0].to_i) || 0
end

#parse_operands(operands_as_string) ⇒ Object

Parse the operands in a macro source statement:

LABEL MACRO OPERAND,OPERAND,OPERAND COMMENT X

xxxxxxxxxxxxxxxxxxxxxxx

Example


from this… FIELD1 DFHMDF POS=(6,18),LENGTH=14,ATTRB=(ASKIP,NORM),INITIAL=‘Hello there’

to this… { :pos => [ “6”, “18” ], :length => “14”, :attrb => [ “ASKIP”, “NORM” ],

:initial => "Hello there" }
operands_as_string

The DFHMDF operands as a single string.



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
# File 'lib/dfhmdf.rb', line 88

def parse_operands operands_as_string
  @operands_hash = {}
  # Split on comma except when the comma appears within parentheses.
  # Couldn't figure out how to make regex ignore commas within single quotes,
  # so it misses PICOUT='$,$$0.00' and similar. Using brute force to handle it.
  item = operands_as_string.split(/,(?![^(]*\))/)
  for i in 0..item.length-1
    if item[i].match(/^PICOUT=/)
      item[i] << ',' << item[i+1]
    end  

    if item[i].include? '='
      key_value_pair = item[i].split('=')

      # handle operand values consisting of a comma-separated list within parentheses
      if key_value_pair[1][0] == '('
        key_value_pair[1].gsub!(/[\(\)]/, '')
        key_value_pair[1] = key_value_pair[1].split(',')
      end  

      # handle operand values in single quotes
      if key_value_pair[1][0] == "'"
        key_value_pair[1].gsub!(/'/, '')
      end  

      @operands_hash[key_value_pair[0].downcase.to_sym] = key_value_pair[1]
    end
  end    
  @operands_hash
end

#parse_tokens(tokens) ⇒ Object

Look at the tokens that were extracted from an input line and determine whether we are reading a DFHMDF macro. There may or may not be a label (1st token).

tokens

array of tokens extracted from the current input line



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/dfhmdf.rb', line 58

def parse_tokens tokens
  @dfhmdf = false
  if tokens[0] == 'DFHMDF'
    @dfhmdf = true
    @field_label = nil
    operands = tokens[1]
  elsif tokens[1] == 'DFHMDF'
      @dfhmdf = true
      @field_label = tokens[0].downcase
      operands = tokens[2]
  end
  if dfhmdf? && tokens != nil && operands != nil && operands.include?('=')
    parse_operands operands
  end  
end

#te3270_text_fieldObject

Generate a te3270 text_field declaration using values parsed from a DFHMDF macro.



4
5
6
# File 'lib/dfhmdf.rb', line 4

def te3270_text_field
  "text_field(:#{field_label}, #{line_position}, #{column_position}, #{field_length})" 
end

#tokenize_line(input_line) ⇒ Object

Tokenize an input line from the macro source file.

LABEL MACRO OPERAND,OPERAND,OPERAND COMMENT X 1 2 3 4 discard



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
# File 'lib/dfhmdf.rb', line 19

def tokenize_line input_line
  # Want to split on spaces except when space occurs within single quotes.    
  # Should be able to do it with a regex. Unable to figure it out so far. Using brute force.
  # This regex doesn't work but was as close as I was able to get.
  #    @tokens = [@tokens, input_line.scan(/'.*?'|".*?"|\S+/)].compact.reduce([], :|)
  # +input_line+:: A line of input from the macro source file.

  new_tokens = []
  temp = input_line.split
  new_tokens[0] = temp[0]
  if temp[0] == 'DFHMDF'
    start_ix = 1
  else
    start_ix = 2
    new_tokens[1] = temp[1]
  end    
  temp = input_line.split(' ')
  open_quote = false
  for i in 0..temp.length-1 do
    if temp[i] != nil
      open_quote = true unless temp[i].count("'") % 2 == 0
      while open_quote
        if temp[i+1] != nil
          temp[i] << ' ' << temp[i+1]
          temp[i+1] = nil
          temp.compact!
          open_quote = false if temp[i].count("'") % 2 == 0
        else
          open_quote = false  
        end  
      end  
    end
  end  
  @tokens = [@tokens, temp].compact.reduce([], :|)
end