//----------------------------------------------------------------------- //----------------------------------------------------------------------- // file="ExpSourceReader.cs" // Project: StgSharp // AuthorGroup: Nitload Space // Copyright (c) Nitload Space. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the “Software”), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and // this permission notice shall be included in all copies // or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED “AS IS”, // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //----------------------------------------------------------------------- //----------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; namespace StgSharp.Script.Express { public class ExpSourceReader { private static Regex _commentSplitter = new Regex( @"(?\S*)\s*--.*", RegexOptions.Compiled ), _multiLineCommentBegin = new Regex( @"(?\S*)\s*\(\*.*", RegexOptions.Compiled ), _multiLineCommentEnd = new Regex( @".*\*\)\s*(?\S*)", RegexOptions.Compiled ); private bool _isReadingMultiLineComment; private IScriptSourceProvider _provider; public ExpSourceReader( IScriptSourceProvider provider ) { _provider = provider; } public string ReadLine() { return _provider.ReadLine(); } public string ReadNoCommentLine() { string line = string.Empty; while( TryReadNoCommentLine( ref line ) ) { } return line; } //Returns true when no usable string returns private bool TryReadNoCommentLine( ref string line ) { int index; string str = _provider.ReadLine(); if( string.IsNullOrEmpty( str ) ) { return true; } if( _isReadingMultiLineComment ) { index = str.LastIndexOf( @"*)" ) + 2; //calc by beginning of code if( index == 1 || index >= str.Length ) { return true; } line = str.SliceAndTrim( index ); _isReadingMultiLineComment = false; return string.IsNullOrEmpty(line); } index = str.IndexOf( @"--" ); if( index != -1 ) { line = str.SliceAndTrim( 0, index ); return string.IsNullOrEmpty(str); } index = str.IndexOf(@"(*"); if (index > 0) { if (TrySliceMultiLineCommentInSingleLine(ref str, index)) { line = str; return string.IsNullOrEmpty(str); } line = str.SliceAndTrim(0,index); _isReadingMultiLineComment = true; return string.IsNullOrEmpty(str); } line = str; return string.IsNullOrEmpty(str); } //returns true when a usable string returns private unsafe bool TrySliceMultiLineCommentInSingleLine(ref string source, int commentBegin) { string origin = source; int index = origin.IndexOf("*)",commentBegin); if (index == -1) { return false; } index += 2; int begin = commentBegin - 1; ReadOnlySpan sourceSpan = origin.AsSpan(); while (begin >= 0 && char.IsWhiteSpace(sourceSpan[begin])) { begin--; } while (index < origin.Length && char.IsWhiteSpace(sourceSpan[index])) { index++; } if (begin == 0 && index == origin.Length - 1) { source = string.Empty; return true; } fixed (char* cPtr = sourceSpan) { int secLength = origin.Length - index; Span o = new Span(cPtr, origin.Length); Span s = o.Slice(0, begin + 1 + secLength); Span sec = o.Slice(index), dest = o.Slice(begin+1, secLength); sec.CopyTo(dest); source = new string(s); } return true; } } }