2008-06-07 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / corlib / System / Environment.cs
index 7323df4fd75cab0360d72d63f7d9469d4b7681ba..583f19453a7d630e277db044e394752d65e723dd 100644 (file)
@@ -38,9 +38,13 @@ using System.Runtime.CompilerServices;
 using System.Security;
 using System.Security.Permissions;
 using System.Text;
+using System.Runtime.InteropServices;
 
 namespace System {
 
+#if NET_2_0
+       [ComVisible (true)]
+#endif
 #if NET_2_0
        public static class Environment {
 #else
@@ -59,9 +63,8 @@ namespace System {
                 * Changes which are already detected at runtime, like the addition
                 * of icalls, do not require an increment.
                 */
-               private const int mono_corlib_version = 54;
+               private const int mono_corlib_version = 67;
                
-               [MonoTODO]
                public enum SpecialFolder
                {       // TODO: Determine if these windoze style folder identifiers 
                        //       have unix/linux counterparts
@@ -197,7 +200,7 @@ namespace System {
                public static string StackTrace {
                        [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
                        get {
-                               System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace (1, true);
+                               System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace (0, true);
                                return trace.ToString ();
                        }
                }
@@ -233,7 +236,7 @@ namespace System {
                /// <summary>
                /// Gets a flag indicating whether the process is in interactive mode
                /// </summary>
-               [MonoTODO]
+               [MonoTODO ("Currently always returns false, regardless of interactive state")]
                public static bool UserInteractive {
                        get {
                                return false;
@@ -261,7 +264,7 @@ namespace System {
                /// <summary>
                /// Get the amount of physical memory mapped to process
                /// </summary>
-               [MonoTODO]
+               [MonoTODO ("Currently always returns zero")]
                public static long WorkingSet {
                        [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
                        get { return 0; }
@@ -434,6 +437,48 @@ namespace System {
                        return dir;
                }
 
+               private static string ReadXdgUserDir (string config_dir, string home_dir, 
+                       string key, string fallback)
+               {
+                       string env_path = internalGetEnvironmentVariable (key);
+                       if (env_path != null && env_path != String.Empty) {
+                               return env_path;
+                       }
+
+                       string user_dirs_path = Path.Combine (config_dir, "user-dirs.dirs");
+
+                       if (!File.Exists (user_dirs_path)) {
+                               return Path.Combine (home_dir, fallback);
+                       }
+
+                       try {
+                               using(StreamReader reader = new StreamReader (user_dirs_path)) {
+                                       string line;
+                                       while ((line = reader.ReadLine ()) != null) {
+                                               line = line.Trim ();
+                                               int delim_index = line.IndexOf ('=');
+                        if(delim_index > 8 && line.Substring (0, delim_index) == key) {
+                            string path = line.Substring (delim_index + 1).Trim ('"');
+                            bool relative = false;
+
+                            if (path.StartsWith ("$HOME/")) {
+                                relative = true;
+                                path = path.Substring (6);
+                            } else if (!path.StartsWith ("/")) {
+                                relative = true;
+                            }
+
+                            return relative ? Path.Combine (home_dir, path) : path;
+                        }
+                                       }
+                               }
+                       } catch (FileNotFoundException) {
+                       }
+
+                       return Path.Combine (home_dir, fallback);
+               }
+
+
                // the security runtime (and maybe other parts of corlib) needs the
                // information to initialize themselves before permissions can be checked
                internal static string InternalGetFolderPath (SpecialFolder folder)
@@ -474,8 +519,14 @@ namespace System {
                        case SpecialFolder.Desktop:
 #endif
                        case SpecialFolder.DesktopDirectory:
-                               return Path.Combine (home, "Desktop");
-                       
+                               return ReadXdgUserDir (config, home, "XDG_DESKTOP_DIR", "Desktop");
+
+                       case SpecialFolder.MyMusic:
+                               return ReadXdgUserDir (config, home, "XDG_MUSIC_DIR", "Music");
+
+                       case SpecialFolder.MyPictures:
+                               return ReadXdgUserDir (config, home, "XDG_PICTURES_DIR", "Pictures");
+                               
                        // these simply dont exist on Linux
                        // The spec says if a folder doesnt exist, we
                        // should return ""
@@ -484,8 +535,6 @@ namespace System {
                        case SpecialFolder.SendTo:
                        case SpecialFolder.StartMenu:
                        case SpecialFolder.Startup:
-                       case SpecialFolder.MyMusic:
-                       case SpecialFolder.MyPictures:
                        case SpecialFolder.Templates:
                        case SpecialFolder.Cookies:
                        case SpecialFolder.History:
@@ -509,10 +558,6 @@ namespace System {
                        return GetLogicalDrivesInternal ();
                }
 
-               // FIXME: Anyone using this anywhere ?
-               static internal string GetResourceString (string s) { return String.Empty; }
-
-                
 #if NET_2_0
                public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
                {
@@ -597,7 +642,7 @@ namespace System {
                                if (!IsRunningOnWindows)
                                        return;
                                using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true)) {
-                                       if (value == null || value.Length == 0)
+                                       if (String.IsNullOrEmpty (value))
                                                env.DeleteValue (variable, false);
                                        else
                                                env.SetValue (variable, value);
@@ -607,7 +652,7 @@ namespace System {
                                if (!IsRunningOnWindows)
                                        return;
                                using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.CurrentUser.OpenSubKey ("Environment", true)) {
-                                       if (value == null || value.Length == 0)
+                                       if (String.IsNullOrEmpty (value))
                                                env.DeleteValue (variable, false);
                                        else
                                                env.SetValue (variable, value);
@@ -627,7 +672,7 @@ namespace System {
                        get;                    
                }
 
-               [MonoTODO ("not much documented")]
+               [MonoTODO ("Not implemented")]
                [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode=true)]
                public static void FailFast (string message)
                {