Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
VariablePath.cs323 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Diagnostics;5using System.Diagnostics.CodeAnalysis;6 7namespace System.Management.Automation8{9    [Flags]10    internal enum VariablePathFlags11    {12        None = 0x00,13        Local = 0x01,14        Script = 0x02,15        Global = 0x04,16        Private = 0x08,17        Variable = 0x10,18        Function = 0x20,19        DriveQualified = 0x40,20        Unqualified = 0x80,21 22        // If any of these bits are set, the path does not represent an unscoped variable.23        UnscopedVariableMask = Local | Script | Global | Private | Function | DriveQualified,24    }25 26    /// <summary>27    /// A variable path that you can query the scope and drive of the variable reference.28    /// </summary>29    public class VariablePath30    {31        #region private data32 33        /// <summary>34        /// Stores the path that was passed to the constructor.35        /// </summary>36        private string _userPath;37 38        /// <summary>39        /// The name of the variable without any scope or drive.40        /// </summary>41        private string _unqualifiedPath;42 43        /// <summary>44        /// Store flags about the path, such as private/global/local/etc.45        /// </summary>46        private VariablePathFlags _flags = VariablePathFlags.None;47 48        #endregion private data49 50        #region Constructor51 52        /// <summary>53        /// Private constructor for CloneAndSetLocal().54        /// </summary>55        private VariablePath()56        {57        }58 59        /// <summary>60        /// Constructs a variable path.61        /// </summary>62        /// <param name="path">The path to parse.</param>63        /// <exception cref="ArgumentNullException">64        /// If <paramref name="path"/> is null.65        /// </exception>66        public VariablePath(string path)67            : this(path, VariablePathFlags.None)68        {69        }70 71        /// <summary>72        /// Constructs a scoped item lookup path.73        /// </summary>74        /// <param name="path">The path to parse.</param>75        /// <param name="knownFlags">76        /// These flags for anything known about the path (such as, is it a function) before77        /// being scanned.78        /// </param>79        /// <exception cref="ArgumentNullException">80        /// If <paramref name="path"/> is null.81        /// </exception>82        internal VariablePath(string path, VariablePathFlags knownFlags)83        {84            if (string.IsNullOrEmpty(path))85            {86                throw PSTraceSource.NewArgumentException(nameof(path));87            }88 89            _userPath = path;90            _flags = knownFlags;91 92            string candidateScope = null;93            string candidateScopeUpper = null;94            VariablePathFlags candidateFlags = VariablePathFlags.Unqualified;95 96            int currentCharIndex = 0;97            int lastScannedColon = -1;98 99        scanScope:100            switch (path[0])101            {102                case 'g':103                case 'G':104                    candidateScope = "lobal";105                    candidateScopeUpper = "LOBAL";106                    candidateFlags = VariablePathFlags.Global;107                    break;108                case 'l':109                case 'L':110                    candidateScope = "ocal";111                    candidateScopeUpper = "OCAL";112                    candidateFlags = VariablePathFlags.Local;113                    break;114                case 'p':115                case 'P':116                    candidateScope = "rivate";117                    candidateScopeUpper = "RIVATE";118                    candidateFlags = VariablePathFlags.Private;119                    break;120                case 's':121                case 'S':122                    candidateScope = "cript";123                    candidateScopeUpper = "CRIPT";124                    candidateFlags = VariablePathFlags.Script;125                    break;126                case 'v':127                case 'V':128                    if (knownFlags == VariablePathFlags.None)129                    {130                        // If we see 'variable:', our namespaceId will be empty, and131                        // we'll also need to scan for the scope again.132                        candidateScope = "ariable";133                        candidateScopeUpper = "ARIABLE";134                        candidateFlags = VariablePathFlags.Variable;135                    }136 137                    break;138            }139 140            if (candidateScope != null)141            {142                currentCharIndex += 1; // First character already matched.143                int j;144                for (j = 0; currentCharIndex < path.Length && j < candidateScope.Length; ++j, ++currentCharIndex)145                {146                    if (path[currentCharIndex] != candidateScope[j] && path[currentCharIndex] != candidateScopeUpper[j])147                    {148                        break;149                    }150                }151 152                if (j == candidateScope.Length &&153                    currentCharIndex < path.Length &&154                    path[currentCharIndex] == ':')155                {156                    if (_flags == VariablePathFlags.None)157                    {158                        _flags = VariablePathFlags.Variable;159                    }160 161                    _flags |= candidateFlags;162                    lastScannedColon = currentCharIndex;163                    currentCharIndex += 1;164 165                    // If saw 'variable:', we need to look for a scope after 'variable:'.166                    if (candidateFlags == VariablePathFlags.Variable)167                    {168                        knownFlags = VariablePathFlags.Variable;169                        candidateScope = candidateScopeUpper = null;170                        candidateFlags = VariablePathFlags.None;171                        goto scanScope;172                    }173                }174            }175 176            if (_flags == VariablePathFlags.None)177            {178                lastScannedColon = path.IndexOf(':', currentCharIndex);179                // No colon, or a colon as the first character means we have180                // a simple variable, otherwise it's a drive.181                if (lastScannedColon > 0)182                {183                    _flags = VariablePathFlags.DriveQualified;184                }185            }186 187            if (lastScannedColon == -1)188            {189                _unqualifiedPath = _userPath;190            }191            else192            {193                _unqualifiedPath = _userPath.Substring(lastScannedColon + 1);194            }195 196            if (_flags == VariablePathFlags.None)197            {198                _flags = VariablePathFlags.Unqualified | VariablePathFlags.Variable;199            }200        }201 202        internal VariablePath CloneAndSetLocal()203        {204            Debug.Assert(IsUnscopedVariable, "Special method to clone, input must be unqualified");205 206            VariablePath result = new VariablePath();207            result._userPath = _userPath;208            result._unqualifiedPath = _unqualifiedPath;209            result._flags = VariablePathFlags.Local | VariablePathFlags.Variable;210            return result;211        }212 213        #endregion Constructor214 215        #region data accessors216 217        /// <summary>218        /// Gets the full path including any possibly specified scope and/or drive name.219        /// </summary>220        public string UserPath { get { return _userPath; } }221 222        /// <summary>223        /// Returns true if the path explicitly specifies 'global:'.224        /// </summary>225        public bool IsGlobal { get { return (_flags & VariablePathFlags.Global) != 0; } }226 227        /// <summary>228        /// Returns true if the path explicitly specifies 'local:'.229        /// </summary>230        public bool IsLocal { get { return (_flags & VariablePathFlags.Local) != 0; } }231 232        /// <summary>233        /// Returns true if the path explicitly specifies 'private:'.234        /// </summary>235        public bool IsPrivate { get { return (_flags & VariablePathFlags.Private) != 0; } }236 237        /// <summary>238        /// Returns true if the path explicitly specifies 'script:'.239        /// </summary>240        public bool IsScript { get { return (_flags & VariablePathFlags.Script) != 0; } }241 242        /// <summary>243        /// Returns true if the path specifies no drive or scope qualifiers.244        /// </summary>245        public bool IsUnqualified { get { return (_flags & VariablePathFlags.Unqualified) != 0; } }246 247        /// <summary>248        /// Returns true if the path specifies a variable path with no scope qualifiers.249        /// </summary>250        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Unscoped")]251        public bool IsUnscopedVariable { get { return ((_flags & VariablePathFlags.UnscopedVariableMask) == 0); } }252 253        /// <summary>254        /// Returns true if the path defines a variable.255        /// </summary>256        public bool IsVariable { get { return (_flags & VariablePathFlags.Variable) != 0; } }257 258        /// <summary>259        /// Returns true if the path defines a function.260        /// </summary>261        internal bool IsFunction { get { return (_flags & VariablePathFlags.Function) != 0; } }262 263        /// <summary>264        /// Returns true if the path specifies a drive other than the variable drive.265        /// </summary>266        public bool IsDriveQualified { get { return (_flags & VariablePathFlags.DriveQualified) != 0; } }267 268        /// <summary>269        /// The drive name, or null if the path is for a variable.270        /// It may also be null for some functions (specifically if this is a FunctionScopedItemLookupPath.)271        /// </summary>272        public string DriveName273        {274            get275            {276                if (!IsDriveQualified)277                {278                    return null;279                }280 281                // The drive name is asked for infrequently.  Lots of VariablePath282                // objects are created, so rather than allocate an extra string that will283                // always be null, just compute the drive name on demand.284                return _userPath.Substring(0, _userPath.IndexOf(':'));285            }286        }287 288        /// <summary>289        /// Gets the namespace specific string.290        /// </summary>291        internal string UnqualifiedPath292        {293            get { return _unqualifiedPath; }294        }295 296        /// <summary>297        /// Return the drive qualified name, if any drive specified, otherwise the simple variable name.298        /// </summary>299        internal string QualifiedName300        {301            get { return IsDriveQualified ? _userPath : _unqualifiedPath; }302        }303 304        #endregion data accessors305 306        /// <summary>307        /// Helpful for debugging.308        /// </summary>309        public override string ToString()310        {311            return _userPath;312        }313    }314 315    internal class FunctionLookupPath : VariablePath316    {317        internal FunctionLookupPath(string path)318            : base(path, VariablePathFlags.Function | VariablePathFlags.Unqualified)319        {320        }321    }322}323