function varargout = getMexCompilerInfo(varargin)

%   Copyright 2010-2020 The MathWorks, Inc.

    persistent CompStruct;
    persistent TestNoCompilerInstalled;
    persistent TestNoMSVCCompilerInstalled;
    persistent TestNoMSVCCompilerButMinGWInstalled;
    
    if isempty(TestNoCompilerInstalled)
        TestNoCompilerInstalled = false;
    end
    
    if isempty(TestNoMSVCCompilerInstalled)
        TestNoMSVCCompilerInstalled = false; 
    end
    
    if isempty(TestNoMSVCCompilerButMinGWInstalled)
        TestNoMSVCCompilerButMinGWInstalled = false; 
    end
        
    if (nargin == 0)
        action = 'default';
    else
        action = lower(varargin{1});
    end
    
    if strcmp(action, 'testnomsvccompilerinstalled')
        TestNoMSVCCompilerInstalled = true;
    elseif strcmp(action, 'testnomsvccompilerbutmingwinstalled')
        TestNoMSVCCompilerButMinGWInstalled = true;
    end
    
    if isempty(CompStruct) || TestNoMSVCCompilerInstalled || TestNoMSVCCompilerButMinGWInstalled
        if TestNoMSVCCompilerButMinGWInstalled && ~TestNoMSVCCompilerInstalled
            CompStruct = locGetInstalledAndSupportedComps(TestNoMSVCCompilerInstalled, TestNoMSVCCompilerButMinGWInstalled);
        else
            CompStruct = locGetInstalledAndSupportedComps(TestNoMSVCCompilerInstalled);
        end
    end
    
    % minGW64 compiler: Process the target argument
    if (nargin < 2)
        target = 'validate';
    else
        target = varargin{2};
    end

    mexComp = [];
    
    switch (action)
      
      case 'location'
        % look up the location of the compiler
        if ispc
            % for the PC, the drive letter can be lower-cased, but there is no
            % way to tell what the correct version is, since the windows API
            % won't return the correct value.  For compiler install locations
            % of the PC, we can assume that there won't be 2 compilers
            % installed in directories whos names differ only in case, so
            % just lower the values before the ismember check is done.
            idx = ismember(lower({CompStruct.IComps(:).Location}),...
                           lower(varargin{2}));
        else
            idx = ismember({CompStruct.IComps(:).Location},varargin{2});
        end
        if any(idx)
            compStr = CompStruct.ICompStrs(idx);
            [~,idx2] = ismember(compStr,CompStruct.SComps.compStrs);
            % there could be multiple hits due to the SDK being installed in the
            % same location as a professional version of MSVC.  This will select
            % the one that is higher up on the preference list.
            compStr =  CompStruct.SComps.compStrs(min(idx2));

            filteredICompStrs       = CompStruct.ICompStrs;
            filteredICompStrs(~idx) = {'do not use'};
        else
            compStr = '';
            filteredICompStrs = {};
        end
      case 'manverstring'
        compStr = varargin{2};
        assert(ischar(compStr));
        idx = strcmp(CompStruct.ICompStrs, compStr);
        if any(idx)
            filteredICompStrs       = CompStruct.ICompStrs;
            filteredICompStrs(~idx) = {'do not use'};
        elseif strcmp(compStr, 'LCC-x')
            %Special case for LCC64 since it is not supported by MEX team.
            %coder.make.internal.getMexCompilerInfo('manverstring', 'LCC-x')
            %should return LCC64 compiler because although MEX team does not
            %support it, it is shipped with products that support it.
            %filteredICompStrs will be called later in locGetComp and it
            %should only be used for LCC64 special case, it should not be
            %used as usual.
            filteredICompStrs = {'LCC-x'};
        else
            filteredICompStrs = {};
        end
      case 'manufacturer'
        [compStr, mexComp] = locGetSelectedComp;
        mans = {CompStruct.IComps(:).Manufacturer};
        idx = ismember(mans,varargin{2});
        if any(idx)
            filteredICompStrs       = CompStruct.ICompStrs;
            filteredICompStrs(~idx) = {'do not use'};
        else            
           filteredICompStrs = {};
        end
     case 'msvcbuildcompatible'
        [compStr,mexComp,filteredICompStrs] =...
            locGetCompatibleComp(CompStruct.SComps.msvcBuilds,...
                                 CompStruct.SComps.compStrs,...
                                 CompStruct.ICompStrs);
      case 'tmfcompatible'
        [compStr,mexComp,filteredICompStrs] =...
            locGetCompatibleComp( CompStruct.SComps.tmfBuilds,...
                                 CompStruct.SComps.compStrs,...
                                 CompStruct.ICompStrs, varargin{2:end});
      case 'bticompatible'
        [compStr,mexComp,filteredICompStrs] =...
            locGetCompatibleComp( CompStruct.SComps.btiBuilds,...
                                 CompStruct.SComps.compStrs,...
                                 CompStruct.ICompStrs);
      case 'getinstalledmsvcbuildmvstrings'
        varargout{1} = {};
        msvcCompat = CompStruct.SComps.msvcBuilds;
        if any(msvcCompat)
            filteredSCompStrs       = CompStruct.SComps.compStrs(msvcCompat);
            [~,~,idx]               = intersect(filteredSCompStrs,...
                                                CompStruct.ICompStrs);
            
            filteredICompStrs       = CompStruct.ICompStrs;
            lIdx(1:length(filteredICompStrs)) = false;
            lIdx(idx) = true;
            varargout{1} = filteredICompStrs(lIdx);
        end
        return;
        
      case 'getinstalledmanverstrings'
        if (nargin>=2)
            btiortmfcompatible = varargin{2};
        else
            btiortmfcompatible = '';
        end        
        varargout{1} = locGetInstalledManverStrings(btiortmfcompatible, CompStruct);
        return;
        
      case 'getsupportedmanverstrings'
         varargout{1} = CompStruct.SComps.compStrs;
        return;
      
      case 'envvars'
         varargout{1} = unique(CompStruct.SComps.envVars);
        return;

        
      case 'diagnosticinfo'

        % this action is to assist in debugging customer compiler installation
        % issues.
        rc.current      = CompStruct;
        rc.recalculated = locGetInstalledAndSupportedComps();
        rc.selected = locGetSelectedComp;
        varargout{1} = rc;
        return;
        
      case 'getinstalledandsupportedcompilers'
          
          varargout{1} = CompStruct;
          if TestNoCompilerInstalled
              varargout{1}.IComps = [];
              varargout{1}.ICompStrs = [];
          end
          return;
          
      case 'testnocompilerinstalled'
        
        TestNoCompilerInstalled = true;
        return;
        
      case 'testnomsvccompilerinstalled'
        
        TestNoMSVCCompilerInstalled = true;
        return;
        
      case 'testnomsvccompilerbutmingwinstalled'
        
        TestNoMSVCCompilerButMinGWInstalled = true;
        return;
        
      case 'testcompilerinstalled'
        
        TestNoCompilerInstalled = false;
        TestNoMSVCCompilerInstalled = false;
        TestNoMSVCCompilerButMinGWInstalled =  false;
        CompStruct = [];
        return;
        
      case 'installedorfirstsupported'
        
        % Get the selected or an installed mex compiler
        rc = coder.make.internal.getMexCompilerInfo();
        if isempty(rc)
            % If there are no installed compilers return the first supported one
            supportedComps = CompStruct.SComps;
            rc.compStr   = supportedComps.compStrs{1};
            rc.comp.Name = supportedComps.compStrs{1}; % not reliable
            rc.verStr    = supportedComps.verStrs{1};
            rc.installed = false;
        end
        varargout{1} = rc;
        return;
               
      otherwise
        % check if the selected compiler is supported, otherwise pick from
        % the installed/supported list.
        [compStr, mexComp] = locGetSelectedComp;
        filteredICompStrs  = CompStruct.ICompStrs;
        
    end
    
    if TestNoCompilerInstalled
        rc = [];
    else
        % minGW64 compiler: Consider the target when deciding which
        % compiler to use.  gcc doesn't support all targets yet.
        % Eventually, passing the target can be dropped when all targets are
        % supported.
        rc = locGetComp(compStr, mexComp, CompStruct, filteredICompStrs, target);
    end
        
    varargout{1} = rc;
    return;
end
%End of Function locGetMexCompStruct


%=============================================================================
% Function: locGetComp 
%
% inputs:
%    compStr
%    comp
%
%
% returns:
%
%
%=============================================================================
function rc = locGetComp(selectedCompStr, mexComp, CompStruct, filteredICompStrs, target)

    rc = [];
   
    compStr = selectedCompStr;
    lccCompStr = strcmp(compStr,'LCC-x') && any(strcmp(filteredICompStrs, 'LCC-x'));
    if lccCompStr
        %special case for lccx64 support
        comp.MexOpt         = fullfile(matlabroot, 'rtw','c','tools','lcc-win64.xml');
        comp.Name           = 'LCC64';
        comp.Manufacturer   = 'LCC';
    else
        % minGW46 compiler:
        % Add an extra check for target if using gcc in Windows:
        % If gcc, and target is not on supported list, use default compiler
        % instead.
        % Also, if validate check is happening, indicate gcc is supported.
        mingw_supported_targets = {'validate', 'accel', 'rtwsfcn', ...
            'grt', 'grt_malloc', 'ert', 'modelrefsim', 'raccel'};
        
        idx = strcmp(compStr, filteredICompStrs);
        if (any(idx) && any(strcmp(compStr, CompStruct.SComps.compStrs))) && ...
                ~(strncmp(compStr,'GNU',3) && ~any(strcmp(target, mingw_supported_targets)))
            comp = CompStruct.IComps(idx);
        else
            
            % match the compiler list with the preferred ordering
            [tf,idx] = ismember(CompStruct.SComps.compStrs,filteredICompStrs);
            
            % if there are no supported compilers installed, return
            if ~any(tf)
                return;
            end
            
            % re-sort the common compilers to match the supported compilers
            % ordering.
            commonCompilers = filteredICompStrs(idx(tf));
            
            % the selected compiler will be the first compiler in the common
            % compiler list.
            compStr = commonCompilers{1};
            comp    = CompStruct.IComps(strcmp(CompStruct.ICompStrs, compStr));
        end
    end
    
    rc.compStr         = compStr;
    
    % if the final selected comp matches the selected comp passed in, then use
    % the selected mexComp passed in to override the installed mexcomp.
    if ~isempty(mexComp) && strcmp(compStr, selectedCompStr) 
        rc.comp        = mexComp;
    else
        rc.comp        = comp;
    end

    suppIdx            = strcmp(CompStruct.SComps.compStrs, compStr);
    
    rc.verStr          = CompStruct.SComps.verStrs{suppIdx};
    rc.originalMexOpts = CompStruct.SComps.mexopts{suppIdx};
    rc.envVar          = CompStruct.SComps.envVars{suppIdx}; 
    rc.batFileLoc      = CompStruct.SComps.batFileLocs{suppIdx};
    rc.suffix          = CompStruct.SComps.tmfSuffices{suppIdx};
    rc.batFileArgs     = CompStruct.SComps.batFileArgs{suppIdx};
    rc.toolChain       = CompStruct.SComps.toolChains{suppIdx};
    rc.msvcBuildCompat = CompStruct.SComps.msvcBuilds(suppIdx);
    rc.tmfBuildCompat  = CompStruct.SComps.tmfBuilds(suppIdx);
    rc.btiBuildCompat  = CompStruct.SComps.btiBuilds(suppIdx);
    rc.mixedVerBuilds  = CompStruct.SComps.mixedVerBuilds(suppIdx);

    
    if lccCompStr || (strcmp(compStr,'GNU-x') && ispc)
        %lccx64 support or minGW64 support
       rc.msvcver         = '';
    else
        rc.msvcver         = strrep(rc.comp.Version,'.','0');
    end

end
%End of Function locGetComp

%=============================================================================
% Function: locGetSelectedComp 
%
% inputs:
%
%
% returns:
%
%
%=============================================================================
function [selectedCompStr, selectedMexComp] = locGetSelectedComp
 

    selectedMexComp = [];
    
    try
        selectedMexComp = mex.getCompilerConfigurations('C','selected');
        if isempty(selectedMexComp)
            selectedMexComp = [];
            selectedMexComp.Manufacturer = 'Non-C Compiler Selected';
            selectedMexComp.Name         = 'Non-C Compiler Selected';
            selectedMexComp.Version      = '0.0';
        end
        if (length(selectedMexComp)>1)
            selectedMexComp = selectedMexComp(1);
        end
    catch exc %#ok<NASGU>
              % A compiler may not have been selected.  just default it to dummy
              % values
        selectedMexComp.Manufacturer = 'No Compiler Selected';
        selectedMexComp.Name         = 'No Compiler Selected';
        selectedMexComp.Version      = '0.0';
    end
    % create a string for the selected compiler as well
    selectedCompStr = locCreateCompStr(selectedMexComp);
    
end
%End of Function locGetSelectedComp

%=============================================================================
% Function: locGetCompatibleComp 
%
% inputs:
%      compat    - Logical list of compilers that are compatible
%      SCompStrs - Supported compilers list (same length as compat)
%      ICompStrs - Installed compilers list
%
% returns:
%      compStr           - Currently selected compiler
%      mexComp           - Current mex compiler
%      filteredICompStrs - List of installed compilers compatible with compat 
%
%=============================================================================
function [compStr,mexComp,filteredICompStrs] = locGetCompatibleComp(compat,...
                                                      SCompStrs,...
                                                      ICompStrs, varargin)
    [compStr, mexComp] = locGetSelectedComp(varargin{:}); 
    if any(compat)
        filteredSCompStrs       = SCompStrs(compat);
        [~,~,idx]               = intersect(filteredSCompStrs,ICompStrs);
        
        filteredICompStrs       = ICompStrs;
        lIdx(1:length(filteredICompStrs)) = false;
        lIdx(idx) = true;
        filteredICompStrs(~lIdx) = {'do not use'};
    else            
        filteredICompStrs = {};
    end
    % Since LCC is not a mex compiler, it never appears in the list of installed compilers.
    % If it is the selected compiler but is not compatible then set the selected compiler
    % to empty to avoid LCC from being used and considered as compatible by locGetComp
    lccIdx = strcmpi(compStr, SCompStrs);
    if strcmpi(compStr,'LCC-x') && ~compat(lccIdx)
        compStr = '';
    end
end
%End of Function locGetCompatibleComp

%=============================================================================
% Function: locGetInstalledAndSupportedComps 
%
% inputs:
%
%
% returns:
%     compInfo.IComps     -  the mex struct for all Installed comps
%     compInfo.ICompsStrs -  the strings for the manufacturer/version for
%                            installed comps
%     compInfo.SComps     -  the Supported CompStruct array
%
%
%=============================================================================
function compInfo = locGetInstalledAndSupportedComps(varargin) 

    
    % create a 2-d cell array of compiler configs.
    if isunix
        % unix doesn't recognize 'installed' comps
        compInfo.IComps = mex.getCompilerConfigurations('C','supported');
        if (length(compInfo.IComps) > 1)
            compInfo.IComps = compInfo.IComps(1);
        end
    else
        try
            installedCompilers = mex.getCompilerConfigurations('C','installed');
        catch exc
            msgID = 'RTW:buildProcess:noCompilerInstalled';
            msg   = string(message(msgID));
            mexc  = MException(msgID,'%s',msg);
            mexc  = mexc.addCause(exc);
            throw(mexc);
        end

        TestNoMSVCCompilerInstalled = false;
        TestNoMSVCCompilerButMinGWInstalled = false;
        if nargin == 1
            TestNoMSVCCompilerInstalled = varargin{1};
        elseif nargin == 2
            TestNoMSVCCompilerInstalled = varargin{1};
            TestNoMSVCCompilerButMinGWInstalled = varargin{2};
        end
            
        if TestNoMSVCCompilerInstalled
            % TestNoMSVCCompilerInstalled ignore Intel, MSVC compilers and MinGW64
            % compiler to make the behavior consistent with the one without
            % MinGW compiler support.
            installedCompilers(strcmp({installedCompilers(:).Manufacturer}, ...
                'Intel')) = [];
            installedCompilers(strcmp({installedCompilers(:).Manufacturer}, ...
                'Microsoft')) = [];
            installedCompilers(strcmp({installedCompilers(:).Name}, ...
                'MinGW64 Compiler (C)')) = [];
        elseif TestNoMSVCCompilerButMinGWInstalled
            % TestNoMSVCCompilerButMinGWInstalled ignores Intel and MSVC
            % compilers, it does not ignore MinGW compiler.
            installedCompilers(strcmp({installedCompilers(:).Manufacturer}, ...
                'Microsoft')) = [];
            installedCompilers(strcmp({installedCompilers(:).Manufacturer}, ...
                'Intel')) = [];
        end
        
        compInfo.IComps = installedCompilers;
    
    end
    
    % get the supported compile info
    compInfo.SComps = locGetSupportedCompilerStruct();

    InstCompStrs(1:length(compInfo.IComps)) = {''};
    for i=1:length(compInfo.IComps)
        InstCompStrs{i} = locCreateCompStr(compInfo.IComps(i));
    end
    compInfo.ICompStrs = InstCompStrs;
    
    
end
%End of Function locGetInstalledAndSupportedComps


%=============================================================================
% Function: locGetSupportedCompilerStruct 
%
% inputs:
%
%
% returns:
%    rc
%
%
%=============================================================================
function scomp = locGetSupportedCompilerStruct()

    arch = computer('arch');

    winSupportedComps = {'msvc150', 'msvc140', 'msvc160', 'mssdk71', 'lcc', 'mingw64'};    
            
    intelSupportedComps = {...        
        'INTELC18MSVS2015', 'INTELC18MSVS2017', ...
        'INTELC19MSVS2015', 'INTELC19MSVS2017', 'INTELC19MSVS2019',...
                            'INTELC20MSVS2017', 'INTELC20MSVS2019'};
    winSupportedComps = [winSupportedComps intelSupportedComps];
        
    CC = mex.getCompilerConfigurations( 'C', 'Supported' ); %TODO SHOULD WE ASK FOR CPP?
    idx = 0;
    for i = 1:length( CC )
        shortName = CC(i).ShortName;
        if( ispc && ~any( strcmpi( winSupportedComps, shortName ) ) )
            continue;
        end
        idx = idx + 1;
        priorities{idx} = CC(i).Priority;
        [compStrs{idx},verStrs{idx}] = locCreateCompStr(CC(i)); %#ok<*AGROW> 
        suffices{idx} = getSuffix();
        [~, mexopt] = fileparts( CC(i).MexOpt );
        if (strcmpi(shortName, 'lcc'))
            mexopts{idx} = 'lcc';
        else
            mexopts{idx} = mexopt;
        end
        [envVars{idx}, batFileLocs{idx}] = getBatFileLoc(CC(i).Location, CC(i).Details.CommandLineShell);
        if isempty(envVars{idx})
            envVars{idx} = locGetDefaultEnvVar(compStrs{idx});
        end
        batFileArgs{idx} = strtrim(CC(i).Details.CommandLineShellArg);
        if (isempty(batFileArgs{idx}) == 0 && batFileArgs{idx}(1) == '"' && batFileArgs{idx}(end) == '"')
            batFileArgs{idx} = batFileArgs{idx}(2:end-1);
        end
        toolChain{idx} = getToolChain();    
        if (isunix || strncmpi( shortName, 'msvc', 4 ))
            msvcBuilds(idx)     = true;         
            mixedVerBuilds(idx) = true;
        else
            msvcBuilds(idx)     = false;
            mixedVerBuilds(idx) = false;
        end
        % MinGW and Intel do not support TMF based builds, all others do.
        tmfBuilds(idx)  = ~strncmpi( shortName, 'mingw64', 4 ) && ~strncmpi( shortName, 'intel', 5 );        
        % all compilers can do BTI builds currently
        btiBuilds(idx)  = true;         
    end

    if (~isempty( CC ))
        [~, sortIdx] = sort( priorities );
        if (isunix && length(sortIdx) > 1) 
            sortIdx = sortIdx(1);
        end
        scomp.compStrs    = compStrs( sortIdx );
        scomp.verStrs     = verStrs( sortIdx );
        scomp.tmfSuffices = suffices( sortIdx );
        scomp.mexopts     = mexopts( sortIdx );
        scomp.envVars     = envVars( sortIdx );
        scomp.batFileLocs = batFileLocs( sortIdx );
        scomp.batFileArgs = batFileArgs( sortIdx );
        scomp.toolChains  = toolChain( sortIdx );
        scomp.msvcBuilds  = msvcBuilds( sortIdx );
        scomp.tmfBuilds   = tmfBuilds( sortIdx );
        scomp.btiBuilds   = btiBuilds( sortIdx );
        scomp.mixedVerBuilds   = mixedVerBuilds( sortIdx );
    end
%    size = length(CC);
    if( strcmpi( arch, 'win64' ) )
        scomp.compStrs{end+1} = 'LCC-x';
        scomp.verStrs{end+1} = 'x';
        scomp.tmfSuffices{end+1} = '_lcc64.tmf';
        scomp.mexopts{end+1} = 'lcc64opts';
        scomp.envVars{end+1} = '';
        scomp.batFileLocs{end+1} = '';
        scomp.batFileArgs{end+1} = '';
        scomp.toolChains{end+1} = 'lcc';
        scomp.msvcBuilds(end+1) = false;
        scomp.tmfBuilds(end+1) = true;
        scomp.btiBuilds(end+1) = true;
        scomp.mixedVerBuilds(end+1) = true;
    end
    
    function [comp, batfile] = getBatFileLoc(compLoc, fullpathBatFile)
       batfile = '';
       comp = '';
       if (strncmpi(shortName, 'msvc90', 6))
           comp = 'VS90COMNTOOLS';
       elseif (strncmpi(shortName, 'msvc100', 7))
           comp = 'VS100COMNTOOLS';
       elseif (strncmpi(shortName, 'msvc110', 7))
           comp = 'VS110COMNTOOLS';
       elseif (strncmpi(shortName, 'msvc120', 7))
           comp = 'VS120COMNTOOLS';
       elseif (strncmpi(shortName, 'msvc140', 7))
           comp = 'VS140COMNTOOLS';
       end
       fullpathBatFile = strtrim(fullpathBatFile);
       if (isempty(fullpathBatFile))
           return;
       end
       if (fullpathBatFile(1) == '"' && fullpathBatFile(end) == '"')
           fullpathBatFile = fullpathBatFile(2:end-1);
       end
       compLoc = strtrim(compLoc);
       if (isempty(compLoc))
           return;
       end
       if (compLoc(1) == '"' && compLoc(end) == '"')
           compLoc = compLoc(2:end-1);
       end
       if (strncmpi(fullpathBatFile, compLoc, length(compLoc)))
           batfile = ['..\..', fullpathBatFile(length(compLoc) + 1 : end)];
       elseif ~isempty(regexp(compLoc,'\\\w*\\\.\.\\','match')) %find pattern '\*\..\'
           % for msvc2013, compLoc is 
           % C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\..\
           % and fullpathBatFile is 
           % C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\VCVARSALL.BAT.
           % Thus, need to get rid of '\VC\..' to obtain the real compLoc path.
           compLoc = regexprep(compLoc,'\\\w*\\\.\.\\','');
           if (strncmpi(fullpathBatFile, compLoc, length(compLoc)))
               batfile = ['..\..', fullpathBatFile(length(compLoc) + 1 : end)];
           end    
       end
    end
        
    function suffix = getSuffix()
        if( ismac || isunix )
            suffix = '_unix.tmf';
            return;
        end
        
        if( strncmpi( shortName, 'ms', 2 ) )
            suffix = '_vc';
            if( strcmpi( arch, 'win64' ) )
                suffix  = [suffix 'x64'];
            end
        elseif( strncmpi( shortName, 'lcc', 3 ) )
            suffix = '_lcc';
        elseif( strncmpi( shortName, 'mingw', 5 ) )
            suffix = '_mingw';
            if( strcmpi( arch, 'win64' ) )
                suffix  = [suffix '64'];
            end
        elseif strncmpi(shortName, 'intel', 5)
            suffix = '_intel';
        end
        
        suffix  = [suffix '.tmf'];
      
    end

    function tc = getToolChain()
        if( ismac || isunix )
            tc = 'unix';
            return;
        end
        
        if( strncmpi( shortName, 'ms', 2 ) )
            if( strcmpi( arch, 'win32' ) )
                tc = 'vc';
            else
                tc = 'vcx64';
            end
        elseif( strncmpi( shortName, 'lcc', 3 ) )
            tc = 'lcc';
        elseif( strncmpi( shortName, 'mingw', 5 ) )
            tc = shortName;
        elseif strncmpi( shortName, 'intel', 5)
            tc = 'intel';
        else
            tc = '';
        end
        
    end
    

end
%End of Function locGetSupportedCompilerStruct


%=============================================================================
% Function: locCreateCompStr
%
% inputs:
%    comp
%
%
% returns:
%
%
%=============================================================================
function [compStr, cver] = locCreateCompStr(comp)
 
	manufacturer = comp.Manufacturer;
	if strcmp(manufacturer, 'lcc')
		manufacturer = 'LCC';
	end

    switch (manufacturer)
      case {'LCC', 'Apple'}
        % for some compilers we don't care about the version, since we only
        % support 1.
        cver = 'x';
      case 'GNU'
        cver = 'x';
      case 'Intel'        
        % The Intel compilers have two versions, one for the compiler and
        % another for the version of MSVS. The shortname has the form
        % INTELC##MSVS#### where the # are the version numbers. Strip off
        % the first 6 characters.
        compStr = comp.ShortName;
        cver = compStr(7:end);
       
        return;
                
      otherwise
        cver = comp.Version;
    end
    
    if (~isempty(strfind(comp.Name,'Microsoft')) &&...
        ~isempty(strfind(comp.Name,'SDK')))
       cver = [cver 'SDK'];
    end

    compStr = [manufacturer '-'  cver];

end
%End of Function locCreateCompStr


%=============================================================================
% Function: locGetInstalledManverStrings 
%
% inputs:
%
%
% returns:
%
%
%=============================================================================
function compStrs = locGetInstalledManverStrings(btiortmfcompatible, CompStruct)

    switch btiortmfcompatible
        case 'bticompatible'
            sCompStrs = CompStruct.SComps.compStrs(CompStruct.SComps.btiBuilds);
        case 'tmfcompatible'
            sCompStrs = CompStruct.SComps.compStrs(CompStruct.SComps.tmfBuilds);
        otherwise
            sCompStrs = CompStruct.SComps.compStrs;
    end
            
    [~,idx] = intersect(sCompStrs,CompStruct.ICompStrs);
    compStrs = sCompStrs(sort(idx));
end
%End of Function locGetInstalledManverStrings

%=============================================================================
% Function: locGetDefaultEnvVar 
%
% inputs:
%
%
% returns:
%
%
%=============================================================================
function envVar = locGetDefaultEnvVar(compStr)
    switch compStr
      case 'Microsoft-15.0'
        envVar = 'VS150COMNTOOLS';
      case 'Microsoft-14.0'
        envVar = 'VS140COMNTOOLS';
        otherwise
        envVar = '';
    end
    
end

%[EOF] get_tmf_for_target.m

% LocalWords:  Sybase IComps Strs SComps configs rc vc tmf msvc COMNTOOLS SDK
% LocalWords:  vsvars freeopts vcvarsall vcvars lcc lccopts watc openwatcopts
% LocalWords:  vcx manverstring getinstalledmanverstrings envvars gccopts SDK
% LocalWords:  diagnosticinfo testnocompilerinstalled testcompilerinstalled
% LocalWords:  getsupportedmanverstrings settestcompiler gettestcompiler mssdk
% LocalWords:  sdk msvcbuildcompatible getinstalledmsvcbuildmvstrings IComp
% LocalWords:  setselectedcompiler clearselectedcompiler mexcomp openwatc BTI
% LocalWords:  testnomsvccompilerinstalled fullpath toolchain Toochain Manver
% LocalWords:  Env INTELC MSVS intel shortname
