#!/usr/bin/ruby # vim: et sw=2 VER="(d4e2ac8)" ME="bldx: " $chdr="1;36" $cinf="1;37" $cadd="1;32" $cdel="1;31" $incl=[] $excl=[] $fld=nil $opt=nil def in_list(s,list) for i in list if i.match(s) return true end end return false end def regexfix2(str) tmp=[] for t in str.scan(/(_)|(\|)|([^_\|]*)/).flatten.compact tmp.push(t) if not t.empty? end res="" while t=tmp.shift case t when "_" then res+=(tmp.empty? or tmp[0]=="|") ? '([ ."\[\]\(\)\{\}]+|$)' : '[ ."\[\]\(\)\{\}]+' when "|" then res+="|" else res+="#{t}" end end return res end class Block attr_reader :la, :name Line=Struct.new :port, :ln, :lp, :arr, :del, :add, :ln2, :lp2 def initialize(h) @hdr=h @fld=nil @sep=nil @flds=[] @ft=[] @la=[] @ca=[] @arr=[] @name=/^# ([^ ]*)/.match(h)[1] end def hdr(h) @hdr=h end def fld(f,s) @fld=f @sep=s tmp=@fld.scan(/[^\t]*\t*/) tmp.delete_if { |t| t.empty? } tc=0 for t in tmp @flds<n k=1+(n-i) return if k>=st1.length str=st1[k] z=@la.last if i==1 and !z.ln2 and not (st1[1].start_with?("!") or st1[1].start_with?("-")) st2=st1[1].split(":") z.ln2=st2[0] z.lp2=st2[1] end else return if st1.length<2 return if st1[0]=="-" or st1[1].start_with?("-") port=st1[0] st2=st1[1].split(":") ln=st2[0] lp=st2[1] i=@flds.index($fld) return if i>=st1.length str=st1[i] if !z=find(port) z=Line.new(port,ln,lp,[],[],[]) @la<n i=1+(n-i) return if i>=tmp.length str=tmp[i] else i=@flds.index($fld) return if i>=tmp.length str=tmp[i] end return if str.start_with?("-") or str.start_with?("!") arr=[] for v in str.split(",") if v.include?("-") t=v.split("-") t[0].to_i.upto(t[1].to_i) { |x| arr<y.to_i end arr=combine(@arr) c=$chdr out.puts "\e[#{c}m%s\e[m" % @hdr out.puts "#{$fld}: %s" % arr.join(",") return end if $opt=="cmp" return if @ca.empty? c=$chdr out.puts "\e[#{c}m%s\e[m" % @hdr for l in @ca next if l.arr.empty? arr=combine(l.arr) str=l.ln str+=":"+l.lp if l.lp c=$cinf out.puts "\e[#{c}mport: %s\e[m link: %s" % [l.port,str] out.puts "#{$fld}: %s" % arr.join(",") end return end return if prepare<1 c=$chdr out.puts "\e[#{c}m%s\e[m" % @hdr for l in @la next if l.del.empty? and l.add.empty? str=l.ln str+=":"+l.lp if l.lp c=$cinf out.puts "\e[#{c}mport: %s\e[m link: %s" % [l.port,str] c=$cdel out.puts "del: \e[#{c}m%s\e[m" % l.del.join(",") if not l.del.empty? c=$cadd out.puts "add: \e[#{c}m%s\e[m" % l.add.join(",") if not l.add.empty? end return end private def find(port) for l in @la return l if l.port==port end return nil end def combine(list) arr=[] u=nil for v in list if u and v.to_i==u+1 u+=1 next end if u and arr.last.to_iy.to_i end l.add.sort! do |x,y| next -1 if x.start_with?("+") or x.start_with?("*") next 1 if y.start_with?("+") or y.start_with?("*") next x.to_i<=>y.to_i end l.del=combine(l.del) l.add=combine(l.add) end return cnt end end def usage me=ME.delete(":") puts "Usage: "+me+"" puts " -B - include blocks matching RegEx " puts " -S - skip blocks matching RegEx " puts " -l - make list from input (aggregation)" puts " -cmp - compare given links " exit end def p_diff(isdf) blocks=[] bl=fld=nil inbl=false igbl=false st=" " for l in $stdin l.chop! next if l.empty? st=l.slice!(0,1) if isdf if inbl if l.start_with?("-----") blocks<=ARGV.length $fld=ARGV[i] case $opt when "cmp" then blocks=p_diff(false) when "list" then blocks=p_data else blocks=p_diff(true) end exit if blocks.empty? do_cmp(blocks) if $opt=="cmp" if $istty out=IO.popen("less -fqRFX","w") else out=$stdout end begin blocks.each { |b| b.output(out) } rescue Errno::EPIPE end out.close if out!=$stdout