<commit_before>import csnUtility
import csnContext
import csnGenerator
import csnProject
import csnPrebuilt
import RollbackImporter
import glob
import inspect
import string
import os
import subprocess
import sys
from csnListener import ChangeListener
import logging

class RootNotFound(IOError):
    pass

class NotARoot(IOError):
    pass

class RollbackHandler:
    """
    This helper class instantiates the RollbackImporter and extends the python search path 
    """
    def SetUp(self, _projectPath, _rootFolders, _thirdPartyFolders):
        """
        Set up the roll back. 
        """
        # set up roll back of imported modules
        self.rbi = RollbackImporter.RollbackImporter()
        self.previousPaths = list(sys.path)
        
        # extend python path with project folder, source root and third party root
        newPaths = list(_rootFolders)
        newPaths.extend(_thirdPartyFolders) 
        newPaths.extend([_projectPath]) 
        for path in newPaths:
            if not path in sys.path:
                sys.path.append(path)
    
    def TearDown(self):
        """
        Execute roll back. 
        """
        # roll back imported modules
        self.rbi.rollbackImports()

        # undo additions to the python path
        sys.path = list(self.previousPaths)
                    
class Handler:
    def __init__(self):
        self.context = None
        self.contextFilename = None
        self.generator = csnGenerator.Generator()
        # contains the last result of calling __GetProjectInstance
        self.cachedProjectInstance = None
        # logger
        self.__logger = logging.getLogger("CSnake")
        # change flags
        self.contextModified = False
        self.changeListener = ChangeListener(self)
    
    def LoadContext(self, filename):
        self.contextFilename = filename
        self.context = csnContext.Load(filename)
        self.context.AddListener(self.changeListener)
        csnProject.globalCurrentContext = self.context
        return self.context
        
    def __GetProjectInstance(self):
        """ Instantiates and returns the _instance in _projectPath. """
        self.DeletePycFiles()
        
        # set up roll back of imported modules
        rollbackHandler = RollbackHandler()
        rollbackHandler.SetUp(self.context.GetCsnakeFile(), self.context.GetRootFolders(), self.context.GetThirdPartyFolders())
        (projectFolder, name) = os.path.split(self.context.GetCsnakeFile())
        (name, _) = os.path.splitext(name)
        
        try:
            projectModule = csnUtility.LoadModule(projectFolder, name)
            projectModule # prevent warning
            exec "self.cachedProjectInstance = csnProject.ToProject(projectModule.%s)" % self.context.GetInstance()
        finally:
            # undo additions to the python path
            rollbackHandler.TearDown()

        relocator = csnPrebuilt.ProjectRelocator()
        relocator.Do(self.cachedProjectInstance, self.context.GetPrebuiltBinariesFolder())
        self.UpdateRecentlyUsedCSnakeFiles()
        
        return self.cachedProjectInstance
    
    def ConfigureProjectToBuildFolder(self, _alsoRunCMake, _callback = None):
        """ 
        Configures the project to the build folder.
        """
        instance = self.__GetProjectInstance()
        
        instance.installManager.ResolvePathsOfFilesToInstall()
        self.generator.Generate(instance)
        instance.dependenciesManager.WriteDependencyStructureToXML("%s/projectStructure.xml" % instance.GetBuildFolder())
            
        if _alsoRunCMake:
            argList = [self.context.GetCmakePath(), "-G", self.context.GetCompiler().GetName(), instance.GetCMakeListsFilename()]
            process = subprocess.Popen(argList, cwd = instance.GetBuildFolder()) # , stdout=subProcess.PIPE, stderr=subProcess.PIPE
            while process.poll() is None:
                (outdata, errdata) = process.communicate()
                if _callback:
                    _callback.Report(outdata)
                    _callback.Error(errdata)
            if process.poll() == 0:
                self.generator.PostProcess(instance)
                return True
            else:
                if _callback:
                    _callback.Warn("Configuration failed.")
                    if not self.CMakeIsFound():
                        _callback.Warn("CMake not found at %s" % self.context.GetCmakePath())
                return False
            
    def InstallBinariesToBuildFolder(self):
        return self.generator.InstallBinariesToBuildFolder(self.__GetProjectInstance())
             
    def CMakeIsFound(self):
        found = os.path.exists(self.context.GetCmakePath()) and os.path.isfile(self.context.GetCmakePath())
        if not found:
            try:
                retcode = subprocess.Popen(self.context.GetCmakePath()).wait()
            except:
                retcode = 1
            found = retcode == 0
        return found        
    
    def ConfigureThirdPartyFolders(self, _nrOfTimes = 2):
        """ 
        Runs cmake to install the libraries in the third party folder.
        By default, the third party folder is configured twice because this works around
        some problems with incomplete configurations.
        """
        result = True

        for index in range(0, self.context.GetNumberOfThirdPartyFolders( ) ):
            result = self.ConfigureThirdPartyFolder( self.context.GetThirdPartyFolder( index ), self.context.GetThirdPartyBuildFolderByIndex( index ), _nrOfTimes = _nrOfTimes, allBuildFolders = self.context.GetThirdPartyBuildFoldersComplete() )
            if not result:
                print "Configuration failed.\n"   
                if not self.CMakeIsFound():
                    print "Please specify correct path to CMake (current is %s)" % self.context.GetCmakePath() 
                    return False
            
        return result

    def ConfigureThirdPartyFolder(self, source, build, allBuildFolders, _nrOfTimes = 2):
        """ 
        Runs cmake to install the libraries in the third party folder.
        By default, the third party folder is configured twice because this works around
        some problems with incomplete configurations.
        """
        result = True
        
        # create the build folder if it doesn't exist
        os.path.exists(build) or os.makedirs(build)
        
        if not os.path.exists( self.context.GetCmakePath() ):
            raise Exception( "Please provide a valid CMake path" )
        
        cmakeModulePath = ""
        for buildFolder in allBuildFolders:
            cmakeModulePath = cmakeModulePath + buildFolder + ";"
        cmakeModulePath = cmakeModulePath[0:-1]
        argList = [self.context.GetCmakePath(), \
                  "-G", self.context.GetCompiler().GetName(), \
                  "-D", "THIRDPARTY_BUILD_FOLDERS:STRING='%s'" % cmakeModulePath] + \
                  self.context.GetCompiler().GetThirdPartyCMakeParameters() + \
                  [source]
        for _ in range(0, _nrOfTimes):
            result = result and 0 == subprocess.Popen(argList, cwd = build).wait() 

        if not result:
            print "Configuration failed.\n"   
            if not self.CMakeIsFound():
                print "Please specify correct path to CMake (current is %s)" % self.context.GetCmakePath() 
                return False

        return result

    def DeletePycFiles(self):
        """
        Tries to delete all pyc files from _projectPath, _rootFolders and thirdPartyFolders.
        However, __init__.pyc files are not removed.
        """
        # determine list of folders to search for pyc files
        folderList = []
        folderList.extend(self.context.GetThirdPartyFolders())
        folderList.extend(self.context.GetRootFolders())

        # remove pyc files
        while len(folderList) > 0:
            newFolders = []
            for folder in folderList:
                pycFiles = [csnUtility.NormalizePath(x) for x in glob.glob("%s/*.pyc" % folder)]
                for pycFile in pycFiles:
                    if not os.path.basename(pycFile) == "__init__.pyc":
                        os.remove(pycFile)
<commit_msg>Protect against null context.<commit_after>import csnUtility
import csnContext
import csnGenerator
import csnProject
import csnPrebuilt
import RollbackImporter
import glob
import inspect
import string
import os
import subprocess
import sys
from csnListener import ChangeListener
import logging

class RootNotFound(IOError):
    pass

class NotARoot(IOError):
    pass

class RollbackHandler:
    """
    This helper class instantiates the RollbackImporter and extends the python search path 
    """
    def SetUp(self, _projectPath, _rootFolders, _thirdPartyFolders):
        """
        Set up the roll back. 
        """
        # set up roll back of imported modules
        self.rbi = RollbackImporter.RollbackImporter()
        self.previousPaths = list(sys.path)
        
        # extend python path with project folder, source root and third party root
        newPaths = list(_rootFolders)
        newPaths.extend(_thirdPartyFolders) 
        newPaths.extend([_projectPath]) 
        for path in newPaths:
            if not path in sys.path:
                sys.path.append(path)
    
    def TearDown(self):
        """
        Execute roll back. 
        """
        # roll back imported modules
        self.rbi.rollbackImports()

        # undo additions to the python path
        sys.path = list(self.previousPaths)
                    
class Handler:
    def __init__(self):
        self.context = None
        self.contextFilename = None
        self.generator = csnGenerator.Generator()
        # contains the last result of calling __GetProjectInstance
        self.cachedProjectInstance = None
        # logger
        self.__logger = logging.getLogger("CSnake")
        # change flags
        self.contextModified = False
        self.changeListener = ChangeListener(self)
    
    def LoadContext(self, filename):
        self.contextFilename = filename
        self.context = csnContext.Load(filename)
        self.context.AddListener(self.changeListener)
        csnProject.globalCurrentContext = self.context
        return self.context
        
    def __GetProjectInstance(self):
        """ Instantiates and returns the _instance in _projectPath. """
        self.DeletePycFiles()
        
        # set up roll back of imported modules
        rollbackHandler = RollbackHandler()
        rollbackHandler.SetUp(self.context.GetCsnakeFile(), self.context.GetRootFolders(), self.context.GetThirdPartyFolders())
        (projectFolder, name) = os.path.split(self.context.GetCsnakeFile())
        (name, _) = os.path.splitext(name)
        
        try:
            projectModule = csnUtility.LoadModule(projectFolder, name)
            projectModule # prevent warning
            exec "self.cachedProjectInstance = csnProject.ToProject(projectModule.%s)" % self.context.GetInstance()
        finally:
            # undo additions to the python path
            rollbackHandler.TearDown()

        relocator = csnPrebuilt.ProjectRelocator()
        relocator.Do(self.cachedProjectInstance, self.context.GetPrebuiltBinariesFolder())
        self.UpdateRecentlyUsedCSnakeFiles()
        
        return self.cachedProjectInstance
    
    def ConfigureProjectToBuildFolder(self, _alsoRunCMake, _callback = None):
        """ 
        Configures the project to the build folder.
        """
        instance = self.__GetProjectInstance()
        
        instance.installManager.ResolvePathsOfFilesToInstall()
        self.generator.Generate(instance)
        instance.dependenciesManager.WriteDependencyStructureToXML("%s/projectStructure.xml" % instance.GetBuildFolder())
            
        if _alsoRunCMake:
            argList = [self.context.GetCmakePath(), "-G", self.context.GetCompiler().GetName(), instance.GetCMakeListsFilename()]
            process = subprocess.Popen(argList, cwd = instance.GetBuildFolder()) # , stdout=subProcess.PIPE, stderr=subProcess.PIPE
            while process.poll() is None:
                (outdata, errdata) = process.communicate()
                if _callback:
                    _callback.Report(outdata)
                    _callback.Error(errdata)
            if process.poll() == 0:
                self.generator.PostProcess(instance)
                return True
            else:
                if _callback:
                    _callback.Warn("Configuration failed.")
                    if not self.CMakeIsFound():
                        _callback.Warn("CMake not found at %s" % self.context.GetCmakePath())
                return False
            
    def InstallBinariesToBuildFolder(self):
        return self.generator.InstallBinariesToBuildFolder(self.__GetProjectInstance())
             
    def CMakeIsFound(self):
        found = os.path.exists(self.context.GetCmakePath()) and os.path.isfile(self.context.GetCmakePath())
        if not found:
            try:
                retcode = subprocess.Popen(self.context.GetCmakePath()).wait()
            except:
                retcode = 1
            found = retcode == 0
        return found        
    
    def ConfigureThirdPartyFolders(self, _nrOfTimes = 2):
        """ 
        Runs cmake to install the libraries in the third party folder.
        By default, the third party folder is configured twice because this works around
        some problems with incomplete configurations.
        """
        result = True

        for index in range(0, self.context.GetNumberOfThirdPartyFolders( ) ):
            result = self.ConfigureThirdPartyFolder( self.context.GetThirdPartyFolder( index ), self.context.GetThirdPartyBuildFolderByIndex( index ), _nrOfTimes = _nrOfTimes, allBuildFolders = self.context.GetThirdPartyBuildFoldersComplete() )
            if not result:
                print "Configuration failed.\n"   
                if not self.CMakeIsFound():
                    print "Please specify correct path to CMake (current is %s)" % self.context.GetCmakePath() 
                    return False
            
        return result

    def ConfigureThirdPartyFolder(self, source, build, allBuildFolders, _nrOfTimes = 2):
        """ 
        Runs cmake to install the libraries in the third party folder.
        By default, the third party folder is configured twice because this works around
        some problems with incomplete configurations.
        """
        result = True
        
        # create the build folder if it doesn't exist
        os.path.exists(build) or os.makedirs(build)
        
        if not os.path.exists( self.context.GetCmakePath() ):
            raise Exception( "Please provide a valid CMake path" )
        
        cmakeModulePath = ""
        for buildFolder in allBuildFolders:
            cmakeModulePath = cmakeModulePath + buildFolder + ";"
        cmakeModulePath = cmakeModulePath[0:-1]
        argList = [self.context.GetCmakePath(), \
                  "-G", self.context.GetCompiler().GetName(), \
                  "-D", "THIRDPARTY_BUILD_FOLDERS:STRING='%s'" % cmakeModulePath] + \
                  self.context.GetCompiler().GetThirdPartyCMakeParameters() + \
                  [source]
        for _ in range(0, _nrOfTimes):
            result = result and 0 == subprocess.Popen(argList, cwd = build).wait() 

        if not result:
            print "Configuration failed.\n"   
            if not self.CMakeIsFound():
                print "Please specify correct path to CMake (current is %s)" % self.context.GetCmakePath() 
                return False

        return result

    def DeletePycFiles(self):
        """
        Tries to delete all pyc files from _projectPath, _rootFolders and thirdPartyFolders.
        However, __init__.pyc files are not removed.
        """
        # determine list of folders to search for pyc files
        folderList = []
        if self.context:
            folderList.extend(self.context.GetThirdPartyFolders())
            folderList.extend(self.context.GetRootFolders())

        # remove pyc files
        while len(folderList) > 0:
            newFolders = []
            for folder in folderList:
                pycFiles = [csnUtility.NormalizePath(x) for x in glob.glob("%s/*.pyc" % folder)]
                for pycFile in pycFiles:
                    if not os.path.basename(pycFile) == "__init__.pyc":
                        os.remove(pycFile)

{'fraction_non_alphanumeric': 0.08176935610403717, 'fraction_numerical': 0.0013276205419105666, 'mean_word_length': 2.15296803652968, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '5590647', 'n_tokens_mistral': 4436, 'n_tokens_neox': 4265, 'n_words': 1091}