singrdk/base/Applications/Seditor/SEditor.cs

1646 lines
79 KiB
C#
Raw Normal View History

2008-11-17 18:29:00 -05:00
// ----------------------------------------------------------------------------
2008-03-05 09:52:00 -05:00
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
2008-11-17 18:29:00 -05:00
// ----------------------------------------------------------------------------
2008-03-05 09:52:00 -05:00
using DirectoryService.Utils;
using FileSystem.Utils;
using System;
using System.Collections;
using System.Text;
using System.Text.RegularExpressions;
using System.ParseNumbers;
using Microsoft.Singularity;
using System.IO;
using System.GC;
using System.Runtime.Remoting;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Diagnostics;
using Microsoft.SingSharp;
using Microsoft.Singularity.Directory;
using Microsoft.Singularity.V1.Services;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.FileSystem;
using Microsoft.Singularity.Channels;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
namespace Microsoft.Singularity.Applications
{
[ConsoleCategory(HelpMessage="Stream Editor", DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
[StringParameter( "filename", Mandatory=true, Position=0, HelpMessage="Name of file.")]
internal string fileName;
reflective internal Parameters();
internal int AppMain() {
SEditor.AppMain(this);
return 0;
}
}
public class SEditor
{
internal static void AppMain(Parameters! config)
{
// constants
string EditorName = "SEditor";
int szLineCount = 0;
int nIndex = 0;
//FOR DEBUG
// Console.WriteLine("Number of cmd line params = {0}", args.Length);
// FOR DEBUG
// Console.WriteLine("args[1] is {0}", args[1]);
string filename = config.fileName;
string szSrcLine;
ArrayList szContents = new ArrayList();
if (File.Exists(filename)) {
FileStream fsInput = new FileStream(filename, FileMode.Open, FileAccess.Read);
StreamReader srInput = new StreamReader(fsInput);
while ((szSrcLine = srInput.ReadLine()) != null) {
szContents.Add(szSrcLine);
// FOR DEBUG
// Console.WriteLine("{0}", szSrcLine);
// Console.ReadLine();
// END DEBUG
}
srInput.Close();
fsInput.Close();
// Display number of lines loaded
szLineCount = szContents.Count;
Console.WriteLine("* Number of lines read from {0} was {1}", filename, szLineCount);
// FOR DEBUG ONLY: display contents of file
// for (nIndex = 0; nIndex < szContents.Count; nIndex++) {
// write line to console with numbering
// Console.WriteLine("{0}: {1}", (nIndex + 1), szContents[nIndex]);
// }
}
else if (System.IO.Directory.Exists(filename)) { // check that it's not a directory
Console.WriteLine("Exiting: {0} is a directory.", filename);
Console.WriteLine("Syntax: {0} filename", EditorName);
return;
}
else { // not a directory, but file doesn't exist, so create it
Console.WriteLine("* Creating new file.");
}
// Command parser - this is the main program loop
Parser(szContents, nIndex, filename);
} // end Main
// Parse incoming commands
static void Parser(ArrayList szArray, int pIndex, string InputFileName)
{
//FOR DEBUG
// Console.WriteLine("* Parser called.");
// Console.WriteLine("* Current line index is {0}," pIndex);
Console.Write("* ");
string ParserInput;
string ParserInputFirstChar;
string BackupFileName = "";
int tempIndex = 0;
ArrayList tempArray = new ArrayList();
bool IsTextUpdated = false;
int tempSize = 0;
// build proper backup file name - look for extension if it exists, and replace it with (or add to) ".bak"
if (Path.HasExtension(InputFileName) && (Path.GetExtension(InputFileName) != ".bak")) { // has an extension other than .bak
BackupFileName = Path.ChangeExtension(InputFileName, ".bak");
}
else if (Path.HasExtension(InputFileName) && (Path.GetExtension(InputFileName) == ".bak")) { // .bak already in use, use something else
Console.WriteLine("{0} ends in .bak - using .ba2 for backup files...", InputFileName);
Console.Write("* ");
BackupFileName = Path.ChangeExtension(InputFileName, ".ba2");
}
else { // no extension, so add one
BackupFileName = InputFileName + ".bak";
}
while (((ParserInput = GetConsoleInput()) != "q") && (ParserInput != "Q") && (ParserInput != null)) {
if (ParserInput != "") {
//FOR DEBUG
//Console.WriteLine("* Input was {0}", ParserInput);
//Console.Write("* ");
// ParserInputFirstChar = Convert.ToString(ParserInput[0]);
ParserInputFirstChar = ParserInput[0].ToString();
}
else {
Console.Write("* ");
continue;
}
// Simple switch based parsing of commands
switch (ParserInputFirstChar) {
case "h":
case "H":
case "?":
Console.WriteLine("* Commands available are:");
Console.WriteLine("* ?, (h | H) - prints this message");
Console.WriteLine("* [number] - start editing at line [number]");
Console.WriteLine("* (a | A) - append lines at end of file");
Console.WriteLine("* (c | C)[num1],[num2],[destnum] - copy lines from num1 to num2 to dest num");
Console.WriteLine("* (d | D); (d | D)[num]; (d | D)[num1],[num2] - delete current line, ");
Console.WriteLine("* line at num, lines from num1 to num2");
Console.WriteLine("* (e | E) - exit, saving changes");
Console.WriteLine("* (i | I); (i | I)[num] - insert line above current line, or above line num");
Console.WriteLine("* (l | L); (l | L)[num]; (l | L)[num1],[num2] - list the whole file, ");
Console.WriteLine("* list the line at num, list the lines from num1 to num2");
Console.WriteLine("* (m | M)[num1],[num2],[destnum] - move lines from num1 to num2 to dest num");
Console.WriteLine("* (n | N) - print current line number (location in file)");
Console.WriteLine("* (p | P) - same as l, only displays one page at a time.");
Console.WriteLine("* (q | Q) - quit, saving no changes since last write");
Console.WriteLine("* (r | R)[num1],([num2] | ?),[searchstr]^[replacestr] - replace");
Console.WriteLine("* searchstr with replacestr. If ? is used as second param, sub is prompted");
Console.WriteLine("* (s | S)[num1],([num2] | ?),[searchstr] - search for searchstr. ");
Console.WriteLine("* If ? is used as second param, occurrence is displayed with prompt");
Console.WriteLine("* until accepted with y, Y, or newline.");
Console.WriteLine("* (t | T)[num],[filename] - insert contents of filename above line num.");
Console.WriteLine("* (w | W) - write contents of memory to filename. Original contents will be");
Console.WriteLine("* backed up as for exit command.");
break;
case "a":
case "A":
// FOR DEBUG
// Console.WriteLine("* Input was for AppendAtEOF()");
tempSize = szArray.Count;
tempArray = AppendAtEOF(szArray);
if (tempArray.Count > tempSize) { // array has grown, so assume text modified
IsTextUpdated = true;
}
szArray = tempArray;
pIndex = tempArray.Count; // move line pointer to the end of the file
break;
case "c":
case "C":
// FOR DEBUG
// Console.WriteLine("* Input was for CopyLines()");
if (szArray.Count == 0) {
Console.WriteLine("* No text available to copy - new empty file");
}
else {
tempArray = CopyLines(szArray, ParserInput, pIndex);
if (szArray.Count != pIndex) { // assume the array has changed, ergo text modified
IsTextUpdated = true;
}
szArray = tempArray;
}
break;
case "d":
case "D":
// FOR DEBUG
// Console.WriteLine("* Input was for DeleteLines()");
if (szArray.Count == 0) {
Console.WriteLine("* No text available to delete - new empty file");
}
else {
tempArray = DeleteLines(szArray, ParserInput, pIndex);
if (szArray.Count != pIndex) { // assume the array has changed, ergo text modified
IsTextUpdated = true;
}
szArray = tempArray;
tempIndex = szArray.Count;
if (tempIndex < pIndex) { // deletion has reduced line count below pIndex - reset the pointer
pIndex = tempIndex;
}
}
break;
case "e":
case "E":
// FOR DEBUG
// Console.WriteLine("* Input was for Exit ...");
if (szArray.Count == 0) {
Console.WriteLine("* No text to save, exiting without write.");
return;
}
else {
Console.WriteLine("* Exiting....");
EditorWrite(szArray, InputFileName, BackupFileName);
return;
}
break;
case "i":
case "I":
// FOR DEBUG
// Console.WriteLine("* Input was for InsertAtLine()");
// Insert is a special case. The line pointer for the file needs to move
// to the point of insertion if an argument is given, so we will parse that
// here and pass the results, since we need to get the updated array back.
if (szArray.Count == 0) {
Console.WriteLine("* No lines to insert above - new empty file");
}
else {
Regex shortr = new Regex(@"^[iI](?<1>\d+)", RegexOptions.Compiled);
Match shortm;
shortm = shortr.Match(ParserInput);
Group shortg1 = shortm.Groups[1];
if ((ParserInput == "i") || (ParserInput == "i")) { //insert above current line pointer pIndex
InsertAtLine(szArray, pIndex);
IsTextUpdated = true;
}
else if (shortm.Success) { // we have one line number
//FOR DEBUG
//Console.WriteLine("Line number {0}", shortm.Groups[1]);
// write out line
Capture shortc1 = shortg1.Captures[0];
// tempIndex = Convert.ToInt32(shortc1.Value);
tempIndex = Int32.Parse(shortc1.Value);
if (tempIndex >= 1 && tempIndex <= szArray.Count) { // check for line numbers in range of file
pIndex = tempIndex; // update pIndex
InsertAtLine(szArray, pIndex);
IsTextUpdated = true;
}
else {
Console.WriteLine("* Line number {0} out of range. File length is {1}", tempIndex, szArray.Count);
}
}
else {
Console.WriteLine("Invalid match");
}
}
break;
case "l":
case "L":
// FOR DEBUG
//Console.WriteLine("* Input was for ListText()");
tempIndex = ListText(szArray, ParserInput, pIndex);
if (tempIndex != -1) { // update current line number if list command moved the pointer
pIndex = tempIndex;
}
break;
case "m":
case "M":
//FOR DEBUG
//Console.WriteLine("* Input was for MoveLines()");
if (szArray.Count == 0) {
Console.WriteLine("* No text available to move - new empty file");
}
else {
tempArray = MoveLines(szArray, ParserInput, pIndex);
szArray = tempArray;
IsTextUpdated = true;
}
break;
case "n":
case "N":
//FOR DEBUG
// Console.WriteLine("* Input was for PrintLineNumber()");
Console.WriteLine("* {0}", pIndex);
break;
case "p":
case "P":
// FOR DEBUG
// Console.WriteLine("* Input was for PageText()");
tempIndex = PageText(szArray, ParserInput, pIndex);
if (tempIndex != -1) { // update current line number if list command moved the pointer
pIndex = tempIndex;
}
break;
case "r":
case "R":
//FOR DEBUG
// Console.WriteLine("* Input was for ReplaceText()");
if (szArray.Count == 0) {
Console.WriteLine("* No text available to replace");
}
else {
tempArray = ReplaceText(szArray, ParserInput, pIndex);
szArray = tempArray;
IsTextUpdated = true;
}
break;
case "s":
case "S":
//FOR DEBUG
// Console.WriteLine("* Input was for SearchForText()");
if (szArray.Count == 0) {
Console.WriteLine("* No text available to search");
}
else {
tempIndex = SearchForText(szArray, ParserInput, pIndex);
if (tempIndex != -1) { // update current line number if list command moved the pointer
pIndex = tempIndex;
}
}
break;
case "t":
case "T":
// FOR DEBUG
// Console.WriteLine("* Input was for TransferText()");
tempArray = TransferText(szArray, ParserInput);
if (szArray.Count != pIndex) { // assume the array has changed, ergo text modified
IsTextUpdated = true;
}
szArray = tempArray;
break;
case "w":
case "W":
// FOR DEBUG
// Console.WriteLine("* Input was for WriteTextToFile()");
if (szArray.Count == 0) {
Console.WriteLine("* No text to save.");
}
else {
EditorWrite(szArray, InputFileName, BackupFileName);
IsTextUpdated = false;
}
break;
case "":
break;
default:
int LineNumber = 0;
if (szArray.Count == 0) {
Console.WriteLine("* No lines to edit at - new empty file");
break;
}
else {
try {
// LineNumber = Convert.ToInt32(ParserInput);
LineNumber = Int32.Parse(ParserInput);
}
catch (System.ArgumentNullException) {
Console.WriteLine("String is null.");
break;
}
catch (System.FormatException) {
Console.WriteLine("* Unrecognized command");
break;
}
catch (System.OverflowException) {
Console.WriteLine("* Overflow in string to int conversion.");
break;
}
}
//FOR DEBUG
// Console.WriteLine("* Input was for EditAtLine() - line {0}", LineNumber);
// update line pointer to LineNumber
pIndex = LineNumber;
tempArray = EditAtLine(szArray, pIndex);
szArray = tempArray;
IsTextUpdated = true;
break;
}
Console.Write("* ");
}
if (IsTextUpdated == true) { // ask them if they really wanted to quit without writing text out
Console.WriteLine("* WARNING: modified text not saved.");
Console.Write("* Save? (Y/N) ");
string SaveReply = GetConsoleInput();
// string SaveReplyFirstChar = Convert.ToString(SaveReply[0]);
if (SaveReply != "") {
string SaveReplyFirstChar = SaveReply[0].ToString();
switch (SaveReplyFirstChar) {
case "y":
case "Y":
Console.WriteLine("* Exiting....");
EditorWrite(szArray, InputFileName, BackupFileName);
break;
default:
Console.WriteLine("* Exiting without save.");
break;
}
}
else {
Console.WriteLine("* Exiting without save.");
}
}
} // end of Parser
// ListText - returns updated list pointer as int
static int ListText(ArrayList szArray, string ParserInput, int nIndex)
{
Regex fullr = new Regex(@"^[lL](?<1>\d+),(?<2>\d+)", RegexOptions.Compiled);
Regex shortr = new Regex(@"^[lL](?<1>\d+)", RegexOptions.Compiled);
Match fullm;
Match shortm;
int listSuccess = 0;
int PAGEWIDTH = 72; // allow for line numbers in printouts - up to 99,999.
// TODO: adjust line number range dynamically for large files
int tempwidth = 0;
string workstring = "";
string tempstring = "";
int remainder = 0;
int division = 0;
int linesinline = 0;
int leftinstring = 0;
int lowLine = 0;
int hiLine = 0;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
fullm = fullr.Match(ParserInput);
shortm = shortr.Match(ParserInput);
Group fullg1 = fullm.Groups[1];
Group fullg2 = fullm.Groups[2];
Group shortg1 = shortm.Groups[1];
2008-11-17 18:29:00 -05:00
if (fullm.Success) { // we think we have two line numbers, set lowLine and hiLine accordingly
2008-03-05 09:52:00 -05:00
//FOR DEBUG
//Console.WriteLine("First line number {0}, last line number {1}", fullm.Groups[1], fullm.Groups[2]);
Capture fullc1 = fullg1.Captures[0];
Capture fullc2 = fullg2.Captures[0];
// int lowLine = Convert.ToInt32(fullc1.Value);
lowLine = Int32.Parse(fullc1.Value) - 1; // offset by one to allow for difference in starting point...
// int hiLine = Convert.ToInt32(fullc2.Value);
hiLine = Int32.Parse(fullc2.Value); // but leave this one alone, due to the loop
// test for numbers out of range or out of order
if ((lowLine <= hiLine) && (lowLine >= 0 && lowLine <= szArray.Count) && (hiLine >= 0 && hiLine <= szArray.Count)) {
// continue on to listing...
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to list, or line out of range.");
Console.WriteLine("* lnum1,num2 where num1 <= num2 and num2 <= length of file.");
Console.WriteLine("* File length is {0}.", szArray.Count);
listSuccess = -1;
return listSuccess;
}
}
else if (shortm.Success) { // we have one line number
//FOR DEBUG
//Console.WriteLine("Line number {0}", shortm.Groups[1]);
// write out line
Capture shortc1 = shortg1.Captures[0];
// nIndex = Convert.ToInt32(shortc1.Value);
nIndex = Int32.Parse(shortc1.Value);
if (nIndex >= 1 && nIndex <= szArray.Count) { // check for line numbers in range of file
lowLine = nIndex - 1;
hiLine = nIndex;
// proceed to listing
}
else {
Console.WriteLine("* Line number {0} out of range. File length is {1}", nIndex, szArray.Count);
listSuccess = -1;
return listSuccess;
}
}
else if ((ParserInput == "l") || (ParserInput == "L")) { // set lowLine = 0, hiLine = szArray.Count
lowLine = 0;
hiLine = szArray.Count;
}
else {
Console.WriteLine("Invalid match");
listSuccess = -1;
return listSuccess;
}
// print out buffer contents between lowLine and hiLine
2008-11-17 18:29:00 -05:00
for (nIndex = lowLine; nIndex < hiLine; nIndex++) {
2008-03-05 09:52:00 -05:00
workstring = szArray[nIndex].ToString();
tempwidth = workstring.Length;
2008-11-17 18:29:00 -05:00
if (tempwidth > PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
//FOR DEBUG
//Console.WriteLine(" need to break up line length");
2008-11-17 18:29:00 -05:00
while (division != 1) {
2008-03-05 09:52:00 -05:00
linesinline++;
division = tempwidth / PAGEWIDTH;
remainder = tempwidth % PAGEWIDTH;
tempwidth = tempwidth - PAGEWIDTH;
//FOR DEBUG
//Console.WriteLine("remainder = {0}, division = {1}, tempwidth = {2}, linesinline = {3}", remainder, division, tempwidth, linesinline);
//Console.ReadLine();
}
2008-11-17 18:29:00 -05:00
if (remainder != 0) {
2008-03-05 09:52:00 -05:00
linesinline++;
//FOR DEBUG
//Console.WriteLine("remainder = {0}, division = {1}, tempwidth = {2}, linesinline = {3}", remainder, division, tempwidth, linesinline);
//Console.ReadLine();
}
leftinstring = workstring.Length;
2008-11-17 18:29:00 -05:00
while (linesinline > 0) {
if (leftinstring >= PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, PAGEWIDTH);
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, remainder);
}
Console.WriteLine("{0,5}: {1}", (nIndex + 1), tempstring);
linesinline--;
2008-11-17 18:29:00 -05:00
if (leftinstring > PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
leftinstring = leftinstring - PAGEWIDTH;
}
}
// rezero worker constants
remainder = 0;
division = 0;
linesinline = 0;
leftinstring = 0;
listSuccess = 1;
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
Console.WriteLine("{0,5}: {1}", (nIndex + 1), szArray[nIndex]);
}
listSuccess = 1;
}
if (listSuccess == 1) {
return nIndex; // paging worked
}
else { // note: you should never get here
return -1; // bad arguments, don't move line pointer
}
} // end of ListText
// CopyLines() - returns updated ArrayList with copies done, or the original ArrayList
static ArrayList CopyLines(ArrayList szArray, string ParserInput, int nIndex)
{
Queue copyQueue = new Queue();
Regex copyr = new Regex(@"^[cC](?<1>\d+),(?<2>\d+),(?<3>\d+)", RegexOptions.Compiled);
Match copym;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
copym = copyr.Match(ParserInput);
Group copyg1 = copym.Groups[1];
Group copyg2 = copym.Groups[2];
Group copyg3 = copym.Groups[3];
if (copym.Success) { // we think we have two line numbers and a dest number
//FOR DEBUG
//Console.WriteLine("First line number {0}, last line number {1}, dest {2}", copym.Groups[1], copym.Groups[2], copym.Groups[3]);
//Put array elements to be copied into copyQueue
Capture copyc1 = copyg1.Captures[0]; // first line of copy
Capture copyc2 = copyg2.Captures[0]; // last line of copy
// int lowLine = Convert.ToInt32(copyc1.Value);
int lowLine = Int32.Parse(copyc1.Value);
// int hiLine = Convert.ToInt32(copyc2.Value);
int hiLine = Int32.Parse(copyc2.Value);
// test for numbers out of range or out of order
if ((lowLine <= hiLine) && (lowLine >= 1 && lowLine <= szArray.Count) && (hiLine >= 1 && hiLine <= szArray.Count)) {
for (nIndex = lowLine; nIndex <= hiLine; nIndex++) {
//FOR DEBUG
// Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
copyQueue.Enqueue(szArray[nIndex - 1]);
}
// check dest num valid
Capture copyc3 = copyg3.Captures[0];
// int destLine = Convert.ToInt32(copyc3.Value);
int destLine = Int32.Parse(copyc3.Value);
if (destLine >= 1 && destLine <= szArray.Count) {
// insert copyQueue at point dest in szArray
// note that due to the indexing offset you need to decrement destLine by 1 here
szArray.InsertRange(destLine - 1, copyQueue);
}
else if (destLine > szArray.Count) { // ask them if they want the copy at the end of the file
Console.Write("* Copy past end of file - do you want block appended? (y/n) ");
string appendReply = GetConsoleInput();
// string appendReplyFirstChar = Convert.ToString(appendReply[0]);
if (appendReply != "") {
string appendReplyFirstChar = appendReply[0].ToString();
switch (appendReplyFirstChar) {
case "y":
case "Y":
szArray.AddRange(copyQueue);
break;
default:
Console.WriteLine("* Aborting copy.");
break;
}
}
else {
Console.WriteLine("* Aborting copy.");
}
}
else {
Console.WriteLine("* Invalid copy destination.");
Console.WriteLine("* cnum1,num2,dest where num1 <= num2, num2 and dest <= length of file.");
Console.WriteLine("* File length is {0}.", szArray.Count);
}
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to copy, or line out of range.");
Console.WriteLine("* cnum1,num2 where num1 <= num2, num2 and dest <= length of file.");
Console.WriteLine("* File length is {0}.", szArray.Count);
}
return szArray; // c[num1,num2,dest] worked
}
else {
Console.WriteLine("Invalid match");
return szArray;
}
} // end of CopyLines
// DeleteLines() - returns updated ArrayList with deletes done, or the original ArrayList
static ArrayList DeleteLines(ArrayList szArray, string ParserInput, int nIndex)
{
Regex fullr = new Regex(@"^[dD](?<1>\d+),(?<2>\d+)", RegexOptions.Compiled);
Regex shortr = new Regex(@"^[dD](?<1>\d+)", RegexOptions.Compiled);
Match fullm;
Match shortm;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
fullm = fullr.Match(ParserInput);
shortm = shortr.Match(ParserInput);
Group fullg1 = fullm.Groups[1];
Group fullg2 = fullm.Groups[2];
Group shortg1 = shortm.Groups[1];
if ((ParserInput == "d") || (ParserInput == "D")) { // delete line at current nIndex (which means subtracting 1)
szArray.RemoveAt(nIndex - 1);
return szArray;
}
else if (fullm.Success) { // we think we have two line numbers
//FOR DEBUG
//Console.WriteLine("First line number {0}, last line number {1}", fullm.Groups[1], fullm.Groups[2]);
//delete lines between first and second numbers
Capture fullc1 = fullg1.Captures[0];
Capture fullc2 = fullg2.Captures[0];
// int lowLine = Convert.ToInt32(fullc1.Value);
int lowLine = Int32.Parse(fullc1.Value);
// int hiLine = Convert.ToInt32(fullc2.Value);
int hiLine = Int32.Parse(fullc2.Value);
// test for numbers out of range or out of order
if ((lowLine <= hiLine) && (lowLine >= 1 && lowLine <= szArray.Count) && (hiLine >= 1 && hiLine <= szArray.Count) && ((hiLine - lowLine) != 0)) {
szArray.RemoveRange(lowLine - 1, ((hiLine - lowLine) + 1));
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to list, or line out of range.");
Console.WriteLine("* dnum1,num2 where num1 <= num2 and num2 <= length of file.");
Console.WriteLine("* File length is {0}.", szArray.Count);
}
return szArray; // end of d[num1,num]
}
else if (shortm.Success) { // we have one line number
//FOR DEBUG
//Console.WriteLine("Line number {0}", shortm.Groups[1]);
// delete line
Capture shortc1 = shortg1.Captures[0];
// nIndex = Convert.ToInt32(shortc1.Value);
nIndex = Int32.Parse(shortc1.Value);
if (nIndex >= 1 && nIndex <= szArray.Count) { // check for line numbers in range of file
szArray.RemoveAt(nIndex - 1);
}
else {
Console.WriteLine("* Line number {0} out of range. File length is {1}", nIndex, szArray.Count);
return szArray;
}
return szArray;
}
else {
Console.WriteLine("Invalid match");
return szArray;
}
} // end of DeleteLines
// EditAtLine() - edit the line at nIndex in szArray. Since we know the line number, we don't have
// to parse ParserInput here.
static ArrayList EditAtLine(ArrayList szArray, int nIndex)
{
Queue editQueue = new Queue();
if (nIndex >= 1 && nIndex <= szArray.Count) { // check that line number is in range of file
Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
Console.Write("> ");
string editInput = GetConsoleInput();
if (editInput == "") {
return szArray;
}
else {
editQueue.Enqueue(editInput);
szArray.RemoveAt(nIndex - 1);
szArray.InsertRange(nIndex - 1, editQueue);
}
}
else {
Console.WriteLine("* Line number {0} out of range. File length is {1}", nIndex, szArray.Count);
}
return szArray;
} // end of EditAtLine
// InsertAtLine() - insert line(s) above nIndex in szArray. Since we know the line number, we don't have
// to parse ParserInput here.
static ArrayList InsertAtLine(ArrayList szArray, int nIndex)
{
Queue insertQueue = new Queue();
string insertInput = null;
Console.WriteLine("* Inserting text above {0}: {1}", nIndex, szArray[nIndex - 1]);
Console.WriteLine("* Press ^^ to end input.");
while (insertInput != "^^") { // Double carat ^^ ends input - would have used control char, but need tty to understand them....
Console.Write("> ");
insertInput = GetConsoleInput();
if (insertInput != "^^") {
insertQueue.Enqueue(insertInput);
}
}
szArray.InsertRange(nIndex - 1, insertQueue);
return szArray;
} // end of InsertAtLine
// AppendAtEOF() - append line(s) below current end of szArray. Since we are appending, we don't have
// to parse ParserInput here.
static ArrayList AppendAtEOF(ArrayList szArray)
{
Queue appendQueue = new Queue();
string appendInput = null;
Console.WriteLine("* Appending text at EOF - Press ^^ to end input.");
while (appendInput != "^^") { // ^^ ends input
Console.Write("> ");
appendInput = GetConsoleInput();
if (appendInput != "^^") {
appendQueue.Enqueue(appendInput);
}
}
szArray.AddRange(appendQueue);
return szArray;
} // end of AppendAtEOF()
// MoveLines() - returns updated ArrayList with moves done, or the original ArrayList
static ArrayList MoveLines(ArrayList szArray, string ParserInput, int nIndex)
{
Queue moveQueue = new Queue();
Regex mover = new Regex(@"^[mM](?<1>\d+),(?<2>\d+),(?<3>\d+)", RegexOptions.Compiled);
Match movem;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
movem = mover.Match(ParserInput);
Group moveg1 = movem.Groups[1];
Group moveg2 = movem.Groups[2];
Group moveg3 = movem.Groups[3];
if (movem.Success) { // we think we have two line numbers and a dest number
//FOR DEBUG
// Console.WriteLine("First line number {0}, last line number {1}, dest {2}", movem.Groups[1], movem.Groups[2], movem.Groups[3]);
//Put array elements to be moved into moveQueue
Capture movec1 = moveg1.Captures[0]; // first line of move
Capture movec2 = moveg2.Captures[0]; // last line of move
// int lowLine = Convert.ToInt32(movec1.Value);
int lowLine = Int32.Parse(movec1.Value);
// int hiLine = Convert.ToInt32(movec2.Value);
int hiLine = Int32.Parse(movec2.Value);
// test for numbers out of range or out of order
if ((lowLine <= hiLine) && (lowLine >= 1 && lowLine <= szArray.Count) && (hiLine >= 1 && hiLine <= szArray.Count)) {
for (nIndex = lowLine; nIndex <= hiLine; nIndex++) {
//FOR DEBUG
// Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
moveQueue.Enqueue(szArray[nIndex - 1]);
}
// check dest num valid
// However, you can't overlap - dest must either be before the block you're moving, or after it.
Capture movec3 = moveg3.Captures[0];
// int destLine = Convert.ToInt32(movec3.Value);
int destLine = Int32.Parse(movec3.Value);
if ((destLine >= 1 && destLine <= szArray.Count) && ((destLine < lowLine) || (destLine) > hiLine)) {
// insert moveQueue at point dest in szArray
// note that due to the indexing offset you need to decrement destLine by 1 here
szArray.InsertRange(destLine - 1, moveQueue);
// once the insertion is complete, then you can delete the lines from the original
// however, need to be careful about seeing what happened to the original lines - they
// may have moved their indexes in the array depending on where you did the insertion
if (destLine > hiLine) { // indexes stayed the same for the original block - delete it
szArray.RemoveRange(lowLine - 1, ((hiLine - lowLine) + 1));
}
else { // destLine above lowLine, need to adjust
int padLine = hiLine - lowLine;
szArray.RemoveRange((lowLine + padLine), ((hiLine - lowLine) + 1));
}
}
else if (destLine > szArray.Count) { // ask them if they want the move at the end of the file
Console.Write("* Move past end of file - do you want block appended? (y/n) ");
string appendReply = GetConsoleInput();
// string appendReplyFirstChar = Convert.ToString(appendReply[0]);
if (appendReply != "") {
string appendReplyFirstChar = appendReply[0].ToString();
switch (appendReplyFirstChar) {
case "y":
case "Y":
szArray.AddRange(moveQueue);
// we don't have to worry about the index adjustment here - we can just remove the lines
// from their original location
szArray.RemoveRange(lowLine - 1, ((hiLine - lowLine) + 1));
break;
default:
Console.WriteLine("* Aborting move.");
break;
}
}
else {
Console.WriteLine("* Aborting move.");
}
}
else {
Console.WriteLine("* Invalid move destination.");
Console.WriteLine("* mnum1,num2,dest where num1 <= num2, num2 and dest <= length of file,");
Console.WriteLine("* but dest not within num1 - num2 range.");
Console.WriteLine("* File length is {0}.", szArray.Count);
}
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to move, or line out of range.");
Console.WriteLine("* mnum1,num2 where num1 <= num2, num2 and dest <= length of file,");
Console.WriteLine("* but dest not within num1 - num2 range.");
Console.WriteLine("* File length is {0}.", szArray.Count);
}
return szArray; // m[num1,num2,dest] worked
}
else {
Console.WriteLine("Invalid match");
return szArray;
}
} // end of MoveLines
// SearchForText() - returns updated list pointer, since we're not modifying any text
static int SearchForText(ArrayList szArray, string ParserInput, int nIndex)
{
Regex closedsearchr = new Regex(@"^[sS](?<1>\d+),(?<2>\d+),(?<3>.+)", RegexOptions.Compiled);
Regex opensearchr = new Regex(@"^[sS](?<1>\d+),\?,(?<2>.+)", RegexOptions.Compiled);
Match closedsearchm;
Match opensearchm;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
closedsearchm = closedsearchr.Match(ParserInput);
opensearchm = opensearchr.Match(ParserInput);
Group closedsearchg1 = closedsearchm.Groups[1];
Group closedsearchg2 = closedsearchm.Groups[2];
Group closedsearchg3 = closedsearchm.Groups[3];
Group opensearchg1 = opensearchm.Groups[1];
Group opensearchg2 = opensearchm.Groups[2];
int searchSuccess = 0;
if (closedsearchm.Success) { // we think we have two line numbers and a search string
//FOR DEBUG
// Console.WriteLine("First line number {0}, last line number {1}, string {2}", closedsearchm.Groups[1], closedsearchm.Groups[2], closedsearchm.Groups[3]);
Capture closedsearchc1 = closedsearchg1.Captures[0];
Capture closedsearchc2 = closedsearchg2.Captures[0];
Capture closedsearchc3 = closedsearchg3.Captures[0];
// int lowLine = Convert.ToInt32(closedsearchc1.Value);
int lowLine = Int32.Parse(closedsearchc1.Value);
// int hiLine = Convert.ToInt32(closedsearchc2.Value);
int hiLine = Int32.Parse(closedsearchc2.Value);
Regex searchstringr = new Regex(Regex.Escape(closedsearchc3.Value));
Match searchstringm;
// test for numbers out of range or out of order
if ((lowLine <= hiLine) && (lowLine >= 1 && lowLine <= szArray.Count) && (hiLine >= 1 && hiLine <= szArray.Count)) {
for (nIndex = lowLine; nIndex <= hiLine; nIndex++) {
//FOR DEBUG
// Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
// search for the searchstring in the current line
// searchstringm = searchstringr.Match(Regex.Escape(Convert.ToString(szArray[nIndex - 1])));
searchstringm = searchstringr.Match(Regex.Escape(szArray[nIndex - 1].ToString()));
if (searchstringm.Success) { // found a match
Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
searchSuccess = 1;
break;
}
else { // no match found
//FOR DEBUG
// Console.WriteLine("* No match found");
searchSuccess = -1;
}
}
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to search, or line out of range.");
Console.WriteLine("* snum1,[num2 | ?],string where num1 <= num2 and");
Console.WriteLine("* num2 <= length of file. File length is {0}", szArray.Count);
searchSuccess = -1;
}
if (searchSuccess == 1) {
return nIndex;
}
else {
Console.WriteLine("* No match found");
return -1;
}
}
else if (opensearchm.Success) { // we have a starting line number and a string
//FOR DEBUG
// Console.WriteLine("First line number {0}, last line number {1}, string {2}", closedsearchm.Groups[1], closedsearchm.Groups[2], closedsearchm.Groups[3]);
Capture opensearchc1 = opensearchg1.Captures[0];
Capture opensearchc2 = opensearchg2.Captures[0];
// int lowLine = Convert.ToInt32(opensearchc1.Value);
int lowLine = Int32.Parse(opensearchc1.Value);
Regex searchstringr = new Regex(Regex.Escape(opensearchc2.Value));
Match searchstringm;
// test for start number out of range
if (lowLine >= 1 && lowLine <= szArray.Count) {
for (nIndex = lowLine; nIndex <= szArray.Count; nIndex++) {
//FOR DEBUG
// Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
// search for the searchstring in the current line
// searchstringm = searchstringr.Match(Regex.Escape(Convert.ToString(szArray[nIndex - 1])));
searchstringm = searchstringr.Match(Regex.Escape(szArray[nIndex - 1].ToString()));
if (searchstringm.Success) { // found a match
Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
Console.Write("O.K.? ");
string searchReply = GetConsoleInput();
if (searchReply == "") {
searchSuccess = 1;
}
else {
// string searchReplyFirstChar = Convert.ToString(searchReply[0]);
string searchReplyFirstChar = searchReply[0].ToString();
switch (searchReplyFirstChar) {
case "y":
case "Y":
searchSuccess = 1;
break;
default:
searchSuccess = -1;
break;
}
}
if (searchSuccess == 1) { // found a match, so stop looking (break from the for loop)
break;
}
}
else { // no match found
//FOR DEBUG
// Console.WriteLine("* No match found");
searchSuccess = -1;
}
}
2008-11-17 18:29:00 -05:00
}
else { // bad arguments
2008-03-05 09:52:00 -05:00
Console.WriteLine("* Malformed arguments to search, or line out of range.");
Console.WriteLine("* snum1,[num2 | ?],string where num1 <= num2 and");
Console.WriteLine("* num2 <= length of file. File length is {0}", szArray.Count);
searchSuccess = -1;
}
if (searchSuccess == 1) {
return nIndex;
}
else {
Console.WriteLine("* No match found");
return -1;
}
}
else { // bad match to initial parse of command args
Console.WriteLine("* Malformed arguments to search, or line out of range.");
Console.WriteLine("* snum1,[num2 | ?],string where num1 <= num2 and");
Console.WriteLine("* num2 <= length of file. File length is {0}", szArray.Count);
return -1;
}
} // end of SearchForText
// ReplaceText() - returns updated list pointer, since we're not modifying any text
static ArrayList ReplaceText(ArrayList szArray, string ParserInput, int nIndex)
{
Regex closedreplacer = new Regex(@"^[rR](?<1>\d+),(?<2>\d+),(?<3>.+)\^(?<4>.+)", RegexOptions.Compiled);
Regex openreplacer = new Regex(@"^[rR](?<1>\d+),\?,(?<2>.+)\^(?<3>.+)", RegexOptions.Compiled);
Match closedreplacem;
Match openreplacem;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
closedreplacem = closedreplacer.Match(ParserInput);
openreplacem = openreplacer.Match(ParserInput);
Group closedreplaceg1 = closedreplacem.Groups[1];
Group closedreplaceg2 = closedreplacem.Groups[2];
Group closedreplaceg3 = closedreplacem.Groups[3];
Group closedreplaceg4 = closedreplacem.Groups[4];
Group openreplaceg1 = openreplacem.Groups[1];
Group openreplaceg2 = openreplacem.Groups[2];
Group openreplaceg3 = openreplacem.Groups[3];
if (closedreplacem.Success) { // we think we have two line numbers, a search string, and a replace string
//FOR DEBUG
// Console.WriteLine("First line number {0}, last line number {1}, string {2}, string {3}", closedreplacem.Groups[1], closedreplacem.Groups[2], closedreplacem.Groups[3], closedreplacem.Groups[4]);
Capture closedreplacec1 = closedreplaceg1.Captures[0];
Capture closedreplacec2 = closedreplaceg2.Captures[0];
Capture closedreplacec3 = closedreplaceg3.Captures[0];
Capture closedreplacec4 = closedreplaceg4.Captures[0];
// int lowLine = Convert.ToInt32(closedreplacec1.Value);
int lowLine = Int32.Parse(closedreplacec1.Value);
// int hiLine = Convert.ToInt32(closedreplacec2.Value);
int hiLine = Int32.Parse(closedreplacec2.Value);
Regex searchstringr = new Regex(Regex.Escape(closedreplacec3.Value));
// Match searchstringm;
Regex replacestringr = new Regex(Regex.Escape(closedreplacec4.Value));
string replaceresult = null;
// test for numbers out of range or out of order
if ((lowLine <= hiLine) && (lowLine >= 1 && lowLine <= szArray.Count) && (hiLine >= 1 && hiLine <= szArray.Count)) {
for (nIndex = lowLine; nIndex <= hiLine; nIndex++) {
//FOR DEBUG
// Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
// search for the searchstring in the current line and replace it with the replacement string if found
// replaceresult = Regex.Replace(Convert.ToString(szArray[nIndex - 1]), Convert.ToString(searchstringr), Convert.ToString(replacestringr));
replaceresult = Regex.Replace(szArray[nIndex - 1].ToString(), searchstringr.ToString(), replacestringr.ToString());
Queue replaceQueue = new Queue();
replaceQueue.Enqueue(replaceresult);
szArray.InsertRange(nIndex - 1, replaceQueue);
szArray.RemoveAt(nIndex);
}
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to replace, or line out of range.");
Console.WriteLine("* rnum1,[num2 | ?],string,string where num1 <= num2 and");
Console.WriteLine("* num2 <= length of file. File length is {0}", szArray.Count);
}
return szArray;
}
else if (openreplacem.Success) { // we have a starting line number, a search string and a replace string
//FOR DEBUG
// Console.WriteLine("First line number {0}, string {1}, string {2}", openreplacem.Groups[1], openreplacem.Groups[2], openreplacem.Groups[3]);
Capture openreplacec1 = openreplaceg1.Captures[0];
Capture openreplacec2 = openreplaceg2.Captures[0];
Capture openreplacec3 = openreplaceg3.Captures[0];
// int lowLine = Convert.ToInt32(openreplacec1.Value);
int lowLine = Int32.Parse(openreplacec1.Value);
Regex searchstringr = new Regex(Regex.Escape(openreplacec2.Value));
Match searchstringm;
Regex replacestringr = new Regex(Regex.Escape(openreplacec3.Value));
string replaceresult = null;
// test for start number out of range
if (lowLine >= 1 && lowLine <= szArray.Count) {
for (nIndex = lowLine; nIndex <= szArray.Count; nIndex++) {
//FOR DEBUG
// Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
// search for the searchstring in the current line
// searchstringm = searchstringr.Match(Regex.Escape(Convert.ToString(szArray[nIndex - 1])));
searchstringm = searchstringr.Match(Regex.Escape(szArray[nIndex - 1].ToString()));
if (searchstringm.Success) { // found a match
Console.WriteLine("{0}: {1}", nIndex, szArray[nIndex - 1]);
Console.Write("O.K.? ");
string replaceReply = GetConsoleInput();
if (replaceReply == "") {
// replaceresult = Regex.Replace(Convert.ToString(szArray[nIndex - 1]), Convert.ToString(searchstringr), Convert.ToString(replacestringr));
replaceresult = Regex.Replace(szArray[nIndex - 1].ToString(), searchstringr.ToString(), replacestringr.ToString());
Queue replaceQueue = new Queue();
replaceQueue.Enqueue(replaceresult);
szArray.InsertRange(nIndex - 1, replaceQueue);
szArray.RemoveAt(nIndex);
}
else {
// string replaceReplyFirstChar = Convert.ToString(replaceReply[0]);
string replaceReplyFirstChar = replaceReply[0].ToString();
switch (replaceReplyFirstChar) {
case "y":
case "Y":
// replaceresult = Regex.Replace(Convert.ToString(szArray[nIndex - 1]), Convert.ToString(searchstringr), Convert.ToString(replacestringr));
replaceresult = Regex.Replace(szArray[nIndex - 1].ToString(), searchstringr.ToString(), replacestringr.ToString());
Queue replaceQueue = new Queue();
replaceQueue.Enqueue(replaceresult);
szArray.InsertRange(nIndex - 1, replaceQueue);
szArray.RemoveAt(nIndex);
break;
default:
break;
}
}
}
else { // no match found
//FOR DEBUG
// Console.WriteLine("* No match found");
}
}
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to replace, or line out of range.");
Console.WriteLine("* rnum1,[num2 | ?],string,string where num1 <= num2 and");
Console.WriteLine("* num2 <= length of file. File length is {0}", szArray.Count);
}
return szArray;
}
else { // bad match to initial parse of command args
Console.WriteLine("* Malformed arguments to replace, or line out of range.");
Console.WriteLine("* rnum1,[num2 | ?],string,string where num1 <= num2 and");
Console.WriteLine("* num2 <= length of file. File length is {0}", szArray.Count);
return szArray;
}
} // end of ReplaceText
static void EditorWrite(ArrayList szArray, string InputFileName, string BackupFileName)
{
int pIndex = 0;
// check to see if file exists at all, first - if it doesn't,
// we have to create it, but don't have to back it up.
if (File.Exists(InputFileName)) { // it does exist, ergo we need to back it up
// Test to see if the backup file exists, if it does, delete it (to clear it)
if (File.Exists(BackupFileName)) {
File.Delete(BackupFileName);
}
// Then, copy the original file to one with bak at the end
File.Copy(InputFileName, BackupFileName, true);
// Then delete the original file (to clear it)
File.Delete(InputFileName);
// Then write out the contents of the buffer to our InputFileName
FileStream fsOutput = new FileStream(InputFileName, FileMode.Create, FileAccess.Write);
StreamWriter srOutput = new StreamWriter(fsOutput);
for (pIndex = 0; pIndex < szArray.Count; pIndex++) {
//FOR DEBUG
// Console.WriteLine("* pIndex = {0}, line = {1}", pIndex, szArray[pIndex]);
srOutput.WriteLine(szArray[pIndex]);
}
srOutput.Close();
fsOutput.Close();
return;
}
else { // file didn't exist, so create it, and don't back it up
FileStream fsOutput = new FileStream(InputFileName, FileMode.Create, FileAccess.Write);
StreamWriter srOutput = new StreamWriter(fsOutput);
for (pIndex = 0; pIndex < szArray.Count; pIndex++) {
srOutput.WriteLine(szArray[pIndex]);
}
srOutput.Close();
fsOutput.Close();
return;
}
} // end of EditorWrite();
// PageText - returns updated list pointer as int
static int PageText(ArrayList szArray, string ParserInput, int nIndex)
{
Regex fullr = new Regex(@"^[pP](?<1>\d+),(?<2>\d+)", RegexOptions.Compiled);
Regex shortr = new Regex(@"^[pP](?<1>\d+)", RegexOptions.Compiled);
Match fullm;
Match shortm;
int listSuccess = 0;
int pageCounter = 0;
string pageReply = "";
string pageReplyFirstChar = "";
int PAGELENGTH = 47; // allow for Singularity "activity" line at top of console
int PAGEWIDTH = 72; // allow for line numbers in printouts - up to 99,999.
// TODO: adjust line number range dynamically for large files
int tempwidth = 0;
string workstring = "";
string tempstring = "";
int remainder = 0;
int division = 0;
int linesinline = 0;
int leftinstring = 0;
int lowLine = 0;
int hiLine = 0;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
fullm = fullr.Match(ParserInput);
shortm = shortr.Match(ParserInput);
Group fullg1 = fullm.Groups[1];
Group fullg2 = fullm.Groups[2];
Group shortg1 = shortm.Groups[1];
2008-11-17 18:29:00 -05:00
if (fullm.Success) { // we think we have two line numbers, set lowLine and hiLine accordingly
2008-03-05 09:52:00 -05:00
//FOR DEBUG
//Console.WriteLine("First line number {0}, last line number {1}", fullm.Groups[1], fullm.Groups[2]);
Capture fullc1 = fullg1.Captures[0];
Capture fullc2 = fullg2.Captures[0];
// int lowLine = Convert.ToInt32(fullc1.Value);
lowLine = Int32.Parse(fullc1.Value) - 1; // offset by one to allow for difference in starting point...
// int hiLine = Convert.ToInt32(fullc2.Value);
hiLine = Int32.Parse(fullc2.Value); // but leave this one alone, due to the loop
// test for numbers out of range or out of order
if ((lowLine <= hiLine) && (lowLine >= 0 && lowLine <= szArray.Count) && (hiLine >= 0 && hiLine <= szArray.Count)) {
// continue on to listing...
}
else { // bad arguments
Console.WriteLine("* Malformed arguments to page, or line out of range.");
Console.WriteLine("* pnum1,num2 where num1 <= num2 and num2 <= length of file.");
Console.WriteLine("* File length is {0}.", szArray.Count);
listSuccess = -1;
return listSuccess;
}
}
else if (shortm.Success) { // we have one line number
//FOR DEBUG
//Console.WriteLine("Line number {0}", shortm.Groups[1]);
// write out line
Capture shortc1 = shortg1.Captures[0];
// nIndex = Convert.ToInt32(shortc1.Value);
nIndex = Int32.Parse(shortc1.Value);
if (nIndex >= 1 && nIndex <= szArray.Count) { // check for line numbers in range of file
lowLine = nIndex - 1;
hiLine = nIndex;
// proceed to listing
}
else {
Console.WriteLine("* Line number {0} out of range. File length is {1}", nIndex, szArray.Count);
listSuccess = -1;
return listSuccess;
}
}
else if ((ParserInput == "p") || (ParserInput == "P")) { // set lowLine = 0, hiLine = szArray.Count
lowLine = 0;
hiLine = szArray.Count;
}
else {
Console.WriteLine("Invalid match");
listSuccess = -1;
return listSuccess;
}
// print out buffer contents between lowLine and hiLine by pages
2008-11-17 18:29:00 -05:00
for (nIndex = lowLine; nIndex < hiLine; nIndex++) {
2008-03-05 09:52:00 -05:00
workstring = szArray[nIndex].ToString();
tempwidth = workstring.Length;
2008-11-17 18:29:00 -05:00
if (tempwidth > PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
//FOR DEBUG
//Console.WriteLine(" need to break up line length");
2008-11-17 18:29:00 -05:00
while (division != 1) {
2008-03-05 09:52:00 -05:00
linesinline++;
division = tempwidth / PAGEWIDTH;
remainder = tempwidth % PAGEWIDTH;
tempwidth = tempwidth - PAGEWIDTH;
//FOR DEBUG
//Console.WriteLine("remainder = {0}, division = {1}, tempwidth = {2}, linesinline = {3}", remainder, division, tempwidth, linesinline);
//Console.ReadLine();
}
2008-11-17 18:29:00 -05:00
if (remainder != 0) {
2008-03-05 09:52:00 -05:00
linesinline++;
//FOR DEBUG
//Console.WriteLine("remainder = {0}, division = {1}, tempwidth = {2}, linesinline = {3}", remainder, division, tempwidth, linesinline);
//Console.ReadLine();
}
2008-11-17 18:29:00 -05:00
if (linesinline < (PAGELENGTH - pageCounter)) {
// room to print the whole wrapped line
2008-03-05 09:52:00 -05:00
leftinstring = workstring.Length;
2008-11-17 18:29:00 -05:00
while (linesinline > 0) {
if (leftinstring >= PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, PAGEWIDTH);
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, remainder);
}
Console.WriteLine("{0,5}: {1}", (nIndex + 1), tempstring);
pageCounter++;
linesinline--;
2008-11-17 18:29:00 -05:00
if (leftinstring > PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
leftinstring = leftinstring - PAGEWIDTH;
}
}
}
2008-11-17 18:29:00 -05:00
else if (pageCounter <= PAGELENGTH) {
// less than PAGELENGTH, but not enough room to print the whole wrapped line
2008-03-05 09:52:00 -05:00
leftinstring = workstring.Length;
2008-11-17 18:29:00 -05:00
while (linesinline > 0) {
if (leftinstring >= PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, PAGEWIDTH);
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, remainder);
}
Console.WriteLine("{0,5}: {1}", (nIndex + 1), tempstring);
pageCounter++;
linesinline--;
2008-11-17 18:29:00 -05:00
if (leftinstring > PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
leftinstring = leftinstring - PAGEWIDTH;
}
2008-11-17 18:29:00 -05:00
if (pageCounter > PAGELENGTH) {
2008-03-05 09:52:00 -05:00
pageCounter = 0;
Console.Write("-- <ENTER> -- ");
pageReply = GetConsoleInput();
2008-11-17 18:29:00 -05:00
if (pageReply != "") {
2008-03-05 09:52:00 -05:00
//pageReplyFirstChar = Convert.ToString(pageReply[0]);
pageReplyFirstChar = pageReply[0].ToString();
2008-11-17 18:29:00 -05:00
switch (pageReplyFirstChar) {
2008-03-05 09:52:00 -05:00
case "q":
case "Q":
return nIndex + 1;
default:
2008-11-17 18:29:00 -05:00
if (leftinstring >= PAGEWIDTH) {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, PAGEWIDTH);
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
tempstring = workstring.Substring(workstring.Length - leftinstring, remainder);
}
Console.WriteLine("{0,5}: {1}", (nIndex + 1), tempstring);
pageCounter++;
linesinline--;
break;
}
}
}
}
}
// rezero worker constants
remainder = 0;
division = 0;
linesinline = 0;
leftinstring = 0;
listSuccess = 1;
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
Console.WriteLine("{0,5}: {1}", (nIndex + 1), szArray[nIndex]);
2008-11-17 18:29:00 -05:00
if (pageCounter < PAGELENGTH) {
2008-03-05 09:52:00 -05:00
pageCounter++;
}
2008-11-17 18:29:00 -05:00
else {
2008-03-05 09:52:00 -05:00
pageCounter = 0;
Console.Write("-- <ENTER> -- ");
pageReply = GetConsoleInput();
2008-11-17 18:29:00 -05:00
if (pageReply != "") {
2008-03-05 09:52:00 -05:00
//pageReplyFirstChar = Convert.ToString(pageReply[0]);
pageReplyFirstChar = pageReply[0].ToString();
2008-11-17 18:29:00 -05:00
switch (pageReplyFirstChar) {
2008-03-05 09:52:00 -05:00
case "q":
case "Q":
return nIndex + 1;
default:
break;
}
}
}
listSuccess = 1;
}
}
if (listSuccess == 1) {
return nIndex; // paging worked
}
else { // note that you should never get here
return -1; // bad arguments, don't move line pointer
}
} // end of PageText
// TransferText() - returns updated ArrayList with content merged in from external file, or the original ArrayList
static ArrayList TransferText(ArrayList szArray, string ParserInput)
{
Queue transferQueue = new Queue();
Regex transferr = new Regex(@"^[tT](?<1>\d+),(?<2>.+)", RegexOptions.Compiled);
Match transferm;
//FOR DEBUGGING
//Console.WriteLine("Current line number is {0}", nIndex);
transferm = transferr.Match(ParserInput);
Group transferg1 = transferm.Groups[1];
Group transferg2 = transferm.Groups[2];
2008-11-17 18:29:00 -05:00
if (transferm.Success) { // we think we have a line number and a filename of some sort
2008-03-05 09:52:00 -05:00
//FOR DEBUG
// Console.WriteLine("First line number {0}, filename {1}", transferm.Groups[1], transferm.Groups[2]);
//Put file contents to be copied into transferQueue
Capture transferc1 = transferg1.Captures[0]; // insertion point
// int lowLine = Convert.ToInt32(transferc1.Value);
int lowLine = Int32.Parse(transferc1.Value);
Capture transferc2 = transferg2.Captures[0]; // filename
// string TransferFileName = Convert.ToString(transferc2.Value);
string TransferFileName = transferc2.Value.ToString();
if (File.Exists(TransferFileName)) { // file exists, so read it into a buffer
string TransferLine;
ArrayList transferContents = new ArrayList();
FileStream fsInput = new FileStream(TransferFileName, FileMode.Open, FileAccess.Read);
StreamReader srInput = new StreamReader(fsInput);
while ((TransferLine = srInput.ReadLine()) != null) {
transferContents.Add(TransferLine);
}
srInput.Close();
fsInput.Close();
for (int transferIndex = 0; transferIndex < transferContents.Count; transferIndex++) {
//FOR DEBUG
// Console.WriteLine("{0}: {1}", transferIndex, transferContents[transferIndex]);
transferQueue.Enqueue(transferContents[transferIndex]);
}
}
else { // file to be merged wasn't there
Console.WriteLine("* File to be merged doesn't exist.");
return szArray;
}
// test for numbers out of range or out of order
if (lowLine >= 1 && lowLine <= szArray.Count) { //
szArray.InsertRange(lowLine - 1, transferQueue);
return szArray;
}
else if (lowLine > szArray.Count) { // check if number is past the end of the file and they want to append
Console.Write("* Transfer past end of file - do you want file appended? (Y/N) ");
string appendReply = GetConsoleInput();
// string appendReplyFirstChar = Convert.ToString(appendReply[0]);
if (appendReply != "") {
string appendReplyFirstChar = appendReply[0].ToString();
switch (appendReplyFirstChar) {
case "y":
case "Y":
szArray.AddRange(transferQueue);
break;
default:
Console.WriteLine("* Aborting transfer.");
break;
}
}
else {
Console.WriteLine("* Aborting transfer.");
}
return szArray;
}
else { // something else is wrong with the insertion point
Console.WriteLine("* Invalid transfer destination.");
Console.WriteLine("* tnum1, filename where num1 is insertion point and filename");
Console.WriteLine("* is what is to be inserted. File length is {0}.", szArray.Count);
return szArray;
}
}
else {// bad arguments
Console.WriteLine("* Malformed arguments to transfer.");
Console.WriteLine("* tnum1, filename where num1 is insertion point and filename");
Console.WriteLine("* is what is to be inserted. File length is {0}.", szArray.Count);
return szArray;
}
} // end of TransferText
static string GetConsoleInput() { // filter Console.ReadLine input for backspaces
string InputString = "";
string InputCheck = "";
InputString = Console.ReadLine();
if (InputString != "") {
//FOR DEBUG
//Console.WriteLine("* Input was {0}", InputString);
//Console.Write("* ");
//
//for (int i = 0; i < InputString.Length; i++) {
// Console.Write("{0:x}",(int)InputString[i]);
//}
//Console.Write("* ");
// END DEBUG
// Check for backspace chars and remove them if present, but also delete the character(s) they meant to delete
int j = 0;
string TempString = "";
for (int i = 0; i < InputString.Length; i++) {
if ((int)InputString[i] != 0x08) {
TempString = string.Concat(InputCheck,InputString[i].ToString());
InputCheck = TempString;
j++;
}
else {
InputCheck = InputCheck.Remove(j - 1,1);
j--;
}
}
//FOR DEBUG
//Console.WriteLine("* Check was {0}", InputCheck);
//Console.Write("* ");
//
//for (int i = 0; i < InputCheck.Length; i++) {
// Console.Write("{0:x}",(int)InputCheck[i]);
//}
//END DEBUG
}
return InputCheck;
} // end of GetConsoleInput()
}
}