예제 #1
0
        // Expand directory path - these cases exist:
        //
        // 1. Empty string or nil means return current directory
        // 2. ~ with non-existent HOME directory throws exception
        // 3. ~, ~/ or ~\ which expands to HOME
        // 4. ~foo is left unexpanded
        // 5. Expand to full path if path is a relative path
        //
        // No attempt is made to determine whether the path is valid or not
        // Returned path is always canonicalized to forward slashes

        private static MutableString /*!*/ ExpandPath(RubyContext /*!*/ context, MutableString /*!*/ path)
        {
            PlatformAdaptationLayer pal = context.DomainManager.Platform;
            int length = path.Length;

            try {
                if (path == null || length == 0)
                {
                    return(Glob.CanonicalizePath(MutableString.Create(Directory.GetCurrentDirectory())));
                }

                if (length == 1 && path.GetChar(0) == '~')
                {
                    return(Glob.CanonicalizePath(MutableString.Create(Path.GetFullPath(pal.GetEnvironmentVariable("HOME")))));
                }

                if (path.GetChar(0) == '~' && (path.GetChar(1) == Path.DirectorySeparatorChar || path.GetChar(1) == Path.AltDirectorySeparatorChar))
                {
                    string homeDirectory = pal.GetEnvironmentVariable("HOME");
                    return(Glob.CanonicalizePath(length < 3 ? MutableString.Create(homeDirectory) : MutableString.Create(Path.Combine(homeDirectory, path.GetSlice(2).ConvertToString()))));
                }
                else
                {
                    return(Glob.CanonicalizePath(MutableString.Create(Path.GetFullPath(path.ConvertToString()))));
                }
            } catch (Exception e) {
                // Re-throw exception as a reasonable Ruby exception
                throw new Errno.InvalidError(path.ConvertToString(), e);
            }
        }
예제 #2
0
        internal static IEnumerable <char> /*!*/ ExpandRanges(MutableString /*!*/ str, int start, int end, bool infinite)
        {
            int  rangeMax  = -1;
            char c         = '\0';
            int  i         = start;
            char lookahead = str.GetChar(start);

            while (true)
            {
                if (c < rangeMax)
                {
                    // next character of the current range:
                    c++;
                }
                else if (i < end)
                {
                    c = lookahead;
                    i++;
                    lookahead = (i < end) ? str.GetChar(i) : '\0';
                    if (lookahead == '-' && i + 1 < end)
                    {
                        // range:
                        rangeMax  = str.GetChar(i + 1);
                        i        += 2;
                        lookahead = (i < end) ? str.GetChar(i) : '\0';

                        if (c > rangeMax)
                        {
                            continue;
                        }
                    }
                    else
                    {
                        rangeMax = -1;
                    }
                }
                else
                {
                    break;
                }

                yield return(c);
            }

            if (infinite)
            {
                while (true)
                {
                    yield return(c);
                }
            }
        }
예제 #3
0
        private static MutableString /*!*/ TrimTrailingSlashes(MutableString /*!*/ path)
        {
            int offset = path.Length - 1;

            while (offset > 0)
            {
                if (path.GetChar(offset) != '/' && path.GetChar(offset) != '\\')
                {
                    break;
                }
                --offset;
            }
            return(path.GetSlice(0, offset + 1));
        }
예제 #4
0
        private static void AppendDirectoryName(MutableString /*!*/ result, MutableString /*!*/ name)
        {
            int resultLength = result.GetCharCount();

            int i;

            for (i = resultLength - 1; i >= 0; i--)
            {
                if (!IsDirectorySeparator(result.GetChar(i)))
                {
                    break;
                }
            }

            if (i == resultLength - 1)
            {
                if (!IsDirectorySeparator(name.GetFirstChar()))
                {
                    result.Append(DirectorySeparatorChar);
                }
                result.Append(name);
            }
            else if (IsDirectorySeparator(name.GetFirstChar()))
            {
                result.Replace(i + 1, resultLength - i - 1, name);
            }
            else
            {
                result.Append(name);
            }
        }
예제 #5
0
        public static char Create(RubyClass /*!*/ self, [DefaultProtocol] MutableString /*!*/ str)
        {
            if (str.IsEmpty)
            {
                throw EmptyError("string");
            }

            return(str.GetChar(0));
        }
예제 #6
0
        public static MutableString /*!*/ Basename(RubyClass /*!*/ self,
                                                   [DefaultProtocol, NotNull] MutableString /*!*/ path, [DefaultProtocol, NotNull, Optional] MutableString extensionFilter)
        {
            if (path.IsEmpty)
            {
                return(path);
            }

            MutableString trimmedPath = TrimTrailingSlashes(path);

            // Special cases of drive letters C:\\ or C:/
            if (trimmedPath.Length == 2)
            {
                if (Char.IsLetter(trimmedPath.GetChar(0)) && trimmedPath.GetChar(1) == ':')
                {
                    var result = (path.Length > 2 ? MutableString.Create(path.GetChar(2).ToString()) : MutableString.CreateMutable());
                    return(result.TaintBy(path));
                }
            }

            string trimmedPathAsString = trimmedPath.ConvertToString();

            if (trimmedPathAsString == "/")
            {
                return(trimmedPath);
            }

            string filename = Path.GetFileName(trimmedPath.ConvertToString());

            // Handle UNC host names correctly
            string root = Path.GetPathRoot(trimmedPath.ConvertToString());

            if (MutableString.IsNullOrEmpty(extensionFilter))
            {
                return(MutableString.Create(trimmedPathAsString == root ? root : filename));
            }

            string fileExtension = Path.GetExtension(filename);
            string basename      = Path.GetFileNameWithoutExtension(filename);

            string strResult = WildcardExtensionMatch(fileExtension, extensionFilter.ConvertToString()) ? basename : filename;

            return(Glob.CanonicalizePath(MutableString.Create(strResult)).TaintBy(path));
        }
예제 #7
0
        internal static MutableString /*!*/ AppendEscapeForwardSlash(MutableString /*!*/ result, MutableString /*!*/ pattern)
        {
            int first = 0;
            int i     = SkipToUnescapedForwardSlash(pattern, 0);

            while (i >= 0)
            {
                Debug.Assert(i < pattern.Length);
                Debug.Assert(pattern.GetChar(i) == '/' && (i == 0 || pattern.GetChar(i - 1) != '\\'));

                result.Append(pattern, first, i - first);
                result.Append('\\');
                first = i; // include forward slash in the next append
                i     = SkipToUnescapedForwardSlash(pattern, i + 1);
            }

            result.Append(pattern, first, pattern.Length - first);
            return(result);
        }
예제 #8
0
파일: Glob.cs 프로젝트: gaybro8777/ironruby
 public static MutableString /*!*/ CanonicalizePath(MutableString /*!*/ path)
 {
     for (int i = 0; i < path.Length; i++)
     {
         if (path.GetChar(i) == '\\')
         {
             path.SetChar(i, '/');
         }
     }
     return(path);
 }
예제 #9
0
        private static int SkipToUnescapedForwardSlash(MutableString /*!*/ pattern, int patternLength, int i)
        {
            while (i < patternLength)
            {
                i = pattern.IndexOf('/', i);
                if (i <= 0)
                {
                    return(i);
                }

                if (pattern.GetChar(i - 1) != '\\')
                {
                    return(i);
                }

                i++;
            }
            return(-1);
        }
예제 #10
0
파일: IO.cs 프로젝트: gaybro8777/ironruby
        public MutableString ReadLine(MutableString separator)
        {
            AssertOpenedForReading();

            int c = ReadByteNormalizeEoln();

            if (c == -1)
            {
                return(null);
            }

            int           separatorOffset = 0;
            MutableString result          = MutableString.CreateMutable();

            do
            {
                result.Append((char)c);

                if (separator != null && c == separator.GetChar(separatorOffset))
                {
                    if (separatorOffset == separator.Length - 1)
                    {
                        break;
                    }
                    separatorOffset++;
                }
                else if (separatorOffset > 0)
                {
                    separatorOffset = 0;
                }

                c = ReadByteNormalizeEoln();
            } while (c != -1);

            return(result);
        }
예제 #11
0
        internal static RubyRegexOptions StringToRegexEncoding(MutableString encoding)
        {
            if (MutableString.IsNullOrEmpty(encoding))
            {
                return(RubyRegexOptions.NONE);
            }

            switch (encoding.GetChar(0))
            {
            case 'N':
            case 'n': return(RubyRegexOptions.FIXED);

            case 'E':
            case 'e': return(RubyRegexOptions.EUC);

            case 'S':
            case 's': return(RubyRegexOptions.SJIS);

            case 'U':
            case 'u': return(RubyRegexOptions.UTF8);
            }

            return(RubyRegexOptions.NONE);
        }
예제 #12
0
        public static CharacterMap /*!*/ Create(MutableString /*!*/ from, MutableString /*!*/ to)
        {
            Debug.Assert(!from.IsEmpty);

            int  fromLength   = from.GetCharCount();
            bool complemental = from.StartsWith('^') && fromLength > 1;

            // TODO: kcodings
            // TODO: surrogates
            // TODO: max - min > threshold

            int min, max;

            if (from.DetectByteCharacters())
            {
                min = 0;
                max = 255;
            }
            else
            {
                min = Int32.MaxValue;
                max = -1;
                for (int i = (complemental ? 1 : 0); i < fromLength; i++)
                {
                    int c = from.GetChar(i);
                    if (c < min)
                    {
                        min = c;
                    }
                    if (c > max)
                    {
                        max = c;
                    }
                }
            }

            BitArray map;

            char[] image;

            if (complemental || to.IsEmpty)
            {
                image = null;
                map   = MakeBitmap(from, fromLength, complemental, min, max);
            }
            else
            {
                map   = null;
                image = new char[max - min + 1];

                // no need to initialize the array:
                Debug.Assert(Unmapped == 0);

                bool needMap = false;
                var  toEnum  = ExpandRanges(to, 0, to.GetCharCount(), true).GetEnumerator();
                foreach (var f in ExpandRanges(from, 0, fromLength, false))
                {
                    toEnum.MoveNext();
                    needMap |= (image[f - min] = toEnum.Current) == Unmapped;
                }

                if (needMap)
                {
                    map = MakeBitmap(from, fromLength, false, min, max);
                }
            }

            return(new CharacterMap(map, image, complemental ? to.GetLastChar() : -1, complemental, min, max));
        }
예제 #13
0
파일: Glob.cs 프로젝트: gaybro8777/ironruby
            internal void DoGlob(string /*!*/ baseDirectory, int position, bool isPreviousDoubleStar)
            {
                if (!_pal.DirectoryExists(baseDirectory))
                {
                    return;
                }

                bool   containsWildcard;
                int    patternEnd        = FindNextSeparator(position, true, out containsWildcard);
                bool   isLastPathSegment = (patternEnd == _pattern.Length);
                string dirSegment        = _pattern.Substring(position, patternEnd - position);

                if (!isLastPathSegment)
                {
                    patternEnd++;
                }

                if (!containsWildcard)
                {
                    string path = baseDirectory + "/" + dirSegment;
                    TestPath(path, patternEnd, isLastPathSegment);
                    return;
                }

                MutableString mPattern   = MutableString.Create(dirSegment);
                bool          doubleStar = dirSegment.Equals("**");

                if (doubleStar && !isPreviousDoubleStar)
                {
                    DoGlob(baseDirectory, patternEnd, true);
                }

                string[] files = Directory.GetFileSystemEntries(baseDirectory);
                foreach (string file in files)
                {
                    string objectName = Path.GetFileName(file);
                    if (FnMatch(mPattern, MutableString.Create(objectName), _flags))
                    {
                        TestPath(file, patternEnd, isLastPathSegment);
                        if (doubleStar)
                        {
                            DoGlob(file, position, true);
                        }
                    }
                }
                if (isLastPathSegment && (_flags & Constants.FNM_DOTMATCH) != 0 || mPattern.GetChar(0) == '.')
                {
                    if (FnMatch(mPattern, MutableString.Create("."), _flags))
                    {
                        string directory = baseDirectory + "/.";
                        if (_dirOnly)
                        {
                            directory += '/';
                        }
                        TestPath(directory, patternEnd, true);
                    }
                    if (FnMatch(mPattern, MutableString.Create(".."), _flags))
                    {
                        string directory = baseDirectory + "/..";
                        if (_dirOnly)
                        {
                            directory += '/';
                        }
                        TestPath(directory, patternEnd, true);
                    }
                }
            }