In class/Microsoft.Build.Tasks/Microsoft.Build.Tasks:
[mono.git] / mcs / class / Microsoft.Build.Tasks / Microsoft.Build.Tasks / CreateCSharpManifestResourceName.cs
index 6e04696e00b2cc1b53fd3f1526d9aceb906ea06f..1a0f7f52ea0c132ecd832bf60dc3198e2b063257 100644 (file)
@@ -29,6 +29,7 @@
 
 using System;
 using System.IO;
+using System.Text;
 using Microsoft.Build.Framework;
 
 namespace Microsoft.Build.Tasks {
@@ -37,22 +38,165 @@ 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 ();
                }
+
        }
 }