using System;
using System.Collections;
using System.IO;
using Premake.Tests.Framework;
namespace Premake.Tests.CodeBlocks
{
public class CodeBlocksParser : Parser
{
#region Parser Methods
public override string TargetName
{
get { return "cb-gcc"; }
}
#endregion
#region Workspace Parsing
public override void Parse(Project project, string filename)
{
/* File header */
Begin(filename + ".workspace");
Match("");
Match("");
Match("\t");
Hashtable packageDependencies = new Hashtable();
while (!Match("\t", true))
{
string[] matches = Regex("\t\t");
Package package = new Package();
project.Package.Add(package);
package.Name = Path.GetFileNameWithoutExtension(matches[0]);
package.Path = Path.GetDirectoryName(matches[0]);
package.ScriptName = Path.GetFileName(matches[0]);
ArrayList deps = new ArrayList();
while (!Match("\t\t", true))
{
matches = Regex("\t\t\t");
deps.Add(Path.GetFileNameWithoutExtension(matches[0]));
}
packageDependencies.Add(package, deps.ToArray(typeof(string)));
}
Match("");
foreach (Package package in project.Package)
{
filename = Path.Combine(Path.Combine(project.Path, package.Path), package.ScriptName);
ParseCpp(project, package, filename);
foreach (Configuration cfg in package.Config)
cfg.Dependencies = (string[])packageDependencies[package];
}
}
#endregion
#region C++ Parsing
private void ParseCpp(Project project, Package package, string filename)
{
Begin(filename);
Match("");
Match("");
Match("\t");
Match("\t");
Match("\t\t");
Match("\t\t", true);
Match("\t\t");
Match("\t\t");
package.Language = "c++";
while (!Match("\t\t", true))
{
Configuration config = new Configuration();
package.Config.Add(config);
string[] matches = Regex("\t\t\t");
config.Name = matches[0];
while (!Match("\t\t\t", 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");
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");
config.ObjDir = matches[0];
matches = Regex("\t\t\t\t");
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");
if (config.Kind == "dll")
{
Match("\t\t\t\t");
matches = Regex("\t\t\t\t");
if (matches[0] == "0")
buildFlags.Add("no-import-lib");
}
Match("\t\t\t\t");
while (!Match("\t\t\t\t", true))
{
matches = Regex("\t\t\t\t\t", 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", true);
if (matches != null)
{
incPaths.Add(matches[0]);
}
}
Match("\t\t\t\t");
while (!Match("\t\t\t\t", true))
{
matches = Regex("\t\t\t\t\t", 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", true);
if (matches != null)
{
libPaths.Add(matches[0]);
}
matches = Regex("\t\t\t\t\t", true);
if (matches != null)
{
libs.Add(matches[0]);
}
}
ArrayList resPaths = new ArrayList();
if (Match("\t\t\t\t", true))
{
while (!Match("\t\t\t\t", true))
{
matches = Regex("\t\t\t\t\t");
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", true))
{
string[] matches = Regex("\t\t");
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");
}
else
{
if (Match("\t\t\t", true))
package.Language = "c";
else
Match("\t\t\t", true);
if (!name.EndsWith(".c") && !name.EndsWith(".cpp"))
{
// Match("\t\t\t");
// Match("\t\t\t");
}
}
foreach (Configuration cfg in package.Config)
Match("\t\t\t");
Match("\t\t");
}
Match("\t");
Match("");
}
#endregion
}
}