node/lib/metasm/metasm/gui/dasm_graph.rb
def order_graph(groups)
		roots = groups.find_all { |g| g.from.empty? }
		o = {}	# tentative order
		todo = []

		loop do
			roots.each { |g|
				o[g] ||= 0
				todo |= g.to.find_all { |gg| not o[gg] }
			}

			# order nodes from the tentative roots
			until todo.empty?
				n = todo.find { |g| g.from.all? { |gg| o[gg] } } || order_solve_cycle(todo, o)
				todo.delete n
				o[n] = n.from.map { |g| o[g] }.compact.max + 1
				todo |= n.to.find_all { |g| not o[g] }
			end
			break if o.length >= groups.length

			# pathological cases

			if noroot = groups.find_all { |g| o[g] and g.from.find { |gg| not o[gg] } }.sort_by { |g| o[g] }.first
				# we picked a root in the middle of the graph, walk up
				todo |= noroot.from.find_all { |g| not o[g] }
				until todo.empty?
					n = todo.find { |g| g.to.all? { |gg| o[gg] } } ||
					    todo.sort_by { |g| g.to.map { |gg| o[gg] }.compact.min }.first
					todo.delete n
					o[n] = n.to.map { |g| o[g] }.compact.min - 1
					todo |= n.from.find_all { |g| not o[g] }
				end
				# setup todo for next fwd iteration
				todo |= groups.find_all { |g| not o[g] and g.from.find { |gg| o[gg] } }
			else
				# disjoint graph, start over from one other random node
				roots << groups.find { |g| not o[g] }
			end
		end

		if o.values.find { |rank| rank < 0 }
			# did hit a pathological case, restart with found real roots
			roots = groups.find_all { |g| not g.from.find { |gg| o[gg] < o[g] } }
			o = {}
			todo = []
			roots.each { |g|
				o[g] ||= 0
				todo |= g.to.find_all { |gg| not o[gg] }
			}
			until todo.empty?
				n = todo.find { |g| g.from.all? { |gg| o[gg] } } || order_solve_cycle(todo, o)
				todo.delete n
				o[n] = n.from.map { |g| o[g] }.compact.max + 1
				todo |= n.to.find_all { |g| not o[g] }
			end

			# there's something screwy around here !
			raise "moo" if o.length < groups.length
		end

		o
	end
# find the minimal set of nodes from which we can reach all others
# this is done *before* removing cycles in the graph
# returns the order (Hash group => group_order)
# roots have an order of 0
find the minimal set of nodes from which we can reach all others
this is done *before* removing cycles in the graph
returns the order (Hash group => group_order)
roots have an order of 0
find the minimal set of nodes from which we can reach all others this is done * before * removing cycles in the graph returns the order ( Hash group = > group_order ) roots have an order of 0
def order_graph(groups)
		roots = groups.find_all { |g| g.from.empty? }
		o = {}	
		todo = []
		loop do
			roots.each { |g|
				o[g] ||= 0
				todo |= g.to.find_all { |gg| not o[gg] }
			}
			until todo.empty?
				n = todo.find { |g| g.from.all? { |gg| o[gg] } } || order_solve_cycle(todo, o)
				todo.delete n
				o[n] = n.from.map { |g| o[g] }.compact.max + 1
				todo |= n.to.find_all { |g| not o[g] }
			end
			break if o.length >= groups.length
			if noroot = groups.find_all { |g| o[g] and g.from.find { |gg| not o[gg] } }.sort_by { |g| o[g] }.first
				todo |= noroot.from.find_all { |g| not o[g] }
				until todo.empty?
					n = todo.find { |g| g.to.all? { |gg| o[gg] } } ||
					    todo.sort_by { |g| g.to.map { |gg| o[gg] }.compact.min }.first
					todo.delete n
					o[n] = n.to.map { |g| o[g] }.compact.min - 1
					todo |= n.from.find_all { |g| not o[g] }
				end
				todo |= groups.find_all { |g| not o[g] and g.from.find { |gg| o[gg] } }
			else
				roots << groups.find { |g| not o[g] }
			end
		end
		if o.values.find { |rank| rank < 0 }
			roots = groups.find_all { |g| not g.from.find { |gg| o[gg] < o[g] } }
			o = {}
			todo = []
			roots.each { |g|
				o[g] ||= 0
				todo |= g.to.find_all { |gg| not o[gg] }
			}
			until todo.empty?
				n = todo.find { |g| g.from.all? { |gg| o[gg] } } || order_solve_cycle(todo, o)
				todo.delete n
				o[n] = n.from.map { |g| o[g] }.compact.max + 1
				todo |= n.to.find_all { |g| not o[g] }
			end
			raise "moo" if o.length < groups.length
		end
		o
	end
def order_graph ( groups ) roots = groups . find_all { | g | g . from . empty? } o = { } todo = [ ] loop do roots . each { | g | o [ g ] ||= 0 todo |= g . to . find_all { | gg | not o [ gg ] } } until todo . empty? n = todo . find { | g | g . from . all? { | gg | o [ gg ] } } || order_solve_cycle ( todo , o ) todo . delete n o [ n ] = n . from . map { | g | o [ g ] } . compact . max + 1 todo |= n . to . find_all { | g | not o [ g ] } end break if o . length >= groups . length if noroot = groups . find_all { | g | o [ g ] and g . from . find { | gg | not o [ gg ] } } . sort_by { | g | o [ g ] } . first todo |= noroot . from . find_all { | g | not o [ g ] } until todo . empty? n = todo . find { | g | g . to . all? { | gg | o [ gg ] } } || todo . sort_by { | g | g . to . map { | gg | o [ gg ] } . compact . min } . first todo . delete n o [ n ] = n . to . map { | g | o [ g ] } . compact . min - 1 todo |= n . from . find_all { | g | not o [ g ] } end todo |= groups . find_all { | g | not o [ g ] and g . from . find { | gg | o [ gg ] } } else roots << groups . find { | g | not o [ g ] } end end if o . values . find { | rank | rank < 0 } roots = groups . find_all { | g | not g . from . find { | gg | o [ gg ] < o [ g ] } } o = { } todo = [ ] roots . each { | g | o [ g ] ||= 0 todo |= g . to . find_all { | gg | not o [ gg ] } } until todo . empty? n = todo . find { | g | g . from . all? { | gg | o [ gg ] } } || order_solve_cycle ( todo , o ) todo . delete n o [ n ] = n . from . map { | g | o [ g ] } . compact . max + 1 todo |= n . to . find_all { | g | not o [ g ] } end raise "moo" if o . length < groups . length end o end
find the minimal set of nodes from which we can reach all others
this is done *before* removing cycles in the graph
returns the order (Hash group => group_order)
roots have an order of 0
find the minimal set of nodes from which we can reach all others this is done * before * removing cycles in the graph returns the order ( Hash group = > group_order ) roots have an order of 0
# tentative order # order nodes from the tentative roots # pathological cases # we picked a root in the middle of the graph, walk up # setup todo for next fwd iteration # disjoint graph, start over from one other random node # did hit a pathological case, restart with found real roots # there's something screwy around here !
groups