package main import ( "bufio" "fmt" "os" "path" "strings" ) var infhcache = make(map[string]string, 1024) func infh(name string) string { if s, ok := infhcache[name]; ok { return s } s := " [" + name + "]" infhcache[name] = s return s } func scanheader(name string, scan *bufio.Scanner) { ln := 0 var regionfile *os.File symtab := symbolTable{ "ZE_APICALL": symbol{symbolTypeConst, "ZE_APICALL", []string{""}}, "ZE_APIEXPORT": symbol{symbolTypeConst, "ZE_APIEXPORT", []string{""}}, "ZE_DLLEXPORT": symbol{symbolTypeConst, "ZE_DLLEXPORT", []string{""}}, } for scan.Scan() { ln++ t := scan.Text() switch { // pragma start case strings.HasPrefix(t, "#pragma region "): region := strings.TrimSpace(t[15:]) if region == "" { panic(fmt.Sprintf("%s L%d: unexpected empty region", name, ln)) } fmt.Println(infh(name), "scanning region", region) _ = os.RemoveAll(name) err := os.MkdirAll(name, 0755) if err != nil { panic(fmt.Sprintf("%s L%d: cannot create region folder %s, err: %v", name, ln, region, err)) } f, err := os.Create(path.Join(name, region+".go")) if err != nil { panic(fmt.Sprintf("%s L%d: cannot create region %s, err: %v", name, ln, region, err)) } f.WriteString("// Code generated by gen. DO NOT EDIT.\n\npackage ") f.WriteString(name) f.WriteString("\n") regionfile = f // block barrier case strings.HasPrefix(t, "///////////////////////////////////////////////////////////////////////////////"): regionfile.WriteString(t) regionfile.WriteString("\n") ln = scanblocks(name, scan, regionfile, ln, symtab) // pragma end case strings.HasPrefix(t, "#pragma endregion"): fmt.Println(infh(name), "close region", regionfile.Name()) _ = regionfile.Close() regionfile = nil } } } func scanblocks( name string, scan *bufio.Scanner, f *os.File, ln int, symtab symbolTable, ) int { sb := strings.Builder{} skip2nextblk := false //TODO: check logic ifdepth := 0 isparsing := func() bool { //TODO: more condition return ifdepth > 0 } for scan.Scan() { ln++ t := scan.Text() switch { // block end case t == "": if isparsing() { continue } if sb.Len() != 0 { panic(fmt.Sprintf("%s L%d: unexpected non-0 sb at block end: %s", name, ln, &sb)) } return ln case skip2nextblk: continue // is definition's comment case strings.HasPrefix(t, "/// "): sb.WriteString(t) sb.WriteString("\n") case strings.HasPrefix(t, "#if"): if len(t) <= 8 { panic(fmt.Sprintf("%s L%d: unexpected short #if", name, ln)) } if t[3] == ' ' { // is platform related judgement skip2nextblk = true continue } if t[:8] != "#ifndef " { panic(fmt.Sprintf("%s L%d: unexpected #if type %s", name, ln, t)) } sname := strings.TrimSpace(t[8:]) _, ok := symtab[sname] if ok { ln = skip2endif(scan, ln) continue } ifdepth++ case strings.HasPrefix(t, "#endif"): ifdepth-- if ifdepth < 0 { panic(fmt.Sprintf("%s L%d: unexpected unpaired #endif", name, ln)) } case strings.HasPrefix(t, "#define"): } } return ln }