package main import ( "bufio" "fmt" "fwh-toolbox-server/domain" "os" "regexp" "strconv" "strings" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/clause" ) type MacroItem struct { MacroName string // 宏名 VID_XXX PID_XXX SubNo uint // 子序号-在本组ID中的序号 TotalNo uint // 总序号-在总内存中的序号 Type string // 数据类型 UINT32 INT32 FLOAT CHAR* Description string // 描述 } // 更新vid_macro.h和pid_macro.h的数据到sqlite func main() { // 打开 GBK 编码的文件 vidFile, err := os.Open("./utils/emspara/updateCmd/vid_macro.h") if err != nil { panic(err) } defer vidFile.Close() pidFile, err := os.Open("./utils/emspara/updateCmd/pid_macro.h") if err != nil { panic(err) } defer pidFile.Close() // 打开 SQLite db, err := gorm.Open(sqlite.Open("./utils/emspara/emspara.db"), &gorm.Config{}) if err != nil { panic(err) } // 自动建表 if err := db.AutoMigrate(&domain.ParamsVidMacroModel{}, &domain.ParamsPidMacroModel{}); err != nil { panic(err) } // 处理vid文件 err = parserMacroFile(vidFile, func(line string) error { item, err := parserMacroLine(line) if err != nil { return err } // 非 macro 数据行 if item == nil { return nil } // 检查多组数据,如PE、MPPT、APbox2.0等 itemList := checkMacroDataGroup(*item) for _, it := range itemList { if it.TotalNo == 0 { // 0无法插入,抛弃 continue } // 插入VID数据 db.Clauses(clause.OnConflict{UpdateAll: true}).Create(&domain.ParamsVidMacroModel{ID: it.TotalNo, MacroName: it.MacroName, Description: it.Description}) } return nil }) if err != nil { panic(err) } // 处理pid文件 err = parserMacroFile(pidFile, func(line string) error { item, err := parserMacroLine(line) if err != nil { return err } // 非 macro 数据行 if item == nil { return nil } // 检查多组数据,如PE、MPPT、APbox2.0等 itemList := checkMacroDataGroup(*item) for _, it := range itemList { if it.TotalNo == 0 { // 0无法插入,抛弃 continue } // 插入VID数据 db.Clauses(clause.OnConflict{UpdateAll: true}).Create(&domain.ParamsPidMacroModel{ID: it.TotalNo, MacroName: it.MacroName, Description: it.Description}) } return nil }) if err != nil { panic(err) } } func parserMacroFile(file *os.File, fn func(line string) error) error { // 使用 transform 将 GBK 转成 UTF-8 // reader := transform.NewReader(file, simplifiedchinese.GBK.NewDecoder()) // scanner := bufio.NewScanner(reader) scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() // 已经是 UTF-8 的字符串 line = strings.TrimSpace(line) // 去掉前后空格、制表符和换行符 fmt.Println("原始行:", line) if err := fn(line); err != nil { fmt.Printf("[Warn]\nline: %s\nerror: %s\n", line, err.Error()) } } return scanner.Err() } func parserMacroLine(line string) (*MacroItem, error) { if strings.HasPrefix(line, "VID_") || strings.HasPrefix(line, "PID_") { // macro 数据 // 正则匹配: // ^(\w+),\s*///<\s*\((\d+)/(\d+)\)\s*(\w+)\s+(.*)$ // 解释: // 1. ^(\w+), -> 宏名 + 逗号 // 2. \s*///<\s* -> 注释标记,空格可有可无 // 3. \((\d+)/(\d+)\) -> 括号中的两个数字 // 4. (UINT32|INT32|FLOAT|CHAR\*) -> 类型 // 5. (.*)$ -> 剩余描述 re := regexp.MustCompile(`^(\w+),\s*///<\s*\((\d+)/(\d+)\)\s*(UINT32|INT32|FLOAT|CHAR\*)\s+(.*)$`) matches := re.FindStringSubmatch(line) if len(matches) == 6 { macroName := matches[1] subNoStr := matches[2] totalNoStr := matches[3] typ := matches[4] desc := matches[5] fmt.Println("宏名:", macroName) fmt.Println("子序号:", subNoStr) fmt.Println("总序号:", totalNoStr) fmt.Println("类型:", typ) fmt.Println("描述:", desc) subNo, err := strconv.ParseUint(subNoStr, 10, 64) if err != nil { return nil, err } totalNo, err := strconv.ParseUint(totalNoStr, 10, 64) if err != nil { return nil, err } return &MacroItem{ MacroName: macroName, SubNo: uint(subNo), TotalNo: uint(totalNo), Type: typ, Description: desc, }, nil } else { return nil, fmt.Errorf("无法匹配该行") } } // 非macro 数据 return nil, nil } func checkMacroDataGroup(item MacroItem) []MacroItem { // 排除_MAX_NUM if strings.HasSuffix(item.MacroName, "_MAX_NUM") { return []MacroItem{} } var subMaxNum uint = 0 var groupNum uint = 1 if strings.HasPrefix(item.MacroName, "VID_PE_") { // VID_PE_ 每组128个数据,共16组 subMaxNum = 128 groupNum = 16 } else if strings.HasPrefix(item.MacroName, "VID_BMS_") { // NOSONAR // VID_BMS_ 每组128个数据,共16组 subMaxNum = 128 groupNum = 16 } else if strings.HasPrefix(item.MacroName, "VID_MPPT_") { // NOSONAR // VID_MPPT_ 每组128个数据,共16组 subMaxNum = 128 groupNum = 16 } else if strings.HasPrefix(item.MacroName, "VID_APBOX20_") { // VID_APBOX20_ 每组256个数据,共4组 subMaxNum = 256 groupNum = 4 } else if strings.HasPrefix(item.MacroName, "PID_APOWER_") { // NOSONAR // PID_APOWER_ 每组128个数据,共16组 subMaxNum = 128 groupNum = 16 } else if strings.HasPrefix(item.MacroName, "PID_APBOX20_") { // NOSONAR // VID_APBOX20_ 每组256个数据,共4组 subMaxNum = 256 groupNum = 4 } if groupNum == 1 { return []MacroItem{item} } var itemList []MacroItem = []MacroItem{} for i := uint(0); i < groupNum; i++ { itemList = append(itemList, MacroItem{ MacroName: fmt.Sprintf("%s_%s", item.MacroName, strconv.FormatUint(uint64(i+1), 10)), SubNo: item.SubNo, TotalNo: item.TotalNo + (i * subMaxNum), Type: item.Type, Description: item.Description, }) } return itemList }