From 51a008d9fd1731903c780da664a99db760e5bbbf Mon Sep 17 00:00:00 2001 From: Tyler Rhodes Date: Sat, 31 Mar 2018 17:34:34 -0700 Subject: [PATCH] Add better support for 'after' in spec file. after max/min are still unsupported. --- spec.go | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) 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 {