func ReadAndParse(filename string) (*Properties, *validate.Results, error) { data, err := ioutil.ReadFile(filename) if err != nil { return nil, nil, fmt.Errorf("could not open/read file '%s': %s", filename, err.Error()) } var v validate.Results v.Resource = filename var p Properties p.file = filename parse(data, &p, &v) return &p, &v, nil }
func parse(data []byte, props *Properties, validate *validate.Results) { lines := splitLines(data) props.props = make([]*Property, 0, lines.Len()/2) props.ByKey = make(map[string]*Property) ctx := context{ key: make([]byte, 0, 4096), val: make([]byte, 0, 4096), props: props, validate: validate, } var res parseResult for nr, iter := 1, lines.Front(); iter != nil; nr, iter = nr+1, iter.Next() { line, ok := iter.Value.([]byte) if !ok { panic("internal error: not a byte-slice") } if res != PARTIAL_LINE { if isEmptyOrComment(line) { continue } ctx.lineNr = nr res = ctx.readStart(line) } else { res = ctx.readContinue(line) } if res == KEY_VALUE { ctx.finishKeyValue() } else if res == ONLY_KEY { msg := fmt.Sprintf("line contains only a key: '%s'", string(ctx.key)) validate.AddErrorN(msg, nr) ctx.reset() } } if !ctx.isEmpty() { ctx.finishKeyValue() } }