diff --git a/spec.go b/spec.go index 7270982..31df456 100644 --- a/spec.go +++ b/spec.go @@ -1,6 +1,7 @@ package spicy import ( + "container/list" "errors" "fmt" "github.com/alecthomas/participle" @@ -279,6 +280,9 @@ func ParseSpec(r io.Reader) (*Spec, error) { if err == nil { log.Debugf("Parsed: %v", out) } + for _, w := range out.Waves { + w.correctOrdering() + } return out, err } @@ -315,6 +319,41 @@ func (w *Wave) checkValidity() error { return nil } +func findElement(l *list.List, name string) *list.Element { + for e := l.Front(); e != nil; e = e.Next() { + original, _ := e.Value.(*Segment) + if original.Name == name { + return e + } + } + return nil +} + +func (w *Wave) correctOrdering() { + // TODO(trhodeos): Make this actually correct. This just places any + // explicitly addressed segments before any 'after.*' segments. If + // 'after' segments depend on other 'after' segments, this'll break. + l := list.New() + for _, seg := range w.ObjectSegments { + if seg.Positioning.Address != 0 { + l.PushBack(seg) + } + } + for _, seg := range w.ObjectSegments { + if seg.Positioning.Address == 0 { + e := findElement(l, seg.Positioning.AfterSegment) + l.InsertAfter(seg, e) + } + } + + newSegments := make([]*Segment, 0) + for e := l.Front(); e != nil; e = e.Next() { + original, _ := e.Value.(*Segment) + newSegments = append(newSegments, original) + } + w.ObjectSegments = newSegments +} + func (w *Wave) GetBootSegment() *Segment { for _, seg := range w.ObjectSegments { if seg.Flags.Boot {