autoc 1.2 → 1.3
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/CHANGES +4 -0
 - data/README +3 -1
 - data/doc/AutoC.html +23 -7
 - data/doc/AutoC/Code.html +3 -3
 - data/doc/AutoC/Collection.html +289 -76
 - data/doc/AutoC/HashMap.html +44 -46
 - data/doc/AutoC/HashSet.html +20 -17
 - data/doc/AutoC/List.html +56 -92
 - data/doc/AutoC/Module.html +2 -2
 - data/doc/AutoC/Module/File.html +2 -2
 - data/doc/AutoC/Module/Header.html +6 -4
 - data/doc/AutoC/Module/Source.html +26 -26
 - data/doc/AutoC/Priority.html +2 -2
 - data/doc/AutoC/Queue.html +30 -92
 - data/doc/AutoC/Reference.html +217 -61
 - data/doc/AutoC/String.html +1393 -0
 - data/doc/AutoC/Type.html +240 -128
 - data/doc/AutoC/UserDefinedType.html +688 -47
 - data/doc/AutoC/Vector.html +154 -62
 - data/doc/_index.html +9 -2
 - data/doc/class_list.html +1 -1
 - data/doc/file.CHANGES.html +10 -2
 - data/doc/file.README.html +5 -3
 - data/doc/index.html +5 -3
 - data/doc/method_list.html +235 -97
 - data/doc/top-level-namespace.html +2 -2
 - data/lib/autoc.rb +3 -1
 - data/lib/autoc/code.rb +3 -2
 - data/lib/autoc/collection.rb +36 -40
 - data/lib/autoc/collection/hash_map.rb +10 -14
 - data/lib/autoc/collection/hash_set.rb +12 -11
 - data/lib/autoc/collection/list.rb +21 -11
 - data/lib/autoc/collection/queue.rb +5 -8
 - data/lib/autoc/collection/vector.rb +28 -12
 - data/lib/autoc/string.rb +492 -0
 - data/lib/autoc/type.rb +155 -66
 - data/test/test.rb +157 -35
 - data/test/test_char_string.rb +270 -0
 - data/test/test_int_list.rb +35 -0
 - data/test/test_int_vector.rb +34 -0
 - data/test/test_value_hash_map.rb +162 -0
 - data/test/test_value_hash_set.rb +173 -0
 - data/test/test_value_list.rb +193 -0
 - data/test/test_value_queue.rb +275 -0
 - data/test/test_value_vector.rb +155 -0
 - data/test/value.rb +80 -0
 - metadata +15 -8
 - data/test/test.c +0 -1041
 - data/test/test.h +0 -41
 - data/test/test_auto.c +0 -3407
 - data/test/test_auto.h +0 -765
 
    
        data/lib/autoc/type.rb
    CHANGED
    
    | 
         @@ -1,4 +1,3 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require "set"
         
     | 
| 
       2 
1 
     | 
    
         
             
            require "forwardable"
         
     | 
| 
       3 
2 
     | 
    
         
             
            require "autoc/code"
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
         @@ -24,9 +23,10 @@ class Dispatcher 
     | 
|
| 
       24 
23 
     | 
    
         
             
                def ===(other) other.is_a?(ParameterArray) && types == other.types end
         
     | 
| 
       25 
24 
     | 
    
         
             
                def types; collect {|x| x.first} end
         
     | 
| 
       26 
25 
     | 
    
         
             
                def names; collect {|x| x.last} end
         
     | 
| 
       27 
     | 
    
         
            -
                def pass; names.join( 
     | 
| 
       28 
     | 
    
         
            -
                 
     | 
| 
       29 
     | 
    
         
            -
                def  
     | 
| 
      
 26 
     | 
    
         
            +
                def pass; names.join(",") end
         
     | 
| 
      
 27 
     | 
    
         
            +
                # ANSI C instructs the empty parameter list to be marked as `void`
         
     | 
| 
      
 28 
     | 
    
         
            +
                def declaration; empty? ? :void : types.join(",") end
         
     | 
| 
      
 29 
     | 
    
         
            +
                def definition; empty? ? :void : collect {|x| "#{x.first} #{x.last}"}.join(",") end
         
     | 
| 
       30 
30 
     | 
    
         
             
              end # ParameterArray
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
              # def call(*params)
         
     | 
| 
         @@ -106,10 +106,12 @@ class Type < Code 
     | 
|
| 
       106 
106 
     | 
    
         
             
                def write_intf(stream)
         
     | 
| 
       107 
107 
     | 
    
         
             
                  stream << %$
         
     | 
| 
       108 
108 
     | 
    
         
             
                    #ifndef AUTOC_INLINE
         
     | 
| 
       109 
     | 
    
         
            -
                      # 
     | 
| 
       110 
     | 
    
         
            -
                        #define AUTOC_INLINE __inline
         
     | 
| 
      
 109 
     | 
    
         
            +
                      #if defined(_MSC_VER) || defined(__DMC__)
         
     | 
| 
      
 110 
     | 
    
         
            +
                        #define AUTOC_INLINE AUTOC_STATIC __inline
         
     | 
| 
      
 111 
     | 
    
         
            +
                      #elif defined(__LCC__)
         
     | 
| 
      
 112 
     | 
    
         
            +
                        #define AUTOC_INLINE AUTOC_STATIC /* LCC rejects static __inline */
         
     | 
| 
       111 
113 
     | 
    
         
             
                      #elif __STDC_VERSION__ >= 199901L
         
     | 
| 
       112 
     | 
    
         
            -
                        #define AUTOC_INLINE inline 
     | 
| 
      
 114 
     | 
    
         
            +
                        #define AUTOC_INLINE  AUTOC_STATIC inline
         
     | 
| 
       113 
115 
     | 
    
         
             
                      #else
         
     | 
| 
       114 
116 
     | 
    
         
             
                        #define AUTOC_INLINE AUTOC_STATIC
         
     | 
| 
       115 
117 
     | 
    
         
             
                      #endif
         
     | 
| 
         @@ -122,7 +124,7 @@ class Type < Code 
     | 
|
| 
       122 
124 
     | 
    
         
             
                      #endif
         
     | 
| 
       123 
125 
     | 
    
         
             
                    #endif
         
     | 
| 
       124 
126 
     | 
    
         
             
                    #ifndef AUTOC_STATIC
         
     | 
| 
       125 
     | 
    
         
            -
                      # 
     | 
| 
      
 127 
     | 
    
         
            +
                      #if defined(_MSC_VER)
         
     | 
| 
       126 
128 
     | 
    
         
             
                        #define AUTOC_STATIC __pragma(warning(suppress:4100)) static
         
     | 
| 
       127 
129 
     | 
    
         
             
                      #elif defined(__GNUC__)
         
     | 
| 
       128 
130 
     | 
    
         
             
                        #define AUTOC_STATIC __attribute__((__used__)) static
         
     | 
| 
         @@ -161,7 +163,7 @@ class Type < Code 
     | 
|
| 
       161 
163 
     | 
    
         | 
| 
       162 
164 
     | 
    
         
             
              def prefix
         
     | 
| 
       163 
165 
     | 
    
         
             
                # Lazy evaluator for simple types like char* which do not actually use
         
     | 
| 
       164 
     | 
    
         
            -
                # this method and hence do not require the prefix to be valid C identifier
         
     | 
| 
      
 166 
     | 
    
         
            +
                # this method and hence do not require the prefix to be a valid C identifier
         
     | 
| 
       165 
167 
     | 
    
         
             
                AutoC.c_id(type)
         
     | 
| 
       166 
168 
     | 
    
         
             
              end
         
     | 
| 
       167 
169 
     | 
    
         | 
| 
         @@ -169,20 +171,27 @@ class Type < Code 
     | 
|
| 
       169 
171 
     | 
    
         
             
                @type = type.to_s
         
     | 
| 
       170 
172 
     | 
    
         
             
                @type_ref = "#{self.type}*"
         
     | 
| 
       171 
173 
     | 
    
         
             
                @visibility = [:public, :private, :static].include?(visibility) ? visibility : raise("unsupported visibility")
         
     | 
| 
       172 
     | 
    
         
            -
                @capability = Set[:constructible, :destructible, :copyable, :comparable, :hashable, :orderable] # Can be used to disable specific capabilities for a type
         
     | 
| 
       173 
174 
     | 
    
         
             
                # Canonic special method signatures
         
     | 
| 
       174 
     | 
    
         
            -
                @ 
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
     | 
    
         
            -
             
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
             
     | 
| 
      
 175 
     | 
    
         
            +
                @signature = {
         
     | 
| 
      
 176 
     | 
    
         
            +
                  :ctor => Function::Signature.new([type^:self]),
         
     | 
| 
      
 177 
     | 
    
         
            +
                  :dtor => Function::Signature.new([type^:self]),
         
     | 
| 
      
 178 
     | 
    
         
            +
                  :copy => Function::Signature.new([type^:dst, type^:src]),
         
     | 
| 
      
 179 
     | 
    
         
            +
                  :equal => Function::Signature.new([type^:lt, type^:rt], :int),
         
     | 
| 
      
 180 
     | 
    
         
            +
                  :identify => Function::Signature.new([type^:self], :size_t),
         
     | 
| 
      
 181 
     | 
    
         
            +
                  :less => Function::Signature.new([type^:lt, type^:rt], :int),
         
     | 
| 
      
 182 
     | 
    
         
            +
                }
         
     | 
| 
       180 
183 
     | 
    
         
             
              end
         
     | 
| 
       181 
184 
     | 
    
         | 
| 
       182 
185 
     | 
    
         
             
              def method_missing(method, *args)
         
     | 
| 
       183 
186 
     | 
    
         
             
                str = method.to_s
         
     | 
| 
       184 
187 
     | 
    
         
             
                str = str.sub(/[\!\?]$/, '') # Strip trailing ? or !
         
     | 
| 
      
 188 
     | 
    
         
            +
                x = false # Have leading underscore
         
     | 
| 
      
 189 
     | 
    
         
            +
                if /_(.*)/ =~ str
         
     | 
| 
      
 190 
     | 
    
         
            +
                  str = $1
         
     | 
| 
      
 191 
     | 
    
         
            +
                  x = true
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
       185 
193 
     | 
    
         
             
                fn = prefix + str[0,1].capitalize + str[1..-1] # Ruby 1.8 compatible
         
     | 
| 
      
 194 
     | 
    
         
            +
                fn = "_" << fn if x # Carry over the leading underscore
         
     | 
| 
       186 
195 
     | 
    
         
             
                if args.empty?
         
     | 
| 
       187 
196 
     | 
    
         
             
                  fn # Emit bare function name
         
     | 
| 
       188 
197 
     | 
    
         
             
                elsif args.size == 1 && args.first == nil
         
     | 
| 
         @@ -217,27 +226,29 @@ class Type < Code 
     | 
|
| 
       217 
226 
     | 
    
         
             
                end
         
     | 
| 
       218 
227 
     | 
    
         
             
              end
         
     | 
| 
       219 
228 
     | 
    
         | 
| 
      
 229 
     | 
    
         
            +
              # Abstract methods which must be defined in descendant classes
         
     | 
| 
      
 230 
     | 
    
         
            +
              
         
     | 
| 
       220 
231 
     | 
    
         
             
              # def write_intf_types(stream)
         
     | 
| 
       221 
232 
     | 
    
         | 
| 
       222 
233 
     | 
    
         
             
              # def write_intf_decls(stream, declare, define)
         
     | 
| 
       223 
234 
     | 
    
         | 
| 
       224 
235 
     | 
    
         
             
              # def write_impls(stream, define)
         
     | 
| 
       225 
236 
     | 
    
         | 
| 
       226 
     | 
    
         
            -
              def extern;  
     | 
| 
      
 237 
     | 
    
         
            +
              def extern; :AUTOC_EXTERN end
         
     | 
| 
       227 
238 
     | 
    
         | 
| 
       228 
     | 
    
         
            -
              def inline;  
     | 
| 
      
 239 
     | 
    
         
            +
              def inline; :AUTOC_INLINE end
         
     | 
| 
       229 
240 
     | 
    
         | 
| 
       230 
     | 
    
         
            -
              def static;  
     | 
| 
      
 241 
     | 
    
         
            +
              def static; :AUTOC_STATIC end
         
     | 
| 
       231 
242 
     | 
    
         | 
| 
       232 
     | 
    
         
            -
              def assert;  
     | 
| 
      
 243 
     | 
    
         
            +
              def assert; :assert end
         
     | 
| 
       233 
244 
     | 
    
         | 
| 
       234 
     | 
    
         
            -
              def malloc;  
     | 
| 
      
 245 
     | 
    
         
            +
              def malloc; :malloc end
         
     | 
| 
       235 
246 
     | 
    
         | 
| 
       236 
     | 
    
         
            -
              def calloc;  
     | 
| 
      
 247 
     | 
    
         
            +
              def calloc; :calloc end
         
     | 
| 
       237 
248 
     | 
    
         | 
| 
       238 
     | 
    
         
            -
              def free;  
     | 
| 
      
 249 
     | 
    
         
            +
              def free; :free end
         
     | 
| 
       239 
250 
     | 
    
         | 
| 
       240 
     | 
    
         
            -
              def abort;  
     | 
| 
      
 251 
     | 
    
         
            +
              def abort; :abort end
         
     | 
| 
       241 
252 
     | 
    
         | 
| 
       242 
253 
     | 
    
         
             
              def public?; @visibility == :public end
         
     | 
| 
       243 
254 
     | 
    
         | 
| 
         @@ -245,17 +256,29 @@ class Type < Code 
     | 
|
| 
       245 
256 
     | 
    
         | 
| 
       246 
257 
     | 
    
         
             
              def static?; @visibility == :static end
         
     | 
| 
       247 
258 
     | 
    
         | 
| 
       248 
     | 
    
         
            -
               
     | 
| 
      
 259 
     | 
    
         
            +
              # A generic type is not required to provide any special functions therefore all the
         
     | 
| 
      
 260 
     | 
    
         
            +
              # availability methods below return false
         
     | 
| 
      
 261 
     | 
    
         
            +
                
         
     | 
| 
      
 262 
     | 
    
         
            +
              # Returns *true* if the type provides a well-defined parameterless default type constructor
         
     | 
| 
      
 263 
     | 
    
         
            +
              def constructible?; false end
         
     | 
| 
       249 
264 
     | 
    
         | 
| 
       250 
     | 
    
         
            -
               
     | 
| 
      
 265 
     | 
    
         
            +
              # Returns *true* if the type provides a well-defined type constructor which can have extra arguments
         
     | 
| 
      
 266 
     | 
    
         
            +
              def initializable?; false end
         
     | 
| 
       251 
267 
     | 
    
         | 
| 
       252 
     | 
    
         
            -
               
     | 
| 
      
 268 
     | 
    
         
            +
              # Returns *true* if the type provides a well-defined type destructor
         
     | 
| 
      
 269 
     | 
    
         
            +
              def destructible?; false end
         
     | 
| 
       253 
270 
     | 
    
         | 
| 
       254 
     | 
    
         
            -
               
     | 
| 
      
 271 
     | 
    
         
            +
              # Returns *true* if the type provides a well-defined copy constructor to create a clone of an instance
         
     | 
| 
      
 272 
     | 
    
         
            +
              def copyable?; false end
         
     | 
| 
      
 273 
     | 
    
         
            +
             
     | 
| 
      
 274 
     | 
    
         
            +
              # Returns *true* if the type provides a well-defined equality test function
         
     | 
| 
      
 275 
     | 
    
         
            +
              def comparable?; false end
         
     | 
| 
       255 
276 
     | 
    
         | 
| 
       256 
     | 
    
         
            -
               
     | 
| 
      
 277 
     | 
    
         
            +
              # Returns *true* if the type provides a well-defined 'less than' test function
         
     | 
| 
      
 278 
     | 
    
         
            +
              def orderable?; false end
         
     | 
| 
       257 
279 
     | 
    
         | 
| 
       258 
     | 
    
         
            -
               
     | 
| 
      
 280 
     | 
    
         
            +
              # Returns *true* if the type provides a well-defined hash calculation function
         
     | 
| 
      
 281 
     | 
    
         
            +
              def hashable?; false end
         
     | 
| 
       259 
282 
     | 
    
         | 
| 
       260 
283 
     | 
    
         
             
              # Create forwarding readers which take arbitrary number of arguments
         
     | 
| 
       261 
284 
     | 
    
         
             
              [:ctor, :dtor, :copy, :equal, :identify, :less].each do |name|
         
     | 
| 
         @@ -266,12 +289,6 @@ class Type < Code 
     | 
|
| 
       266 
289 
     | 
    
         
             
                $
         
     | 
| 
       267 
290 
     | 
    
         
             
              end
         
     | 
| 
       268 
291 
     | 
    
         | 
| 
       269 
     | 
    
         
            -
              private
         
     | 
| 
       270 
     | 
    
         
            -
             
     | 
| 
       271 
     | 
    
         
            -
              def define_function(name, signature)
         
     | 
| 
       272 
     | 
    
         
            -
                Function.new(method_missing(name), signature)
         
     | 
| 
       273 
     | 
    
         
            -
              end
         
     | 
| 
       274 
     | 
    
         
            -
              
         
     | 
| 
       275 
292 
     | 
    
         
             
            end # Type
         
     | 
| 
       276 
293 
     | 
    
         | 
| 
       277 
294 
     | 
    
         | 
| 
         @@ -299,7 +316,7 @@ class UserDefinedType < Type 
     | 
|
| 
       299 
316 
     | 
    
         
             
              def prefix; @prefix.nil? ? super : @prefix end
         
     | 
| 
       300 
317 
     | 
    
         | 
| 
       301 
318 
     | 
    
         
             
              def initialize(opt)
         
     | 
| 
       302 
     | 
    
         
            -
                opt = {:type => opt} if opt.is_a?(Symbol) || opt.is_a?(String)
         
     | 
| 
      
 319 
     | 
    
         
            +
                opt = {:type => opt} if opt.is_a?(::Symbol) || opt.is_a?(::String)
         
     | 
| 
       303 
320 
     | 
    
         
             
                if opt.is_a?(Hash)
         
     | 
| 
       304 
321 
     | 
    
         
             
                  t = opt[:type].nil? ? raise("type is not specified") : opt[:type].to_s
         
     | 
| 
       305 
322 
     | 
    
         
             
                else
         
     | 
| 
         @@ -308,33 +325,55 @@ class UserDefinedType < Type 
     | 
|
| 
       308 
325 
     | 
    
         
             
                super(t)
         
     | 
| 
       309 
326 
     | 
    
         
             
                @prefix = AutoC.c_id(opt[:prefix]) unless opt[:prefix].nil?
         
     | 
| 
       310 
327 
     | 
    
         
             
                @deps = []; @deps << PublicDeclaration.new(opt[:forward]) unless opt[:forward].nil?
         
     | 
| 
       311 
     | 
    
         
            -
                opt 
     | 
| 
       312 
     | 
    
         
            -
                 
     | 
| 
       313 
     | 
    
         
            -
                 
     | 
| 
       314 
     | 
    
         
            -
                 
     | 
| 
       315 
     | 
    
         
            -
                 
     | 
| 
       316 
     | 
    
         
            -
                 
     | 
| 
       317 
     | 
    
         
            -
                opt[:identify].nil? ? @capability.subtract([:hashable]) : define_callable(:identify, opt) {def call(obj) "((size_t)(#{obj}))" end}
         
     | 
| 
       318 
     | 
    
         
            -
                # Handle specific requirements
         
     | 
| 
       319 
     | 
    
         
            -
                @capability.subtract([:constructible]) if @ctor.parameters.size > 1 # Constructible type must not have extra parameters besides self
         
     | 
| 
      
 328 
     | 
    
         
            +
                define_callable(:ctor, opt) {def call(obj) "((#{obj}) = 0)" end}
         
     | 
| 
      
 329 
     | 
    
         
            +
                define_callable(:dtor, opt) {def call(obj) end}
         
     | 
| 
      
 330 
     | 
    
         
            +
                define_callable(:copy, opt) {def call(dst, src) "((#{dst}) = (#{src}))" end}
         
     | 
| 
      
 331 
     | 
    
         
            +
                define_callable(:equal, opt) {def call(lt, rt) "((#{lt}) == (#{rt}))" end}
         
     | 
| 
      
 332 
     | 
    
         
            +
                define_callable(:less, opt) {def call(lt, rt) "((#{lt}) < (#{rt}))" end}
         
     | 
| 
      
 333 
     | 
    
         
            +
                define_callable(:identify, opt) {def call(obj) "((size_t)(#{obj}))" end}
         
     | 
| 
       320 
334 
     | 
    
         
             
              end
         
     | 
| 
       321 
335 
     | 
    
         | 
| 
      
 336 
     | 
    
         
            +
              def constructible?; !@ctor.nil? && @ctor.parameters.size == 1 end
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
      
 338 
     | 
    
         
            +
              def initializable?; !@ctor.nil? end
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
              def destructible?; !@dtor.nil? end
         
     | 
| 
      
 341 
     | 
    
         
            +
             
     | 
| 
      
 342 
     | 
    
         
            +
              def copyable?; !@copy.nil? end
         
     | 
| 
      
 343 
     | 
    
         
            +
             
     | 
| 
      
 344 
     | 
    
         
            +
              def comparable?; !@equal.nil? end
         
     | 
| 
      
 345 
     | 
    
         
            +
             
     | 
| 
      
 346 
     | 
    
         
            +
              def orderable?; !@less.nil? end
         
     | 
| 
      
 347 
     | 
    
         
            +
             
     | 
| 
      
 348 
     | 
    
         
            +
              def hashable?; !@identify.nil? end
         
     | 
| 
      
 349 
     | 
    
         
            +
                
         
     | 
| 
      
 350 
     | 
    
         
            +
              # The methods below are left empty as the user-defined types have no implementation on their own
         
     | 
| 
      
 351 
     | 
    
         
            +
             
     | 
| 
      
 352 
     | 
    
         
            +
              def write_intf_types(stream) end
         
     | 
| 
      
 353 
     | 
    
         
            +
             
     | 
| 
      
 354 
     | 
    
         
            +
              def write_intf_decls(stream, declare, define) end
         
     | 
| 
      
 355 
     | 
    
         
            +
             
     | 
| 
      
 356 
     | 
    
         
            +
              def write_impls(stream, define) end
         
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
       322 
358 
     | 
    
         
             
              private
         
     | 
| 
       323 
359 
     | 
    
         | 
| 
       324 
360 
     | 
    
         
             
              # Default methods creator
         
     | 
| 
       325 
361 
     | 
    
         
             
              def define_callable(name, opt, &code)
         
     | 
| 
       326 
     | 
    
         
            -
                 
     | 
| 
       327 
     | 
    
         
            -
             
     | 
| 
       328 
     | 
    
         
            -
                c = if opt[name] == :unset
         
     | 
| 
       329 
     | 
    
         
            -
                  # Synthesize statement block with default (canonic) parameter list
         
     | 
| 
       330 
     | 
    
         
            -
                  Class.new(Statement, &code).new(instance_variable_get(ivs).parameters)
         
     | 
| 
       331 
     | 
    
         
            -
                elsif opt[name].is_a?(Function)
         
     | 
| 
       332 
     | 
    
         
            -
                  opt[name] # If a Function instance is given, pass it through
         
     | 
| 
      
 362 
     | 
    
         
            +
                c = if opt.has_key?(name) && opt[name].nil?
         
     | 
| 
      
 363 
     | 
    
         
            +
                  nil # Disable specific capability by explicitly setting the key to nil
         
     | 
| 
       333 
364 
     | 
    
         
             
                else
         
     | 
| 
       334 
     | 
    
         
            -
                   
     | 
| 
       335 
     | 
    
         
            -
                   
     | 
| 
      
 365 
     | 
    
         
            +
                  signature = @signature[name]
         
     | 
| 
      
 366 
     | 
    
         
            +
                  c = if opt[name].nil?
         
     | 
| 
      
 367 
     | 
    
         
            +
                    # Implicit nil as returned by Hash#default method does synthesize statement block with default (canonic) parameter list
         
     | 
| 
      
 368 
     | 
    
         
            +
                    Class.new(Statement, &code).new(signature.parameters)
         
     | 
| 
      
 369 
     | 
    
         
            +
                  elsif opt[name].is_a?(Function)
         
     | 
| 
      
 370 
     | 
    
         
            +
                    opt[name] # If a Function instance is given, pass it through
         
     | 
| 
      
 371 
     | 
    
         
            +
                  else
         
     | 
| 
      
 372 
     | 
    
         
            +
                    # If only a name is specified, assume it is the function name with default signature
         
     | 
| 
      
 373 
     | 
    
         
            +
                    Function.new(opt[name], signature)
         
     | 
| 
      
 374 
     | 
    
         
            +
                  end
         
     | 
| 
       336 
375 
     | 
    
         
             
                end
         
     | 
| 
       337 
     | 
    
         
            -
                instance_variable_set( 
     | 
| 
      
 376 
     | 
    
         
            +
                instance_variable_set("@#{name}", c)
         
     | 
| 
       338 
377 
     | 
    
         
             
              end
         
     | 
| 
       339 
378 
     | 
    
         | 
| 
       340 
379 
     | 
    
         
             
            end # UserDefinedType
         
     | 
| 
         @@ -376,13 +415,18 @@ class Reference < Type 
     | 
|
| 
       376 
415 
     | 
    
         
             
              def_delegators :@target,
         
     | 
| 
       377 
416 
     | 
    
         
             
                :prefix,
         
     | 
| 
       378 
417 
     | 
    
         
             
                :public?, :private?, :static?,
         
     | 
| 
       379 
     | 
    
         
            -
                :constructible?, : 
     | 
| 
       380 
     | 
    
         
            -
             
     | 
| 
      
 418 
     | 
    
         
            +
                :constructible?, :initializable?, :destructible?, :comparable?, :orderable?, :hashable?
         
     | 
| 
      
 419 
     | 
    
         
            +
             
     | 
| 
      
 420 
     | 
    
         
            +
              # Return *true* since reference copying involves no call to the underlying type's copy constructor  
         
     | 
| 
      
 421 
     | 
    
         
            +
              def copyable?; true end
         
     | 
| 
      
 422 
     | 
    
         
            +
                
         
     | 
| 
      
 423 
     | 
    
         
            +
              attr_reader :target
         
     | 
| 
      
 424 
     | 
    
         
            +
                
         
     | 
| 
       381 
425 
     | 
    
         
             
              def initialize(target)
         
     | 
| 
       382 
426 
     | 
    
         
             
                @target = Type.coerce(target)
         
     | 
| 
       383 
427 
     | 
    
         
             
                super(@target.type_ref) # NOTE : the type of the Reference instance itself is actually a pointer type
         
     | 
| 
       384 
     | 
    
         
            -
                @ 
     | 
| 
       385 
     | 
    
         
            -
                define_callable(:ctor, @ 
     | 
| 
      
 428 
     | 
    
         
            +
                @init = Dispatcher::ParameterArray.new(@target.ctor.parameters[1..-1]) # Capture extra parameters from the target type constructor
         
     | 
| 
      
 429 
     | 
    
         
            +
                define_callable(:ctor, @init) {def call(obj, *params) "((#{obj}) = #{@ref.new?}(#{params.join(',')}))" end}
         
     | 
| 
       386 
430 
     | 
    
         
             
                define_callable(:dtor, [type]) {def call(obj) "#{@ref.free?}(#{obj})" end}
         
     | 
| 
       387 
431 
     | 
    
         
             
                define_callable(:copy, [type, type]) {def call(dst, src) "((#{dst}) = #{@ref.ref?}(#{src}))" end}
         
     | 
| 
       388 
432 
     | 
    
         
             
                define_callable(:equal, [type, type]) {def call(lt, rt) @target.equal("*#{lt}", "*#{rt}") end}
         
     | 
| 
         @@ -401,7 +445,7 @@ class Reference < Type 
     | 
|
| 
       401 
445 
     | 
    
         
             
                  /***
         
     | 
| 
       402 
446 
     | 
    
         
             
                  ****  <#{type}> (#{self.class})
         
     | 
| 
       403 
447 
     | 
    
         
             
                  ***/
         
     | 
| 
       404 
     | 
    
         
            -
                  #{declare} #{type} #{new?}(#{@ 
     | 
| 
      
 448 
     | 
    
         
            +
                  #{declare} #{type} #{new?}(#{@init.declaration});
         
     | 
| 
       405 
449 
     | 
    
         
             
                  #{declare} #{type} #{ref?}(#{type});
         
     | 
| 
       406 
450 
     | 
    
         
             
                  #{declare} void #{free?}(#{type});
         
     | 
| 
       407 
451 
     | 
    
         
             
                $
         
     | 
| 
         @@ -410,9 +454,9 @@ class Reference < Type 
     | 
|
| 
       410 
454 
     | 
    
         
             
              def write_impls(stream, define)
         
     | 
| 
       411 
455 
     | 
    
         
             
                stream << %$
         
     | 
| 
       412 
456 
     | 
    
         
             
                #define AUTOC_COUNTER(p) (*(size_t*)((char*)(p) + sizeof(#{@target.type})))
         
     | 
| 
       413 
     | 
    
         
            -
                  #{define} #{type} #{new?}(#{@ 
     | 
| 
      
 457 
     | 
    
         
            +
                  #{define} #{type} #{new?}(#{@init.definition}) {
         
     | 
| 
       414 
458 
     | 
    
         
             
                    #{type} self = (#{type})#{malloc}(sizeof(#{@target.type}) + sizeof(size_t)); #{assert}(self);
         
     | 
| 
       415 
     | 
    
         
            -
                    #{@target.ctor("*self", *@ 
     | 
| 
      
 459 
     | 
    
         
            +
                    #{@target.ctor("*self", *@init.names)};
         
     | 
| 
       416 
460 
     | 
    
         
             
                    AUTOC_COUNTER(self) = 1;
         
     | 
| 
       417 
461 
     | 
    
         
             
                    return self;
         
     | 
| 
       418 
462 
     | 
    
         
             
                  }
         
     | 
| 
         @@ -443,15 +487,60 @@ class Reference < Type 
     | 
|
| 
       443 
487 
     | 
    
         
             
                end
         
     | 
| 
       444 
488 
     | 
    
         
             
              end # BoundStatement
         
     | 
| 
       445 
489 
     | 
    
         | 
| 
       446 
     | 
    
         
            -
              def define_callable(name,  
     | 
| 
       447 
     | 
    
         
            -
                instance_variable_set("@#{name}", Class.new(BoundStatement, &code).new(self, @target,  
     | 
| 
      
 490 
     | 
    
         
            +
              def define_callable(name, param_types, &code)
         
     | 
| 
      
 491 
     | 
    
         
            +
                instance_variable_set("@#{name}", Class.new(BoundStatement, &code).new(self, @target, param_types))
         
     | 
| 
       448 
492 
     | 
    
         
             
              end
         
     | 
| 
       449 
493 
     | 
    
         | 
| 
       450 
494 
     | 
    
         
             
            end # Reference
         
     | 
| 
       451 
495 
     | 
    
         | 
| 
       452 
496 
     | 
    
         | 
| 
      
 497 
     | 
    
         
            +
            # @private
         
     | 
| 
      
 498 
     | 
    
         
            +
            module Type::Redirecting
         
     | 
| 
      
 499 
     | 
    
         
            +
             
     | 
| 
      
 500 
     | 
    
         
            +
              # Setup special methods which receive types by reference instead of by value
         
     | 
| 
      
 501 
     | 
    
         
            +
              def initialize_redirectors
         
     | 
| 
      
 502 
     | 
    
         
            +
                define_redirector(:ctor, Function::Signature.new([type_ref^:self]))
         
     | 
| 
      
 503 
     | 
    
         
            +
                define_redirector(:dtor, Function::Signature.new([type_ref^:self]))
         
     | 
| 
      
 504 
     | 
    
         
            +
                define_redirector(:copy, Function::Signature.new([type_ref^:dst, type_ref^:src]))
         
     | 
| 
      
 505 
     | 
    
         
            +
                define_redirector(:equal, Function::Signature.new([type_ref^:lt, type_ref^:rt], :int))
         
     | 
| 
      
 506 
     | 
    
         
            +
                define_redirector(:identify, Function::Signature.new([type_ref^:self], :size_t))
         
     | 
| 
      
 507 
     | 
    
         
            +
                define_redirector(:less, Function::Signature.new([type_ref^:lt, type_ref^:rt], :int))
         
     | 
| 
      
 508 
     | 
    
         
            +
              end
         
     | 
| 
      
 509 
     | 
    
         
            +
              
         
     | 
| 
      
 510 
     | 
    
         
            +
              def write_redirectors(stream, declare, define)
         
     | 
| 
      
 511 
     | 
    
         
            +
                # Emit default redirection macros
         
     | 
| 
      
 512 
     | 
    
         
            +
                # Unlike other special methods the constructors may have extra arguments
         
     | 
| 
      
 513 
     | 
    
         
            +
                # Assume the constructor's first parameter is always a target
         
     | 
| 
      
 514 
     | 
    
         
            +
                ctor_ex = ctor.parameters.names[1..-1]
         
     | 
| 
      
 515 
     | 
    
         
            +
                ctor_lt = ["self"].concat(ctor_ex).join(',')
         
     | 
| 
      
 516 
     | 
    
         
            +
                ctor_rt = ["&self"].concat(ctor_ex).join(',')
         
     | 
| 
      
 517 
     | 
    
         
            +
                stream << %$
         
     | 
| 
      
 518 
     | 
    
         
            +
                  #define _#{ctor}(#{ctor_lt}) #{ctor}(#{ctor_rt})
         
     | 
| 
      
 519 
     | 
    
         
            +
                  #define _#{dtor}(self) #{dtor}(&self)
         
     | 
| 
      
 520 
     | 
    
         
            +
                  #define _#{identify}(self) #{identify}(&self)
         
     | 
| 
      
 521 
     | 
    
         
            +
                  #define _#{copy}(dst,src) #{copy}(&dst,&src)
         
     | 
| 
      
 522 
     | 
    
         
            +
                  #define _#{equal}(lt,rt) #{equal}(<,&rt)
         
     | 
| 
      
 523 
     | 
    
         
            +
                  #define _#{less}(lt,rt) #{less}(<,&rt)
         
     | 
| 
      
 524 
     | 
    
         
            +
                $
         
     | 
| 
      
 525 
     | 
    
         
            +
              end
         
     | 
| 
      
 526 
     | 
    
         
            +
              
         
     | 
| 
      
 527 
     | 
    
         
            +
            private
         
     | 
| 
      
 528 
     | 
    
         
            +
                  
         
     | 
| 
      
 529 
     | 
    
         
            +
              # @private
         
     | 
| 
      
 530 
     | 
    
         
            +
              class Redirector < Function
         
     | 
| 
      
 531 
     | 
    
         
            +
                # Redirect call to the specific macro
         
     | 
| 
      
 532 
     | 
    
         
            +
                def call(*params) "_#{name}(" + params.join(',') + ')' end
         
     | 
| 
      
 533 
     | 
    
         
            +
              end # Redirector
         
     | 
| 
      
 534 
     | 
    
         
            +
              
         
     | 
| 
      
 535 
     | 
    
         
            +
              def define_redirector(name, signature)
         
     | 
| 
      
 536 
     | 
    
         
            +
                instance_variable_set("@#{name}", Redirector.new(method_missing(name), signature))
         
     | 
| 
      
 537 
     | 
    
         
            +
              end
         
     | 
| 
      
 538 
     | 
    
         
            +
                  
         
     | 
| 
      
 539 
     | 
    
         
            +
            end # Redirecting
         
     | 
| 
      
 540 
     | 
    
         
            +
             
     | 
| 
      
 541 
     | 
    
         
            +
             
     | 
| 
       453 
542 
     | 
    
         
             
            # Class adjustments for the function signature definition DSL
         
     | 
| 
       454 
     | 
    
         
            -
            [Symbol, String, Type].each do |type|
         
     | 
| 
      
 543 
     | 
    
         
            +
            [::Symbol, ::String, Type].each do |type|
         
     | 
| 
       455 
544 
     | 
    
         
             
              type.class_eval do 
         
     | 
| 
       456 
545 
     | 
    
         
             
                def ^(name)
         
     | 
| 
       457 
546 
     | 
    
         
             
                  [self, name]
         
     | 
    
        data/test/test.rb
    CHANGED
    
    | 
         @@ -1,36 +1,158 @@ 
     | 
|
| 
       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 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            =begin
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            This is the AutoC automatic unit test generator.
         
     | 
| 
      
 4 
     | 
    
         
            +
            Usage instruction:
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            1. Generate get test's source code (test_auto.c and test_auto.h):
         
     | 
| 
      
 7 
     | 
    
         
            +
            > ruby -I . -I ../lib test.rb
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            2. Compile the generated code:
         
     | 
| 
      
 10 
     | 
    
         
            +
            > cc test_auto.c
         
     | 
| 
      
 11 
     | 
    
         
            +
              
         
     | 
| 
      
 12 
     | 
    
         
            +
            3. Run the tests:
         
     | 
| 
      
 13 
     | 
    
         
            +
            > ./a.out
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            The code is intended to finish succesfully,
         
     | 
| 
      
 16 
     | 
    
         
            +
            the process' exit code is zero when all tests are passed
         
     | 
| 
      
 17 
     | 
    
         
            +
            ano non-zero if there were failed tests.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            The compile-time warnings are possible and may be ignored.
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            The compiled code should also pass the memory leakage tests
         
     | 
| 
      
 22 
     | 
    
         
            +
            (with Valgrind, Dr.Memory etc.)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            =end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            require "autoc"
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            Prologue = Class.new(AutoC::Code) do
         
     | 
| 
      
 29 
     | 
    
         
            +
              def write_defs(stream)
         
     | 
| 
      
 30 
     | 
    
         
            +
                stream << %~
         
     | 
| 
      
 31 
     | 
    
         
            +
                  #include <stdio.h>
         
     | 
| 
      
 32 
     | 
    
         
            +
                  struct {
         
     | 
| 
      
 33 
     | 
    
         
            +
                    int total, processed, failed;
         
     | 
| 
      
 34 
     | 
    
         
            +
                  } tests;
         
     | 
| 
      
 35 
     | 
    
         
            +
                  int failure;
         
     | 
| 
      
 36 
     | 
    
         
            +
                  typedef void (*test_func)(void);
         
     | 
| 
      
 37 
     | 
    
         
            +
                  void run_test(const char* name, test_func func) {
         
     | 
| 
      
 38 
     | 
    
         
            +
                    fprintf(stdout, "+   %s\\n", name);
         
     | 
| 
      
 39 
     | 
    
         
            +
                    fflush(stdout);
         
     | 
| 
      
 40 
     | 
    
         
            +
                    failure = 0;
         
     | 
| 
      
 41 
     | 
    
         
            +
                    func();
         
     | 
| 
      
 42 
     | 
    
         
            +
                    if(failure) tests.failed++;
         
     | 
| 
      
 43 
     | 
    
         
            +
                    tests.processed++;
         
     | 
| 
      
 44 
     | 
    
         
            +
                  }
         
     | 
| 
      
 45 
     | 
    
         
            +
                  void print_condition_failure(const char* message, const char* condition, const char* file, int line) {
         
     | 
| 
      
 46 
     | 
    
         
            +
                    fprintf(stderr, "*** %s : %s (%s:%d)\\n", condition, message, file, line);
         
     | 
| 
      
 47 
     | 
    
         
            +
                    fflush(stderr);
         
     | 
| 
      
 48 
     | 
    
         
            +
                    failure = 1;
         
     | 
| 
      
 49 
     | 
    
         
            +
                  }
         
     | 
| 
      
 50 
     | 
    
         
            +
                  void print_equality_failure(const char* message, const char* x, const char* y, const char* file, int line) {
         
     | 
| 
      
 51 
     | 
    
         
            +
                    fprintf(stderr, "*** %s == %s : %s (%s:%d)\\n", x, y, message, file, line);
         
     | 
| 
      
 52 
     | 
    
         
            +
                    fflush(stderr);
         
     | 
| 
      
 53 
     | 
    
         
            +
                    failure = 1;
         
     | 
| 
      
 54 
     | 
    
         
            +
                  }
         
     | 
| 
      
 55 
     | 
    
         
            +
                  void print_summary(void) {
         
     | 
| 
      
 56 
     | 
    
         
            +
                    if(tests.failed)
         
     | 
| 
      
 57 
     | 
    
         
            +
                      fprintf(stdout, "*** Failed %d of %d tests\\n", tests.failed, tests.processed);
         
     | 
| 
      
 58 
     | 
    
         
            +
                    else
         
     | 
| 
      
 59 
     | 
    
         
            +
                      fprintf(stdout, "+++ All %d tests passed successfully\\n", tests.processed);
         
     | 
| 
      
 60 
     | 
    
         
            +
                    fflush(stdout);
         
     | 
| 
      
 61 
     | 
    
         
            +
                  }
         
     | 
| 
      
 62 
     | 
    
         
            +
                  #define TEST_MESSAGE(s) fprintf(stderr, "*** %s\\n", s); fflush(stderr);
         
     | 
| 
      
 63 
     | 
    
         
            +
                  #define TEST_ASSERT(x) if(x) {} else print_condition_failure("evaluated to FALSE", #x, __FILE__, __LINE__) 
         
     | 
| 
      
 64 
     | 
    
         
            +
                  #define TEST_TRUE(x) if(x) {} else print_condition_failure("expected TRUE but got FALSE", #x, __FILE__, __LINE__) 
         
     | 
| 
      
 65 
     | 
    
         
            +
                  #define TEST_FALSE(x) if(x) print_condition_failure("expected FALSE but got TRUE", #x, __FILE__, __LINE__)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  #define TEST_NULL(x) if((x) == NULL) {} else print_condition_failure("expected NULL", #x, __FILE__, __LINE__) 
         
     | 
| 
      
 67 
     | 
    
         
            +
                  #define TEST_NOT_NULL(x) if((x) == NULL) print_condition_failure("expected not NULL", #x, __FILE__, __LINE__)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  #define TEST_EQUAL(x, y) if((x) == (y)) {} else print_equality_failure("expected equality", #x, #y, __FILE__, __LINE__)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  #define TEST_NOT_EQUAL(x, y) if((x) == (y)) print_equality_failure("expected non-equality", #x, #y, __FILE__, __LINE__)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  #define TEST_EQUAL_CHARS(x, y) if(strcmp(x, y) == 0) {} else print_equality_failure("expected strings equality", #x, #y, __FILE__, __LINE__)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  #define TEST_NOT_EQUAL_CHARS(x, y) if(strcmp(x, y) == 0) print_equality_failure("expected strings non-equality", #x, #y, __FILE__, __LINE__)
         
     | 
| 
      
 72 
     | 
    
         
            +
                ~
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
            end.new
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            Epilogue = Class.new(AutoC::Code) do
         
     | 
| 
      
 78 
     | 
    
         
            +
              def priority; AutoC::Priority::MIN end
         
     | 
| 
      
 79 
     | 
    
         
            +
              def write_defs(stream)
         
     | 
| 
      
 80 
     | 
    
         
            +
                total = 0
         
     | 
| 
      
 81 
     | 
    
         
            +
                $tests.each {|t| total += t.tests.size}
         
     | 
| 
      
 82 
     | 
    
         
            +
                stream << %~int main(int argc, char** argv) {~
         
     | 
| 
      
 83 
     | 
    
         
            +
                stream << %~
         
     | 
| 
      
 84 
     | 
    
         
            +
                  tests.total = #{total};
         
     | 
| 
      
 85 
     | 
    
         
            +
                  tests.processed = tests.failed = 0;
         
     | 
| 
      
 86 
     | 
    
         
            +
                ~
         
     | 
| 
      
 87 
     | 
    
         
            +
                $tests.each {|t| t.write_test_calls(stream)}
         
     | 
| 
      
 88 
     | 
    
         
            +
                stream << %~print_summary();~
         
     | 
| 
      
 89 
     | 
    
         
            +
                stream << %~return tests.failed > 0;}~
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
            end.new
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
            $tests = []
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            def type_test(cls, *opts, &code)
         
     | 
| 
      
 98 
     | 
    
         
            +
              t = Class.new(cls) do
         
     | 
| 
      
 99 
     | 
    
         
            +
                def entities; super << Prologue end
         
     | 
| 
      
 100 
     | 
    
         
            +
                attr_reader :tests
         
     | 
| 
      
 101 
     | 
    
         
            +
                def initialize(*args)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  super
         
     | 
| 
      
 103 
     | 
    
         
            +
                  @tests = []
         
     | 
| 
      
 104 
     | 
    
         
            +
                  @test_names = []
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
                def setup(code = nil)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  @setup_code = code
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
                def cleanup(code = nil)
         
     | 
| 
      
 110 
     | 
    
         
            +
                  @cleanup_code = code
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
                def test(name, code)
         
     | 
| 
      
 113 
     | 
    
         
            +
                  s = name.to_s
         
     | 
| 
      
 114 
     | 
    
         
            +
                  @test_names << [name, func_name = eval("test#{s[0,1].upcase}#{s[1..-1]}")]
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @tests << %~
         
     | 
| 
      
 116 
     | 
    
         
            +
                    void #{func_name}(void) {
         
     | 
| 
      
 117 
     | 
    
         
            +
                      #{@setup_code}
         
     | 
| 
      
 118 
     | 
    
         
            +
                      #{code}
         
     | 
| 
      
 119 
     | 
    
         
            +
                      #{@cleanup_code}
         
     | 
| 
      
 120 
     | 
    
         
            +
                    }
         
     | 
| 
      
 121 
     | 
    
         
            +
                  ~
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
                def write_defs(stream)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  super
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @tests.each {|f| stream << f}
         
     | 
| 
      
 126 
     | 
    
         
            +
                  stream << %~void #{runTests}(void) {~
         
     | 
| 
      
 127 
     | 
    
         
            +
                    stream << %~
         
     | 
| 
      
 128 
     | 
    
         
            +
                      fprintf(stdout, "+ %s\\n", "#{type}");
         
     | 
| 
      
 129 
     | 
    
         
            +
                      fflush(stdout);
         
     | 
| 
      
 130 
     | 
    
         
            +
                    ~
         
     | 
| 
      
 131 
     | 
    
         
            +
                    @test_names.each do |name, func_name|
         
     | 
| 
      
 132 
     | 
    
         
            +
                      stream << %~
         
     | 
| 
      
 133 
     | 
    
         
            +
                        run_test("#{name}", #{func_name});
         
     | 
| 
      
 134 
     | 
    
         
            +
                      ~
         
     | 
| 
      
 135 
     | 
    
         
            +
                    end
         
     | 
| 
      
 136 
     | 
    
         
            +
                  stream << %~
         
     | 
| 
      
 137 
     | 
    
         
            +
                    fputs("\\n", stdout); fflush(stdout);}
         
     | 
| 
      
 138 
     | 
    
         
            +
                  ~
         
     | 
| 
      
 139 
     | 
    
         
            +
                end
         
     | 
| 
      
 140 
     | 
    
         
            +
                def write_test_calls(stream)
         
     | 
| 
      
 141 
     | 
    
         
            +
                  stream << %$
         
     | 
| 
      
 142 
     | 
    
         
            +
                    #{runTests}();
         
     | 
| 
      
 143 
     | 
    
         
            +
                  $
         
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
              end.new(*opts)
         
     | 
| 
      
 146 
     | 
    
         
            +
              $tests << t
         
     | 
| 
      
 147 
     | 
    
         
            +
              t.instance_eval(&code)
         
     | 
| 
      
 148 
     | 
    
         
            +
            end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
            Dir["**/test_*.rb"].each {|t| load t}
         
     | 
| 
      
 152 
     | 
    
         
            +
              
         
     | 
| 
      
 153 
     | 
    
         
            +
              
         
     | 
| 
      
 154 
     | 
    
         
            +
            AutoC::Module.generate!(:Test) do |c|
         
     | 
| 
      
 155 
     | 
    
         
            +
              c << Prologue
         
     | 
| 
      
 156 
     | 
    
         
            +
              $tests.each {|t| c << t}
         
     | 
| 
      
 157 
     | 
    
         
            +
              c << Epilogue
         
     | 
| 
       36 
158 
     | 
    
         
             
            end
         
     |