github.com/cilium/cilium@v1.16.2/tools/legacyhguardcheck/main.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package main 5 6 import ( 7 "bytes" 8 "fmt" 9 "os" 10 "path" 11 "regexp" 12 "slices" 13 14 "github.com/cilium/cilium/pkg/safeio" 15 ) 16 17 func main() { 18 if len(os.Args) < 2 { 19 fmt.Fprintln(os.Stderr, "Usage: legacyhguardcheck <path>") 20 os.Exit(1) 21 } 22 23 found, err := checkDir(os.Args[1]) 24 if err != nil { 25 fmt.Fprintln(os.Stderr, err) 26 os.Exit(1) 27 } 28 if found { 29 fmt.Fprintln(os.Stderr, "Found legacy header guards, please replace with #pragma once or "+ 30 "add to the exclude list of a false positive found in 'tools/legacyhguardcheck/main.go'") 31 os.Exit(1) 32 } 33 } 34 35 func checkDir(dirPath string) (bool, error) { 36 var guardFound bool 37 38 dir, err := os.ReadDir(dirPath) 39 if err != nil { 40 return false, err 41 } 42 43 for _, entry := range dir { 44 entryName := path.Join(dirPath, entry.Name()) 45 if entry.IsDir() { 46 foundGuard, err := checkDir(entryName) 47 if err != nil { 48 return false, err 49 } 50 if foundGuard { 51 guardFound = true 52 } 53 continue 54 } 55 56 foundGuard, err := checkFile(entryName) 57 if err != nil { 58 return false, err 59 } 60 if foundGuard { 61 guardFound = true 62 } 63 } 64 65 return guardFound, nil 66 } 67 68 var ifndefRegex = regexp.MustCompile(`#ifndef\s+([A-Za-z0-9_]+)\s*\n#define ([A-Za-z0-9_]+)`) 69 70 var exclude = []string{ 71 "bpf/node_config.h", 72 "bpf/lib/clustermesh.h", 73 "bpf/include/linux/byteorder/big_endian.h", 74 "bpf/include/linux/byteorder/little_endian.h", 75 "bpf/tests/common.h", 76 "bpf/tests/bpf_skb_255_tests.c", 77 "bpf/tests/bpf_skb_511_tests.c", 78 } 79 80 func checkFile(filePath string) (bool, error) { 81 if slices.Contains(exclude, filePath) { 82 return false, nil 83 } 84 85 f, err := os.Open(filePath) 86 if err != nil { 87 return false, err 88 } 89 defer f.Close() 90 91 const MB = 1 << 20 92 content, err := safeio.ReadAllLimit(f, 128*MB) 93 if err != nil { 94 return false, err 95 } 96 97 for _, match := range ifndefRegex.FindAllSubmatch(content, -1) { 98 if bytes.Equal(match[1], match[2]) && bytes.HasPrefix(match[1], []byte("_")) { 99 i := bytes.Index(content, match[0]) 100 line := bytes.Count(content[:i], []byte("\n")) + 1 101 fmt.Printf("Found legacy header guard with %s macro at %s:%d\n", match[1], filePath, line) 102 return true, nil 103 } 104 } 105 106 return false, nil 107 }