github.com/cilium/ebpf@v0.16.0/cmd/bpf2go/makedep.go (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"path/filepath"
    10  	"strings"
    11  )
    12  
    13  func adjustDependencies(w io.Writer, baseDir string, deps []dependency) error {
    14  	for _, dep := range deps {
    15  		relativeFile, err := filepath.Rel(baseDir, dep.file)
    16  		if err != nil {
    17  			return err
    18  		}
    19  
    20  		if len(dep.prerequisites) == 0 {
    21  			_, err := fmt.Fprintf(w, "%s:\n\n", relativeFile)
    22  			if err != nil {
    23  				return err
    24  			}
    25  			continue
    26  		}
    27  
    28  		var prereqs []string
    29  		for _, prereq := range dep.prerequisites {
    30  			relativePrereq, err := filepath.Rel(baseDir, prereq)
    31  			if err != nil {
    32  				return err
    33  			}
    34  
    35  			prereqs = append(prereqs, relativePrereq)
    36  		}
    37  
    38  		_, err = fmt.Fprintf(w, "%s: \\\n %s\n\n", relativeFile, strings.Join(prereqs, " \\\n "))
    39  		if err != nil {
    40  			return err
    41  		}
    42  	}
    43  	return nil
    44  }
    45  
    46  type dependency struct {
    47  	file          string
    48  	prerequisites []string
    49  }
    50  
    51  func parseDependencies(baseDir string, in io.Reader) ([]dependency, error) {
    52  	abs := func(path string) string {
    53  		if filepath.IsAbs(path) {
    54  			return path
    55  		}
    56  		return filepath.Join(baseDir, path)
    57  	}
    58  
    59  	scanner := bufio.NewScanner(in)
    60  	var line strings.Builder
    61  	var deps []dependency
    62  	for scanner.Scan() {
    63  		buf := scanner.Bytes()
    64  		if line.Len()+len(buf) > 1024*1024 {
    65  			return nil, errors.New("line too long")
    66  		}
    67  
    68  		if bytes.HasSuffix(buf, []byte{'\\'}) {
    69  			line.Write(buf[:len(buf)-1])
    70  			continue
    71  		}
    72  
    73  		line.Write(buf)
    74  		if line.Len() == 0 {
    75  			// Skip empty lines
    76  			continue
    77  		}
    78  
    79  		parts := strings.SplitN(line.String(), ":", 2)
    80  		if len(parts) < 2 {
    81  			return nil, fmt.Errorf("invalid line without ':'")
    82  		}
    83  
    84  		// NB: This doesn't handle filenames with spaces in them.
    85  		// It seems like make doesn't do that either, so oh well.
    86  		var prereqs []string
    87  		for _, prereq := range strings.Fields(parts[1]) {
    88  			prereqs = append(prereqs, abs(prereq))
    89  		}
    90  
    91  		deps = append(deps, dependency{
    92  			abs(string(parts[0])),
    93  			prereqs,
    94  		})
    95  		line.Reset()
    96  	}
    97  	if err := scanner.Err(); err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	// There is always at least a dependency for the main file.
   102  	if len(deps) == 0 {
   103  		return nil, fmt.Errorf("empty dependency file")
   104  	}
   105  	return deps, nil
   106  }