using System;
using System.IO;
+using System.Text;
using Microsoft.Build.Framework;
namespace Microsoft.Build.Tasks {
public CreateCSharpManifestResourceName ()
{
}
+
+ protected override bool IsSourceFile (string fileName)
+ {
+ return Path.GetExtension (fileName).ToLower () == ".cs";
+ }
- [MonoTODO]
protected override string CreateManifestName (string fileName,
string linkFileName,
string rootNamespace,
string dependentUponFileName,
Stream binaryStream)
{
- throw new NotImplementedException ();
+ string filename_to_use = String.IsNullOrEmpty (linkFileName) ? fileName : linkFileName;
+ if (String.IsNullOrEmpty (dependentUponFileName) || binaryStream == null)
+ return GetResourceIdFromFileName (filename_to_use, rootNamespace);
+
+ string ns = null;
+ string classname = null;
+
+ using (StreamReader rdr = new StreamReader (binaryStream)) {
+ int numopen = 0;
+ while (true) {
+ string tok = GetNextToken (rdr);
+ if (tok == null)
+ break;
+
+ if (tok == "@") {
+ //Handle @namespace, @class
+ GetNextToken (rdr);
+ continue;
+ }
+
+ if (String.Compare (tok, "namespace", false) == 0)
+ ns = GetNextToken (rdr);
+
+ if (tok == "{")
+ numopen ++;
+
+ if (tok == "}") {
+ numopen --;
+ if (numopen == 0)
+ ns = String.Empty;
+ }
+
+ if (tok == "class") {
+ classname = GetNextToken (rdr);
+ break;
+ }
+ }
+
+ if (classname == null)
+ return GetResourceIdFromFileName (filename_to_use, rootNamespace);
+
+ string culture, extn, only_filename;
+ if (AssignCulture.TrySplitResourceName (filename_to_use, out only_filename, out culture, out extn))
+ extn = "." + culture;
+ else
+ extn = String.Empty;
+
+ if (ns == null)
+ return classname + extn;
+ else
+ return ns + '.' + classname + extn;
+ }
}
-
- [MonoTODO]
- protected override bool IsSourceFile (string fileName)
+
+ /* Special parser for C# files
+ * Assumes that the file is compilable
+ * skips comments,
+ * skips strings "foo",
+ * skips anything after a # , eg. #region, #if
+ * Won't handle #if false etc kinda blocks*/
+ static string GetNextToken (StreamReader sr)
{
- throw new NotImplementedException ();
+ StringBuilder sb = new StringBuilder ();
+
+ while (true) {
+ int c = sr.Peek ();
+ if (c == -1)
+ return null;
+
+ if (c == '\r' || c == '\n') {
+ sr.ReadLine ();
+ if (sb.Length > 0)
+ break;
+
+ continue;
+ }
+
+ if (c == '/') {
+ sr.Read ();
+
+ if (sr.Peek () == '*') {
+ /* multi-line comment */
+ sr.Read ();
+
+ while (true) {
+ int n = sr.Read ();
+ if (n == -1)
+ break;
+ if (n != '*')
+ continue;
+
+ if (sr.Peek () == '/') {
+ /* End of multi-line comment */
+ if (sb.Length > 0) {
+ sr.Read ();
+ return sb.ToString ();
+ }
+ break;
+ }
+ }
+ } else if (sr.Peek () == '/') {
+ //Single line comment, skip the rest of the line
+ sr.ReadLine ();
+ continue;
+ }
+ } else if (c == '"') {
+ /* String "foo" */
+ sr.Read ();
+ while (true) {
+ int n = sr.Peek ();
+ if (n == '\r' || n == '\n' || n == -1)
+ throw new Exception ("String literal not closed");
+
+ if (n == '"') {
+ /* end of string */
+ if (sb.Length > 0) {
+ sr.Read ();
+ return sb.ToString ();
+ }
+
+ break;
+ }
+ sr.Read ();
+ }
+ } else if (c == '#') {
+ //skip rest of the line
+ sr.ReadLine ();
+ } else {
+ if (Char.IsLetterOrDigit ((char) c) || c == '_' || c == '.') {
+ sb.Append ((char) c);
+ } else {
+ if (sb.Length > 0)
+ break;
+
+ if (c != ' ' && c != '\t') {
+ sr.Read ();
+ return ((char) c).ToString ();
+ }
+ }
+ }
+
+ sr.Read ();
+ }
+
+ return sb.ToString ();
}
+
}
}