/// <summary> /// Insert in the buffer a text line that can be split. /// </summary> /// <param name="text">The text</param> /// <param name="from">from position in the buffer</param> /// <param name="to">to position in the buffer</param> /// <param name="bInsertSplit">true if splitting must handle, false otherwise</param> private void InsertLineMaybeSplit(SourceText buffer, string text, int from, int to, bool bInsertSplit) { if (bInsertSplit && this.Layout == ColumnsLayout.CobolReferenceFormat) { int crPos = text.LastIndexOf('\r'); int lfPos = text.LastIndexOf('\n'); int crlf = 0; crlf += crPos >= 0 ? 1 : 0; crlf += lfPos >= 0 ? 1 : 0; int lineStartOffset; int lineEndOffset; int lineLen = buffer.GetLineInfo(from, out lineStartOffset, out lineEndOffset); if (((from - lineStartOffset) + (text.Length - crlf)) >= LEGAL_COBOL_LINE_LENGTH) { string lefttext = buffer.GetTextAt(lineStartOffset, from); ICollection <ITextLine> lines = CobolTextLine.CreateCobolLines(this.Layout, -1, ' ', "", lefttext + (crlf > 0 ? text.Substring(0, text.Length - crlf) : text), LEGAL_COBOL_LINE_LENGTH, 65, false); StringWriter sw = new StringWriter(); string sep = ""; foreach (var line in lines) { sw.Write(sep); sw.WriteLine(line.Text); sep = Environment.NewLine; } //We must insert "\r\n" if the target line is empty and the inserted test has one. if ((lineEndOffset == lineStartOffset) && crlf > 0) { sw.Write(Environment.NewLine); } sw.Flush(); text = sw.ToString(); buffer.Insert(text, lineStartOffset, to); } else { buffer.Insert(text, from, to); } } else { buffer.Insert(text, from, to); } }
/// <summary> /// Insert a code in a buffer at given position, and check if line exceed int Cobol ReferenceFormat /// </summary> /// <param name="from">The from position int the buffer</param> /// <param name="to">The to position in the buffer</param> /// <param name="buffer">The target buffer</param> /// <param name="code">The code to insert</param> /// <param name="lineNumber">The current lien number</param> private void GenerateIntoBufferCheckLineExceed(Position from, Position to, SourceText buffer, string code, int lineNumber) { int lineLen = -1; int lineStartOffset = -1; int lineEndOffset = -1; int start = Math.Min(from.Pos, buffer.Size); int end = Math.Min(to.Pos, buffer.Size); if (ExceedLines != null) { ExceedLines.Remove(lineNumber); } lineLen = buffer.GetLineInfo(start, out lineStartOffset, out lineEndOffset); buffer.Insert(code, start, end); int delta = -(end - start) + code.Length; int newLineLen = lineLen + delta; bool newHas73Chars = false; if (newLineLen > LEGAL_COBOL_LINE_LENGTH) { for (int k = LEGAL_COBOL_LINE_LENGTH; k < newLineLen & !newHas73Chars; k++) { newHas73Chars = !Char.IsWhiteSpace(buffer[lineStartOffset + k]); } //Error //Emit an error. if ((newLineLen > MAX_COBOL_LINE_LENGTH) || newHas73Chars) { if (ExceedLines == null) { ExceedLines = new HashSet <int>(); } ExceedLines.Add(lineNumber); } } }
/// <summary> /// Insert a code in a buffer at given position, and check if line exceed int Cobol ReferenceFormat /// </summary> /// <param name="from">The from position int the buffer</param> /// <param name="to">The to position in the buffer</param> /// <param name="buffer">The target buffer</param> /// <param name="code">The code to insert</param> /// <param name="lineNumber">The current lien number</param> private void GenerateIntoBufferCheckLineExceed(Position from, Position to, SourceText buffer, string code, int lineNumber) { //Lines_73_80_Map int start = Math.Min(from.Pos, buffer.Size); int end = Math.Min(to.Pos, buffer.Size); if (this.Layout != ColumnsLayout.CobolReferenceFormat) {//Maybe Free Format buffer.Insert(code, start, end); return; } int lineLen = -1; int lineStartOffset = -1; int lineEndOffset = -1; if (ExceedLines != null) { ExceedLines.Remove(lineNumber); } lineLen = buffer.GetLineInfo(start, out lineStartOffset, out lineEndOffset); if (!Lines_73_80_Flags.Contains(lineNumber)) {//Replace by spaces any characters in columns[73-80] Lines_73_80_Flags.Add(lineNumber); if (lineLen > LEGAL_COBOL_LINE_LENGTH) { int replace_len = lineLen - LEGAL_COBOL_LINE_LENGTH; buffer.Insert(new string(' ', replace_len), LEGAL_COBOL_LINE_LENGTH, lineLen); } } buffer.Insert(code, start, end); int delta = -(end - start) + code.Length; int newLineLen = lineLen + delta; bool newHas73Chars = false; if (newLineLen > LEGAL_COBOL_LINE_LENGTH) { for (int k = LEGAL_COBOL_LINE_LENGTH; k < newLineLen & !newHas73Chars; k++) { char ch = buffer[lineStartOffset + k]; newHas73Chars = !(ch == '\r' || ch == '\n' || Char.IsWhiteSpace(ch)); } //Error //Emit an error. if (newHas73Chars) { if (ExceedLines == null) { ExceedLines = new Dictionary <int, Tuple <int, int> >(); } ExceedLines.Add(lineNumber, new Tuple <int, int>(lineStartOffset, newLineLen)); } else if (newLineLen > MAX_COBOL_LINE_LENGTH) {//Here we know that the line the line exceed with only white characters. ==> Remove extra white characters buffer.Delete(LEGAL_COBOL_LINE_LENGTH, newLineLen); } } //Hanlde Buffer Exceed Map. if (ExceedLines != null && ExceedLines.ContainsKey(lineNumber)) { if (BufferExceedMap == null) { BufferExceedMap = new Dictionary <SourceText, Dictionary <int, List <Position> > >(); } if (!BufferExceedMap.ContainsKey(buffer)) { BufferExceedMap[buffer] = new Dictionary <int, List <Position> >(); } if (!BufferExceedMap[buffer].ContainsKey(lineNumber)) { BufferExceedMap[buffer][lineNumber] = new List <Position>(); } //Add the position at the code added BufferExceedMap[buffer][lineNumber].Add(new Position(start)); //Add the position after the code added BufferExceedMap[buffer][lineNumber].Add(new Position(start + code.Length)); } else {//Remove any line reference in the buffer exceed map. if (BufferExceedMap != null) { if (BufferExceedMap.ContainsKey(buffer)) { if (BufferExceedMap[buffer].ContainsKey(lineNumber)) { BufferExceedMap[buffer].Remove(lineNumber); if (BufferExceedMap[buffer].Count == 0) { BufferExceedMap.Remove(buffer); } } } } } }
/// <summary> /// Append a source buffer at the end of a target buffer /// </summary> /// <param name="dstBuffer"></param> /// <param name="srcBuffer"></param> private void AppendBufferContent(SourceText dstBuffer, SourceText srcBuffer) { if (BufferExceedMap != null) { if (BufferExceedMap.ContainsKey(srcBuffer)) {//Create all start positions in the buffer. //originalPosition keep the original position of the position so that we can calculate //the exceed length, for the minimal spliting. Dictionary <Position, int> originalPositions = new Dictionary <Position, int>(); foreach (var linePos in BufferExceedMap[srcBuffer]) { foreach (var start in linePos.Value) { originalPositions[start] = start.Pos; srcBuffer.AddPosition(start); } } bool bLineStillTooLong = false; //Split each exceeded line based on the right most exceed position. foreach (var linePos in BufferExceedMap[srcBuffer]) { List <Position> splittingPositionStack = new List <Position>(); int lineNumber = linePos.Key; Tuple <int, int> lineStartLength = ExceedLines[lineNumber]; int lineStartPos = lineStartLength.Item1; int lineLength = lineStartLength.Item2; int lastEndOrgPos = lineStartPos + lineLength; int firstSplitablePos = originalPositions[linePos.Value[0]]; int targeSplittColumn = 0; for (int i = linePos.Value.Count - 1; i >= 0; i--) { Position start = linePos.Value[i]; int originalPos = originalPositions[start]; if (IsPlitablePosition(firstSplitablePos, lineLength, originalPos, out targeSplittColumn)) { //we can split here => so check if the rest at the left still exceed //Push this splitting position splittingPositionStack.Add(start); if ((originalPos - lineStartPos) < LEGAL_COBOL_LINE_LENGTH) { //The line is till too long? break; //No ==> Stop splitting this line } } else {//This means that the line will stil too long. bLineStillTooLong = true; } } if (splittingPositionStack.Count > 0) {//This line can be splitted so split it. int rightPos = lineLength; for (int i = splittingPositionStack.Count - 1; i >= 0; i--) { Position start = splittingPositionStack[i]; int originalPos = originalPositions[start]; for (int j = 0; j <= i; j++) { if (IsPlitablePosition(firstSplitablePos, rightPos, originalPos, out targeSplittColumn)) { string pad = new StringBuilder().Append(Environment.NewLine).Append(new string(' ', Math.Abs(targeSplittColumn - lineStartPos))).ToString(); //So break here srcBuffer.Insert(pad, start.Pos, start.Pos); i = j; break; } else { Position jstart = splittingPositionStack[j]; rightPos = originalPositions[jstart]; } } } //Remove it from exceed, if the line has been correctly splitted if (!bLineStillTooLong) { ExceedLines.Remove(lineNumber); } } } } } int pos = dstBuffer.Size; dstBuffer.Insert(srcBuffer, pos, pos); }
/// <summary> /// Append a source buffer at the end of a target buffer /// </summary> /// <param name="dstBuffer"></param> /// <param name="srcBuffer"></param> private static void AppendBufferContent(SourceText dstBuffer, SourceText srcBuffer) { int pos = dstBuffer.Size; dstBuffer.Insert(srcBuffer, pos, pos); }