#!/bin/sh
# label compactor on cad schematic files generated by make_sch_from_vhdl
# a[3],a[2],gnd,a[1],a[0]  --> a[3:2],gnd,a[1:0]
# Note: only works on lists of single bits does not compact things like:
# a[8:3],a[2:1],gnd,b[3],b[2]
# also only works on lists of signals that can be represented as decreasing vectors:
# a[3],a[2],a[1],gnd  --> ok
# a[0],a[1],a[2],gnd  --> not ok

awk '


FNR == 1 {
    if (_filename_ != "")
        endfile(_filename_)
    _filename_ = FILENAME
    print "processing: " FILENAME
    beginfile(FILENAME)
}

END  { endfile(_filename_) }


# user code

/^C .*lab=/{
 lab=$0
 sub(/^.*lab=/,"",lab)
 sub(/ *\}.*$/,"",lab)
 if(lab ~ /,/ && lab !~ /:/) {
   newlab=compact_label(lab)
   sub(/lab=.* *\}/,"lab=" newlab "}", $0)
 }
}

function compact_label(lab)
{
  n=split(lab,lab_array,",")
  startbus=-1
  start=-1
  newlab=""
  for(i=1;i<=n;i++) {
   if(lab_array[i] ~ /\[/) {
     bus_current=lab_index(lab_array[i])

     if( start!=-1 &&  lab_array[i] != name )
         print_signal()
     if( (startbus!=-1) && (lab_name(lab_array[i]) != busname) ) 
         print_bus()
     # 09032004 fix for errors on buses like D[5],D[4],D[2],D[1]
     if( (startbus!=-1) && (lab_name(lab_array[i]) == busname) && (bus_current+1!=last) )
         print_bus()

     if(startbus==-1) { busname=lab_name(lab_array[i]); startbus=bus_current; last=bus_current }
     else if(lab_name(lab_array[i])==busname && bus_current+1==last) { last=bus_current }

     if( (startbus!=-1) && i==n )
         print_bus()
   }
   else {
     if(lab_name(lab_array[i]) != busname&& startbus!=-1) 
       print_bus()
     if( (start!=-1) && ( lab_array[i] != name) )
       print_signal()

     if(start==-1) { name=lab_array[i] ; start++ }
     else if(lab_array[i] == name) { start++ }

     if( (start!=-1) && i==n )
       print_signal()
   }
  }
  sub(/,$/,"",newlab)
  return newlab
}

function print_bus() {
   if(startbus>last)
       newlab=newlab busname "[" startbus ":" last "],"
   else
       newlab=newlab busname "[" startbus "],"
   startbus=-1
}

function print_signal() {
   if(start>0)
      newlab = newlab start+1 "*" name ","
   else
      newlab = newlab name ","
   start=-1
}

function lab_name(lab)
{
 sub(/\[.*/,"",lab)
 return lab
}


function lab_index(lab) 
{
 sub(/.*\[/,"",lab)
 sub(/\].*/,"",lab)
 return lab+0
}

# end user code

{
 a[lines++] = $0 
}

function beginfile(f)
{
 print compact_label("D[5],D[4],D[2],D[1]")
 lines=0
}

function endfile(f)
{
 for(i=0;i<lines;i++)
 {
  print a[i] > f
 }
 close(f)
} 

' $@ 


