debconf: implement dat file parser
This commit is contained in:
parent
0b91c379b8
commit
053e07c319
92
debconf/debconf.go
Normal file
92
debconf/debconf.go
Normal file
@ -0,0 +1,92 @@
|
||||
package debconf
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultConfigDat = `/var/cache/debconf/config.dat`
|
||||
DefaultPasswordsDat = `/var/cache/debconf/passwords.dat`
|
||||
DefaultTemplatesDat = `/var/cache/debconf/templates.dat`
|
||||
)
|
||||
|
||||
type Entry struct {
|
||||
Name string
|
||||
Properties [][2]string
|
||||
}
|
||||
|
||||
type Database struct {
|
||||
Entries []Entry
|
||||
AllColumnNames []string
|
||||
}
|
||||
|
||||
func Parse(r io.Reader) (*Database, error) {
|
||||
sc := bufio.NewScanner(r)
|
||||
|
||||
var entries []Entry
|
||||
var wip Entry
|
||||
var linenum int = 0
|
||||
|
||||
knownColumnNames := map[string]struct{}{
|
||||
"Name": struct{}{},
|
||||
}
|
||||
var discoveredColumns []string
|
||||
|
||||
for sc.Scan() {
|
||||
linenum++
|
||||
line := sc.Text()
|
||||
|
||||
if line == "" {
|
||||
if wip.Name != "" {
|
||||
entries = append(entries, wip)
|
||||
wip = Entry{}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if line[0] == ' ' {
|
||||
// continuation of last text entry
|
||||
if len(wip.Properties) == 0 {
|
||||
return nil, fmt.Errorf("Continuation of nonexistent entry on line %d", linenum)
|
||||
}
|
||||
|
||||
wip.Properties[len(wip.Properties)-1][1] += line[1:]
|
||||
|
||||
} else {
|
||||
// New pair on current element
|
||||
key, rest, ok := strings.Cut(line, `:`)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("Missing : on line %d", linenum)
|
||||
}
|
||||
|
||||
if _, ok := knownColumnNames[key]; !ok {
|
||||
knownColumnNames[key] = struct{}{}
|
||||
discoveredColumns = append(discoveredColumns, key)
|
||||
}
|
||||
|
||||
if key == `Name` {
|
||||
wip.Name = rest
|
||||
} else {
|
||||
wip.Properties = append(wip.Properties, [2]string{key, rest})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if sc.Err() != nil {
|
||||
return nil, sc.Err()
|
||||
}
|
||||
|
||||
if wip.Name != "" {
|
||||
entries = append(entries, wip)
|
||||
}
|
||||
|
||||
return &Database{
|
||||
Entries: entries,
|
||||
AllColumnNames: discoveredColumns,
|
||||
}, nil
|
||||
}
|
30
debconf/debconf_test.go
Normal file
30
debconf/debconf_test.go
Normal file
@ -0,0 +1,30 @@
|
||||
package debconf
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDebconfParse(t *testing.T) {
|
||||
src, err := os.Open(DefaultConfigDat)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
t.Skip(err)
|
||||
}
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
db, err := Parse(src)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse: %v", err)
|
||||
}
|
||||
|
||||
if len(db.Entries) == 0 {
|
||||
t.Errorf("expected >0 entries, got %v", len(db.Entries))
|
||||
}
|
||||
|
||||
if len(db.AllColumnNames) == 0 {
|
||||
t.Errorf("expected >0 column names, got %v", len(db.AllColumnNames))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user