~ubuntu-branches/ubuntu/oneiric/ctioga2/oneiric

« back to all changes in this revision

Viewing changes to lib/ctioga2/metabuilder/types/lists.rb

  • Committer: Bazaar Package Importer
  • Author(s): Vincent Fourmond
  • Date: 2011-01-24 21:36:06 UTC
  • Revision ID: james.westby@ubuntu.com-20110124213606-9ettx0ugl83z0bzp
Tags: upstream-0.1
ImportĀ upstreamĀ versionĀ 0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# lists.rb : Different Types to deal with types where
 
2
# you can choose among several possibilities
 
3
# Copyright (C) 2006, 2009 Vincent Fourmond
 
4
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free Software Foundation; either version 2 of the License, or
 
8
# (at your option) any later version.
 
9
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
18
 
 
19
require 'ctioga2/utils'
 
20
 
 
21
module CTioga2
 
22
 
 
23
  Version::register_svn_info('$Revision: 222 $', '$Date: 2011-01-11 00:52:31 +0100 (Tue, 11 Jan 2011) $')
 
24
 
 
25
 
 
26
  module MetaBuilder
 
27
 
 
28
    # The module Types should be used for all subclasses of
 
29
    # Type, to keep the place clean and tidy.
 
30
    module Types
 
31
 
 
32
      # A regular expression matching true
 
33
      TRUE_RE = /^\s*(true|yes|on)\s*$/i
 
34
 
 
35
      # A regular expression matching false
 
36
      FALSE_RE = /^\s*(false|no(ne)?|off)\s*$/i
 
37
 
 
38
 
 
39
      # A boolean parameter
 
40
      class BooleanParameter < Type
 
41
 
 
42
        type_name :boolean
 
43
        
 
44
        def type_name
 
45
          return 'bool'
 
46
        end
 
47
 
 
48
        # Yes, this *really* is a boolean !
 
49
        def boolean?
 
50
          return true
 
51
        end
 
52
        
 
53
        def string_to_type_internal(str)
 
54
          if str == true or str =~ TRUE_RE
 
55
            return true
 
56
          else
 
57
            return false
 
58
          end
 
59
        end
 
60
 
 
61
        def type_to_string_internal(val)
 
62
          if val
 
63
            return "true"
 
64
          else
 
65
            return "false"
 
66
          end
 
67
        end
 
68
 
 
69
        # Booleans are a special case for option parser, as they
 
70
        # are handled completely differently
 
71
        def option_parser_long_option(name, biniou = nil)
 
72
          return "--[no-]#{name}"
 
73
        end
 
74
      end
 
75
 
 
76
      # A list of symbols. A hash :list must be provided that states
 
77
      # the correspondance between the legal symbols that can be
 
78
      # accepted by this parameter and their "english" name.
 
79
      # This parameter can typically be used to prompt the user
 
80
      # for different choices.
 
81
      class ListParameter < Type
 
82
 
 
83
        type_name :list
 
84
 
 
85
        def initialize(type)
 
86
          super
 
87
          raise "type must have a :list key" unless type.has_key?(:list)
 
88
          # We make a copy for our own purposes.
 
89
          @hash = type[:list].dup
 
90
        end
 
91
        
 
92
        def type_name
 
93
          return 'list'
 
94
        end
 
95
        
 
96
        def string_to_type_internal(str)
 
97
          if @hash.has_key?(str.to_sym)
 
98
            return str.to_sym
 
99
          else
 
100
            raise IncorrectInput, "Invalid input: #{str} should be one of " +
 
101
              @hash.keys.map {|s| s.to_s}.join(',')
 
102
          end
 
103
        end
 
104
 
 
105
        def type_to_string_internal(val)
 
106
          return val.to_s
 
107
        end
 
108
      end
 
109
 
 
110
 
 
111
      # A choice between different symbols based on regular expressions.
 
112
      class REListParameter < Type
 
113
 
 
114
        type_name :re_list
 
115
 
 
116
        def initialize(type)
 
117
          super
 
118
          raise "type must have a :list key" unless type.has_key?(:list)
 
119
          # We make a copy for our own purposes.
 
120
          @re_hash = type[:list].dup
 
121
        end
 
122
        
 
123
        def type_name
 
124
          return 'relist'
 
125
        end
 
126
        
 
127
        def string_to_type_internal(str)
 
128
          for k,v in @re_hash
 
129
            if str =~ /^\s*#{k}\s*$/
 
130
              return v
 
131
            end
 
132
          end
 
133
          raise IncorrectInput, "Invalid input: #{str} should match " +
 
134
            @re_hash.keys.map {|s| s.to_s}.join(',')
 
135
        end
 
136
 
 
137
        def type_to_string_internal(val)
 
138
          return val.to_s
 
139
        end
 
140
      end
 
141
 
 
142
      # An array of identical elements of type specified by :subtype. Defaults
 
143
      # to String
 
144
      class ArrayParameter < Type
 
145
        type_name :array
 
146
 
 
147
        def initialize(type)
 
148
          super
 
149
          # We make a copy for our own purposes.
 
150
          subtype = type[:subtype] || {:type => :string}
 
151
          @subtype = Type.get_type(subtype)
 
152
          @separator = /\s*,\s*/
 
153
          @separator_out = ','
 
154
        end
 
155
 
 
156
        def type_name
 
157
          return 'array'
 
158
        end
 
159
 
 
160
        def string_to_type_internal(str)
 
161
          ary = str.split(@separator)
 
162
          return ary.map do |a|
 
163
            @subtype.string_to_type(a)
 
164
          end
 
165
        end
 
166
 
 
167
        def type_to_string_internal(val)
 
168
          return val.map do |a|
 
169
            @subtype.type_to_string(a)
 
170
          end.join(@separator_out)
 
171
        end
 
172
      end
 
173
 
 
174
      # A Type used for sets for Graphics::Styles::CircularArray
 
175
      # objects.
 
176
      #
 
177
      # \todo write a gradient stuff !!!
 
178
      class SetParameter < ArrayParameter
 
179
        type_name :set
 
180
 
 
181
        def initialize(type)
 
182
          super
 
183
          @separator = /\s*\|\s*/
 
184
          @separator_out = '|'
 
185
        end
 
186
 
 
187
        def type_name
 
188
          return 'set'
 
189
        end
 
190
 
 
191
        def string_to_type_internal(str)
 
192
          multiply = nil
 
193
          if str =~ /(.*)\*\s*(\d+)\s*$/
 
194
            multiply = $2.to_i
 
195
            str = $1
 
196
          end
 
197
          if str =~ /^\s*gradient:(.+)--(.+),(\d+)\s*$/
 
198
            s,e,nb = $1, $2, $3.to_i
 
199
            s,e = @subtype.string_to_type(s),@subtype.string_to_type(e)
 
200
            fact = if nb > 1
 
201
                     1.0/(nb - 1)     # The famous off-by one...
 
202
                   else
 
203
                     warn { "Incorrect gradient number: #{nb}" }
 
204
                     1.0
 
205
                   end
 
206
            array = []
 
207
            nb.times do |i|
 
208
              array << Utils::mix_objects(e,s, i * fact)
 
209
            end
 
210
          else
 
211
            array = super
 
212
          end
 
213
          if multiply
 
214
            # Seems that I've finally managed to understand what zip
 
215
            # is useful for !
 
216
            array = array.zip(*([array]*(multiply-1))).flatten(1)
 
217
          end
 
218
          return array
 
219
        end
 
220
 
 
221
      end
 
222
 
 
223
    end
 
224
  end
 
225
end