diff options
Diffstat (limited to 'vendor/modernc.org/cc/v3/cc.go')
-rw-r--r-- | vendor/modernc.org/cc/v3/cc.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/vendor/modernc.org/cc/v3/cc.go b/vendor/modernc.org/cc/v3/cc.go index cc8e90c4..dc8f98a3 100644 --- a/vendor/modernc.org/cc/v3/cc.go +++ b/vendor/modernc.org/cc/v3/cc.go @@ -792,6 +792,14 @@ func (c *context) openFile(name string, sys bool) (io.ReadCloser, error) { // Execution of HostConfig is not free, so caching of the results is // recommended. func HostConfig(cpp string, opts ...string) (predefined string, includePaths, sysIncludePaths []string, err error) { + if predefined, includePaths, sysIncludePaths, err = hostConfigv3(cpp, opts...); err == nil { + return predefined, includePaths, sysIncludePaths, nil + } + + return hostConfigv4(opts) +} + +func hostConfigv3(cpp string, opts ...string) (predefined string, includePaths, sysIncludePaths []string, err error) { if cpp == "" { cpp = "cpp" } @@ -843,6 +851,74 @@ func HostConfig(cpp string, opts ...string) (predefined string, includePaths, sy return "", nil, nil, fmt.Errorf("failed parsing %s -v output", cpp) } +func hostConfigv4(opts []string) (predefined string, includePaths, sysIncludePaths []string, err error) { + for _, cc := range []string{os.Getenv("CC"), "cc", "gcc"} { + if cc == "" { + continue + } + + cc, err = exec.LookPath(cc) + if err != nil { + continue + } + + args := append(opts, "-dM", "-E", "-") + pre, err := exec.Command(cc, args...).CombinedOutput() + if err != nil { + continue + } + + sep := "\n" + if env("GOOS", runtime.GOOS) == "windows" { + sep = "\r\n" + } + a := strings.Split(string(pre), sep) + w := 0 + for _, v := range a { + if strings.HasPrefix(v, "#") { + a[w] = v + w++ + } + } + predefined = strings.Join(a[:w], "\n") + args = append(opts, "-v", "-E", "-") + out, err := exec.Command(cc, args...).CombinedOutput() + if err != nil { + continue + } + + a = strings.Split(string(out), sep) + for i := 0; i < len(a); { + switch a[i] { + case "#include \"...\" search starts here:": + loop: + for i = i + 1; i < len(a); { + switch v := a[i]; { + case strings.HasPrefix(v, "#") || v == "End of search list.": + break loop + default: + includePaths = append(includePaths, strings.TrimSpace(v)) + i++ + } + } + case "#include <...> search starts here:": + for i = i + 1; i < len(a); { + switch v := a[i]; { + case strings.HasPrefix(v, "#") || v == "End of search list.": + return predefined, includePaths, sysIncludePaths, nil + default: + sysIncludePaths = append(sysIncludePaths, strings.TrimSpace(v)) + i++ + } + } + default: + i++ + } + } + } + return "", nil, nil, fmt.Errorf("cannot determine C compiler configuration") +} + func env(key, val string) string { if s := os.Getenv(key); s != "" { return s |