gaulthiergain-tools/srcs/dependtool/sources_analyser.go
2023-06-12 15:36:08 +02:00

113 lines
3 KiB
Go

package dependtool
import (
"fmt"
"os"
"path/filepath"
"strings"
u "tools/srcs/common"
)
// ---------------------------------Gather Data---------------------------------
// findSourcesFiles puts together all C/C++ source files found in a given application folder.
//
// It returns a slice containing the found source file names and an error if any, otherwise it
// returns nil.
func findSourceFiles(workspace string) ([]string, error) {
var filenames []string
err := filepath.Walk(workspace,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
ext := filepath.Ext(info.Name())
if ext == ".c" || ext == ".cpp" || ext == ".cc" || ext == ".h" || ext == ".hpp" ||
ext == ".hcc" {
filenames = append(filenames, path)
}
return nil
})
if err != nil {
return nil, err
}
return filenames, nil
}
// addSourceFileSymbols adds all the symbols present in 'output' to the static data field in
// 'data'.
func addSourceFileSymbols(output string, data *u.SourcesData) {
outputTab := strings.Split(output, ",")
// Get the list of system calls
systemCalls := initSystemCalls()
for _, s := range outputTab {
if _, isSyscall := systemCalls[s]; isSyscall {
data.SystemCalls[s] = systemCalls[s]
} else {
data.Symbols[s] = ""
}
}
}
// extractPrototype executes the parserClang.py script on each source file to extracts all possible
// symbols of each of these files.
//
// It returns an error if any, otherwise it returns nil.
func extractPrototype(sourcesFiltered []string, data *u.SourcesData) error {
for _, f := range sourcesFiltered {
script := filepath.Join(os.Getenv("GOPATH"), "src", "tools", "srcs", "dependtool",
"parserClang.py")
output, err := u.ExecuteCommand("python3", []string{script, "-q", "-t", f})
if err != nil {
u.PrintWarning("Incomplete analysis with file " + f)
continue
}
addSourceFileSymbols(output, data)
}
return nil
}
// gatherSourceFileSymbols gathers symbols of source files from a given application folder.
//
// It returns an error if any, otherwise it returns nil.
func gatherSourceFileSymbols(data *u.SourcesData, programPath string) error {
sourceFiles, err := findSourceFiles(programPath)
if err != nil {
u.PrintErr(err)
}
u.PrintOk(fmt.Sprint(len(sourceFiles)) + " source files found")
if err := extractPrototype(sourceFiles, data); err != nil {
u.PrintErr(err)
}
return nil
}
// -------------------------------------Run-------------------------------------
// staticAnalyser runs the static analysis to get system calls and library calls of a given
// application.
func sourcesAnalyser(data *u.Data, programPath string) {
sourcesData := &data.SourcesData
// Init symbols members
sourcesData.Symbols = make(map[string]string)
sourcesData.SystemCalls = make(map[string]int)
// Detect symbols from source files
u.PrintHeader2("(*) Gathering symbols from source files")
if err := gatherSourceFileSymbols(sourcesData, programPath); err != nil {
u.PrintWarning(err)
}
}