1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
9 attr_reader :name, :opts, :children
11 def initialize(name, opts = { })
22 mp = @opts[:merge_points].first if @opts[:merge_points]
24 @children.insert(mp.position, desc)
25 @opts[:merge_points].step!
31 def first_valid_merge_point
32 if @opts[:merge_points]
33 @opts[:merge_points].first
38 "(#{@name} #{@opts.inspect}#{@children.map{|c| ' ' + c.to_sexp}.join})"
41 def merge!(other, prefix = "")
42 if name == other.name and
43 opts[:name] == other.opts[:name]
44 other.children.each do |child2|
46 children.each do |child|
47 if child.merge!(child2, prefix + " ")
52 merge_child(child2.dup) unless merged
55 elsif name == :group and other.opts[:group] == opts[:name]
63 attr_accessor :position, :count
79 raise "Stepping invalid merge point list" if @mps.empty?
90 @mps.delete_if {|mp| not mp.valid? }
94 def initialize(position, count = -1)
97 raise "Creating invalid merge point" if @count == 0
106 attr_reader :__desc__
113 def method_missing(name, *args, &blk)
114 opts = if args.empty?
117 if args.first.is_a? Hash
120 { :name => args.first }
123 args[-1].merge(:name => args.first)
125 child = Descriptor.new(name, opts)
126 blk[self.class.new(child)] if block_given?
127 __desc__.add_child(child)
130 def merge_point(count = -1)
131 mp = MergePoint.new(@__desc__.children.size, count)
132 @__desc__.opts[:merge_points] ||= MergePoint::List.new
133 @__desc__.opts[:merge_points].add(mp)