<commit_before>/*
 * Copyright 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.nativebinaries.language.cpp.fixtures;

import com.google.common.base.Joiner;
import net.rubygrapefruit.platform.SystemInfo;
import net.rubygrapefruit.platform.WindowsRegistry;
import org.gradle.api.internal.file.TestFiles;
import org.gradle.internal.nativeplatform.ProcessEnvironment;
import org.gradle.internal.nativeplatform.services.NativeServices;
import org.gradle.internal.os.OperatingSystem;
import org.gradle.nativebinaries.platform.internal.DefaultPlatform;
import org.gradle.nativebinaries.toolchain.Clang;
import org.gradle.nativebinaries.toolchain.Gcc;
import org.gradle.nativebinaries.toolchain.VisualCpp;
import org.gradle.nativebinaries.toolchain.internal.gcc.version.GccVersionDeterminer;
import org.gradle.nativebinaries.toolchain.internal.gcc.version.GccVersionResult;
import org.gradle.nativebinaries.toolchain.internal.msvcpp.DefaultVisualStudioLocator;
import org.gradle.nativebinaries.toolchain.internal.msvcpp.VisualStudioInstall;
import org.gradle.nativebinaries.toolchain.internal.msvcpp.VisualStudioLocator;
import org.gradle.nativebinaries.toolchain.plugins.ClangCompilerPlugin;
import org.gradle.nativebinaries.toolchain.plugins.GccCompilerPlugin;
import org.gradle.nativebinaries.toolchain.plugins.MicrosoftVisualCppPlugin;
import org.gradle.process.internal.DefaultExecAction;
import org.gradle.process.internal.ExecAction;
import org.gradle.process.internal.ExecActionFactory;
import org.gradle.test.fixtures.file.TestFile;
import org.gradle.util.VersionNumber;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AvailableToolChains {
    /**
     * @return The tool chain with the given name.
     */
    public static ToolChainCandidate getToolChain(ToolChainRequirement requirement) {
        for (ToolChainCandidate toolChainCandidate : getToolChains()) {
            if (toolChainCandidate.meets(requirement)) {
                return toolChainCandidate;
            }
        }
        return null;
    }

    /**
     * @return A list of all tool chains for this platform, with the default tool chain listed first.
     */
    public static List<ToolChainCandidate> getToolChains() {
        List<ToolChainCandidate> compilers = new ArrayList<ToolChainCandidate>();
        if (OperatingSystem.current().isWindows()) {
            compilers.add(findVisualCpp());
            compilers.add(findMinGW());
            compilers.add(findCygwin());
        } else {
            // GCC4.x must be on the path
            compilers.add(findGcc("4", null));

            // Clang must be on the path
            compilers.add(findClang());
        }
        return compilers;
    }

    static private ToolChainCandidate findClang() {
        File compilerExe = OperatingSystem.current().findInPath("clang");
        if (compilerExe != null) {
            return new InstalledClang();
        }
        return new UnavailableToolChain("clang");
    }

    static private ToolChainCandidate findVisualCpp() {
        // Search in the standard installation locations
        VisualStudioLocator vsLocator = new DefaultVisualStudioLocator(OperatingSystem.current(), NativeServices.getInstance().get(WindowsRegistry.class), NativeServices.getInstance().get(SystemInfo.class));
        VisualStudioLocator.SearchResult searchResult = vsLocator.locateVisualStudioInstalls(null);
        if (searchResult.isAvailable()) {
            VisualStudioInstall install = searchResult.getVisualStudio();
            return new InstalledVisualCpp("visual c++").withInstall(install);
        }

        return new UnavailableToolChain("visual c++");
    }

    static private ToolChainCandidate findMinGW() {
        // Search in the standard installation locations
        File compilerExe = new File("C:/MinGW/bin/g++.exe");
        if (compilerExe.isFile()) {
            return new InstalledWindowsGcc("mingw").inPath(compilerExe.getParentFile());
        }

        return new UnavailableToolChain("mingw");
    }

    static private ToolChainCandidate findCygwin() {
        // Search in the standard installation locations
        File compilerExe = new File("C:/cygwin/bin/g++.exe");
        if (compilerExe.isFile()) {
            return new InstalledWindowsGcc("gcc cygwin").inPath(compilerExe.getParentFile());
        }

        return new UnavailableToolChain("gcc cygwin");
    }

    static private ToolChainCandidate findGcc(String versionPrefix, String hardcodedFallback) {
        String name = String.format("gcc %s", versionPrefix);
        GccVersionDeterminer versionDeterminer = new GccVersionDeterminer(new ExecActionFactory() {
            public ExecAction newExecAction() {
                return new DefaultExecAction(TestFiles.resolver());
            }
        });

        List<File> gppCandidates = OperatingSystem.current().findAllInPath("g++");
        for (int i = 0; i < gppCandidates.size(); i++) {
            File candidate = gppCandidates.get(i);
            GccVersionResult version = versionDeterminer.transform(candidate);
            if (version.isAvailable() && version.getVersion().startsWith(versionPrefix)) {
                InstalledGcc gcc = new InstalledGcc(name);
                if (i > 0) {
                    // Not the first g++ in the path, needs the path variable updated
                    gcc.inPath(candidate.getParentFile());
                }
                return gcc;
            }
        }

        if (hardcodedFallback != null) {
            File fallback = new File(hardcodedFallback);
            if (fallback.isFile()) {
                return new InstalledGcc(name).inPath(fallback.getParentFile());
            }
        }

        return new UnavailableToolChain(name);
    }

    public static abstract class ToolChainCandidate {
        @Override<commit_msg>Fix for broken int test on linux.<commit_after>/*
 * Copyright 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gradle.nativebinaries.language.cpp.fixtures;

import com.google.common.base.Joiner;
import net.rubygrapefruit.platform.SystemInfo;
import net.rubygrapefruit.platform.WindowsRegistry;
import org.gradle.api.internal.file.TestFiles;
import org.gradle.internal.nativeplatform.ProcessEnvironment;
import org.gradle.internal.nativeplatform.services.NativeServices;
import org.gradle.internal.os.OperatingSystem;
import org.gradle.nativebinaries.platform.internal.DefaultPlatform;
import org.gradle.nativebinaries.toolchain.Clang;
import org.gradle.nativebinaries.toolchain.Gcc;
import org.gradle.nativebinaries.toolchain.VisualCpp;
import org.gradle.nativebinaries.toolchain.internal.gcc.version.GccVersionDeterminer;
import org.gradle.nativebinaries.toolchain.internal.gcc.version.GccVersionResult;
import org.gradle.nativebinaries.toolchain.internal.msvcpp.DefaultVisualStudioLocator;
import org.gradle.nativebinaries.toolchain.internal.msvcpp.VisualStudioInstall;
import org.gradle.nativebinaries.toolchain.internal.msvcpp.VisualStudioLocator;
import org.gradle.nativebinaries.toolchain.plugins.ClangCompilerPlugin;
import org.gradle.nativebinaries.toolchain.plugins.GccCompilerPlugin;
import org.gradle.nativebinaries.toolchain.plugins.MicrosoftVisualCppPlugin;
import org.gradle.process.internal.DefaultExecAction;
import org.gradle.process.internal.ExecAction;
import org.gradle.process.internal.ExecActionFactory;
import org.gradle.test.fixtures.file.TestFile;
import org.gradle.util.VersionNumber;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AvailableToolChains {
    /**
     * @return The tool chain with the given name.
     */
    public static ToolChainCandidate getToolChain(ToolChainRequirement requirement) {
        for (ToolChainCandidate toolChainCandidate : getToolChains()) {
            if (toolChainCandidate.meets(requirement)) {
                return toolChainCandidate;
            }
        }
        return null;
    }

    /**
     * @return A list of all tool chains for this platform, with the default tool chain listed first.
     */
    public static List<ToolChainCandidate> getToolChains() {
        List<ToolChainCandidate> compilers = new ArrayList<ToolChainCandidate>();
        if (OperatingSystem.current().isWindows()) {
            compilers.add(findVisualCpp());
            compilers.add(findMinGW());
            compilers.add(findCygwin());
        } else {
            // GCC4.x must be on the path
            compilers.add(findGcc());

            // Clang must be on the path
            compilers.add(findClang());
        }
        return compilers;
    }

    static private ToolChainCandidate findClang() {
        File compilerExe = OperatingSystem.current().findInPath("clang");
        if (compilerExe != null) {
            return new InstalledClang();
        }
        return new UnavailableToolChain("clang");
    }

    static private ToolChainCandidate findVisualCpp() {
        // Search in the standard installation locations
        VisualStudioLocator vsLocator = new DefaultVisualStudioLocator(OperatingSystem.current(), NativeServices.getInstance().get(WindowsRegistry.class), NativeServices.getInstance().get(SystemInfo.class));
        VisualStudioLocator.SearchResult searchResult = vsLocator.locateVisualStudioInstalls(null);
        if (searchResult.isAvailable()) {
            VisualStudioInstall install = searchResult.getVisualStudio();
            return new InstalledVisualCpp("visual c++").withInstall(install);
        }

        return new UnavailableToolChain("visual c++");
    }

    static private ToolChainCandidate findMinGW() {
        // Search in the standard installation locations
        File compilerExe = new File("C:/MinGW/bin/g++.exe");
        if (compilerExe.isFile()) {
            return new InstalledWindowsGcc("mingw").inPath(compilerExe.getParentFile());
        }

        return new UnavailableToolChain("mingw");
    }

    static private ToolChainCandidate findCygwin() {
        // Search in the standard installation locations
        File compilerExe = new File("C:/cygwin/bin/g++.exe");
        if (compilerExe.isFile()) {
            return new InstalledWindowsGcc("gcc cygwin").inPath(compilerExe.getParentFile());
        }

        return new UnavailableToolChain("gcc cygwin");
    }

    static private ToolChainCandidate findGcc() {
        GccVersionDeterminer versionDeterminer = new GccVersionDeterminer(new ExecActionFactory() {
            public ExecAction newExecAction() {
                return new DefaultExecAction(TestFiles.resolver());
            }
        });

        List<File> gppCandidates = OperatingSystem.current().findAllInPath("g++");
        for (int i = 0; i < gppCandidates.size(); i++) {
            File candidate = gppCandidates.get(i);
            GccVersionResult version = versionDeterminer.transform(candidate);
            if (version.isAvailable() && version.getVersion().startsWith("4.")) {
                InstalledGcc gcc = new InstalledGcc("gcc");
                if (i > 0) {
                    // Not the first g++ in the path, needs the path variable updated
                    gcc.inPath(candidate.getParentFile());
                }
                return gcc;
            }
        }

        return new UnavailableToolChain("gcc");
    }

    public static abstract class ToolChainCandidate {
        @Override
{'fraction_non_alphanumeric': 0.09521918678526048, 'fraction_numerical': 0.0019059720457433292, 'mean_word_length': 3.1809428950863214, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1379887', 'n_tokens_mistral': 3472, 'n_tokens_neox': 3290, 'n_words': 778}