public void CompareTo(Configuration actual)
        {
            Test(this.Name,         actual.Name,         "Configuration name");
            Test(this.BinDir,       actual.BinDir,       "BinDir");
            Test(this.LibDir,       actual.LibDir,       "LibDir");
            Test(this.ObjDir,       actual.ObjDir,       "ObjDir");
            Test(this.OutDir,       actual.OutDir,       "Output directory");
            Test(this.Target,       actual.Target,       "Target");
            Test(this.OutFile,      actual.OutFile,      "Output file");
            Test(this.Kind,         actual.Kind,         "Kind");
            Test(this.BuildOptions, actual.BuildOptions, "Build options");
            Test(this.LinkOptions,  actual.LinkOptions,  "Link options");
            Test(this.ImportLib,    actual.ImportLib,    "Import library");
            Test(this.PchHeader,    actual.PchHeader,    "PCH Header");
            Test(this.PchSource,    actual.PchSource,    "PCH Source");
            Test(this.ResOptions,   actual.ResOptions,   "Resource options");
            Test(this.Pch,          actual.Pch,          "Precompiled headers");

            TestList(this.IncludePaths, actual.IncludePaths, "Include paths");
            TestList(this.Defines,      actual.Defines,      "Defined symbols");
            TestList(this.LibPaths,     actual.LibPaths,     "Lib paths");
            TestList(this.Links,        actual.Links,        "Links");
            TestList(this.BuildFlags,   actual.BuildFlags,   "Build flags");
            TestList(this.LinkFlags,    actual.LinkFlags,    "Link flags");
            TestList(this.Dependencies, actual.Dependencies, "Dependencies");
            TestList(this.LinkDeps,     actual.LinkDeps,     "Linker dependencies");
            TestList(this.ResDefines,   actual.ResDefines,   "Resource defines");
            TestList(this.ResPaths,     actual.ResPaths,     "Resource paths");
        }
 public void Add(Project project)
 {
     foreach (string name in project.Configuration)
     {
         Configuration config = new Configuration();
         config.Name = name;
         List.Add(config);
     }
 }
        public void CompareTo(Configuration actual)
        {
            Test(this.Name, actual.Name,     "Configuration name");
            Test(this.BinDir,  actual.BinDir,  "BinDir");
            Test(this.LibDir,  actual.LibDir,  "LibDir");
            Test(this.ObjDir,  actual.ObjDir,  "ObjDir");
            Test(this.OutDir,  actual.OutDir,  "Output directory");
            Test(this.Target,  actual.Target,  "Target");
            Test(this.OutFile, actual.OutFile, "Output file");
            Test(this.BuildOptions, actual.BuildOptions, "Build options");
            Test(this.LinkOptions,  actual.LinkOptions,  "Link options");
            Test(this.ImportLib,    actual.ImportLib,    "Import library");

            TestList(this.IncludePaths, actual.IncludePaths, "Include paths");
            TestList(this.Defines,      actual.Defines,      "Defined symbols");
            TestList(this.LibPaths,     actual.LibPaths,     "Lib paths");
            TestList(this.Links,        actual.Links,        "Links");
            TestList(this.BuildFlags,   actual.BuildFlags,   "Build flags");
            TestList(this.LinkFlags,    actual.LinkFlags,    "Link flags");
            TestList(this.Dependencies, actual.Dependencies, "Dependencies");
            TestList(this.LinkDeps,     actual.LinkDeps,     "Linker dependencies");
        }
Esempio n. 4
0
        private void ParseCpp(Project project, Package package, string filename)
        {
            Begin(filename);
            Match("# Microsoft Developer Studio Project File - Name=\"" + package.Name + "\" - Package Owner=<4>");
            Match("# Microsoft Developer Studio Generated Build File, Format Version 6.00");
            Match("# ** DO NOT EDIT **");
            Match("");

            string[] matches = Regex("# TARGTYPE (.+)");
            switch (matches[0])
            {
            case "\"Win32 (x86) Application\" 0x0101":
                package.Kind = "winexe";
                break;
            case "\"Win32 (x86) Console Application\" 0x0103":
                package.Kind = "exe";
                break;
            case "\"Win32 (x86) Dynamic-Link Library\" 0x0102":
                package.Kind = "dll";
                break;
            case "\"Win32 (x86) Static Library\" 0x0104":
                package.Kind = "lib";
                break;
            default:
                throw new FormatException("Unrecognized target type: '" + matches[0] + "'");
            }
            string baseKind = matches[0].Substring(0, matches[0].Length - 7);
            Match("");

            matches = Regex("CFG=" + package.Name + " - (.+)");
            string defaultConfig = matches[0];

            Match("!MESSAGE This is not a valid makefile. To build this project using NMAKE,");
            Match("!MESSAGE use the Export Makefile command and run");
            Match("!MESSAGE ");
            Match("!MESSAGE NMAKE /f \"" + package.Name + ".mak\".");
            Match("!MESSAGE ");
            Match("!MESSAGE You can specify a configuration when running NMAKE");
            Match("!MESSAGE by defining the macro CFG on the command line. For example:");
            Match("!MESSAGE ");
            Match("!MESSAGE NMAKE /f \"" + package.Name + ".mak\" CFG=\"" + package.Name + " - " + defaultConfig + "\"");
            Match("!MESSAGE ");
            Match("!MESSAGE Possible choices for configuration are:");
            Match("!MESSAGE ");

            baseKind = baseKind.Replace("(", "\\(");
            baseKind = baseKind.Replace(")", "\\)");
            while (!Match("!MESSAGE ", true))
            {
                matches = Regex("!MESSAGE \"" + package.Name + " - ([^\"]+)\" \\(based on " + baseKind + "\\)");

                Configuration config = new Configuration();
                config.Name = matches[0];
                config.Dependencies = new string[0];
                package.Config.Add(config);
            }
            Match("");

            /* Verify configurations */
            if (project.Configuration.Count == 0)
            {
                foreach (Configuration config in package.Config)
                    project.Configuration.Add(config.Name);
            }
            else
            {
                foreach (Configuration config in package.Config)
                    if (!project.Configuration.Contains(config.Name))
                        throw new FormatException("Config '" + config.Name + "' not found in project");
            }

            Match("# Begin Project");
            Match("# PROP AllowPerConfigDependencies 0");
            Match("# PROP Scc_ProjName \"\"");
            Match("# PROP Scc_LocalPath \"\"");
            Match("CPP=cl.exe");
            if (package.Kind != "lib")
                Match("MTL=midl.exe");
            Match("RSC=rc.exe");
            Match("");

            bool first = true;
            foreach (Configuration config in package.Config)
            {
                ArrayList bldflags = new ArrayList();
                ArrayList lnkflags = new ArrayList();
                ArrayList defines  = new ArrayList();
                ArrayList incpaths = new ArrayList();
                ArrayList links    = new ArrayList();
                ArrayList libpaths = new ArrayList();

                string cond = (first) ? "!IF" : "!ELSEIF";
                first = false;

                Match(cond + "  \"$(CFG)\" == \"" + package.Name + " - " + config.Name + "\"");
                Match("");

                Match("# PROP BASE Use_MFC 0");

                matches = Regex("# PROP BASE Use_Debug_Libraries ([0-1])");
                string useDebugLib = matches[0];

                matches = Regex("# PROP BASE Output_Dir \"(.+)\"");
                config.OutDir = matches[0];
                config.BinDir = matches[0];
                config.LibDir = matches[0];

                matches = Regex("# PROP BASE Intermediate_Dir \"(.+)\"");
                config.ObjDir = matches[0];

                Match("# PROP BASE Target_Dir \"\"");
                Match("# PROP Use_MFC 0");
                Match("# PROP Use_Debug_Libraries " + useDebugLib);
                Match("# PROP Output_Dir \"" + config.OutDir + "\"");
                Match("# PROP Intermediate_Dir \"" + config.ObjDir + "\"");

                if (Match("# PROP Ignore_Export_Lib 1", true))
                    bldflags.Add("no-import-lib");

                Match("# PROP Target_Dir \"\"");

                matches = Regex("# ADD BASE CPP /nologo (.+)");
                string flags = matches[0];
                matches = flags.Split(' ');

                int i = 0;
                if (matches[i] == "/MTd" || matches[i] == "/MT")
                {
                    lnkflags.Add("static-runtime");
                }
                else
                {
                    Expect(matches[i], "/MDd", "/MD");
                }
                ++i;

                if (matches[i] == "/W4")
                {
                    bldflags.Add("extra-warnings");
                }
                else
                {
                    Expect(matches[i], "/W3");
                }
                ++i;

                if (matches[i] == "/WX")
                {
                    bldflags.Add("fatal-warnings");
                    ++i;
                }

                if (matches[i] == "/Gm")
                {
                    ++i;
                }

                if (matches[i] == "/GR")
                {
                    ++i;
                }
                else
                {
                    bldflags.Add("no-rtti");
                }

                if (matches[i] == "/GX")
                {
                    ++i;
                }
                else
                {
                    bldflags.Add("no-exceptions");
                }

                if (matches[i] == "/ZI")
                {
                    ++i;
                }
                else
                {
                    bldflags.Add("no-symbols");
                }

                if (matches[i] == "/O1")
                {
                    bldflags.Add("optimize-size");
                }
                else if (matches[i] == "/O2")
                {
                    bldflags.Add("optimize");
                }
                else
                {
                    Expect(matches[i], "/Od");
                }
                ++i;

                if (matches[i] == "/Oy")
                {
                    bldflags.Add("no-frame-pointer");
                    ++i;
                }

                while (matches[i] == "/I")
                {
                    incpaths.Add(matches[++i].Trim('\"'));
                    ++i;
                }

                while (matches[i] == "/D")
                {
                    defines.Add(matches[++i].Trim('\"'));
                    ++i;
                }

                Expect(matches[i], "/YX");
                Expect(matches[++i], "/FD");
                if (matches[++i] == "/GZ")
                    ++i;
                Expect(matches[i++], "/c");

                config.BuildOptions = String.Empty;
                while (i < matches.Length)
                    config.BuildOptions += " " + matches[i++];
                config.BuildOptions = config.BuildOptions.Trim();

                Match("# ADD CPP /nologo " + flags);

                string debugSymbol = bldflags.Contains("no-symbols") ? "NDEBUG" : "_DEBUG";

                bool hasMtl = Match("# ADD BASE MTL /nologo /D \"" + debugSymbol + "\" /mktyplib203 /win32", true);
                if (hasMtl)
                    Match("# ADD MTL /nologo /D \"" + debugSymbol + "\" /mktyplib203 /win32");

                ArrayList resDefines = new ArrayList();
                ArrayList resPaths = new ArrayList();
                matches = Regex("# ADD BASE RSC /l 0x409 (.+)");
                while (matches[0].Length > 0)
                {
                    if (matches[0].StartsWith("/d") || matches[0].StartsWith("/i"))
                    {
                        int split = matches[0].IndexOf('"', 4);
                        string value = matches[0].Substring(4, split - 4);
                        if (matches[0].StartsWith("/d"))
                            resDefines.Add(value);
                        else
                            resPaths.Add(value);
                        matches[0] = matches[0].Substring(split + 1).TrimStart();
                    }
                    else
                    {
                        config.ResOptions = matches[0];
                        matches[0] = "";
                    }
                }

                config.ResDefines = (string[])resDefines.ToArray(typeof(string));
                config.ResPaths = (string[])resPaths.ToArray(typeof(string));

                string rsc = "# ADD RSC /l 0x409";
                foreach (string symbol in resDefines)
                    rsc += " /d \"" + symbol + "\"";
                foreach (string symbol in resPaths)
                    rsc += " /i \"" + symbol + "\"";
                if (config.ResOptions != null)
                    rsc += " " + config.ResOptions;
                Match(rsc);

                Match("BSC32=bscmake.exe");
                Match("# ADD BASE BSC32 /nologo");
                Match("# ADD BSC32 /nologo");

                if (Match("LINK32=link.exe -lib", true))
                {
                    config.Kind = "lib";
                    Match("# ADD BASE LIB32 /nologo");
                    matches = Regex("# ADD LIB32 /nologo /out:\"(.+)\"", true);
                    if (matches != null)
                    {
                        config.Target = matches[0];
                    }
                    else
                    {
                        Match("# ADD LIB32 /nologo");
                    }
                }
                else
                {
                    Match("LINK32=link.exe");
                    matches = Regex("# ADD BASE LINK32 (.+)");
                    flags = matches[0];
                    matches = flags.Split(' ');

                    i = 0;
                    while (i < matches.Length && matches[i][0] != '/')
                        links.Add(matches[i++]);

                    Expect(matches[i++], "/nologo");

                    bool noMain = true;
                    if (matches[i] == "/entry:\"mainCRTStartup\"")
                    {
                        noMain = false;
                        ++i;
                    }

                    if (matches[i] == "/subsystem:windows")
                    {
                        config.Kind = "winexe";
                    }
                    else if (matches[i] == "/subsystem:console")
                    {
                        config.Kind = "exe";
                    }
                    else if (matches[i] == "/dll")
                    {
                        config.Kind = "dll";
                    }
                    else
                    {
                        throw new FormatException("Unexpected subsystem flag: " + matches[i]);
                    }
                    ++i;

                    if (hasMtl && config.Kind != "winexe" && config.Kind != "dll")
                        throw new FormatException("Found unexpected MTL block");

                    if ((config.Kind == "winexe" || config.Kind == "exe") && noMain)
                        bldflags.Add("no-main");

                    if (!bldflags.Contains("no-symbols"))
                    {
                        Expect(matches[i++], "/incremental:yes");
                        Expect(matches[i++], "/debug");
                    }

                    Expect(matches[i++], "/machine:I386");

                    if (config.Kind == "dll")
                    {
                        config.ImportLib = matches[i].Substring(9, matches[i].Length - 10);
                        ++i;
                    }

                    config.Target = matches[i].Substring(6, matches[i].Length - 7);
                    if (config.Target.StartsWith(config.OutDir))
                        config.Target = config.Target.Substring(config.OutDir.Length + 1);
                    ++i;

                    if (!bldflags.Contains("no-symbols"))
                        Expect(matches[i++], "/pdbtype:sept");

                    config.LibDir = matches[i].Substring(10, matches[i].Length - 11);
                    ++i;

                    while (i < matches.Length && matches[i].StartsWith("/libpath:"))
                    {
                        libpaths.Add(matches[i].Substring(10, matches[i].Length - 11));
                        ++i;
                    }

                    Match("# ADD LINK32 " + flags);
                }

                config.BuildFlags = (string[])bldflags.ToArray(typeof(string));
                config.LinkFlags  = (string[])lnkflags.ToArray(typeof(string));
                config.Defines    = (string[])defines.ToArray(typeof(string));
                config.IncludePaths = (string[])incpaths.ToArray(typeof(string));
                config.Links      = (string[])links.ToArray(typeof(string));
                config.LibPaths   = (string[])libpaths.ToArray(typeof(string));

                Match("");
            }

            Match("!ENDIF");
            Match("");
            Match("# Begin Target");
            Match("");

            foreach (Configuration config in package.Config)
                Match("# Name \"" + package.Name + " - " + config.Name + "\"");

            string folder = "";
            while (!Match("# End Target", true))
            {
                matches = Regex("# Begin Group \"(.+)\"", true);
                if (matches != null)
                {
                    folder = Path.Combine(folder, matches[0]);
                    Match("");
                    Match("# PROP Default_Filter \"\"");
                    continue;
                }

                matches = Regex("# End Group", true);
                if (matches != null)
                {
                    folder = Path.GetDirectoryName(folder);
                    continue;
                }

                Match("# Begin Source File");
                Match("");
                matches = Regex("SOURCE=(.+)");

                filename = matches[0];
                package.File.Add(filename);

                if (filename.StartsWith("./"))
                    filename = filename.Substring(2);
                while (filename.StartsWith("../"))
                    filename = filename.Substring(3);
                if (Path.GetDirectoryName(filename) != folder)
                    throw new FormatException("File '" + matches[0] + "' is in folder '" + folder + "'");

                Match("# End Source File");
            }
        }
        public override void Parse(Project project, string filename)
        {
            Begin(filename + ".cmbx");

            string[] matches = Regex("<Combine fileversion=\"(.+)\" name=\"(.+)\" description=\"(.*)\">");
            project.Name = matches[1];

            matches = Regex("  <StartMode startupentry=\"\" single=\"True\">");

            while (!Match("  </StartMode>", true))
            {
                matches = Regex("    <Execute entry=\"(.+)\" type=\"None\" />");
                Package package = new Package();
                package.Name = matches[0];
                project.Package.Add(package);
            }

            Match("  <Entries>");
            foreach (Package package in project.Package)
            {
                matches = Regex("    <Entry filename=\"(.+)\" />");
                /* Pull out directory, but keep the path separators intact (no translation) */
                package.Path = matches[0].Substring(0, Path.GetDirectoryName(matches[0]).Length);
                package.ScriptName = Path.GetFileName(matches[0]);
            }
            Match("  </Entries>");

            matches = Regex("  <Configurations active=\"(.+)\">");
            string active = matches[0];

            while (!Match("  </Configurations>", true))
            {
                matches = Regex("    <Configuration name=\"(.+)\">");
                Configuration config = new Configuration();
                config.Name = matches[0];
                project.Configuration.Add(matches[0]);

                foreach (Package package in project.Package)
                {
                    package.Config.Add(config);
                    Match("      <Entry name=\"" + package.Name + "\" configurationname=\"" + active + "\" build=\"False\" />");
                }

                Match("    </Configuration>");
            }

            if (active != (string)project.Configuration[0])
                throw new FormatException("Active configuration should be '" + project.Configuration[0] + "' but is '" + active + "'");

            Match("</Combine>");

            foreach (Package package in project.Package)
            {
                filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName);
                ParsePackage(project, package, filename);

                /* SHARPDEV_DEPENDENCY_BUG: Dependencies are set correctly here! */
            #if SHARPDEV_DEPENDENCY_BUG
                Console.WriteLine(package.Name + ": ");
                foreach (Configuration config in package.Config)
                {
                    Console.WriteLine("  " + config.Name + ": " + config.Dependencies.Length);
                }
            #endif
            }
        }
 public void Add(Configuration config)
 {
     List.Add(config);
 }
        private void ParseCpp(Project project, Package package, string filename)
        {
            Begin(filename);

            Match("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>");
            Match("<CodeBlocks_project_file>");
            Match("\t<FileVersion major=\"1\" minor=\"6\" />");
            Match("\t<Project>");
            Match("\t\t<Option title=\"" + package.Name + "\" />");
            Match("\t\t<Option pch_mode=\"2\" />", true);
            Match("\t\t<Option compiler=\"gcc\" />");
            Match("\t\t<Build>");

            package.Language = "c++";

            while (!Match("\t\t</Build>", true))
            {
                Configuration config = new Configuration();
                package.Config.Add(config);

                string[] matches = Regex("\t\t\t<Target title=\"(.+?)\">");
                config.Name = matches[0];

                while (!Match("\t\t\t</Target>", true))
                {
                    ArrayList buildFlags = new ArrayList();
                    ArrayList defines = new ArrayList();
                    ArrayList incPaths = new ArrayList();
                    ArrayList libPaths = new ArrayList();
                    ArrayList libs = new ArrayList();
                    config.BuildOptions = "";
                    config.LinkOptions = "";

                    matches = Regex("\t\t\t\t<Option output=\"(.+?)\" prefix_auto=\"0\" extension_auto=\"0\" />");
                    config.Target = Path.GetFileName(matches[0]).Replace('\\', '/');
                    config.OutDir = Path.GetDirectoryName(matches[0]).Replace('\\', '/'); ;
                    config.OutFile = Path.GetFileName(matches[0]).Replace('\\', '/'); ;

                    matches = Regex("\t\t\t\t<Option object_output=\"(.+?)\" />");
                    config.ObjDir = matches[0];

                    matches = Regex("\t\t\t\t<Option type=\"([0-9])\" />");
                    switch (matches[0])
                    {
                    case "0":
                        config.Kind = "winexe";
                        break;
                    case "1":
                        config.Kind = "exe";
                        break;
                    case "2":
                        config.Kind = "lib";
                        break;
                    case "3":
                        config.Kind = "dll";
                        break;
                    default:
                        throw new FormatException("Unknown configuration type " + matches[0]);
                    }

                    if (config.Kind == "lib")
                    {
                        config.BinDir = "";
                        config.LibDir = config.OutDir;
                    }
                    else
                    {
                        config.BinDir = config.OutDir;
                        config.LibDir = "";
                    }

                    Match("\t\t\t\t<Option compiler=\"gcc\" />");

                    if (config.Kind == "dll")
                    {
                        Match("\t\t\t\t<Option createDefFile=\"0\" />");

                        matches = Regex("\t\t\t\t<Option createStaticLib=\"([0-1])\" />");
                        if (matches[0] == "0")
                            buildFlags.Add("no-import-lib");
                    }

                    Match("\t\t\t\t<Compiler>");

                    while (!Match("\t\t\t\t</Compiler>", true))
                    {
                        matches = Regex("\t\t\t\t\t<Add option=\"(.+?)\" />", true);
                        if (matches != null)
                        {
                            switch (matches[0])
                            {
                            case "-fomit-frame-pointer":
                                buildFlags.Add("no-frame-pointer");
                                break;
                            case "--no-exceptions":
                                buildFlags.Add("no-exceptions");
                                break;
                            case "--no-rtti":
                                buildFlags.Add("no-rtti");
                                break;
                            case "-O":
                                buildFlags.Add("optimize");
                                break;
                            case "-O3":
                                buildFlags.Add("optimize-speed");
                                break;
                            case "-Os":
                                buildFlags.Add("optimize-size");
                                break;
                            case "-g":
                                break;
                            case "-Wall":
                                buildFlags.Add("extra-warnings");
                                break;
                            case "-Werror":
                                buildFlags.Add("fatal-warnings");
                                break;
                            default:
                                if (matches[0].StartsWith("-D"))
                                {
                                    defines.Add(matches[0].Substring(2));
                                }
                                else
                                {
                                    config.BuildOptions += matches[0] + " ";
                                }
                                break;
                            }
                        }

                        matches = Regex("\t\t\t\t\t<Add directory=\"(.+?)\" />", true);
                        if (matches != null)
                        {
                            incPaths.Add(matches[0]);
                        }
                    }

                    Match("\t\t\t\t<Linker>");
                    while (!Match("\t\t\t\t</Linker>", true))
                    {
                        matches = Regex("\t\t\t\t\t<Add option=\"(.+?)\" />", true);
                        if (matches != null)
                        {
                            switch (matches[0])
                            {
                            case "-s":
                                buildFlags.Add("no-symbols");
                                break;
                            default:
                                config.LinkOptions += matches[0] + " ";
                                break;
                            }
                        }

                        matches = Regex("\t\t\t\t\t<Add directory=\"(.+?)\" />", true);
                        if (matches != null)
                        {
                            libPaths.Add(matches[0]);
                        }

                        matches = Regex("\t\t\t\t\t<Add library=\"(.+?)\" />", true);
                        if (matches != null)
                        {
                            libs.Add(matches[0]);
                        }
                    }

                    ArrayList resPaths = new ArrayList();
                    if (Match("\t\t\t\t<ResourceCompiler>", true))
                    {
                        while (!Match("\t\t\t\t</ResourceCompiler>", true))
                        {
                            matches = Regex("\t\t\t\t\t<Add directory=\"(.+?)\" />");
                            resPaths.Add(matches[0]);
                        }
                    }

                    config.BuildFlags = (string[])buildFlags.ToArray(typeof(string));
                    config.Defines = (string[])defines.ToArray(typeof(string));
                    config.IncludePaths = (string[])incPaths.ToArray(typeof(string));
                    config.LibPaths = (string[])libPaths.ToArray(typeof(string));
                    config.Links = (string[])libs.ToArray(typeof(string));
                    config.BuildOptions = config.BuildOptions.Trim(' ');
                    config.LinkOptions = config.LinkOptions.Trim(' ');
                    config.ResPaths = (string[])resPaths.ToArray(typeof(string));
                }
            }

            if (project.Configuration.Count == 0)
            {
                foreach (Configuration config in package.Config)
                    project.Configuration.Add(config.Name);
            }

            while (!Match("\t\t<Extensions />", true))
            {
                string[] matches = Regex("\t\t<Unit filename=\"(.+?)\">");
                string name = matches[0];
                package.File.Add(name);

                if (Path.GetExtension(name) == ".rc")
                {
                    string resname = name.Replace("../", "");
                    resname = resname.Replace(".rc", ".res");

                    Match("\t\t\t<Option compilerVar=\"WINDRES\" />");
                }
                else
                {
                    if (Match("\t\t\t<Option compilerVar=\"CC\" />", true))
                        package.Language = "c";
                    else
                        Match("\t\t\t<Option compilerVar=\"CPP\" />", true);

                    if (!name.EndsWith(".c") && !name.EndsWith(".cpp"))
                    {
            //						Match("\t\t\t<Option compile=\"0\" />");
            //						Match("\t\t\t<Option link=\"0\" />");
                    }
                }

                foreach (Configuration cfg in package.Config)
                    Match("\t\t\t<Option target=\"" + cfg.Name + "\" />");
                Match("\t\t</Unit>");

            }

            Match("\t</Project>");
            Match("</CodeBlocks_project_file>");
        }
        public override void Parse(Project project, string filename)
        {
            Begin(filename + ".mds");

            string[] matches = Regex("<Combine name=\"(.+)\" fileversion=\"2.0\">");
            project.Name = matches[0];

            matches = Regex("  <Configurations active=\"(.+)\">");
            string active = matches[0];

            // Parse configurations
            while (!Match("  </Configurations>", true))
            {
                matches = Regex("    <Configuration name=\"(.+)\" ctype=\"CombineConfiguration\">");
                Configuration config = new Configuration();
                config.Name = matches[0];
                project.Configuration.Add(matches[0]);

                int i = 0;
                while (!Match("    </Configuration>", true))
                {
                    matches = Regex("      <Entry build=\"True\" name=\"(.+?)\" configuration=\"" + active + "\" />");
                    if (i == project.Package.Count)
                    {
                        Package package = new Package();
                        package.Name = matches[0];
                        project.Package.Add(package);
                    }
                    else
                    {
                        if (project.Package[i].Name != matches[0])
                            throw new FormatException("Package name should be " + project.Package[i] + ", is " + matches[0]);
                    }
                }
            }

            foreach (Package package in project.Package)
            {
                foreach (string name in project.Configuration)
                {
                    Configuration config = new Configuration();
                    config.Name = name;
                    package.Config.Add(config);
                }
            }

            // Parse startup entries
            Match("  <StartMode startupentry=\"" + project.Package[0].Name + "\" single=\"True\">");
            foreach (Package package in project.Package)
            {
                Match("    <Execute type=\"None\" entry=\"" + package.Name + "\" />");
            }
            Match("  </StartMode>");

            // Parse project entries
            Match("  <Entries>");
            foreach (Package package in project.Package)
            {
                matches = Regex("    <Entry filename=\"(.+)\" />");
                /* Pull out directory, but keep the path separators intact (no translation) */
                package.Path = matches[0].Substring(0, Path.GetDirectoryName(matches[0]).Length);
                package.ScriptName = Path.GetFileName(matches[0]);
            }
            Match("  </Entries>");

            Match("</Combine>");

            foreach (Package package in project.Package)
            {
                string pkgfilename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName);
                ParsePackage(project, package, pkgfilename);

                /* SHARPDEV_DEPENDENCY_BUG: Dependencies are set correctly here! */
            #if SHARPDEV_DEPENDENCY_BUG
                Console.WriteLine(package.Name + ": ");
                foreach (Configuration config in package.Config)
                {
                    Console.WriteLine("  " + config.Name + ": " + config.Dependencies.Length);
                }
            #endif
            }
        }