diff --git a/srcs/buildtool/unikraft_files_process.go b/srcs/buildtool/unikraft_files_process.go index fc5023a..640d808 100644 --- a/srcs/buildtool/unikraft_files_process.go +++ b/srcs/buildtool/unikraft_files_process.go @@ -230,17 +230,6 @@ func addAndApplyPatchFiles(patchPath string, patchFolder, appFolder string) erro return nil } -// conformPatchPath conforms a path in a user-provided patch file to the unikernel directory format -// so that this path describes a source file located in the unikernel folder. -func conformPatchPath(match *[]string, index int) { - extension := filepath.Ext((*match)[index]) - if extension == ".h" || extension == ".hpp" || extension == ".hcc" { - (*match)[index] = "include" + u.SEP + filepath.Base((*match)[index]) - } else { - (*match)[index] = filepath.Base((*match)[index]) - } -} - // conformPatchFile copies all the user-provided patch files to the unikernel directory and // conforms them to the unikernel directory format so that all paths in the patch files are paths // to source files located in the unikernel folder. @@ -254,10 +243,10 @@ func conformPatchFile(patchPath, newPatchPath string) error { } // Find paths in patch file using regexp - var re1 = regexp.MustCompile(`( )(.*)( \| )(.*)`) - var re2 = regexp.MustCompile(`(diff --git )(a/)?(.*)( )(b/)?(.*)`) - var re3 = regexp.MustCompile(`(--- )(a/)?(.*)`) - var re4 = regexp.MustCompile(`(\+\+\+ )(b/)?(.*)`) + re1 := regexp.MustCompile(`( )(.*)( \| )(.*)`) + re2 := regexp.MustCompile(`(diff --git )(a/)?(.*)( )(b/)?(.*)`) + re3 := regexp.MustCompile(`(--- )(a/)?(.*)`) + re4 := regexp.MustCompile(`(\+\+\+ )(b/)?(.*)`) for lineIndex := range patchLines { @@ -301,8 +290,19 @@ func conformPatchFile(patchPath, newPatchPath string) error { return nil } +// conformPatchPath conforms a path in a user-provided patch file to the unikernel directory format +// so that this path describes a source file located in the unikernel folder. +func conformPatchPath(match *[]string, index int) { + extension := filepath.Ext((*match)[index]) + if extension == ".h" || extension == ".hpp" || extension == ".hcc" { + (*match)[index] = "include" + u.SEP + filepath.Base((*match)[index]) + } else { + (*match)[index] = filepath.Base((*match)[index]) + } +} + // conformIncludeDirectives conforms all the user-defined include directives of all C/C++ source -// files to the unikernel directory format so that all these directives are paths to header files +// files to the unikernel directory format so that all these directives are paths to source files // located in the include folder of the unikernel directory. // // It returns an error if any, otherwise it returns nil. @@ -332,7 +332,7 @@ func conformIncludeDirectives(sourcePath string) error { } // conformFile conforms all the user-defined include directives of a C/C++ source file to the -// unikernel directory format so that all these directives are paths to header files located in the +// unikernel directory format so that all these directives are paths to source files located in the // include folder. // // It returns an error if any, otherwise it returns nil. @@ -343,24 +343,50 @@ func conformFile(filePath string, isHeader bool) (err error) { return err } - // Find user-defined include directives using regexp - var re = regexp.MustCompile(`(.*)(#include)(.*)(")(.*)(")(.*)`) + // Find include directives using regexp + re := regexp.MustCompile(`(.*)(#include)(.*)("|<)(.*)("|>)(.*)`) for lineIndex := range fileLines { for _, match := range re.FindAllStringSubmatch(fileLines[lineIndex], -1) { - // Replace the path by (include/ +) its last element + // Only interested in included files not coming from the standard library + if incDirContainsStdFold(fileLines[lineIndex]) { + break + } + for i := 1; i < len(match); i++ { - if match[i] == "\"" { - if isHeader { - match[i+1] = filepath.Base(match[i+1]) + if match[i] == "\"" || match[i] == "<" { + + // Determine the included source file extension to know what the path to it + // must be in the current file + var extIsHeader bool + extension := filepath.Ext(match[i+1]) + if extension == ".h" || extension == ".hpp" || extension == ".hcc" { + extIsHeader = true + } else if extension == ".c" || extension == ".cpp" || extension == ".cc" { + extIsHeader = false } else { - match[i+1] = "include" + u.SEP + filepath.Base(match[i+1]) + + // C++ header + break } + + // Modify the include path + match[i] = "\"" + if isHeader && !extIsHeader { + match[i+1] = "../" + filepath.Base(match[i+1]) + } else if !isHeader && extIsHeader { + match[i+1] = "include" + u.SEP + filepath.Base(match[i+1]) + } else { + match[i+1] = filepath.Base(match[i+1]) + } + match[i+2] = "\"" fileLines[lineIndex] = strings.Join(match[1:], "") + "\n" break } } + + break } } @@ -373,6 +399,45 @@ func conformFile(filePath string, isHeader bool) (err error) { return nil } +// incDirContainsStdFold determines if an include directive is a path to a standard header. +// +// It returns true if it is the case, false otherwise. +func incDirContainsStdFold(fileLine string) bool { + + // Standard header list + stdHeaders := []string{ + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "