deviceinfo: implement a new simple parser (MR 4)
This replaces an external toml library with a simple parser for unmarshalling a deviceinfo.
This commit is contained in:
@@ -4,59 +4,123 @@
|
||||
package deviceinfo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
toml "github.com/pelletier/go-toml/v2"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Note: fields must be exported (start with capital letter)
|
||||
// https://github.com/BurntSushi/toml/issues/121
|
||||
type DeviceInfo struct {
|
||||
AppendDtb string `toml:"deviceinfo_append_dtb"`
|
||||
Arch string `toml:"deviceinfo_arch"`
|
||||
BootimgAppendSEAndroidEnforce string `toml:"deviceinfo_bootimg_append_seandroidenforce"`
|
||||
BootimgBlobpack string `toml:"deviceinfo_bootimg_blobpack"`
|
||||
BootimgDtbSecond string `toml:"deviceinfo_bootimg_dtb_second"`
|
||||
BootimgMtkMkimage string `toml:"deviceinfo_bootimg_mtk_mkimage"`
|
||||
BootimgPxa string `toml:"deviceinfo_bootimg_pxa"`
|
||||
BootimgQcdt string `toml:"deviceinfo_bootimg_qcdt"`
|
||||
Dtb string `toml:"deviceinfo_dtb"`
|
||||
FlashKernelOnUpdate string `toml:"deviceinfo_flash_kernel_on_update"`
|
||||
FlashOffsetBase string `toml:"deviceinfo_flash_offset_base"`
|
||||
FlashOffsetKernel string `toml:"deviceinfo_flash_offset_kernel"`
|
||||
FlashOffsetRamdisk string `toml:"deviceinfo_flash_offset_ramdisk"`
|
||||
FlashOffsetSecond string `toml:"deviceinfo_flash_offset_second"`
|
||||
FlashOffsetTags string `toml:"deviceinfo_flash_offset_tags"`
|
||||
FlashPagesize string `toml:"deviceinfo_flash_pagesize"`
|
||||
GenerateBootimg string `toml:"deviceinfo_generate_bootimg"`
|
||||
GenerateLegacyUbootInitfs string `toml:"deviceinfo_generate_legacy_uboot_initfs"`
|
||||
InitfsCompression string `toml:"deviceinfo_initfs_compression"`
|
||||
KernelCmdline string `toml:"deviceinfo_kernel_cmdline"`
|
||||
LegacyUbootLoadAddress string `toml:"deviceinfo_legacy_uboot_load_address"`
|
||||
MesaDriver string `toml:"deviceinfo_mesa_driver"`
|
||||
MkinitfsPostprocess string `toml:"deviceinfo_mkinitfs_postprocess"`
|
||||
ModulesInitfs string `toml:"deviceinfo_modules_initfs"`
|
||||
AppendDtb string
|
||||
Arch string
|
||||
BootimgAppendSEAndroidEnforce string
|
||||
BootimgBlobpack string
|
||||
BootimgDtbSecond string
|
||||
BootimgMtkMkimage string
|
||||
BootimgPxa string
|
||||
BootimgQcdt string
|
||||
Dtb string
|
||||
FlashKernelOnUpdate string
|
||||
FlashOffsetBase string
|
||||
FlashOffsetKernel string
|
||||
FlashOffsetRamdisk string
|
||||
FlashOffsetSecond string
|
||||
FlashOffsetTags string
|
||||
FlashPagesize string
|
||||
GenerateBootimg string
|
||||
GenerateLegacyUbootInitfs string
|
||||
InitfsCompression string
|
||||
KernelCmdline string
|
||||
LegacyUbootLoadAddress string
|
||||
MesaDriver string
|
||||
MkinitfsPostprocess string
|
||||
ModulesInitfs string
|
||||
}
|
||||
|
||||
func ReadDeviceinfo() (DeviceInfo, error) {
|
||||
file := "/etc/deviceinfo"
|
||||
func ReadDeviceinfo(file string) (DeviceInfo, error) {
|
||||
var deviceinfo DeviceInfo
|
||||
|
||||
_, err := os.Stat(file)
|
||||
if err != nil {
|
||||
return deviceinfo, errors.New("Unable to find deviceinfo: " + file)
|
||||
}
|
||||
|
||||
fd, err := os.Open(file)
|
||||
if err != nil {
|
||||
return deviceinfo, err
|
||||
}
|
||||
defer fd.Close()
|
||||
// contents,_ := toml.LoadFile(file)
|
||||
decoder := toml.NewDecoder(fd)
|
||||
if err := decoder.Decode(&deviceinfo); err != nil {
|
||||
|
||||
if err := unmarshal(fd, &deviceinfo); err != nil {
|
||||
return deviceinfo, err
|
||||
}
|
||||
|
||||
return deviceinfo, nil
|
||||
}
|
||||
|
||||
// Unmarshals a deviceinfo into a DeviceInfo struct
|
||||
func unmarshal(r io.Reader, devinfo *DeviceInfo) error {
|
||||
s := bufio.NewScanner(r)
|
||||
for s.Scan() {
|
||||
line := s.Text()
|
||||
if strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
// line isn't setting anything, so just ignore it
|
||||
if !strings.Contains(line, "=") {
|
||||
continue
|
||||
}
|
||||
|
||||
// sometimes line has a comment at the end after setting an option
|
||||
line = strings.SplitN(line, "#", 2)[0]
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
// must support having '=' in the value (e.g. kernel cmdline)
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
return fmt.Errorf("error parsing deviceinfo line, invalid format: %s", line)
|
||||
}
|
||||
|
||||
name, val := parts[0], parts[1]
|
||||
val = strings.ReplaceAll(val, "\"", "")
|
||||
|
||||
if name == "deviceinfo_format_version" && val != "0" {
|
||||
return fmt.Errorf("deviceinfo format version %q is not supported", val)
|
||||
}
|
||||
|
||||
fieldName := nameToField(name)
|
||||
|
||||
if fieldName == "" {
|
||||
return fmt.Errorf("error parsing deviceinfo line, invalid format: %s", line)
|
||||
}
|
||||
|
||||
field := reflect.ValueOf(devinfo).Elem().FieldByName(fieldName)
|
||||
if !field.IsValid() {
|
||||
// an option that meets the deviceinfo "specification", but isn't
|
||||
// one we care about in this module
|
||||
continue
|
||||
}
|
||||
field.SetString(val)
|
||||
}
|
||||
if err := s.Err(); err != nil {
|
||||
log.Print("unable to parse deviceinfo: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert string into the string format used for DeviceInfo fields.
|
||||
// Note: does not test that the resulting field name is a valid field in the
|
||||
// DeviceInfo struct!
|
||||
func nameToField(name string) string {
|
||||
var field string
|
||||
parts := strings.Split(name, "_")
|
||||
for _, p := range parts {
|
||||
if p == "deviceinfo" {
|
||||
continue
|
||||
}
|
||||
field = field + strings.Title(p)
|
||||
}
|
||||
|
||||
return field
|
||||
}
|
||||
|
Reference in New Issue
Block a user