ide/Project: Fixed mixing up configurations/compilers
authorJerome St-Louis <jerome@ecere.com>
Fri, 17 Feb 2012 10:46:48 +0000 (17:46 +0700)
committerJerome St-Louis <jerome@ecere.com>
Fri, 17 Feb 2012 10:46:48 +0000 (17:46 +0700)
For example doing a rebuild and toggling a config before the Clean is done would mix up configs
Compiler and Config are now obtained once, and passed as parameter as they should.
Things that should never have been properties were changed to methods expecting a config and a compiler if necessary.

epj2make/epj2make.ec
ide/src/debugger/Debugger.ec
ide/src/designer/CodeEditor.ec
ide/src/dialogs/NewProjectDialog.ec
ide/src/ide.ec
ide/src/project/Project.ec
ide/src/project/ProjectConfig.ec
ide/src/project/ProjectNode.ec
ide/src/project/ProjectView.ec
ide/src/project/vsSupport.ec

index 75c6c2c..e08dec7 100644 (file)
@@ -353,7 +353,7 @@ class epj2makeApp : GuiApplication
                   }
                   if(valid)
                   {
-                     if(project.GenerateMakefile(makePath, noResources, includemkPath))
+                     if(project.GenerateMakefile(makePath, noResources, includemkPath, defaultCompiler, project.config))
                      {
                         if(makePath)
                            printf("%s\n", makePath);
index 0f9b87b..cab4699 100644 (file)
@@ -381,6 +381,7 @@ class Debugger
 
    OldList stackFrames;
 
+   CompilerConfig currentCompiler;
    ProjectConfig prjConfig;
 
    CodeEditor codeEditor;
@@ -415,7 +416,7 @@ class Debugger
          {
             case restart:
                breakType = none;
-               Restart();
+               Restart(currentCompiler, prjConfig);
                break;
             case stop:
                breakType = none;
@@ -598,6 +599,7 @@ class Debugger
       bpRunToCursor = null;
       bpHit = null;
 
+      delete currentCompiler;
       prjConfig = null;
       codeEditor = null;
 
@@ -665,7 +667,7 @@ class Debugger
       }
    }
 
-   void Restart()
+   void Restart(CompilerConfig compiler, ProjectConfig config)
    {
       switch(state)
       {
@@ -680,7 +682,7 @@ class Debugger
             GdbAbortExec();
          case none:
          case terminated:
-            if(!GdbInit())
+            if(!GdbInit(compiler, config))
                break;
          case loaded:
             GdbExecRun();
@@ -854,14 +856,14 @@ class Debugger
       ide.Update(null);
    }
       
-   void Start()
+   void Start(CompilerConfig compiler, ProjectConfig config)
    {
       ide.outputView.debugBox.Clear();
       switch(state)
       {
          case none:
          case terminated:
-            if(!GdbInit())
+            if(!GdbInit(compiler, config))
                break;
          case loaded:
             GdbExecRun();
@@ -869,13 +871,13 @@ class Debugger
       }
    }
 
-   void StepInto()
+   void StepInto(CompilerConfig compiler, ProjectConfig config)
    {
       switch(state)
       {
          case none:
          case terminated:
-            if(!GdbInit()) 
+            if(!GdbInit(compiler, config)) 
                break;
          case loaded:
             ide.outputView.ShowClearSelectTab(debug);
@@ -889,13 +891,13 @@ class Debugger
       }
    }
 
-   void StepOver(bool ignoreBkpts)
+   void StepOver(CompilerConfig compiler, ProjectConfig config, bool ignoreBkpts)
    {
       switch(state)
       {
          case none:
          case terminated:
-            if(!GdbInit()) 
+            if(!GdbInit(compiler, config)) 
                break;
          case loaded:
             ide.outputView.ShowClearSelectTab(debug);
@@ -924,7 +926,7 @@ class Debugger
       }
    }
 
-   void RunToCursor(char * absoluteFilePath, int lineNumber, bool ignoreBkpts)
+   void RunToCursor(CompilerConfig compiler, ProjectConfig config, char * absoluteFilePath, int lineNumber, bool ignoreBkpts)
    {
       char relativeFilePath[MAX_LOCATION];
       DebuggerState oldState = state;
@@ -935,7 +937,7 @@ class Debugger
       {
          case none:
          case terminated:
-            Start();
+            Start(compiler, config);
          case stopped:
          case loaded:
             if(symbols)
@@ -1482,7 +1484,7 @@ class Debugger
       {
          //if(!breakpointsInserted)
          {
-            DirExpression objDir = ide.project.objDir;
+            DirExpression objDir = ide.project.GetObjDir(currentCompiler, prjConfig);
             for(bp : sysBPs)
             {
                if(!bp.inserted)
@@ -1803,17 +1805,23 @@ class Debugger
       return true;
    }
 
-   bool GdbInit()
+   bool GdbInit(CompilerConfig compiler, ProjectConfig config)
    {
       bool result = true;
       char oldDirectory[MAX_LOCATION];
       char tempPath[MAX_LOCATION];
       char command[MAX_LOCATION];
       Project project = ide.project;
-      DirExpression targetDirExp = project.targetDir;
+      DirExpression targetDirExp = project.GetTargetDir(compiler, config);
       PathBackup pathBackup { };
 
-      prjConfig = project.config;
+      if(currentCompiler != compiler)
+      {
+         delete currentCompiler;
+         currentCompiler = compiler;
+         incref currentCompiler;
+      }
+      prjConfig = config;
 
       ChangeState(loaded);
       sentKill = false;
@@ -1837,7 +1845,7 @@ class Debugger
       PathCatSlash(tempPath, targetDirExp.dir);
       delete targetDir;
       targetDir = CopyString(tempPath);
-      project.CatTargetFileName(tempPath);
+      project.CatTargetFileName(tempPath, compiler, config);
       delete targetFile;
       targetFile = CopyString(tempPath);
 
@@ -1852,7 +1860,7 @@ class Debugger
       else
          ChangeWorkingDir(ide.workspace.projectDir);
       
-      ide.SetPath(true);
+      ide.SetPath(true, compiler, config);
 
       // TODO: This pollutes the environment, but at least it works
       // It shouldn't really affect the IDE as the PATH gets restored and other variables set for testing will unlikely cause problems
index a380f0c..e4b9af0 100644 (file)
@@ -1896,7 +1896,12 @@ class CodeEditor : Window
          {
             int line = editBox.lineNumber + 1;
             if(projectView)
-               ide.debugger.RunToCursor(fileName, line, false);
+            {
+               CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+               ProjectConfig config = projectView.project.config;
+               ide.debugger.RunToCursor(compiler, config, fileName, line, false);
+               delete compiler;
+            }
          }
          return true;
       }
@@ -1909,7 +1914,12 @@ class CodeEditor : Window
          ProjectView projectView = ide.projectView;
          int line = editBox.lineNumber + 1;
          if(projectView)
-            ide.debugger.RunToCursor(fileName, line, true);
+         {
+            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+            ProjectConfig config = projectView.project.config;
+            ide.debugger.RunToCursor(compiler, config, fileName, line, true);
+            delete compiler;
+         }
          return true;
       }
    };
@@ -2703,9 +2713,12 @@ class CodeEditor : Window
       // TODO: Get symbolsDir from project settings instead...
       if(ide.projectView)
       {
-         DirExpression objDir = project.objDir;
+         CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+         ProjectConfig config = project.config;
+         DirExpression objDir = project.GetObjDir(compiler, config);
          SetSymbolsDir(objDir.dir);
          delete objDir;
+         delete compiler;
          // SetIncludeDirs(ide.projectView.project.config.includeDirs);
          // SetSysIncludeDirs(ide.ideSettings.systemDirs[includes]);
       }
index 5b566f1..e5a5001 100644 (file)
@@ -147,7 +147,7 @@ class NewProjectDialog : Window
             targetType = ((TargetTypes)targetType.GetTag());
             targetFileName = /*CopyString(*/name/*)*/;
          };
-         if(project.targetType != staticLibrary)
+         if(project.options.targetType != staticLibrary)
          {
             project.options.libraries = { [ CopyString("ecere") ] };
          }
@@ -217,7 +217,12 @@ class NewProjectDialog : Window
          }
 
          if(project && projectWindow)
-            projectWindow.ProjectPrepareMakefile(project, force, true, true);
+         {
+            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+            ProjectConfig config = project.config;
+            projectWindow.ProjectPrepareMakefile(project, force, true, true, compiler, config);
+            delete compiler;
+         }
 
          Destroy(0);
          return true;
@@ -416,7 +421,7 @@ class QuickProjectDialog : Window
             targetFileName = /*CopyString(*/prjName/*)*/;
          };
 
-         if(project.targetType != staticLibrary)
+         if(project.options.targetType != staticLibrary)
          {
             project.options.libraries = { [ CopyString("ecere") ] };
          }
@@ -495,7 +500,12 @@ class QuickProjectDialog : Window
          visible = false;
 
          if(project && projectWindow)
-            projectWindow.ProjectPrepareMakefile(project, force, true, true);
+         {
+            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+            ProjectConfig config = project.config;
+            projectWindow.ProjectPrepareMakefile(project, force, true, true, compiler, config);
+            delete compiler;
+         }
 
          ide.projectView.ProjectBuild(null, Modifiers { });
 
index 3810e4b..a136cb3 100644 (file)
@@ -1267,7 +1267,7 @@ class IDE : Window
       {
          Project project = projectView.project;
          if(project)
-            if(project.targetType == executable)
+            if(project.GetTargetType(project.config) == executable)
                return false;
            
       }
@@ -1415,7 +1415,7 @@ class IDE : Window
 
       projectCloseItem.disabled        = unavailable;
 
-      projectRunItem.disabled          = unavailable || project.targetType != executable;
+      projectRunItem.disabled          = unavailable || project.GetTargetType(project.config) != executable;
       projectBuildItem.disabled        = unavailable;
       projectLinkItem.disabled         = unavailable;
       projectRebuildItem.disabled      = unavailable;
@@ -1426,7 +1426,7 @@ class IDE : Window
 
    void AdjustDebugMenus()
    {
-      bool unavailable = !project || project.targetType != executable ||
+      bool unavailable = !project || project.GetTargetType(project.config) != executable ||
                projectView.buildInProgress == buildingMainProject;
       bool active = ide.debugger.isActive;
       bool executing = ide.debugger.state == running;
@@ -1602,7 +1602,11 @@ class IDE : Window
                         workspace.Save();
 
                         ide.projectView.ShowOutputBuildLog(true);
-                        ide.projectView.DisplayCompiler(false);
+                        {
+                           CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+                           ide.projectView.DisplayCompiler(compiler, false);
+                           delete compiler;
+                        }
                         UpdateMakefiles();
                         {
                            char newWorkingDir[MAX_LOCATION];
@@ -2218,7 +2222,7 @@ class IDE : Window
 #endif
    }
 
-   void SetPath(bool projectsDirs)
+   void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
    {
       int c, len, count;
       char * newList;
@@ -2231,7 +2235,6 @@ class IDE : Window
       Array<String> newLibPaths { };
       Map<String, bool> libPathExists { };
 #endif
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
 
       if(projectsDirs)
       {
@@ -2242,7 +2245,7 @@ class IDE : Window
             // SKIP FIRST PROJECT...
             if(prj == workspace.projects.firstIterator.data) continue;
 
-            targetDirExp = prj.targetDir;
+            targetDirExp = prj.GetTargetDir(compiler, config);
 
             /*if(prj.config.targetType == sharedLibrary && prj.config.debug)
                cfg = prj.config;
@@ -2395,7 +2398,6 @@ class IDE : Window
       if(compiler.distccEnabled && compiler.distccHosts)
          SetEnvironment("DISTCC_HOSTS", compiler.distccHosts);
 
-      delete compiler;
       delete oldList;
    }
 
index f6021f9..1613204 100644 (file)
@@ -6,6 +6,8 @@ public import "ecere"
 
 #ifndef MAKEFILE_GENERATOR
 import "ide"
+// We should have the .sln/.vcproj generation even on other platforms
+// e.g. detect from an environment variable pointing to a Windows drive
 #ifdef __WIN32__
 import "vsSupport"
 #endif
@@ -760,175 +762,134 @@ private:
       }
    }
 
-   property TargetTypes targetType
+   TargetTypes GetTargetType(ProjectConfig config)
    {
-      get
-      {
-         // TODO: Implement platform specific options?
-         TargetTypes targetType = localTargetType;
-         return targetType;
-      }
+      // TODO: Implement platform specific options?
+      TargetTypes targetType = localTargetType;
+      return targetType;
    }
 
-   property char * objDirExpression
+   char * GetObjDirExpression(CompilerConfig compiler, ProjectConfig config)
    {
-      get
-      {
-         // TODO: Support platform options
-         char * expression = localObjectsDirectory;
-         if(!expression)
-            expression = settingsObjectsDirectory;
-         return expression;
-      }
+      // TODO: Support platform options
+      char * expression = localObjectsDirectory;
+      if(!expression)
+         expression = settingsObjectsDirectory;
+      return expression;
    }
-   property DirExpression objDir
+
+   DirExpression GetObjDir(CompilerConfig compiler, ProjectConfig config)
    {
-      get
-      {
-         char * expression = objDirExpression;
-         DirExpression objDir { type = intermediateObjectsDir };
-         objDir.Evaluate(expression, this);
-         return objDir;
-      }
+      char * expression = GetObjDirExpression(compiler, config);
+      DirExpression objDir { type = intermediateObjectsDir };
+      objDir.Evaluate(expression, this, compiler, config);
+      return objDir;
    }
-   property char * targetDirExpression
+
+   char * GetTargetDirExpression(CompilerConfig compiler, ProjectConfig config)
    {
-      get
-      {
-         // TODO: Support platform options
-         char * expression = localTargetDirectory;
-         if(!expression)
-            expression = settingsTargetDirectory;
-         return expression;
-      }
+      // TODO: Support platform options
+      char * expression = localTargetDirectory;
+      if(!expression)
+         expression = settingsTargetDirectory;
+      return expression;
    }
-   property DirExpression targetDir
+
+   DirExpression GetTargetDir(CompilerConfig compiler, ProjectConfig config)
    {
-      get
-      {
-         char * expression = targetDirExpression;
-         DirExpression targetDir { type = DirExpressionType::targetDir /*intermediateObjectsDir*/};
-         targetDir.Evaluate(expression, this);
-         return targetDir;
-      }
+      char * expression = GetTargetDirExpression(compiler, config);
+      DirExpression targetDir { type = DirExpressionType::targetDir /*intermediateObjectsDir*/};
+      targetDir.Evaluate(expression, this, compiler, config);
+      return targetDir;
    }
 
-   property WarningsOption warnings
+   WarningsOption GetWarnings(ProjectConfig config)
    {
-      get
-      {
-         WarningsOption warnings = localWarnings;
-         return warnings;
-      }
+      WarningsOption warnings = localWarnings;
+      return warnings;
    }
-   property bool debug
+
+   bool GetDebug(ProjectConfig config)
    {
-      get
-      {
-         SetBool debug = localDebug;
-         return debug == true;
-      }
+      SetBool debug = localDebug;
+      return debug == true;
    }
-   property bool memoryGuard
+
+   bool GetMemoryGuard(ProjectConfig config)
    {
-      get
-      {
-         SetBool memoryGuard = localMemoryGuard;
-         return memoryGuard == true;
-      }
+      SetBool memoryGuard = localMemoryGuard;
+      return memoryGuard == true;
    }
-   property bool noLineNumbers
+
+   bool GetNoLineNumbers(ProjectConfig config)
    {
-      get
-      {
-         SetBool noLineNumbers = localNoLineNumbers;
-         return noLineNumbers == true;
-      }
+      SetBool noLineNumbers = localNoLineNumbers;
+      return noLineNumbers == true;
    }
-   property bool profile
+
+   bool GetProfile(ProjectConfig config)
    {
-      get
-      {
-         SetBool profile = localProfile;
-         return profile == true;
-      }
+      SetBool profile = localProfile;
+      return profile == true;
    }
-   property OptimizationStrategy optimization
+
+   OptimizationStrategy GetOptimization(ProjectConfig config)
    {
-      get
-      {
-         OptimizationStrategy optimization = localOptimization;
-         return optimization;
-      }
+      OptimizationStrategy optimization = localOptimization;
+      return optimization;
    }
-   property String defaultNameSpace
+
+   String GetDefaultNameSpace(ProjectConfig config)
    {
-      get
-      {
-         String defaultNameSpace = localDefaultNameSpace;
-         return defaultNameSpace;
-      }
+      String defaultNameSpace = localDefaultNameSpace;
+      return defaultNameSpace;
    }
-   property bool strictNameSpaces
+
+   bool GetStrictNameSpaces(ProjectConfig config)
    {
-      get
-      {
-         SetBool strictNameSpaces = localStrictNameSpaces;
-         return strictNameSpaces == true;
-      }
+      SetBool strictNameSpaces = localStrictNameSpaces;
+      return strictNameSpaces == true;
    }
-   property String targetFileName
+
+   String GetTargetFileName(ProjectConfig config)
    {
-      get
-      {
-         String targetFileName = localTargetFileName;
-         return targetFileName;
-      }
+      String targetFileName = localTargetFileName;
+      return targetFileName;
    }
+
    //String targetDirectory;
    //String objectsDirectory;
-   property bool console
+   bool GetConsole(ProjectConfig config)
    {
-      get
-      {
-         SetBool console = localConsole;
-         return console == true;
-      }
+      SetBool console = localConsole;
+      return console == true;
    }
-   property bool compress
+
+   bool GetCompress(ProjectConfig config)
    {
-      get
-      {
-         SetBool compress = localCompress;
-         return compress == true;
-      }
+      SetBool compress = localCompress;
+      return compress == true;
    }
    //SetBool excludeFromBuild;
 
-   property bool configIsInActiveDebugSession
+   bool GetConfigIsInActiveDebugSession(ProjectConfig config)
    {
-      get
-      {
 #ifndef MAKEFILE_GENERATOR
-         return ide.project == this  && ide.debugger && ide.debugger.prjConfig == config && ide.debugger.isActive;
+      return ide.project == this && ide.debugger && ide.debugger.prjConfig == config && ide.debugger.isActive;
 #endif
-      }
    }
 
-   property bool configIsInDebugSession
+   bool GetConfigIsInDebugSession(ProjectConfig config)
    {
-      get
-      {
 #ifndef MAKEFILE_GENERATOR
-         return ide.project == this  && ide.debugger && ide.debugger.prjConfig == config && ide.debugger.isPrepared;
+      return ide.project == this  && ide.debugger && ide.debugger.prjConfig == config && ide.debugger.isPrepared;
 #endif
-      }
    }
 
-   void SetPath(bool projectsDirs)
+   void SetPath(bool projectsDirs, CompilerConfig compiler, ProjectConfig config)
    {
 #ifndef MAKEFILE_GENERATOR
-      ide.SetPath(projectsDirs);
+      ide.SetPath(projectsDirs, compiler, config);
 #endif
    }
 
@@ -980,10 +941,10 @@ private:
    }
 #endif
 
-   void CatTargetFileName(char * string)
+   void CatTargetFileName(char * string, CompilerConfig compiler, ProjectConfig config)
    {
-      CompilerConfig compiler = GetCompilerConfig();
-
+      TargetTypes targetType = GetTargetType(config);
+      String targetFileName = GetTargetFileName(config);
       if(targetType == staticLibrary)
       {
          PathCatSlash(string, "lib");
@@ -1015,19 +976,16 @@ private:
             strcat(string, ".a");
             break;
       }
-      delete compiler;
    }
 
-   void CatMakeFileName(char * string)
+   void CatMakeFileName(char * string, CompilerConfig compiler, ProjectConfig config)
    {
       char projectName[MAX_LOCATION];
-      CompilerConfig compiler = GetCompilerConfig();
       strcpy(projectName, name);
       if(strcmpi(compiler.name, defaultCompilerName))
          sprintf(string, "%s-%s-%s.Makefile", projectName, compiler.name, config.name);
       else
          sprintf(string, "%s%s%s.Makefile", projectName, config ? "-" : "", config ? config.name : "");
-      delete compiler;
    }
 
 #ifndef MAKEFILE_GENERATOR
@@ -1126,15 +1084,15 @@ private:
       }
    }
 
-   bool ProcessBuildPipeOutput(DualPipe f, DirExpression objDirExp, bool isARun, ProjectNode onlyNode)
+   bool ProcessBuildPipeOutput(DualPipe f, DirExpression objDirExp, bool isARun, ProjectNode onlyNode,
+      CompilerConfig compiler, ProjectConfig config)
    {
       char line[65536];
       bool compiling = false, linking = false, precompiling = false;
       int compilingEC = 0;
       int numErrors = 0, numWarnings = 0;
       bool loggedALine = false;
-      CompilerConfig compiler = GetCompilerConfig();
-      char * configName = this.configName;
+      char * configName = config.name;
       int lenMakeCommand = strlen(compiler.makeCommand);
       
       char cppCommand[MAX_LOCATION];
@@ -1385,7 +1343,7 @@ private:
          else
          {
             if(!onlyNode)
-               ide.outputView.buildBox.Logf("\n%s (%s) - ", targetFileName, configName);
+               ide.outputView.buildBox.Logf("\n%s (%s) - ", GetTargetFileName(config), configName);
             if(numErrors)
                ide.outputView.buildBox.Logf("%d %s, ", numErrors, (numErrors > 1) ? "errors" : "error");
             else
@@ -1397,15 +1355,12 @@ private:
                ide.outputView.buildBox.Logf("no warning\n");
          }
       }
-      
-      delete compiler;
       return numErrors == 0;
    }
 
-   void ProcessCleanPipeOutput(DualPipe f)
+   void ProcessCleanPipeOutput(DualPipe f, CompilerConfig compiler, ProjectConfig config)
    {
       char line[65536];
-      CompilerConfig compiler = GetCompilerConfig();
       int lenMakeCommand = strlen(compiler.makeCommand);
       while(!f.Eof())
       {
@@ -1436,10 +1391,9 @@ private:
             app.Wait();
          //Sleep(1.0 / PEEK_RESOLUTION);
       }
-      delete compiler;
    }
 
-   bool Build(bool isARun, ProjectNode onlyNode)
+   bool Build(bool isARun, ProjectNode onlyNode, CompilerConfig compiler, ProjectConfig config)
    {
       bool result = false;
       DualPipe f;
@@ -1448,20 +1402,19 @@ private:
       char makeFile[MAX_LOCATION];
       char makeFilePath[MAX_LOCATION];
       char configName[MAX_LOCATION];
-      CompilerConfig compiler = GetCompilerConfig();
-      DirExpression objDirExp = objDir;
+      DirExpression objDirExp = GetObjDir(compiler, config);
       PathBackup pathBackup { };
 
       int numJobs = compiler.numJobs;
       char command[MAX_LOCATION];
 
-      strcpy(configName, this.configName);
+      strcpy(configName, config ? config.name : "Common");
       
-      SetPath(false); //true
-      CatTargetFileName(targetFileName);
+      SetPath(false, compiler, config); //true
+      CatTargetFileName(targetFileName, compiler, config);
 
       strcpy(makeFilePath, topNode.path);
-      CatMakeFileName(makeFile);
+      CatMakeFileName(makeFile, compiler, config);
       PathCatSlash(makeFilePath, makeFile);
       
       // TODO: TEST ON UNIX IF \" around makeTarget is ok
@@ -1518,7 +1471,7 @@ private:
                makeTarget, topNode.path, makeFilePath);
          if((f = DualPipeOpen(PipeOpenMode { output = true, error = true, input = true }, command)))
          {
-            result = ProcessBuildPipeOutput(f, objDirExp, isARun, onlyNode);
+            result = ProcessBuildPipeOutput(f, objDirExp, isARun, onlyNode, compiler, config);
             delete f;
          }
          else
@@ -1528,23 +1481,21 @@ private:
       delete pathBackup;
 
       delete objDirExp;
-      delete compiler;
       return result;
    }
 
-   void Clean()
+   void Clean(CompilerConfig compiler, ProjectConfig config)
    {
       char makeFile[MAX_LOCATION];
       char makeFilePath[MAX_LOCATION];
       char command[MAX_LOCATION];
       DualPipe f;
-      CompilerConfig compiler = GetCompilerConfig();
       PathBackup pathBackup { };
 
-      SetPath(false);
+      SetPath(false, compiler, config);
 
       strcpy(makeFilePath, topNode.path);
-      CatMakeFileName(makeFile);
+      CatMakeFileName(makeFile, compiler, config);
       PathCatSlash(makeFilePath, makeFile);
       
       if(compiler.type.isVC)
@@ -1571,7 +1522,7 @@ private:
          if((f = DualPipeOpen(PipeOpenMode { output = 1, error = 1, input = 2 }, command)))
          {
             ide.outputView.buildBox.Tell("Deleting target and object files...");
-            ProcessCleanPipeOutput(f);
+            ProcessCleanPipeOutput(f, compiler, config);
             delete f;
 
             ide.outputView.buildBox.Logf("Target and object files deleted\n");
@@ -1579,15 +1530,13 @@ private:
       }
 
       delete pathBackup;
-      delete compiler;
    }
 
-   void Run(char * args)
+   void Run(char * args, CompilerConfig compiler, ProjectConfig config)
    {   
       String target = new char[maxPathLen];
       char oldDirectory[MAX_LOCATION];
-      DirExpression targetDirExp = targetDir;
-      CompilerConfig compiler = GetCompilerConfig();
+      DirExpression targetDirExp = GetTargetDir(compiler, config);
       PathBackup pathBackup { };
 
       // Build(project, ideMain, true, null);
@@ -1598,7 +1547,7 @@ private:
       strcpy(target, "");
    #endif
       PathCatSlash(target, targetDirExp.dir);
-      CatTargetFileName(target);
+      CatTargetFileName(target, compiler, config);
       sprintf(target, "%s %s", target, args);
       GetWorkingDir(oldDirectory, MAX_LOCATION);
 
@@ -1612,7 +1561,7 @@ private:
       else
          ChangeWorkingDir(topNode.path);
       // ChangeWorkingDir(topNode.path);
-      SetPath(true);
+      SetPath(true, compiler, config);
       if(compiler.execPrefixCommand)
       {
          char * prefixedTarget = new char[strlen(compiler.execPrefixCommand) + strlen(target) + 2];
@@ -1630,23 +1579,22 @@ private:
       delete pathBackup;
 
       delete targetDirExp;
-      delete compiler;
       delete target;
    }
 
-   void Compile(ProjectNode node)
+   void Compile(ProjectNode node, CompilerConfig compiler, ProjectConfig config)
    {
-      Build(false, node);
+      Build(false, node, compiler, config);
    }
 #endif
 
-   void GetMakefileTargetFileName(TargetTypes targetType, char * fileName)
+   void GetMakefileTargetFileName(TargetTypes targetType, char * fileName, ProjectConfig config)
    {
       char s[MAX_LOCATION];
       fileName[0] = '\0';
       if(targetType == staticLibrary || targetType == sharedLibrary)
          strcat(fileName, "$(LP)");
-      ReplaceSpaces(s, targetFileName);
+      ReplaceSpaces(s, GetTargetFileName(config));
       strcat(fileName, s);
       switch(targetType)
       {
@@ -1662,12 +1610,12 @@ private:
       }
    }
 
-   bool GenerateMakefile(char * altMakefilePath, bool noResources, char * includemkPath)
+   bool GenerateMakefile(char * altMakefilePath, bool noResources, char * includemkPath,
+      CompilerConfig compiler, ProjectConfig config)
    {
       bool result = false;
       char filePath[MAX_LOCATION];
       char makeFile[MAX_LOCATION];
-      CompilerConfig compiler = GetCompilerConfig();
       // PathBackup pathBackup { };
       // char oldDirectory[MAX_LOCATION];
       File f = null;
@@ -1675,21 +1623,21 @@ private:
       if(!altMakefilePath)
       {
          strcpy(filePath, topNode.path);
-         CatMakeFileName(makeFile);
+         CatMakeFileName(makeFile, compiler, config);
          PathCatSlash(filePath, makeFile);
       }
 
 #if defined(__WIN32__) && !defined(MAKEFILE_GENERATOR)
       if(compiler.type.isVC)
       {
-         GenerateVSSolutionFile(this);
-         GenerateVCProjectFile(this);
+         GenerateVSSolutionFile(this, compiler);
+         GenerateVCProjectFile(this, compiler);
       }
       else
 #endif
       f = FileOpen(altMakefilePath ? altMakefilePath : filePath, write);
 
-      /*SetPath(false);
+      /*SetPath(false, compiler, config);
       GetWorkingDir(oldDirectory, MAX_LOCATION);
       ChangeWorkingDir(topNode.path);*/
 
@@ -1708,7 +1656,8 @@ private:
          int c, len;
          int numCObjects = 0;
          bool sameObjTargetDirs;
-         DirExpression objDirExp = objDir;
+         DirExpression objDirExp = GetObjDir(compiler, config);
+         TargetTypes targetType = GetTargetType(config);
 
          bool crossCompiling = compiler.targetPlatform != GetRuntimePlatform();
          bool gccCompiler = compiler.ccCommand && strstr(compiler.ccCommand, "gcc") != null;
@@ -1721,13 +1670,13 @@ private:
          Map<String, NameCollisionInfo> namesInfo { };
 
          ReplaceSpaces(objDirNoSpaces, objDirExp.dir);
-         strcpy(temp, targetDirExpression);
+         strcpy(temp, GetTargetDirExpression(compiler, config));
          ReplaceSpaces(targetDirExpNoSpaces, temp);
-         GetMakefileTargetFileName(targetType, target);
+         GetMakefileTargetFileName(targetType, target, config);
          PathCatSlash(temp, target);
          ReplaceSpaces(targetNoSpaces, temp);
 
-         strcpy(objDirExpNoSpaces, objDirExpression);
+         strcpy(objDirExpNoSpaces, GetObjDirExpression(compiler, config));
          ChangeCh(objDirExpNoSpaces, '\\', '/'); // TODO: this is a hack, paths should never include win32 path seperators - fix this in ProjectSettings and ProjectLoad instead
          ReplaceSpaces(objDirExpNoSpaces, objDirExpNoSpaces);
          ReplaceSpaces(resDirNoSpaces, resNode.path ? resNode.path : "");
@@ -1760,33 +1709,33 @@ private:
          f.Printf("RES = %s%s\n\n", resDirNoSpaces, resDirNoSpaces[0] ? "/" : "");
 
          if(targetType == executable)
-            f.Printf("CONSOLE = %s\n\n", console ? "-mconsole" : "-mwindows");
+            f.Printf("CONSOLE = %s\n\n", GetConsole(config) ? "-mconsole" : "-mwindows");
 
          f.Printf("TARGET = %s\n\n", targetNoSpaces);
 
          varStringLenDiffs["$(OBJ)"] = strlen(objDirNoSpaces) - 6;
 
-         topNode.GenMakefileGetNameCollisionInfo(namesInfo);
+         topNode.GenMakefileGetNameCollisionInfo(namesInfo, config);
 
-         numCObjects = topNode.GenMakefilePrintNode(f, this, objects, namesInfo, listItems);
+         numCObjects = topNode.GenMakefilePrintNode(f, this, objects, namesInfo, listItems, config);
          if(numCObjects)
             listItems.Add(CopyString("$(OBJ)$(MODULE).main$(O)"));
          objectsParts = OutputFileList(f, "OBJECTS", listItems, varStringLenDiffs);
 
-         topNode.GenMakefilePrintNode(f, this, cObjects, namesInfo, listItems);
+         topNode.GenMakefilePrintNode(f, this, cObjects, namesInfo, listItems, config);
          cobjectsParts = OutputFileList(f, "COBJECTS", listItems, varStringLenDiffs);
 
-         topNode.GenMakefilePrintNode(f, this, symbols, null, listItems);
+         topNode.GenMakefilePrintNode(f, this, symbols, null, listItems, config);
          symbolsParts = OutputFileList(f, "SYMBOLS", listItems, varStringLenDiffs);
 
-         topNode.GenMakefilePrintNode(f, this, imports, null, listItems);
+         topNode.GenMakefilePrintNode(f, this, imports, null, listItems, config);
          importsParts = OutputFileList(f, "IMPORTS", listItems, varStringLenDiffs);
 
-         topNode.GenMakefilePrintNode(f, this, sources, null, listItems);
+         topNode.GenMakefilePrintNode(f, this, sources, null, listItems, config);
          OutputFileList(f, "SOURCES", listItems, varStringLenDiffs);
 
          if(!noResources)
-            resNode.GenMakefilePrintNode(f, this, resources, null, listItems);
+            resNode.GenMakefilePrintNode(f, this, resources, null, listItems, config);
          OutputFileList(f, "RESOURCES", listItems, varStringLenDiffs);
 
          if(includemkPath)
@@ -1846,7 +1795,7 @@ private:
          if(gccCompiler)
          {
             f.Printf(" -fmessage-length=0");
-            switch(optimization)
+            switch(GetOptimization(config))
             {
                case speed:
                   f.Printf(" -O2");
@@ -1863,16 +1812,14 @@ private:
             f.Printf(" $(FPIC)");
             //f.Printf(" -fpack-struct");
          }
-         if(warnings)
+         switch(GetWarnings(config))
          {
-            if(warnings == all)
-               f.Printf(" -Wall");
-            if(warnings == none)
-               f.Printf(" -w");
+            case all: f.Printf(" -Wall"); break;
+            case none: f.Printf(" -w"); break;
          }
-         if(debug)
+         if(GetDebug(config))
             f.Printf(" -g");
-         if(profile)
+         if(GetProfile(config))
             f.Printf(" -pg");
          if(options && options.linkerOptions && options.linkerOptions.count)
          {
@@ -1898,15 +1845,15 @@ private:
          f.Printf("\n\n");
 
          f.Printf("ECFLAGS =");
-         if(memoryGuard)
+         if(GetMemoryGuard(config))
             f.Printf(" -memguard");
-         if(strictNameSpaces)
+         if(GetStrictNameSpaces(config))
             f.Printf(" -strictns");
-         if(noLineNumbers)
+         if(GetNoLineNumbers(config))
             f.Printf(" -nolinenumbers");
          {
             char * s;
-            if((s = defaultNameSpace) && s[0])
+            if((s = GetDefaultNameSpace(config)) && s[0])
                f.Printf(" -defaultns %s", s);
          }
          f.Printf("\n\n");
@@ -1914,7 +1861,7 @@ private:
          if(targetType != staticLibrary)
          {
             f.Printf("OFLAGS = -m32"); // TARGET_TYPE is fixed in a Makefile, we don't want this. $(if TARGET_TYPE_STATIC_LIBRARY,,-m32)");
-            if(profile)
+            if(GetProfile(config))
                f.Printf(" -pg");
             // no if? 
             OutputListOption(f, "L", compiler.libraryDirs, lineEach, true);
@@ -2153,7 +2100,7 @@ private:
             f.Printf("$(OBJ)$(MODULE).main.ec: $(SYMBOLS) $(COBJECTS)\n");
             // use of objDirExpNoSpaces used instead of $(OBJ) to prevent problematic joining of arguments in ecs
             f.Printf("\t$(ECS)%s $(ECSLIBOPT) $(SYMBOLS) $(IMPORTS) -symbols %s -o $(OBJ)$(MODULE).main.ec\n\n", 
-               console ? " -console" : "", objDirExpNoSpaces);
+               GetConsole(config) ? " -console" : "", objDirExpNoSpaces);
             // Main Module (Linking) for ECERE C modules
             f.Printf("$(OBJ)$(MODULE).main.c: $(OBJ)$(MODULE).main.ec\n");
             f.Printf("\t$(ECP) $(CECFLAGS) $(ECFLAGS) $(CFLAGS)"
@@ -2186,11 +2133,11 @@ private:
             //f.Printf("endif\n");
             f.Printf("\t$(CC) $(OFLAGS) $(OBJECTS) $(LIBS) -o $(TARGET) $(INSTALLNAME)\n");
 
-            if(!debug)
+            if(!GetDebug(config))
             {
                f.Printf("\t$(STRIP) $(STRIPOPT) $(TARGET)\n");
 
-               if(compress)
+               if(GetCompress(config))
                {
                   f.Printf("ifndef WINDOWS\n");
                   f.Printf("ifeq \"$(TARGET_TYPE)\" \"executable\"\n");
@@ -2202,7 +2149,7 @@ private:
                }
             }
             if(resNode.files && resNode.files.count && !noResources)
-               resNode.GenMakefileAddResources(f, resNode.path);
+               resNode.GenMakefileAddResources(f, resNode.path, config);
          }
          else
             f.Printf("\t$(AR) rcs $(TARGET) $(OBJECTS) $(LIBS)\n");
@@ -2284,10 +2231,10 @@ private:
          f.Printf("\n");
 
          f.Printf("# SYMBOL RULES\n\n");
-         topNode.GenMakefilePrintSymbolRules(f, this);
+         topNode.GenMakefilePrintSymbolRules(f, this, compiler, config);
 
          f.Printf("# C OBJECT RULES\n\n");
-         topNode.GenMakefilePrintCObjectRules(f, this);
+         topNode.GenMakefilePrintCObjectRules(f, this, compiler, config);
 
          /*if(numCObjects)
          {
@@ -2300,10 +2247,10 @@ private:
          f.Printf("# OBJECT RULES\n\n");
          // todo call this still but only generate rules whith specific options
          // see we-have-file-specific-options in ProjectNode.ec
-         topNode.GenMakefilePrintObjectRules(f, this, namesInfo);
+         topNode.GenMakefilePrintObjectRules(f, this, namesInfo, compiler, config);
 
          if(numCObjects)
-            GenMakefilePrintMainObjectRule(f);
+            GenMakefilePrintMainObjectRule(f, compiler, config);
 
          f.Printf("clean: objdir%s\n", sameObjTargetDirs ? "" : " targetdir");
          f.Printf("\t$(call rmq,%s$(TARGET))\n", numCObjects ? "$(OBJ)$(MODULE).main.c $(OBJ)$(MODULE).main.ec $(OBJ)$(MODULE).main$(I) $(OBJ)$(MODULE).main$(S) " : "");
@@ -2338,13 +2285,10 @@ private:
 
       if(config)
          config.makingModified = false;
-
-      delete compiler;
-
       return result;
    }
 
-   void GenMakefilePrintMainObjectRule(File f)
+   void GenMakefilePrintMainObjectRule(File f, CompilerConfig compiler, ProjectConfig config)
    {
       char extension[MAX_EXTENSION] = "c";
       char modulePath[MAX_LOCATION];
@@ -2352,7 +2296,7 @@ private:
       DualPipe dep;
       char command[2048];
       char objDirNoSpaces[MAX_LOCATION];
-      DirExpression objDirExp = objDir;
+      DirExpression objDirExp = GetObjDir(compiler, config);
 
       ReplaceSpaces(objDirNoSpaces, objDirExp.dir);
       ReplaceSpaces(fixedModuleName, moduleName);
index 923e4fd..6b33bd4 100644 (file)
@@ -32,7 +32,8 @@ class DirExpression : struct
       }
    }
 
-   void Evaluate(char * expression, Project project)
+   void Evaluate(char * expression, Project project,
+      CompilerConfig compiler, ProjectConfig config)
    {
       int len;
       char * expr = expression;
@@ -52,8 +53,6 @@ class DirExpression : struct
       if((len = strlen(expr)))
       {
          int c, d;
-         CompilerConfig compiler = GetCompilerConfig();
-         ProjectConfig config = project.config;
          char * configName = config && config.name && config.name[0] ? config.name : "Common";
          char * projectName = project.name ? project.name : "";
          char * moduleName = project.moduleName ? project.moduleName : "";
@@ -147,7 +146,6 @@ class DirExpression : struct
             delete dir;
          if(!dir)
             dir = CopyString(buffer);
-         delete compiler;
       }
       else
       {
index 0a1a1a2..c10780b 100644 (file)
@@ -348,34 +348,37 @@ public:
       }
    }
 
-   property ProjectConfig config
-   {
-      get
-      {
-         Project prj;
-         ProjectConfig result = null;
-         if(configurations && (prj = property::project) && prj.config)
-         {
-            const char * projectConfigName = prj.config.name;
-            for(config : configurations)
-            {
-               if(!strcmpi(config.name, projectConfigName))
-               {
-                  result = config;
-                  break;
-               }
-            }
-         }
-         return result;
-      }
-   }
+private:
+   ProjectOptions options;
+   Array<PlatformOptions> platforms;
+   List<ProjectConfig> configurations;
+   ProjectNodeType nodeType;
+   ProjectNode parent;
+   char * name;
+   char * info;
 
-   ProjectConfig GetMatchingNodeConfig(ProjectConfig config)
+   // This holds the absolute path of the .epj for the project topnode (without the filename)
+   // It holds a relative path to the topNode (project) for other nodes (folders and files)
+   // For folders, it includes the folder it refers to. If there is a name difference between the
+   // file system folder and the grouping folder of the project view, it maps to that folder.
+   char * path;
+   
+   NodeTypes type;
+   NodeIcons icon;
+   int indent;
+   DataRow row;
+
+   bool modified;
+   
+   // This is only set for Top Nodes
+   Project project;
+
+   ProjectConfig GetMatchingNodeConfig(ProjectConfig prjConfig)
    {
       ProjectConfig nodeConfig = null;
-      if(property::configurations)
+      if(property::configurations && prjConfig)
       {
-         const char * configName = config.name;
+         const char * configName = prjConfig.name;
          for(cfg : property::configurations)
          {
             if(!strcmpi(cfg.name, configName))
@@ -388,84 +391,74 @@ public:
       return nodeConfig;
    }
 
-   property bool ecflags
+   // For makefile generation:
+   bool GetECFLAGS(ProjectConfig prjConfig)
    {
-      get
-      {
-         ProjectConfig config = this.config;
-         ProjectOptions options = property::options;
-         SetBool memoryGuard = localMemoryGuard;
-         String defaultNameSpace = localDefaultNameSpace;
-         SetBool strictNameSpaces = localStrictNameSpaces;
-         SetBool noLineNumbers = localNoLineNumbers;
-
-         if(memoryGuard || defaultNameSpace || strictNameSpaces || noLineNumbers)
-            return true;
-         else if(parent.parent)
-            return parent.ecflags;
-         else
-            return false;
-      }
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
+      ProjectOptions options = property::options;
+      SetBool memoryGuard = localMemoryGuard;
+      String defaultNameSpace = localDefaultNameSpace;
+      SetBool strictNameSpaces = localStrictNameSpaces;
+      SetBool noLineNumbers = localNoLineNumbers;
+
+      if(memoryGuard || defaultNameSpace || strictNameSpaces || noLineNumbers)
+         return true;
+      else if(parent.parent)
+         return parent.GetECFLAGS(prjConfig);
+      else
+         return false;
    }
-   property bool memoryGuard
+   
+   bool GetMemoryGuard(ProjectConfig prjConfig)
    {
-      get
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
+      ProjectOptions options = property::options;
+      SetBool memoryGuard = localMemoryGuard;
+      if(!memoryGuard)
       {
-         ProjectConfig config = this.config;
-         ProjectOptions options = property::options;
-         SetBool memoryGuard = localMemoryGuard;
-         if(!memoryGuard)
-         {
-            if(parent)
-               return parent.memoryGuard;
-         }
-         return memoryGuard == true;
+         if(parent)
+            return parent.GetMemoryGuard(prjConfig);
       }
+      return memoryGuard == true;
    }
-   property String defaultNameSpace
+
+   String GetDefaultNameSpace(ProjectConfig prjConfig)
    {
-      get
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
+      ProjectOptions options = property::options;
+      String defaultNameSpace = localDefaultNameSpace;
+      if(!defaultNameSpace)
       {
-         ProjectConfig config = this.config;
-         ProjectOptions options = property::options;
-         String defaultNameSpace = localDefaultNameSpace;
-         if(!defaultNameSpace)
-         {
-            if(parent)
-               return parent.defaultNameSpace;
-         }
-         return defaultNameSpace;
+         if(parent)
+            return parent.GetDefaultNameSpace(prjConfig);
       }
+      return defaultNameSpace;
    }
-   property bool strictNameSpaces
+
+   bool GetStrictNameSpaces(ProjectConfig prjConfig)
    {
-      get
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
+      ProjectOptions options = property::options;
+      SetBool strictNameSpaces = localStrictNameSpaces;
+      if(!strictNameSpaces)
       {
-         ProjectConfig config = this.config;
-         ProjectOptions options = property::options;
-         SetBool strictNameSpaces = localStrictNameSpaces;
-         if(!strictNameSpaces)
-         {
-            if(parent)
-               return parent.strictNameSpaces;
-         }
-         return strictNameSpaces == true;
+         if(parent)
+            return parent.GetStrictNameSpaces(prjConfig);
       }
+      return strictNameSpaces == true;
    }
-   property bool noLineNumbers
+
+   bool GetNoLineNumbers(ProjectConfig prjConfig)
    {
-      get
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
+      ProjectOptions options = property::options;
+      SetBool noLineNumbers = localNoLineNumbers;
+      if(!noLineNumbers)
       {
-         ProjectConfig config = this.config;
-         ProjectOptions options = property::options;
-         SetBool noLineNumbers = localNoLineNumbers;
-         if(!noLineNumbers)
-         {
-            if(parent)
-               return parent.noLineNumbers;
-         }
-         return noLineNumbers == true;
+         if(parent)
+            return parent.GetNoLineNumbers(prjConfig);
       }
+      return noLineNumbers == true;
    }
 
    property ProjectNode root { get { ProjectNode n; for(n = this; n.parent; n = n.parent); return n; } }
@@ -523,10 +516,10 @@ public:
       return buffer;
    }
 
-   void CollectPerFileAndDirOptions(ProjectConfig projectConfig, Array<String> perFilePreprocessorDefs, Array<DirPath> perFileIncludeDirs)
+   void CollectPerFileAndDirOptions(ProjectConfig prjConfig, Array<String> perFilePreprocessorDefs, Array<DirPath> perFileIncludeDirs)
    {
       ProjectNode node = null;
-      ProjectConfig config = GetMatchingNodeConfig(projectConfig);
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       List<ProjectNode> nodeStack { };
       
       for(node = this; node && node.parent; node = node.parent)
@@ -537,6 +530,7 @@ public:
       // TODO: Check how to fix duplication of following options when configuration is made per-config-per-file
       while((node = nodeStack.lastIterator.data))
       {
+         ProjectConfig config = GetMatchingNodeConfig(prjConfig);
          ProjectOptions nodeOptions = node.property::options;
          if(nodeOptions && nodeOptions.preprocessorDefinitions)
          {
@@ -563,30 +557,6 @@ public:
       delete nodeStack;
    }
 
-private:
-   ProjectOptions options;
-   Array<PlatformOptions> platforms;
-   List<ProjectConfig> configurations;
-   ProjectNodeType nodeType;
-   ProjectNode parent;
-   char * name;
-   char * info;
-
-   // This holds the absolute path of the .epj for the project topnode (without the filename)
-   // It holds a relative path to the topNode (project) for other nodes (folders and files)
-   // For folders, it includes the folder it refers to. If there is a name difference between the
-   // file system folder and the grouping folder of the project view, it maps to that folder.
-   char * path;
-   
-   NodeTypes type;
-   NodeIcons icon;
-   int indent;
-   DataRow row;
-
-   bool modified;
-   
-   // This is only set for Top Nodes
-   Project project;
 
    property Project project
    {
@@ -807,143 +777,136 @@ private:
       }
    }
 
-   property TwoStrings platformSpecificFu
+   TwoStrings GetPlatformSpecificFu(ProjectConfig prjConfig)
    {
-      get
-      {
-         TwoStrings result { a = CopyString(""), b = CopyString("") };
-         // note: unknown platform is for common
-         Map<Platform, SetBool> exclusionInfo { };
-         MapNode<Platform, SetBool> mn;
-         char * exp, * var;
-         int len;
-         SetBool common;
+      TwoStrings result { a = CopyString(""), b = CopyString("") };
+      // note: unknown platform is for common
+      Map<Platform, SetBool> exclusionInfo { };
+      MapNode<Platform, SetBool> mn;
+      char * exp, * var;
+      int len;
+      SetBool common;
 
-         CollectExclusionInfo(exclusionInfo);
-         common = exclusionInfo[unknown];
+      CollectExclusionInfo(exclusionInfo, prjConfig);
+      common = exclusionInfo[unknown];
+      {
+         Map<Platform, SetBool> cleaned { };
+         SetBool opposite = common == true ? false : true;
+         for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
          {
-            Map<Platform, SetBool> cleaned { };
-            SetBool opposite = common == true ? false : true;
-            for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
-            {
-               if(mn.key == unknown || mn.value == opposite)
-                 cleaned[mn.key] = mn.value;
-            }
-            delete exclusionInfo;
-            exclusionInfo = cleaned;
+            if(mn.key == unknown || mn.value == opposite)
+              cleaned[mn.key] = mn.value;
          }
+         delete exclusionInfo;
+         exclusionInfo = cleaned;
+      }
 
-         if(exclusionInfo.count > 1)
+      if(exclusionInfo.count > 1)
+      {
+         if(exclusionInfo.count > 2)
          {
-            if(exclusionInfo.count > 2)
-            {
-               exp = result.a;
-               len = strlen(exp) + strlen("$(if $(or ");
-               exp = renew exp char[len+1];
-               strcat(exp, "$(if $(or ");
-               result.a = exp;
+            exp = result.a;
+            len = strlen(exp) + strlen("$(if $(or ");
+            exp = renew exp char[len+1];
+            strcat(exp, "$(if $(or ");
+            result.a = exp;
 
-               for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
+            for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
+            {
+               if(mn.key != unknown)
                {
-                  if(mn.key != unknown)
-                  {
-                     char * comma = mn.next ? "," : "";
-
-                     var = PlatformToMakefileVariable(mn.key);
-
-                     exp = result.a;
-                     len = strlen(exp) + strlen("$(") + strlen(var) + strlen(")") + strlen(comma);
-                     exp = renew exp char[len+1];
-                     strcat(exp, "$(");
-                     strcat(exp, var);
-                     strcat(exp, ")");
-                     strcat(exp, comma);
-                     result.a = exp;
-                  }
+                  char * comma = mn.next ? "," : "";
+
+                  var = PlatformToMakefileVariable(mn.key);
+
+                  exp = result.a;
+                  len = strlen(exp) + strlen("$(") + strlen(var) + strlen(")") + strlen(comma);
+                  exp = renew exp char[len+1];
+                  strcat(exp, "$(");
+                  strcat(exp, var);
+                  strcat(exp, ")");
+                  strcat(exp, comma);
+                  result.a = exp;
                }
-
-               exp = result.a;
-               len = strlen(exp) + strlen("),");
-               exp = renew exp char[len+1];
-            }
-            else
-            {
-               if(exclusionInfo.root.minimum.key != unknown)
-                  var = PlatformToMakefileVariable(exclusionInfo.root.minimum.key);
-               else
-                  var = PlatformToMakefileVariable(exclusionInfo.root.minimum.next.key);
-
-               exp = result.a;
-               len = strlen(exp) + strlen("$(if $(") + strlen(var) + strlen("),");
-               exp = renew exp char[len+1];
-               strcat(exp, "$(if $(");
-               strcat(exp, var);
             }
 
-            strcat(exp, "),");
-            result.a = exp;
-
-            exp = common == true ? result.b : result.a;
-            len = strlen(exp) + strlen(",");
+            exp = result.a;
+            len = strlen(exp) + strlen("),");
             exp = renew exp char[len+1];
-            strcat(exp, ",");
-            if(common == true) result.b = exp; else result.a = exp;
+         }
+         else
+         {
+            if(exclusionInfo.root.minimum.key != unknown)
+               var = PlatformToMakefileVariable(exclusionInfo.root.minimum.key);
+            else
+               var = PlatformToMakefileVariable(exclusionInfo.root.minimum.next.key);
 
-            exp = result.b;
-            len = strlen(exp) + strlen(")");
+            exp = result.a;
+            len = strlen(exp) + strlen("$(if $(") + strlen(var) + strlen("),");
             exp = renew exp char[len+1];
-            strcat(exp, ")");
-            result.b = exp;
+            strcat(exp, "$(if $(");
+            strcat(exp, var);
          }
-         delete exclusionInfo;
-         
-         return result;
+
+         strcat(exp, "),");
+         result.a = exp;
+
+         exp = common == true ? result.b : result.a;
+         len = strlen(exp) + strlen(",");
+         exp = renew exp char[len+1];
+         strcat(exp, ",");
+         if(common == true) result.b = exp; else result.a = exp;
+
+         exp = result.b;
+         len = strlen(exp) + strlen(")");
+         exp = renew exp char[len+1];
+         strcat(exp, ")");
+         result.b = exp;
       }
+      delete exclusionInfo;
+      
+      return result;
    }
 
-   property bool isExcluded
+   bool GetIsExcluded(ProjectConfig prjConfig)
    {
-      get
+      bool result;
+      // note: unknown platform is for common
+      Map<Platform, SetBool> exclusionInfo { };
+      CollectExclusionInfo(exclusionInfo, prjConfig);
+      if(exclusionInfo.count == 0)
+         result = false;
+      else if(exclusionInfo.count == 1)
+         result = exclusionInfo.root.minimum.value == true;
+      else
       {
-         bool result;
-         // note: unknown platform is for common
-         Map<Platform, SetBool> exclusionInfo { };
-         CollectExclusionInfo(exclusionInfo);
-         if(exclusionInfo.count == 0)
-            result = false;
-         else if(exclusionInfo.count == 1)
-            result = exclusionInfo.root.minimum.value == true;
-         else
+         SetBool check = exclusionInfo.root.minimum.value;
+         MapNode<Platform, SetBool> mn;
+         for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
          {
-            SetBool check = exclusionInfo.root.minimum.value;
-            MapNode<Platform, SetBool> mn;
-            for(mn = exclusionInfo.root.minimum; mn; mn = mn.next)
-            {
-               if(check != mn.value)
-                  break;
-            }
-            if(!mn) // all are same
-               result = check == true;
-            else
-               result = false;
+            if(check != mn.value)
+               break;
          }
-         delete exclusionInfo;
-         return result;
-
+         if(!mn) // all are same
+            result = check == true;
+         else
+            result = false;
       }
+      delete exclusionInfo;
+      return result;
    }
 
-   void CollectExclusionInfo(Map<Platform, SetBool> output)
+   void CollectExclusionInfo(Map<Platform, SetBool> output, ProjectConfig prjConfig)
    {
       // note: unknown platform is for common
       Platform platform;
-      ProjectConfig config = property::config;
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       ProjectOptions options = property::options;
       Array<PlatformOptions> platforms = property::platforms;
       List<ProjectConfig> configurations = property::configurations;
 
       if(parent)
-         parent.CollectExclusionInfo(output);
+         parent.CollectExclusionInfo(output, prjConfig);
       else
          output[unknown] = unset;
 
@@ -1060,7 +1023,8 @@ private:
       return result;
    }
 
-   ProjectNode FindSameNameConflict(char * name, bool includeResources, Map<Platform, SetBool> exclusionInfo)
+   ProjectNode FindSameNameConflict(char * name, bool includeResources,
+      Map<Platform, SetBool> exclusionInfo, ProjectConfig prjConfig)
    {
       ProjectNode result = null;
       Map<Platform, SetBool> compareExclusion { };
@@ -1074,7 +1038,7 @@ private:
             {
                if(child.type != folder && child.name && !strcmpi(child.name, name))
                {
-                  child.CollectExclusionInfo(compareExclusion);
+                  child.CollectExclusionInfo(compareExclusion, prjConfig);
                   common = exclusionInfo[unknown];
                   commonComp = compareExclusion[unknown];
                   if(exclusionInfo.count == 1 && compareExclusion.count == 1)
@@ -1107,7 +1071,7 @@ private:
                   compareExclusion.Free();
                   break;
                }
-               result = child.FindSameNameConflict(name, includeResources, exclusionInfo);
+               result = child.FindSameNameConflict(name, includeResources, exclusionInfo, prjConfig);
                if(result) break;
             }
          }
@@ -1125,8 +1089,10 @@ private:
 
       GetLastDirectory(filePath, temp);
       //if(!checkIfExists || !project.topNode.Find(temp, false))
-      CollectExclusionInfo(exclusionInfo);
-      if(!checkIfExists || !project.topNode.FindSameNameConflict(temp, false, exclusionInfo))
+      
+      // TOCHECK: Shouldn't this apply either for all configs or none?
+      CollectExclusionInfo(exclusionInfo, project.config);
+      if(!checkIfExists || !project.topNode.FindSameNameConflict(temp, false, exclusionInfo, project.config))
       {
          // Do the check for folder in the same parent or resource files only here
          if(type == folder || !checkIfExists)
@@ -1287,7 +1253,7 @@ private:
       return result;
    }
 
-   void GenFileFlags(File f, Project project)
+   void GenFileFlags(File f, Project project, ProjectConfig prjConfig)
    {
       ProjectNode node = null;
       List<ProjectNode> nodeStack { };
@@ -1300,7 +1266,7 @@ private:
       while((node = nodeStack.lastIterator.data))
       {
          ProjectOptions nodeOptions = node.property::options;
-         ProjectConfig config = node.config;
+         ProjectConfig config = node.GetMatchingNodeConfig(prjConfig);
          if(nodeOptions && nodeOptions.preprocessorDefinitions)
             OutputListOption(f, "D", nodeOptions.preprocessorDefinitions, inPlace, false);
          if(config && config.options && config.options.preprocessorDefinitions)
@@ -1315,7 +1281,7 @@ private:
       delete nodeStack;
    }
 
-   void GenMakefileGetNameCollisionInfo(Map<String, NameCollisionInfo> namesInfo)
+   void GenMakefileGetNameCollisionInfo(Map<String, NameCollisionInfo> namesInfo, ProjectConfig prjConfig)
    {
       if(type == file)
       {
@@ -1352,19 +1318,21 @@ private:
       {
          for(child : files)
          {
-            if(child.type != resources && (child.type == folder || !child.isExcluded))
-               child.GenMakefileGetNameCollisionInfo(namesInfo);
+            if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
+               child.GenMakefileGetNameCollisionInfo(namesInfo, prjConfig);
          }
       }
    }
    
-   int GenMakefilePrintNode(File f, Project project, GenMakefilePrintTypes printType, Map<String, NameCollisionInfo> namesInfo, Array<String> items)
+   int GenMakefilePrintNode(File f, Project project, GenMakefilePrintTypes printType,
+      Map<String, NameCollisionInfo> namesInfo, Array<String> items,
+      ProjectConfig prjConfig)
    {
       int count = 0;
       if(type == file)
       {
          char s[2048];
-         TwoStrings ts = platformSpecificFu;
+         TwoStrings ts = GetPlatformSpecificFu(prjConfig);
          char moduleName[MAX_FILENAME];
          char extension[MAX_EXTENSION];
          GetExtension(name, extension);
@@ -1444,19 +1412,18 @@ private:
       {
          for(child : files)
          {
-            if(child.type != resources && (child.type == folder || !child.isExcluded))
-               count += child.GenMakefilePrintNode(f, project, printType, namesInfo, items);
+            if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
+               count += child.GenMakefilePrintNode(f, project, printType, namesInfo, items, prjConfig);
          }
       }
       return count;
    }
 
-   void GenMakefilePrintSymbolRules(File f, Project project)
+   void GenMakefilePrintSymbolRules(File f, Project project, CompilerConfig compiler, ProjectConfig prjConfig)
    {
       //ProjectNode child;
       //char objDir[MAX_LOCATION];
-      CompilerConfig compiler = GetCompilerConfig();
-      //ReplaceSpaces(objDir, project.config.objDir.dir);
+      //ReplaceSpaces(objDir, config.objDir.dir);
 
       //eSystem_Log("Printing Symbol Rules\n");
       if(type == file)
@@ -1560,17 +1527,17 @@ private:
 
             f.Printf("\t$(ECP)");
             // Give priority to file flags
-            GenFileFlags(f, project);
+            GenFileFlags(f, project, prjConfig);
 
             f.Printf(" $(CECFLAGS)");
-            if(ecflags)
+            if(GetECFLAGS(prjConfig))
             {
-               if(memoryGuard)
+               if(GetMemoryGuard(prjConfig))
                   f.Printf(" -memguard");
-               if(strictNameSpaces)
+               if(GetStrictNameSpaces(prjConfig))
                   f.Printf(" -strictns");
                {
-                  char * s = defaultNameSpace;
+                  char * s = GetDefaultNameSpace(prjConfig);
                   if(s && s[0])
                      f.Printf(" -defaultns %s", s);
                }
@@ -1588,19 +1555,18 @@ private:
          for(child : files)
          {
             // TODO: Platform specific options
-            if(child.type != resources && (child.type == folder || !child.isExcluded))
-               child.GenMakefilePrintSymbolRules(f, project);
+            if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
+               child.GenMakefilePrintSymbolRules(f, project, compiler, prjConfig);
          }
       }
-      delete compiler;
    }
 
-   void GenMakefilePrintCObjectRules(File f, Project project)
+   void GenMakefilePrintCObjectRules(File f, Project project, CompilerConfig compiler, ProjectConfig prjConfig)
    {
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       //ProjectNode child;
       //char objDir[MAX_LOCATION];
-      CompilerConfig compiler = GetCompilerConfig();
-      //ReplaceSpaces(objDir, project.config.objDir.dir);
+      //ReplaceSpaces(objDir, config.objDir.dir);
       //eSystem_Log("Printing C Object Rules\n");
       if(type == file)
       {
@@ -1639,7 +1605,7 @@ private:
                   strcat(command, item);
             }
 
-            for(item : project.config.includeDirs)
+            for(item : config.includeDirs)
             {
                strcat(command, " -I");
                if(strchr(item, ' '))
@@ -1651,7 +1617,7 @@ private:
                else
                   strcat(command, item);
             }
-            for(item : project.config.preprocessorDefs)
+            for(item : config.preprocessorDefs)
             {
                strcat(command, " -D");
                strcat(command, item);
@@ -1707,16 +1673,16 @@ private:
 
             f.Printf("\t$(ECC)");
             // Give priority to file flags
-            GenFileFlags(f, project);
-            if(ecflags)
+            GenFileFlags(f, project, prjConfig);
+            if(GetECFLAGS(prjConfig))
             {
-               f.Printf("%s $(CECFLAGS)", noLineNumbers ? " -nolinenumbers" : "");
-               if(memoryGuard)
+               f.Printf("%s $(CECFLAGS)", GetNoLineNumbers(prjConfig) ? " -nolinenumbers" : "");
+               if(GetMemoryGuard(prjConfig))
                   f.Printf(" -memguard");
-               if(strictNameSpaces)
+               if(GetStrictNameSpaces(prjConfig))
                   f.Printf(" -strictns");
                {
-                  char * s = defaultNameSpace;
+                  char * s = GetDefaultNameSpace(prjConfig);
                   if(s && s[0])
                      f.Printf(" -defaultns %s", s);
                }
@@ -1734,19 +1700,20 @@ private:
          for(child : files)
          {
             // TODO: Platform specific options
-            if(child.type != resources && (child.type == folder || !child.isExcluded))
-               child.GenMakefilePrintCObjectRules(f, project);
+            if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
+               child.GenMakefilePrintCObjectRules(f, project, compiler, prjConfig);
          }
       }
-      delete compiler;
    }
 
-   void GenMakefilePrintObjectRules(File f, Project project, Map<String, NameCollisionInfo> namesInfo)
+   void GenMakefilePrintObjectRules(File f, Project project,
+      Map<String, NameCollisionInfo> namesInfo,
+      CompilerConfig compiler, ProjectConfig prjConfig)
    {
+      ProjectConfig config = GetMatchingNodeConfig(prjConfig);
       //ProjectNode child;
       //char objDir[MAX_LOCATION];
-      CompilerConfig compiler = GetCompilerConfig();
-      //ReplaceSpaces(objDir, project.config.objDir.dir);
+      //ReplaceSpaces(objDir, config.objDir.dir);
       //eSystem_Log("Printing Object Rules\n");
       if(type == file)
       {
@@ -1801,7 +1768,7 @@ private:
                      strcat(command, item);
                }
 
-               for(item : project.config.includeDirs)
+               for(item : config.includeDirs)
                {
                   strcat(command, " -I");
                   if(strchr(item, ' '))
@@ -1813,7 +1780,7 @@ private:
                   else
                      strcat(command, item);
                }
-               for(item : project.config.preprocessorDefs)
+               for(item : config.preprocessorDefs)
                {
                   strcat(command, " -D");
                   strcat(command, item);
@@ -1865,7 +1832,7 @@ private:
             }
             f.Printf("\t$(CC)");
             // Give priority to file flags
-            GenFileFlags(f, project);
+            GenFileFlags(f, project, prjConfig);
 
             f.Printf(" $(CFLAGS)");
 
@@ -1882,14 +1849,13 @@ private:
          for(child : files)
          {
             // TODO: Platform specific options
-            if(child.type != resources && (child.type == folder || !child.isExcluded))
-               child.GenMakefilePrintObjectRules(f, project, namesInfo);
+            if(child.type != resources && (child.type == folder || !child.GetIsExcluded(prjConfig)))
+               child.GenMakefilePrintObjectRules(f, project, namesInfo, compiler, prjConfig);
          }
       }
-      delete compiler;
    }
 
-   void GenMakefileAddResources(File f, String resourcesPath)
+   void GenMakefileAddResources(File f, String resourcesPath, ProjectConfig prjConfig)
    {
       int count = 0;
       if(files)
@@ -1903,10 +1869,10 @@ private:
          for(c = 0; c < files.count; c++)
          {
             ProjectNode child = files[c];
-            TwoStrings ts = child.platformSpecificFu;
+            TwoStrings ts = child.GetPlatformSpecificFu(prjConfig);
             if(count > 0 && ts)
                prev = true;
-            if(child.type == file && !child.isExcluded && !(count > 0 && ts))
+            if(child.type == file && !child.GetIsExcluded(prjConfig) && !(count > 0 && ts))
             {
                bool useRes;
                char tempPath[MAX_LOCATION];
@@ -1966,7 +1932,7 @@ private:
          for(child : files)
          {
             if(child.type == folder)
-               child.GenMakefileAddResources(f, resourcesPath);
+               child.GenMakefileAddResources(f, resourcesPath, prjConfig);
          }
       }
    }
index f91efe1..dda3ee6 100644 (file)
@@ -155,49 +155,34 @@ class ProjectView : Window
       get { return workspace; }
    }
    
-   /*property Project project
-   {
-      set
-      {
-         if(project)
-         {
-            DeleteNode(project.topNode);
-            project.Free();
-         }
-         project = value;
-         if(project)
-         {
-            AddNode(project.topNode, null);
-            fileDialog.currentDirectory = project.topNode.path;
-            resourceFileDialog.currentDirectory = project.topNode.path;
-
-            // Make sure this is done already...
-            {
-               char filePath[MAX_LOCATION];
-               strcpy(filePath, project.topNode.path);
-               PathCat(filePath, project.topNode.name);
-               strcat(filePath, ".epj");
-               fileName = filePath;
-            }
-
-            ide.statusBar.text = "Generating Makefile & Dependencies...";
-            app.UpdateDisplay();
-            // REDJ set makefile generation flag so generation occurs only when compiling instead of generating on the spot
-            project.config.makingModified = true;
-            ide.statusBar.text = "Initializing Debugger";
-            ide.statusBar.text = null;
-            app.UpdateDisplay();
-         }
-      }
-      get { return project; }
-   }*/
-
    bool drawingInProjectSettingsDialog;
    bool drawingInProjectSettingsDialogHeader;
    ProjectSettings projectSettingsDialog;
 
    bool stopBuild;
 
+   ProjectView()
+   {
+      NodeIcons c;
+      for(c = 0; c < NodeIcons::enumSize; c++)
+      {
+         icons[c] = BitmapResource { iconNames[c], alphaBlend = true };
+         AddResource(icons[c]);
+      }
+      fileList.AddField(DataField { dataType = class(ProjectNode), freeData = false, userData = this });
+   }
+
+   ~ProjectView()
+   {
+      DebugStop();
+      ide.DestroyTemporaryProjectDir();
+      if(project)
+      {
+         workspace.Free();
+         delete workspace;
+      }
+   }
+
    ListBox fileList
    {
       multiSelect = true, fullRowSelect = false, hasVertScroll = true, hasHorzScroll = true;
@@ -510,19 +495,6 @@ class ProjectView : Window
 
    bool GetRelativePath(char * filePath, char * relativePath)
    {
-      /*ProjectNode node;
-      char moduleName[MAX_FILENAME]; //, modulePath[MAX_LOCATION];
-      GetLastDirectory(filePath, moduleName);
-      
-      // try with workspace dir first?
-      if((node = project.topNode.Find(moduleName, false)))
-      {
-         strcpy(relativePath, node.path);
-         PathCatSlash(relativePath, node.name);
-         return true;
-      }
-      // WARNING: On failure, relative path is uninitialized
-      return false;   */
       return project.GetRelativePath(filePath, relativePath);
    }
 
@@ -555,416 +527,218 @@ class ProjectView : Window
       return null;
    }
 
-   void Compile(ProjectNode node)
+   //                          ((( UTILITY FUNCTIONS )))
+   //
+   //  ************************************************************************
+   //  *** These methods below are part of a sequence of events, and as     ***
+   //  *** such they must be passed the current compiler and project config ***
+   //  ************************************************************************
+   bool DisplayCompiler(CompilerConfig compiler, bool cleanLog)
    {
-      char fileName[MAX_LOCATION];
-      char extension[MAX_EXTENSION];
-      Window document;
-      Project prj = node.project;
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
-      DirExpression objDir = prj.objDir;
+      ShowOutputBuildLog(cleanLog);
+      ide.outputView.buildBox.Logf($"%s Compiler\n", compiler ? compiler.name : $"{problem with compiler selection}");
+   }
 
-      strcpy(fileName, prj.topNode.path);
-      PathCatSlash(fileName, objDir.dir);
-      PathCatSlash(fileName, node.name);
-      StripExtension(fileName);
-      strcat(fileName, ".o");
-      if(FileExists(fileName))
-         DeleteFile(fileName);
+   bool ProjectPrepareForToolchain(Project project, PrepareMakefileMethod method, bool cleanLog, bool displayCompiler,
+      CompilerConfig compiler, ProjectConfig config)
+   {
+      bool isReady = true;
+      char message[MAX_F_STRING];
+      LogBox logBox = ide.outputView.buildBox;
 
-      GetExtension(node.name, extension);
-      if(!strcmp(extension, "ec"))
-      {
-         // Delete generated C file
-         strcpy(fileName, prj.topNode.path);
-         PathCat(fileName, objDir.dir);
-         PathCat(fileName, node.name);
-         StripExtension(fileName);
-         strcat(fileName, ".c");
-         if(FileExists(fileName))
-            DeleteFile(fileName);
+      ShowOutputBuildLog(cleanLog);
 
-         // Delete symbol file
-         strcpy(fileName, prj.topNode.path);
-         PathCat(fileName, node.path);
-         PathCat(fileName, node.name);
-         StripExtension(fileName);
-         strcat(fileName, ".sym");
-         if(FileExists(fileName))
-            DeleteFile(fileName);
-      }
+      if(displayCompiler)
+         DisplayCompiler(compiler, false);
 
-      stopBuild = false;
+      ProjectPrepareMakefile(project, method, false, false, compiler, config);
+      return true;
+   }
 
-      // Check if we have to save
-      strcpy(fileName, prj.topNode.path);
-      PathCatSlash(fileName, node.path);
-      PathCatSlash(fileName, node.name);
-      for(document = ide.firstChild; document; document = document.next)
-      {
-         if(document.modifiedDocument)
-         {
-            char documentFileName[MAX_LOCATION];
-            if(!fstrcmp(GetSlashPathBuffer(documentFileName, document.fileName), fileName))
-               if(!document.MenuFileSave(null, 0))
-                  return;
-         }
-      }
+   bool ProjectPrepareMakefile(Project project, PrepareMakefileMethod method, bool cleanLog, bool displayCompiler,
+      CompilerConfig compiler, ProjectConfig config)
+   {
+      char makefilePath[MAX_LOCATION];
+      char makefileName[MAX_LOCATION];
+      bool exists;
+      LogBox logBox = ide.outputView.buildBox;
+      
+      ShowOutputBuildLog(cleanLog);
 
-      if(ProjectPrepareForToolchain(prj, normal, true, true))
-      {
-         if(!node.isExcluded)
-         {
-            buildInProgress = compilingFile;
-            ide.AdjustBuildMenus();
+      if(displayCompiler)
+         DisplayCompiler(compiler, false);
 
-            //ide.outputView.ShowClearSelectTab(build);
-            // this stuff doesn't even appear
-            //ide.outputView.buildBox.Logf("%s Compiler\n", compiler.name);
-            if(prj.config)
-               ide.outputView.buildBox.Logf($"Compiling single file %s in project %s using the %s configuration...\n", node.name, prj.name, prj.config.name);
-            else
-               ide.outputView.buildBox.Logf($"Compiling single file %s in project %s...\n", node.name, prj.name);
+      strcpy(makefilePath, project.topNode.path);
+      project.CatMakeFileName(makefileName, compiler, config);
+      PathCatSlash(makefilePath, makefileName);
 
-            prj.Compile(node);
-            buildInProgress = none;
-            ide.AdjustBuildMenus();
-         }
+      exists = FileExists(makefilePath);
+      if((method == normal && (!exists || config.makingModified/*|| project.topNode.modified*/)) ||
+            (method == forceExists && exists) || 
+            method == force) // || config.makingModified || makefileDirty
+      {
+         char * reason;
+         char * action;
+         ide.statusBar.text = $"Generating Makefile & Dependencies..."; // Dependencies?
+         app.UpdateDisplay();
+         
+         if((method == normal && !exists) || (method == force && !exists))
+            action = $"Generating ";
+         else if(method == force)
+            action = $"Regenerating ";
+         else if(method == normal || method == forceExists)
+            action = $"Updating ";
          else
-            ide.outputView.buildBox.Logf($"File %s is excluded from current build configuration.\n", node.name);
+            action = "";
+         if(!exists)
+            reason = $"Makefile doesn't exist. ";
+         else if(project.topNode.modified)
+            reason = $"Project has been modified. ";
+         else
+            reason = "";
+
+         //logBox.Logf("%s\n", makefileName);
+         logBox.Logf($"%s - %s%smakefile for %s config...\n", makefileName, reason, action, project.configName);
+         project.GenerateMakefile(null, false, null, compiler, config);
+
+         ide.statusBar.text = null;
+         app.UpdateDisplay();
+         return true;
       }
-      delete objDir;
-      delete compiler;
+      return false;
+   }
+   
+   bool BuildInterrim(Project prj, BuildType buildType, CompilerConfig compiler, ProjectConfig config)
+   {
+      if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
+      {
+         ide.outputView.buildBox.Logf($"Building project %s using the %s configuration...\n", prj.name, prj.configName);
+         return Build(prj, buildType, compiler, config);
+      }
+      return false;
    }
 
-   void GoToError(const char * line)
+   bool Build(Project prj, BuildType buildType, CompilerConfig compiler, ProjectConfig config)
    {
-      char * colon;
-      
-      while(isspace(*line)) line++;
-      colon = strstr(line, ":");
+      bool result = true;
+      Window document;
 
+      stopBuild = false;
+      for(document = master.firstChild; document; document = document.next)
       {
-         int lineNumber = 0;
-         int col = 1;
-         bool lookForLineNumber = true;
-
-         // deal with linking error
-         if(colon && colon[1] == ' ')
+         if(document.modifiedDocument)
          {
-            colon = strstr(colon + 1, ":");
-            if(colon && !colon[1])
-            {
-               colon = strstr(line, ":");
-               lookForLineNumber = false;
-            }
-            else if(colon && !isdigit(colon[1]))
+            ProjectNode node = GetNodeFromWindow(document, prj);
+            if(node && !document.MenuFileSave(null, 0))
             {
-               line = colon + 1;
-               colon = strstr(line, ":");
+               result = false;
+               break;
             }
          }
-         // Don't be mistaken by the drive letter colon
-         if(colon && (colon[1] == '/' || colon[1] == '\\'))
-            colon = strstr(colon + 1, ":");
-         if(colon && lookForLineNumber)
+      }
+      if(result)
+      {
+         DirExpression targetDir = prj.GetTargetDir(compiler, config);
+
+         // TOFIX: DebugStop is being abused and backfiring on us.
+         //        It's supposed to be the 'Debug/Stop' item, not unloading executable or anything else
+
+         //        configIsInDebugSession seems to be used for two OPPOSITE things:
+         //        If we're debugging another config, we need to unload the executable!
+         //        In building, we want to stop if we're debugging the 'same' executable
+         if(buildType != run) ///* && prj == project*/ && prj.configIsInDebugSession)
          {
-            char * comma;
-            // MSVS Errors
-            char * par = RSearchString(line, "(", colon - line, true, false);
-            if(par && strstr(par, ")"))
-               colon = par;
-            else if((colon+1)[0] == ' ')
+            if(buildType == start || buildType == restart)
             {
-               // NOTE: This is the same thing as saying 'colon = line'
-               for( ; colon != line; colon--)
-                  /*if(*colon == '(')
-                     break*/;
+               if(ide.debugger && ide.debugger.isPrepared)
+               {
+                  DebugStop();
+               }
+            }
+            else
+            {
+               if(ide.project == prj && ide.debugger && ide.debugger.prjConfig == config && ide.debugger.isPrepared)
+               {
+                  DebugStop();
+               }
             }
-            lineNumber = atoi(colon + 1);
-            /*
-            comma = strchr(colon, ',');
-            if(comma)
-               col = atoi(comma+1);
-            */
-            comma = strchr(colon+1, ':');
-            if(comma)
-               col = atoi(comma+1);
          }
          
+         // TODO: Disabled until problems fixed... is it fixed?
+         if(buildType == rebuild || (config && config.compilingModified))
+            prj.Clean(compiler, config);
+         else
          {
-            char moduleName[MAX_LOCATION], filePath[MAX_LOCATION];
-            char * bracket;
-            if(colon)
+            if(buildType == relink || (config && config.linkingModified))
             {
-               // Cut module name
-               strncpy(moduleName, line, colon - line);
-               moduleName[colon - line] = '\0';
-            }
-            else
-               strcpy(moduleName, line);
+               char target[MAX_LOCATION];
 
-            // Remove stuff in brackets
-            /*
-            bracket = strstr(moduleName, "(");
-            if(bracket) *bracket = '\0';
-            */
-            MakeSlashPath(moduleName);
-
-            if(!colon)
-            {
-               // Check if it's one of our modules
-               ProjectNode node = project.topNode.Find(moduleName, false);
-               if(node)
-               {
-                  strcpy(moduleName, node.path);
-                  PathCatSlash(moduleName, node.name);
-               }
-               else
-                  moduleName[0] = '\0';
+               strcpy(target, prj.topNode.path);
+               PathCat(target, targetDir.dir);
+               prj.CatTargetFileName(target, compiler, config);
+               if(FileExists(target))
+                  DeleteFile(target);
             }
-            if(moduleName[0])
+            if(config && config.symbolGenModified)
             {
-               CodeEditor codeEditor;
-               strcpy(filePath, project.topNode.path);
-               PathCatSlash(filePath, moduleName);
-      
-               codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, true, null, no, normal);
-               if(!codeEditor)
-               {
-                  char name[MAX_LOCATION];
-                  // TOFIX: Improve on this, don't use only filename, make a function
-                  if(ide && ide.workspace)
-                  {
-                     for(prj : ide.workspace.projects)
-                     {
-                        if(prj.topNode.FindWithPath(moduleName, false))
-                        {
-                           strcpy(filePath, prj.topNode.path);
-                           PathCatSlash(filePath, moduleName);
-                           codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, true, null, no, normal);
-                           if(codeEditor)
-                              break;
-                        }
-                     }
-                  }
-               }
-               if(codeEditor && lineNumber)
-               {
-                  EditBox editBox = codeEditor.editBox;
-                  editBox.GoToLineNum(lineNumber - 1);
-                  editBox.GoToPosition(editBox.line, lineNumber - 1, col ? (col - 1) : 0);
-               }
+               DirExpression objDir = prj.GetObjDir(compiler, config);
+               char fileName[MAX_LOCATION];
+               char moduleName[MAX_FILENAME];
+               strcpy(fileName, prj.topNode.path);
+               PathCatSlash(fileName, objDir.dir);
+               strcpy(moduleName, prj.moduleName);
+               strcat(moduleName, ".main.ec");
+               PathCatSlash(fileName, moduleName);
+               if(FileExists(fileName))
+                  DeleteFile(fileName);
+               ChangeExtension(fileName, "c", fileName);
+               if(FileExists(fileName))
+                  DeleteFile(fileName);
+               ChangeExtension(fileName, "o", fileName);
+               if(FileExists(fileName))
+                  DeleteFile(fileName);
+
+               delete objDir;
             }
          }
-      }
-   }
-
-   bool OpenNode(ProjectNode node)
-   {
-      char filePath[MAX_LOCATION];
-      node.GetFullFilePath(filePath);
-      return ide.OpenFile(filePath, normal, true/*false Why was it opening hidden?*/, null, something, normal) ? true : false;
-   }
-
-   void AddNode(ProjectNode node, DataRow addTo)
-   {
-      DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
-
-      row.tag = (int)node;
-      node.row = row;
-
-      if(node.type == resources)
-         resourceRow = row;
-
-      row.SetData(null, node);
-
-      if(node.files && node.files.first && node.parent && 
-            !(!node.parent.parent && 
-               (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") || 
-                  !strcmpi(node.name, "src") || !strcmpi(node.name, "tools"))))
-         row.collapsed = true;
-      else if(node.type == folder)
-         node.icon = openFolder;
-
-      if(node.files)
-      {
-         for(child : node.files)
-            AddNode(child, row);
-      }
-   }
-
-   void DeleteNode(ProjectNode projectNode)
-   {
-      if(projectNode.files)
-      {
-         ProjectNode child;
-         while(child = projectNode.files.first)
-            DeleteNode(child);
-      }
-      fileList.DeleteRow(projectNode.row);
-      projectNode.Delete();
-   }
-
-   ProjectView()
-   {
-      NodeIcons c;
-      for(c = 0; c < NodeIcons::enumSize; c++)
-      {
-         icons[c] = BitmapResource { iconNames[c], alphaBlend = true };
-         AddResource(icons[c]);
-      }
-      fileList.AddField(DataField { dataType = class(ProjectNode), freeData = false, userData = this });
-   }
+         buildInProgress = prj == project ? buildingMainProject : buildingSecondaryProject;
+         ide.AdjustBuildMenus();
+         ide.AdjustDebugMenus();
 
-   ~ProjectView()
-   {
-      DebugStop();
-      ide.DestroyTemporaryProjectDir();
-      if(project)
-      {
-         workspace.Free();
-         delete workspace;
-      }
-   }
+         result = prj.Build(buildType == run, null, compiler, config);
 
-   bool ProjectSave(MenuItem selection, Modifiers mods)
-   {
-      DataRow row = fileList.currentRow;
-      ProjectNode node = row ? (ProjectNode)row.tag : null;
-      Project prj = node ? node.project : null;
-      if(prj)
-      {
-         if(prj.Save(prj.filePath))
+         if(config)
          {
-            // ProjectUpdateMakefileForAllConfigs(prj, true, true);
-            prj.topNode.modified = false;
-            prj = null;
-            for(p : ide.workspace.projects)
-            {
-               if(p.topNode.modified)
-               { 
-                  prj = p;
-                  break;
-               }
-            }
-            if(!prj)
-               modifiedDocument = false;
-            Update(null);
-         }
-      }
-      return true;
-   }
-
-   bool ShowOutputBuildLog(bool cleanLog)
-   {
-      OutputView output = ide.outputView;
-      if(cleanLog)
-         output.ShowClearSelectTab(build);
-      else
-      {
-         output.SelectTab(build);
-         output.Show();
-      }
-   }
+            config.compilingModified = false;
+            if(!ide.ShouldStopBuild())
+               config.linkingModified = false;
 
-   bool DisplayCompiler(bool cleanLog)
-   {
-      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
-      ShowOutputBuildLog(cleanLog);
-      ide.outputView.buildBox.Logf($"%s Compiler\n", compiler ? compiler.name : $"{problem with compiler selection}");
-      delete compiler;
-   }
+            config.symbolGenModified = false;
+         }
+         buildInProgress = none;
+         ide.AdjustBuildMenus();
+         ide.AdjustDebugMenus();
 
-   bool ProjectUpdateMakefileForAllConfigs(Project project, bool cleanLog, bool displayCompiler)
-   {
-      ProjectConfig currentConfig = project.config;
-      ShowOutputBuildLog(cleanLog);
+         ide.workspace.modified = true;
 
-      if(displayCompiler)
-         DisplayCompiler(false);
-      
-      for(config : project.configurations)
-      {
-         project.config = config;
-         ProjectPrepareMakefile(project, forceExists, false, false);
+         delete targetDir;
       }
-
-      project.config = currentConfig;
-
-      ide.Update(null);
-   }
-
-   bool ProjectPrepareForToolchain(Project project, PrepareMakefileMethod method, bool cleanLog, bool displayCompiler)
-   {
-      bool isReady = true;
-      char message[MAX_F_STRING];
-      LogBox logBox = ide.outputView.buildBox;
-
-      ShowOutputBuildLog(cleanLog);
-
-      if(displayCompiler)
-         DisplayCompiler(false);
-
-      ProjectPrepareMakefile(project, method, false, false);
-      return true;
+      return result;
    }
 
-   bool ProjectPrepareMakefile(Project project, PrepareMakefileMethod method, bool cleanLog, bool displayCompiler)
-   {
-      char makefilePath[MAX_LOCATION];
-      char makefileName[MAX_LOCATION];
-      bool exists;
-      LogBox logBox = ide.outputView.buildBox;
-      
-      ShowOutputBuildLog(cleanLog);
+   //                          ((( USER ACTIONS )))
+   //
+   //  ************************************************************************
+   //  *** Methods below should atomically start a process, and as such     ***
+   //  *** they can query compiler and config directly from ide and project ***
+   //  *** but ONLY ONCE!!!                                                 ***
+   //  ************************************************************************
 
-      if(displayCompiler)
-         DisplayCompiler(false);
-
-      strcpy(makefilePath, project.topNode.path);
-      project.CatMakeFileName(makefileName);
-      PathCatSlash(makefilePath, makefileName);
-
-      exists = FileExists(makefilePath);
-      if((method == normal && (!exists || project.config.makingModified/*|| project.topNode.modified*/)) ||
-            (method == forceExists && exists) || 
-            method == force) // || project.config.makingModified || makefileDirty
-      {
-         char * reason;
-         char * action;
-         ide.statusBar.text = $"Generating Makefile & Dependencies..."; // Dependencies?
-         app.UpdateDisplay();
-         
-         if((method == normal && !exists) || (method == force && !exists))
-            action = $"Generating ";
-         else if(method == force)
-            action = $"Regenerating ";
-         else if(method == normal || method == forceExists)
-            action = $"Updating ";
-         else
-            action = "";
-         if(!exists)
-            reason = $"Makefile doesn't exist. ";
-         else if(project.topNode.modified)
-            reason = $"Project has been modified. ";
-         else
-            reason = "";
-
-         //logBox.Logf("%s\n", makefileName);
-         logBox.Logf($"%s - %s%smakefile for %s config...\n", makefileName, reason, action, project.configName);
-         project.GenerateMakefile(null, false, null);
-
-         ide.statusBar.text = null;
-         app.UpdateDisplay();
-         return true;
-      }
-      return false;
-   }
-   
    bool ProjectBuild(MenuItem selection, Modifiers mods)
    {
       Project prj = project;
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config = prj.config;
       if(selection || !ide.activeClient || activeClient == this)
       {
          DataRow row = fileList.currentRow;
@@ -978,24 +752,19 @@ class ProjectView : Window
          if(node)
             prj = node.project;
       }
-      if(/*prj != project || */!prj.configIsInDebugSession || !ide.DontTerminateDebugSession($"Project Build"))
-         BuildInterrim(prj, build);
-      return true;
-   }
-
-   bool BuildInterrim(Project prj, BuildType buildType)
-   {
-      if(ProjectPrepareForToolchain(prj, normal, true, true))
+      if(/*prj != project || */!prj.GetConfigIsInDebugSession(config) || !ide.DontTerminateDebugSession($"Project Build"))
       {
-         ide.outputView.buildBox.Logf($"Building project %s using the %s configuration...\n", prj.name, prj.configName);
-         return Build(prj, buildType);
+         BuildInterrim(prj, build, compiler, config);
       }
-      return false;
+      delete compiler;
+      return true;
    }
 
    bool ProjectLink(MenuItem selection, Modifiers mods)
    {
       Project prj = project;
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config;
       if(selection || !ide.activeClient || activeClient == this)
       {
          DataRow row = fileList.currentRow;
@@ -1009,52 +778,61 @@ class ProjectView : Window
          if(node)
             prj = node.project;
       }
-      if(ProjectPrepareForToolchain(prj, normal, true, true))
+      config = prj.config;
+      if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
       {
          ide.outputView.buildBox.Logf("Relinking project %s using the %s configuration...\n", prj.name, prj.configName);
-         if(prj.config)
-            prj.config.linkingModified = true;
-         Build(prj, relink);
+         if(config)
+            config.linkingModified = true;
+         Build(prj, relink, compiler, config);
       }
+      delete compiler;
       return true;
    }
 
    bool ProjectRebuild(MenuItem selection, Modifiers mods)
    {
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
       Project prj = GetSelectedProject((bool)selection);
-      if(ProjectPrepareForToolchain(prj, normal, true, true))
+      ProjectConfig config = prj.config;
+      if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
       {
          ide.outputView.buildBox.Logf($"Rebuilding project %s using the %s configuration...\n", prj.name, prj.configName);
-         /*if(prj.config)
+         /*if(config)
          {
-            prj.config.compilingModified = true;
-            prj.config.makingModified = true;
+            config.compilingModified = true;
+            config.makingModified = true;
          }*/ // -- should this still be used depite the new solution of BuildType?
-         Build(prj, rebuild);
+         Build(prj, rebuild, compiler, config);
       }
+      delete compiler;
       return true;
    }
 
    bool ProjectClean(MenuItem selection, Modifiers mods)
    {
       Project prj = GetSelectedProject((bool)selection);
-      if(ProjectPrepareForToolchain(prj, normal, true, true))
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config = prj.config;
+      if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
       {
          ide.outputView.buildBox.Logf($"Cleaning project %s using the %s configuration...\n", prj.name, prj.configName);
          
          buildInProgress = prj == project ? buildingMainProject : buildingSecondaryProject;
          ide.AdjustBuildMenus();
 
-         prj.Clean();
+         prj.Clean(compiler, config);
          buildInProgress = none;
          ide.AdjustBuildMenus();
       }
+      delete compiler;
       return true;
    }
 
    bool ProjectRegenerate(MenuItem selection, Modifiers mods)
    {
       Project prj = project;
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
       if(selection || !ide.activeClient || activeClient == this)
       {
          DataRow row = fileList.currentRow;
@@ -1070,10 +848,94 @@ class ProjectView : Window
             prj = node.project;
       }
 
-      ProjectPrepareMakefile(prj, force, true, true);
+      ProjectPrepareMakefile(prj, force, true, true, compiler, prj.config);
+      delete compiler;
       return true;
    }
 
+   void Compile(ProjectNode node)
+   {
+      char fileName[MAX_LOCATION];
+      char extension[MAX_EXTENSION];
+      Window document;
+      Project prj = node.project;
+      ProjectConfig config = prj.config;
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      DirExpression objDir = prj.GetObjDir(compiler, config);
+
+      strcpy(fileName, prj.topNode.path);
+      PathCatSlash(fileName, objDir.dir);
+      PathCatSlash(fileName, node.name);
+      StripExtension(fileName);
+      strcat(fileName, ".o");
+      if(FileExists(fileName))
+         DeleteFile(fileName);
+
+      GetExtension(node.name, extension);
+      if(!strcmp(extension, "ec"))
+      {
+         // Delete generated C file
+         strcpy(fileName, prj.topNode.path);
+         PathCat(fileName, objDir.dir);
+         PathCat(fileName, node.name);
+         StripExtension(fileName);
+         strcat(fileName, ".c");
+         if(FileExists(fileName))
+            DeleteFile(fileName);
+
+         // Delete symbol file
+         strcpy(fileName, prj.topNode.path);
+         PathCat(fileName, node.path);
+         PathCat(fileName, node.name);
+         StripExtension(fileName);
+         strcat(fileName, ".sym");
+         if(FileExists(fileName))
+            DeleteFile(fileName);
+      }
+
+      stopBuild = false;
+
+      // Check if we have to save
+      strcpy(fileName, prj.topNode.path);
+      PathCatSlash(fileName, node.path);
+      PathCatSlash(fileName, node.name);
+      for(document = ide.firstChild; document; document = document.next)
+      {
+         if(document.modifiedDocument)
+         {
+            char documentFileName[MAX_LOCATION];
+            if(!fstrcmp(GetSlashPathBuffer(documentFileName, document.fileName), fileName))
+               if(!document.MenuFileSave(null, 0))
+                  return;
+         }
+      }
+
+      if(ProjectPrepareForToolchain(prj, normal, true, true, compiler, config))
+      {
+         if(!node.GetIsExcluded(config))
+         {
+            buildInProgress = compilingFile;
+            ide.AdjustBuildMenus();
+
+            //ide.outputView.ShowClearSelectTab(build);
+            // this stuff doesn't even appear
+            //ide.outputView.buildBox.Logf("%s Compiler\n", compiler.name);
+            if(config)
+               ide.outputView.buildBox.Logf($"Compiling single file %s in project %s using the %s configuration...\n", node.name, prj.name, config.name);
+            else
+               ide.outputView.buildBox.Logf($"Compiling single file %s in project %s...\n", node.name, prj.name);
+
+            prj.Compile(node, compiler, config);
+            buildInProgress = none;
+            ide.AdjustBuildMenus();
+         }
+         else
+            ide.outputView.buildBox.Logf($"File %s is excluded from current build configuration.\n", node.name);
+      }
+      delete objDir;
+      delete compiler;
+   }
+
    bool ProjectNewFile(MenuItem selection, Modifiers mods)
    {
       DataRow row = fileList.currentRow;
@@ -1165,6 +1027,24 @@ class ProjectView : Window
       return true;
    }
 
+   bool ProjectUpdateMakefileForAllConfigs(Project project, bool cleanLog, bool displayCompiler)
+   {
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ShowOutputBuildLog(cleanLog);
+
+      if(displayCompiler)
+         DisplayCompiler(compiler, false);
+      
+      for(config : project.configurations)
+      {
+         ProjectPrepareMakefile(project, forceExists, false, false,
+            compiler, config);
+      }
+
+      ide.Update(null);
+      delete compiler;
+   }
+
    bool MenuConfig(MenuItem selection, Modifiers mods)
    {
       if(ProjectActiveConfig { parent = parent.parent, master = parent, project = project }.Modal() == ok)
@@ -1211,152 +1091,30 @@ class ProjectView : Window
          NodeProperties { parent = parent, master = this, node = node, 
                position = { position.x + 100, position.y + 100 } }.Create();
       }
-      return true;
-   }
-
-   bool FileOpenFile(MenuItem selection, Modifiers mods)
-   {
-      OpenSelectedNodes();
-      return true;
-   }
-
-   bool FileRemoveFile(MenuItem selection, Modifiers mods)
-   {
-      RemoveSelectedNodes();
-      return true;
-   }
-
-   bool FileCompile(MenuItem selection, Modifiers mods)
-   {
-      DataRow row = fileList.currentRow;
-      if(row)
-      {
-         ProjectNode node = (ProjectNode)row.tag;
-         Compile(node);
-      }
-      return true;
-   }
-
-   /*bool IsProjectModified()
-   {
-      Window document;
-
-      for(document = master.firstChild; document; document = document.next)
-      {
-         if(document.modifiedDocument)
-            if(GetNodeFromWindow(document), project)
-               return true;
-      }
-      return false;
-   }
-   */
-
-   bool Build(Project prj, BuildType buildType)
-   {
-      bool result = true;
-      Window document;
-
-      stopBuild = false;
-      for(document = master.firstChild; document; document = document.next)
-      {
-         if(document.modifiedDocument)
-         {
-            ProjectNode node = GetNodeFromWindow(document, prj);
-            if(node && !document.MenuFileSave(null, 0))
-            {
-               result = false;
-               break;
-            }
-         }
-      }
-      if(result)
-      {
-         DirExpression targetDir = prj.targetDir;
-
-         // TOFIX: DebugStop is being abused and backfiring on us.
-         //        It's supposed to be the 'Debug/Stop' item, not unloading executable or anything else
-
-         //        configIsInDebugSession seems to be used for two OPPOSITE things:
-         //        If we're debugging another config, we need to unload the executable!
-         //        In building, we want to stop if we're debugging the 'same' executable
-         if(buildType != run) ///* && prj == project*/ && prj.configIsInDebugSession)
-         {
-            if(buildType == start || buildType == restart)
-            {
-               if(ide.debugger && ide.debugger.isPrepared)
-               {
-                  DebugStop();
-               }
-            }
-            else
-            {
-               if(ide.project == prj && ide.debugger && ide.debugger.prjConfig == prj.config && ide.debugger.isPrepared)
-               {
-                  DebugStop();
-               }
-            }
-         }
-         
-         // TODO: Disabled until problems fixed... is it fixed?
-         if(buildType == rebuild || (prj.config && prj.config.compilingModified))
-            prj.Clean();
-         else
-         {
-            if(buildType == relink || (prj.config && prj.config.linkingModified))
-            {
-               char target[MAX_LOCATION];
-
-               strcpy(target, prj.topNode.path);
-               PathCat(target, targetDir.dir);
-               prj.CatTargetFileName(target);
-               if(FileExists(target))
-                  DeleteFile(target);
-            }
-            if(prj.config && prj.config.symbolGenModified)
-            {
-               DirExpression objDir = prj.objDir;
-               char fileName[MAX_LOCATION];
-               char moduleName[MAX_FILENAME];
-               strcpy(fileName, prj.topNode.path);
-               PathCatSlash(fileName, objDir.dir);
-               strcpy(moduleName, prj.moduleName);
-               strcat(moduleName, ".main.ec");
-               PathCatSlash(fileName, moduleName);
-               if(FileExists(fileName))
-                  DeleteFile(fileName);
-               ChangeExtension(fileName, "c", fileName);
-               if(FileExists(fileName))
-                  DeleteFile(fileName);
-               ChangeExtension(fileName, "o", fileName);
-               if(FileExists(fileName))
-                  DeleteFile(fileName);
-
-               delete objDir;
-            }
-         }
-         buildInProgress = prj == project ? buildingMainProject : buildingSecondaryProject;
-         ide.AdjustBuildMenus();
-         ide.AdjustDebugMenus();
-
-         result = prj.Build(buildType == run, null);
-
-         if(prj.config)
-         {
-            prj.config.compilingModified = false;
-            if(!ide.ShouldStopBuild())
-               prj.config.linkingModified = false;
+      return true;
+   }
 
-            prj.config.symbolGenModified = false;
-         }
-         buildInProgress = none;
-         ide.AdjustBuildMenus();
-         ide.AdjustDebugMenus();
+   bool FileOpenFile(MenuItem selection, Modifiers mods)
+   {
+      OpenSelectedNodes();
+      return true;
+   }
 
-         ide.workspace.modified = true;
+   bool FileRemoveFile(MenuItem selection, Modifiers mods)
+   {
+      RemoveSelectedNodes();
+      return true;
+   }
 
-         delete targetDir;
+   bool FileCompile(MenuItem selection, Modifiers mods)
+   {
+      DataRow row = fileList.currentRow;
+      if(row)
+      {
+         ProjectNode node = (ProjectNode)row.tag;
+         Compile(node);
       }
-      return result;
+      return true;
    }
 
    Project GetSelectedProject(bool useSelection)
@@ -1401,34 +1159,39 @@ class ProjectView : Window
 
    bool Run(MenuItem selection, Modifiers mods)
    {
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config = project.config;
       String args = new char[maxPathLen];
       args[0] = '\0';
       if(ide.workspace.commandLineArgs)
          //ide.debugger.GetCommandLineArgs(args);
          strcpy(args, ide.workspace.commandLineArgs);
       if(ide.debugger.isActive)
-         project.Run(args);
-      /*else if(project.config.targetType == sharedLibrary || project.config.targetType == staticLibrary)
+         project.Run(args, compiler, config);
+      /*else if(config.targetType == sharedLibrary || config.targetType == staticLibrary)
          MessageBox { master = ide, type = ok, text = "Run", contents = "Shared and static libraries cannot be run like executables." }.Modal();*/
-      else if(BuildInterrim(project, run))
-         project.Run(args);
+      else if(BuildInterrim(project, run, compiler, config))
+         project.Run(args, compiler, config);
       delete args;
+      delete compiler;
       return true;
    }
 
    bool DebugStart()
    {
       bool result = false;
-      if(project.targetType == sharedLibrary || project.targetType == staticLibrary)
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config = project.config;
+      TargetTypes targetType = project.GetTargetType(config);
+      if(targetType == sharedLibrary || targetType == staticLibrary)
          MessageBox { master = ide, type = ok, text = $"Run", contents = $"Shared and static libraries cannot be run like executables." }.Modal();
-      else if(project.compress)
+      else if(project.GetCompress(config))
          MessageBox { master = ide, text = $"Starting Debug", contents = $"Debugging compressed applications is not supported\n" }.Modal();
-      else if(project.debug ||
+      else if(project.GetDebug(config) ||
          MessageBox { master = ide, type = okCancel, text = $"Starting Debug", contents = $"Attempting to debug non-debug configuration\nProceed anyways?" }.Modal() == ok)
       {
-         if(/*!IsProjectModified() ||*/ BuildInterrim(project, start))
+         if(/*!IsProjectModified() ||*/ BuildInterrim(project, start, compiler, config))
          {
-            CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
             if(compiler.type.isVC)
             {
                //bool result = false;
@@ -1436,12 +1199,12 @@ class ProjectView : Window
                PathBackup pathBackup { };
                char command[MAX_LOCATION];
 
-               ide.SetPath(false); //true
+               ide.SetPath(false, compiler, config);
                
                GetWorkingDir(oldwd, sizeof(oldwd));
                ChangeWorkingDir(project.topNode.path);
 
-               sprintf(command, "%s /useenv %s.sln /projectconfig \"%s|Win32\" /command \"%s\"" , "devenv", project.name, project.config.name, "Debug.Start");
+               sprintf(command, "%s /useenv %s.sln /projectconfig \"%s|Win32\" /command \"%s\"" , "devenv", project.name, config.name, "Debug.Start");
                //ide.outputView.buildBox.Logf("command: %s\n", command);
                Execute(command);
                ChangeWorkingDir(oldwd);
@@ -1450,24 +1213,241 @@ class ProjectView : Window
             }
             else
             {
-               ide.debugger.Start();
+               ide.debugger.Start(compiler, config);
                result = true;
             }
-
-            delete compiler;
          }
       }
+      delete compiler;
       return result;      
    }
 
+   void GoToError(const char * line)
+   {
+      char * colon;
+      
+      while(isspace(*line)) line++;
+      colon = strstr(line, ":");
+
+      {
+         int lineNumber = 0;
+         int col = 1;
+         bool lookForLineNumber = true;
+
+         // deal with linking error
+         if(colon && colon[1] == ' ')
+         {
+            colon = strstr(colon + 1, ":");
+            if(colon && !colon[1])
+            {
+               colon = strstr(line, ":");
+               lookForLineNumber = false;
+            }
+            else if(colon && !isdigit(colon[1]))
+            {
+               line = colon + 1;
+               colon = strstr(line, ":");
+            }
+         }
+         // Don't be mistaken by the drive letter colon
+         if(colon && (colon[1] == '/' || colon[1] == '\\'))
+            colon = strstr(colon + 1, ":");
+         if(colon && lookForLineNumber)
+         {
+            char * comma;
+            // MSVS Errors
+            char * par = RSearchString(line, "(", colon - line, true, false);
+            if(par && strstr(par, ")"))
+               colon = par;
+            else if((colon+1)[0] == ' ')
+            {
+               // NOTE: This is the same thing as saying 'colon = line'
+               for( ; colon != line; colon--)
+                  /*if(*colon == '(')
+                     break*/;
+            }
+            lineNumber = atoi(colon + 1);
+            /*
+            comma = strchr(colon, ',');
+            if(comma)
+               col = atoi(comma+1);
+            */
+            comma = strchr(colon+1, ':');
+            if(comma)
+               col = atoi(comma+1);
+         }
+         
+         {
+            char moduleName[MAX_LOCATION], filePath[MAX_LOCATION];
+            char * bracket;
+            if(colon)
+            {
+               // Cut module name
+               strncpy(moduleName, line, colon - line);
+               moduleName[colon - line] = '\0';
+            }
+            else
+               strcpy(moduleName, line);
+
+            // Remove stuff in brackets
+            /*
+            bracket = strstr(moduleName, "(");
+            if(bracket) *bracket = '\0';
+            */
+            MakeSlashPath(moduleName);
+
+            if(!colon)
+            {
+               // Check if it's one of our modules
+               ProjectNode node = project.topNode.Find(moduleName, false);
+               if(node)
+               {
+                  strcpy(moduleName, node.path);
+                  PathCatSlash(moduleName, node.name);
+               }
+               else
+                  moduleName[0] = '\0';
+            }
+            if(moduleName[0])
+            {
+               CodeEditor codeEditor;
+               strcpy(filePath, project.topNode.path);
+               PathCatSlash(filePath, moduleName);
+      
+               codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, true, null, no, normal);
+               if(!codeEditor)
+               {
+                  char name[MAX_LOCATION];
+                  // TOFIX: Improve on this, don't use only filename, make a function
+                  if(ide && ide.workspace)
+                  {
+                     for(prj : ide.workspace.projects)
+                     {
+                        if(prj.topNode.FindWithPath(moduleName, false))
+                        {
+                           strcpy(filePath, prj.topNode.path);
+                           PathCatSlash(filePath, moduleName);
+                           codeEditor = (CodeEditor)ide.OpenFile(filePath, normal, true, null, no, normal);
+                           if(codeEditor)
+                              break;
+                        }
+                     }
+                  }
+               }
+               if(codeEditor && lineNumber)
+               {
+                  EditBox editBox = codeEditor.editBox;
+                  editBox.GoToLineNum(lineNumber - 1);
+                  editBox.GoToPosition(editBox.line, lineNumber - 1, col ? (col - 1) : 0);
+               }
+            }
+         }
+      }
+   }
+
+   bool OpenNode(ProjectNode node)
+   {
+      char filePath[MAX_LOCATION];
+      node.GetFullFilePath(filePath);
+      return ide.OpenFile(filePath, normal, true/*false Why was it opening hidden?*/, null, something, normal) ? true : false;
+   }
+
+   void AddNode(ProjectNode node, DataRow addTo)
+   {
+      DataRow row = addTo ? addTo.AddRow() : fileList.AddRow();
+
+      row.tag = (int)node;
+      node.row = row;
+
+      if(node.type == resources)
+         resourceRow = row;
+
+      row.SetData(null, node);
+
+      if(node.files && node.files.first && node.parent && 
+            !(!node.parent.parent && 
+               (!strcmpi(node.name, "notes") || !strcmpi(node.name, "sources") || 
+                  !strcmpi(node.name, "src") || !strcmpi(node.name, "tools"))))
+         row.collapsed = true;
+      else if(node.type == folder)
+         node.icon = openFolder;
+
+      if(node.files)
+      {
+         for(child : node.files)
+            AddNode(child, row);
+      }
+   }
+
+   void DeleteNode(ProjectNode projectNode)
+   {
+      if(projectNode.files)
+      {
+         ProjectNode child;
+         while(child = projectNode.files.first)
+            DeleteNode(child);
+      }
+      fileList.DeleteRow(projectNode.row);
+      projectNode.Delete();
+   }
+
+   bool ProjectSave(MenuItem selection, Modifiers mods)
+   {
+      DataRow row = fileList.currentRow;
+      ProjectNode node = row ? (ProjectNode)row.tag : null;
+      Project prj = node ? node.project : null;
+      if(prj)
+      {
+         if(prj.Save(prj.filePath))
+         {
+            // ProjectUpdateMakefileForAllConfigs(prj, true, true);
+            prj.topNode.modified = false;
+            prj = null;
+            for(p : ide.workspace.projects)
+            {
+               if(p.topNode.modified)
+               { 
+                  prj = p;
+                  break;
+               }
+            }
+            if(!prj)
+               modifiedDocument = false;
+            Update(null);
+         }
+      }
+      return true;
+   }
+
+   bool ShowOutputBuildLog(bool cleanLog)
+   {
+      OutputView output = ide.outputView;
+      if(cleanLog)
+         output.ShowClearSelectTab(build);
+      else
+      {
+         output.SelectTab(build);
+         output.Show();
+      }
+   }
+
    bool DebugRestart()
    {
-      if(/*!IsProjectModified() ||*/ BuildInterrim(project, restart))
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config = project.config;
+
+      bool result = false;
+      if(/*!IsProjectModified() ||*/ BuildInterrim(project, restart, compiler, config))
       {
-         ide.debugger.Restart();
-         return true;
+         // For Restart, compiler and config will only be used if for
+         // whatever reason (if at all possible) the Debugger is in a
+         // 'terminated' or 'none' state
+         ide.debugger.Restart(compiler, config);
+         result = true;
       }
-      return false;
+
+      delete compiler;
+      return result;
    }
 
    bool DebugResume()
@@ -1490,15 +1470,24 @@ class ProjectView : Window
 
    bool DebugStepInto()
    {
-      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start)))
-         ide.debugger.StepInto();
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config = project.config;
+
+      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config)))
+         ide.debugger.StepInto(compiler, config);
+      delete compiler;
       return true;
    }
 
    bool DebugStepOver(bool skip)
    {
-      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start)))
-         ide.debugger.StepOver(skip);
+      CompilerConfig compiler = ideSettings.GetCompilerConfig(ide.workspace.compiler);
+      ProjectConfig config = project.config;
+
+      if((ide.debugger.isActive) || (!buildInProgress && BuildInterrim(project, start, compiler, config)))
+         ide.debugger.StepOver(compiler, config, skip);
+
+      delete compiler;
       return true;
    }
 
index d2b8301..84f2d29 100644 (file)
@@ -55,7 +55,7 @@ static void IndentPop()
 #endif
 }
 
-void GenerateVSSolutionFile(Project project)
+void GenerateVSSolutionFile(Project project, CompilerConfig compiler)
 {
    char filePath[MAX_LOCATION];
    char slnFileName[MAX_LOCATION];
@@ -75,7 +75,6 @@ void GenerateVSSolutionFile(Project project)
       char * slnGUID = "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942";
       char * prjGUID = "3A1E5467-4EE2-4299-8F0C-7D26CC8C24BA";
       //char * relPathToVCProjFile = "win32ProjectConsoleApp\\win32ProjectConsoleApp";
-      CompilerConfig compiler = GetCompilerConfig();
 
       f.Print(""); f.Printf("\r\n");
       f.Print("Microsoft Visual Studio Solution File, Format Version ", compiler.type.solutionFileVersionString); f.Printf("\r\n");
@@ -102,19 +101,17 @@ void GenerateVSSolutionFile(Project project)
       f.Print("\tEndGlobalSection"); f.Printf("\r\n");
       f.Print("EndGlobal"); f.Printf("\r\n");
    
-      delete compiler;
       delete f;
    }
 }
 
-void GenerateVCProjectFile(Project project)
+void GenerateVCProjectFile(Project project, CompilerConfig compiler)
 {
    char filePath[MAX_LOCATION];
    char slnFileName[MAX_LOCATION];
    char * projectName = project.name;
    bool usePrecompiledHeaders = false;
    File f;
-   CompilerConfig compiler = GetCompilerConfig();
 
    IndentClear();
 
@@ -129,7 +126,8 @@ void GenerateVCProjectFile(Project project)
       char * prjGUID = "3A1E5467-4EE2-4299-8F0C-7D26CC8C24BA";
       char * rootNamespace = projectName;
       Map<String, NameCollisionInfo> namesInfo { };
-      project.topNode.GenMakefileGetNameCollisionInfo(namesInfo);
+      // TOFIX: Collision and Config-specific!
+      project.topNode.GenMakefileGetNameCollisionInfo(namesInfo, project.config);
 
       f.Print(tagIndent, "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>", tagLine);
       f.Print(tagIndent, "<VisualStudioProject", attribSep);
@@ -160,8 +158,8 @@ void GenerateVCProjectFile(Project project)
          f.Print(tagIndent, "<Configurations>", tagLine);
             IndentPush();
 
-            for(config : project.configurations)
-               PrintConfiguration(f, project, config, usePrecompiledHeaders);
+         for(config : project.configurations)
+            PrintConfiguration(f, project, compiler, config, usePrecompiledHeaders);
 
          IndentPop();
          f.Print(tagIndent, "</Configurations>", tagLine);
@@ -217,10 +215,9 @@ void GenerateVCProjectFile(Project project)
       delete namesInfo;
       delete f;
    }
-   delete compiler;
 }
 
-void PrintConfiguration(File f, Project project, ProjectConfig config, bool usePrecompiledHeaders)
+void PrintConfiguration(File f, Project project, CompilerConfig compiler, ProjectConfig config, bool usePrecompiledHeaders)
 {
    ProjectOptions options = project.options;
    SetBool consoleSet = localConsole;
@@ -234,21 +231,21 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
    char * targetDirExpr = localTargetDirectory;
    DirExpression objDir { type = intermediateObjectsDir };
    DirExpression targetDir { type = DirExpressionType::targetDir };
-   CompilerConfig compiler = GetCompilerConfig();
+   TargetTypes targetType = project.GetTargetType(config);
 
    if(!objDirExpr)
       objDirExpr = settingsObjectsDirectory;
-   objDir.Evaluate(objDirExpr, project);
+   objDir.Evaluate(objDirExpr, project, compiler, config);
    if(!targetDirExpr)
       targetDirExpr = settingsTargetDirectory;
-   targetDir.Evaluate(targetDirExpr, project);
+   targetDir.Evaluate(targetDirExpr, project, compiler, config);
 
    f.Print(tagIndent, "<Configuration", attribSep);
       IndentPush();
       f.Print(attribIndent, "Name=\"", config.name, "|Win32\"", attribSep);
       f.Print(attribIndent, "OutputDirectory=\"$(SolutionDir)", targetDir.dir/*"$(ConfigurationName)"*/, "\"", attribSep);
       f.Print(attribIndent, "IntermediateDirectory=\"", objDir.dir/*"$(ConfigurationName)"*/, "\"", attribSep);
-      f.Print(attribIndent, "ConfigurationType=\"", project.targetType == sharedLibrary ? 2 : project.targetType == staticLibrary ? 4 : 1, "\"", attribSep);
+      f.Print(attribIndent, "ConfigurationType=\"", targetType == sharedLibrary ? 2 : targetType == staticLibrary ? 4 : 1, "\"", attribSep);
       f.Print(attribIndent, "CharacterSet=\"", false/*unicode*/ ? 1 : true/*multibyte*/ ? 2 : 0, "\"", attribSep);
    if(optimizationSet == speed)
       f.Print(attribIndent, "WholeProgramOptimization=\"1\"", attribSep);
@@ -313,9 +310,9 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
          f.Print(";_CRT_SECURE_NO_DEPRECATE");
          if(console)
             f.Print(";_CONSOLE");
-         if(project.targetType == sharedLibrary)
+         if(targetType == sharedLibrary)
             f.Print(";_WINDOWS;_USRDLL;WIN32DYNAMICLIB_EXPORTS");
-         else if(project.targetType == staticLibrary)
+         else if(targetType == staticLibrary)
             f.Print(";_LIB");
          if(project.options && project.options.preprocessorDefinitions)
          {
@@ -360,7 +357,7 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
       f.Print(attribIndent, "/>", tagLine);
       f.Print(tagIndent, "<Tool", attribSep);
          IndentPush();
-         f.Print(attribIndent, "Name=\"", (project.targetType == executable || project.targetType == sharedLibrary) ? "VCLinkerTool" : "VCLibrarianTool", "\"", attribSep);
+         f.Print(attribIndent, "Name=\"", (targetType == executable || targetType == sharedLibrary) ? "VCLinkerTool" : "VCLibrarianTool", "\"", attribSep);
          {
             Array<String> additionalLibraries { };
             if(project.options && project.options.libraries)
@@ -385,14 +382,14 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
             delete additionalLibraries;
          }
          f.Print(attribIndent, "OutputFile=\"$(OutDir)\\", targetFileName, ".");
-         if(project.targetType == executable)
+         if(targetType == executable)
             f.Print("exe");
-         else if(project.targetType == sharedLibrary)
+         else if(targetType == sharedLibrary)
             f.Print("dll");
-         else if(project.targetType == staticLibrary)
+         else if(targetType == staticLibrary)
             f.Print("lib");
          f.Print("\"", attribSep);
-   if(project.targetType == executable)
+   if(targetType == executable)
          f.Print(attribIndent, "LinkIncremental=\"", debug ? 2 : 1, "\"", attribSep);
          {
             Array<DirPath> additionalLibraryDirs { };
@@ -417,7 +414,7 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
             }
             delete additionalLibraryDirs;
          }
-   if(project.targetType == executable)
+   if(targetType == executable)
    {
          f.Print(attribIndent, "GenerateDebugInformation=\"true\"", attribSep);
          f.Print(attribIndent, "SubSystem=\"1\"", attribSep);
@@ -435,7 +432,7 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
          f.Print(attribIndent, "Name=\"VCALinkTool\"", attribSep);
       IndentPop();
       f.Print(attribIndent, "/>", tagLine);
-   if(project.targetType == executable)
+   if(targetType == executable)
    {
       f.Print(tagIndent, "<Tool", attribSep);
          IndentPush();
@@ -458,7 +455,7 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
          f.Print(attribIndent, "Name=\"VCFxCopTool\"", attribSep);
       IndentPop();
       f.Print(attribIndent, "/>", tagLine);
-   if(project.targetType == executable)
+   if(targetType == executable)
    {
       f.Print(tagIndent, "<Tool", attribSep);
          IndentPush();
@@ -483,7 +480,6 @@ void PrintConfiguration(File f, Project project, ProjectConfig config, bool useP
 
    delete objDir;
    delete targetDir;
-   delete compiler;
 }
 
 void CollectPlatformSpecificDirs(Project project, ProjectConfig config, Array<String> additionalPreprocessorDefs,
@@ -662,7 +658,8 @@ bool PrintNodes(File f, Project prj, ProjectNode node, Map<String, NameCollision
       {
          for(child : node.files)
          {
-            if(child.type == folder || (child.type != resources && !child.isExcluded))
+            // TOFIX: Exclusion and Config!
+            if(child.type == folder || (child.type != resources && !child.GetIsExcluded(prj.config)))
             {
                if((hasChild = PrintNodes(f, prj, child, namesInfo, filter, true, usePrecompiledHeaders)))
                   break;
@@ -680,7 +677,8 @@ bool PrintNodes(File f, Project prj, ProjectNode node, Map<String, NameCollision
 
       for(child : node.files)
       {
-         if(child.type == folder || (child.type != resources && !child.isExcluded))
+         // TOFIX: Exclusion and config!
+         if(child.type == folder || (child.type != resources && !child.GetIsExcluded(prj.config)))
          {
             if(PrintNodes(f, prj, child, namesInfo, filter, justHasChild, usePrecompiledHeaders) && justHasChild)
                break;
@@ -750,13 +748,15 @@ void PrintFileConfiguration(File f, Project prj, ProjectNode node,
    info = namesInfo[moduleName];
    nameCollision = info ? info.IsExtensionColliding(extension) : false;
    if(perFilePreprocessorDefs.count || perFileIncludeDirs.count ||
-         node.isExcluded || nameCollision ||
+         // TOFIX: Exclusion and config!
+         node.GetIsExcluded(prj.config) || nameCollision ||
          !strcmpi(extension, "h") || usePrecompiledHeaders)
    {
    f.Print(tagIndent, "<FileConfiguration", attribSep);
       IndentPush();
       f.Print(attribIndent, "Name=\"", config.name, "|Win32\"", attribSep);
-      if(node.isExcluded || !strcmpi(extension, "h"))
+      // TOFIX: Exclusion and config!
+      if(node.GetIsExcluded(prj.config) || !strcmpi(extension, "h"))
          f.Print(attribIndent, "ExcludedFromBuild=\"true\"", attribSep);
       f.Print(attribIndent, ">", tagLine);