Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8149360410 |
@@ -24,42 +24,56 @@ type saaChange struct {
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
var shnRE = regexp.MustCompile(`^[A-Za-z0-9_]{1,16}$`)
|
||||
var (
|
||||
shnRE = regexp.MustCompile(`^[A-Za-z0-9_]{1,16}$`)
|
||||
dmiSectionRE = regexp.MustCompile(`^\[(.+?)\]$`)
|
||||
// Item Name {SHN} = value // comment
|
||||
dmiItemRE = regexp.MustCompile(`^(.+?)\s+\{([A-Za-z0-9]{1,16})\}\s*=\s*(.*)$`)
|
||||
dmiVersionRE = regexp.MustCompile(`(?i)^version\s*=`)
|
||||
)
|
||||
|
||||
// parseDMIFile parses the DMI.txt produced by "saa GetDmiInfo".
|
||||
// Supports two formats:
|
||||
// - Name|Shn|Value (pipe-separated, primary)
|
||||
// - Shn=Value (key=value fallback)
|
||||
// Real format (from SAA User Guide 4.8.1):
|
||||
//
|
||||
// Lines starting with '#', empty lines, "version=..." and section headers are skipped.
|
||||
// [System]
|
||||
// Version {SYVS} = "A Version" // string value
|
||||
// Serial Number {SYSN} = $DEFAULT$ // string value
|
||||
// UUID {SYUU} = 00112233-... // hex value
|
||||
func parseDMIFile(content string) []dmiField {
|
||||
var fields []dmiField
|
||||
currentSection := ""
|
||||
for _, line := range strings.Split(content, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
if line == "" || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
lower := strings.ToLower(line)
|
||||
if strings.HasPrefix(lower, "version=") || strings.HasPrefix(lower, "[") {
|
||||
if dmiVersionRE.MatchString(line) {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(line, "|", 3)
|
||||
if len(parts) == 3 {
|
||||
name := strings.TrimSpace(parts[0])
|
||||
shn := strings.TrimSpace(parts[1])
|
||||
value := strings.TrimSpace(parts[2])
|
||||
if shnRE.MatchString(shn) {
|
||||
fields = append(fields, dmiField{Name: name, Shn: shn, Value: value})
|
||||
continue
|
||||
}
|
||||
if m := dmiSectionRE.FindStringSubmatch(line); m != nil {
|
||||
currentSection = strings.TrimSpace(m[1])
|
||||
continue
|
||||
}
|
||||
if idx := strings.IndexByte(line, '='); idx > 0 {
|
||||
shn := strings.TrimSpace(line[:idx])
|
||||
value := strings.TrimSpace(line[idx+1:])
|
||||
if shnRE.MatchString(shn) {
|
||||
fields = append(fields, dmiField{Name: shn, Shn: shn, Value: value})
|
||||
}
|
||||
m := dmiItemRE.FindStringSubmatch(line)
|
||||
if m == nil {
|
||||
continue
|
||||
}
|
||||
itemName := strings.TrimSpace(m[1])
|
||||
shn := m[2]
|
||||
rawValue := strings.TrimSpace(m[3])
|
||||
// strip trailing comment (space + //)
|
||||
if idx := strings.LastIndex(rawValue, " //"); idx >= 0 {
|
||||
rawValue = strings.TrimSpace(rawValue[:idx])
|
||||
}
|
||||
// strip surrounding double quotes from string values
|
||||
if len(rawValue) >= 2 && rawValue[0] == '"' && rawValue[len(rawValue)-1] == '"' {
|
||||
rawValue = rawValue[1 : len(rawValue)-1]
|
||||
}
|
||||
displayName := itemName
|
||||
if currentSection != "" {
|
||||
displayName = currentSection + " / " + itemName
|
||||
}
|
||||
fields = append(fields, dmiField{Name: displayName, Shn: shn, Value: rawValue})
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user