static void Main(string[] args) { CmdlineParser.Create("sample application", (parser) => { var cmdConfig = parser.AddCommand("config", "configuration", (pConfig) => { var cmdConfigShow = pConfig.AddCommand("show", "show current config"); var cmdConfigUpdate = pConfig.AddCommand("update", "update config item", (pConfigUpdate) => { var param = pConfigUpdate.AddMandatoryParameter("var=value", "assign value to var"); pConfigUpdate.OnCmdlineMatch(() => { System.Console.WriteLine($"setting [{(string)param}]"); }); }); pConfig.OnCmdlineMatch(() => { if (cmdConfigShow) { System.Console.WriteLine($"showing configuration..."); } }); }); parser.AddShort("h", "show usage", null, (item) => item.MatchParser.PrintUsage()); parser.OnCmdlineMatch(() => { }); parser.Run(args); }); }
static void Main(string[] args) { CmdlineParser.Create("shell utils", (parser) => { parser.AddShortLong("h", "help", "show usage", null, (item) => item.MatchParser.PrintUsage()); ShellUtilities.RegisterReplaceToken(parser); ShellUtilities.RegisterMatchRegex(parser); ShellUtilities.RegisterAutoCPULimiter(parser); ShellUtilities.RegisterGraphArea(parser); ShellUtilities.RegisterLogic2FreqGraph(parser); parser.OnCmdlineMatch(() => { }); parser.Run(args); }, useColors: true, unescapeArguments: true); }
public void Run(string[] args) { var cts = new CancellationTokenSource(); ct = cts.Token; Console.CancelKeyPress += (s, e) => { e.Cancel = true; cts.Cancel(); }; CmdlineParser.Create("Synchronize btrfs SOURCE filesystem with given TARGET.", (parser) => { parser.AddShortLong("h", "help", "show usage", null, (item) => item.MatchParser.PrintUsage()); var dryRunMode = parser.AddShortLong("u", "dry-run", "list sync actions without apply (simulation mode)"); var skipSnapResync = parser.AddShortLong("n", "skip-snap-resync", "avoid resync existing subvolume snapshots"); var skipDeleteSubvol = parser.AddShortLong("s", "skip-del-subvol", "avoid to remove destination subvol not present in source"); var SourcePath = parser.AddMandatoryParameter("source", "source path"); var TargetPath = parser.AddMandatoryParameter("target", "target path"); parser.OnCmdlineMatch(() => { Task.Run(async() => { var runMode = RunMode.normal; if (dryRunMode) { runMode = RunMode.dryRun; } await RunIt(runMode, SourcePath, TargetPath, skipSnapResync, skipDeleteSubvol); }).Wait(); }); parser.Run(args); }); }
static void Main(string[] args) { CmdlineParser.Create("clone disk reading parallel to write", (parser) => { var nonInteractive = parser.AddLong("non-interactive", "doesn't prompt before to start"); var sourceDevParam = parser.AddMandatoryParameter("source", "source device"); var targetDevParam = parser.AddMandatoryParameter("target", "target device"); parser.OnCmdlineMatch(() => { var sourceDevice = (string)sourceDevParam; var destDevice = (string)targetDevParam; if (!nonInteractive) { System.Console.WriteLine($"all content of device [{destDevice}] will overwritted"); System.Console.WriteLine($"press ctrl+c to abort"); Console.ReadKey(); } int bucketCount = 8; int bucketSize = 512 * 2 * 1024 * 64; // 64MB byte[][] buckets = new byte[bucketCount][]; int[] bucketLength = new int[bucketCount]; for (int i = 0; i < bucketCount; ++i) { buckets[i] = new byte[bucketSize]; } int readerNextBucket = 0; int readerNextWriteWaitHandle = 0; long readOffset = 0L; WaitHandle[] readWaitHandles = new WaitHandle[bucketCount]; for (int i = 0; i < bucketCount; ++i) { readWaitHandles[i] = new AutoResetEvent(true); } int writerNextBucket = 0; int writerNextReadWaitHandle = 0; long writeOffset = 0L; WaitHandle[] writeWaitHandles = new WaitHandle[bucketCount]; for (int i = 0; i < bucketCount; ++i) { writeWaitHandles[i] = new AutoResetEvent(false); } var sourceSize = GetDeviceSize(sourceDevice); var destSize = GetDeviceSize(destDevice); Console.WriteLine($"source disk = {sourceDevice} size = {sourceSize.HumanReadable()}"); Console.WriteLine($" dest disk = {destDevice}"); if (destSize < sourceSize) { Console.WriteLine($"can't fit source into dest device"); Environment.Exit(3); } var topCursor = 0; Console.Clear(); var fsRead = File.OpenRead(sourceDevice); fsRead.Seek(0, SeekOrigin.Begin); var fsWrite = File.OpenWrite(destDevice); fsWrite.Seek(0, SeekOrigin.Begin); object guiLock = new object(); var taskReader = Task.Run(() => { DateTime dtReadStart = DateTime.Now; while (readOffset < sourceSize) { readWaitHandles[readerNextBucket].WaitOne(); // initially already signaled var len = fsRead.Read(buckets[readerNextBucket], 0, bucketSize); bucketLength[readerNextBucket] = len; long speed = (long)((double)(readOffset + len) / (DateTime.Now - dtReadStart).TotalSeconds); lock (guiLock) { Console.SetCursorPosition(0, topCursor); Console.Write($"<=== read {len} bytes to bucket N. {readerNextBucket}"); Console.Write($" read offset [{readOffset.HumanReadable()}] speed = {speed.HumanReadable()}/s"); } var writeEvt = (AutoResetEvent)writeWaitHandles[readerNextWriteWaitHandle]; readerNextWriteWaitHandle++; writeEvt.Set(); if (readerNextWriteWaitHandle == bucketCount) { readerNextWriteWaitHandle = 0; } readOffset += len; readerNextBucket++; if (readerNextBucket == bucketCount) { readerNextBucket = 0; } } }); var taskWriter = Task.Run(() => { DateTime dtWriteStart = DateTime.Now; while (writeOffset < sourceSize) { writeWaitHandles[writerNextBucket].WaitOne(); var len = bucketLength[writerNextBucket]; fsWrite.Write(buckets[writerNextBucket], 0, len); long speed = (long)((double)(writeOffset + len) / (DateTime.Now - dtWriteStart).TotalSeconds); lock (guiLock) { Console.SetCursorPosition(0, topCursor + 1); Console.Write($"===> write {len} bytes to bucket N. {writerNextBucket}"); Console.Write($" write offset [{writeOffset.HumanReadable()}] speed = {speed.HumanReadable()}/s"); } var readEvt = (AutoResetEvent)readWaitHandles[writerNextReadWaitHandle]; writerNextReadWaitHandle++; readEvt.Set(); if (writerNextReadWaitHandle == bucketCount) { writerNextReadWaitHandle = 0; } writeOffset += len; writerNextBucket++; if (writerNextBucket == bucketCount) { writerNextBucket = 0; } } }); Task.WaitAll(new Task[] { taskReader, taskWriter }); Console.SetCursorPosition(0, topCursor + 2); Console.WriteLine("*** FINISHED ***"); }); parser.Run(args); }); }
static void Main(string[] args) { CmdlineParser.Create("Shows only difference between files", (p) => { var showStats = p.AddShortLong("s", "all-stats", "shows all stats informations"); var showDiff = p.AddShortLong("d", "show-differences", "shows characters difference"); var file1 = p.AddMandatoryParameter("file1", "first file"); var file2 = p.AddMandatoryParameter("file2", "second file"); p.OnCmdlineMatch(() => { var charDiffers1 = 0; var charDiffers2 = 0; var maxChangeWidth = 0; var lineDiffers1 = 0; var lineDiffers2 = 0; var totalLines1 = 0; var totalLines2 = 0; var filesize1 = new FileInfo(file1).Length; var filesize2 = new FileInfo(file2).Length; #region detect maxChangeWidth { using (var sr1 = new StreamReader(file1)) { using (var sr2 = new StreamReader(file2)) { // detect max change width while (!sr1.EndOfStream && !sr2.EndOfStream) { var changed = 0; var line1 = sr1.ReadLine(); var line2 = sr2.ReadLine(); ++totalLines1; ++totalLines2; var len1 = line1.Length; var len2 = line2.Length; var lenmax = Max(len1, len2); int i1 = 0; int i2 = 0; while (true) { if (len1 == 0) { var r = len2 - i2 - 1; changed += r; charDiffers2 += r; break; } else if (len2 == 0) { var r = len1 - i1 - 1; changed += r; charDiffers1 += r; break; } if (line1[i1] != line2[i2]) { ++changed; if (i1 < len1 - 1 && line1[i1 + 1] == line2[i2]) { ++charDiffers1; ++i1; } else if (i2 < len2 - 1 && line2[i2 + 1] == line1[i1]) { ++i2; ++charDiffers2; } else { ++i1; ++i2; ++charDiffers1; ++charDiffers2; } } else { ++i1; ++i2; } if (i1 >= len1 && i2 >= len2) { break; } else if (i1 >= len1) { var r = len2 - i2 - 1; changed += r; charDiffers2 += r; break; } else if (i2 >= len2) { var r = len1 - i1 - 1; changed += r; charDiffers1 += r; break; } } if (changed > 0) { ++lineDiffers1; ++lineDiffers2; } maxChangeWidth = Max(maxChangeWidth, changed); } if (!sr1.EndOfStream) { while (!sr1.EndOfStream) { var line1 = sr1.ReadLine(); ++totalLines1; ++lineDiffers1; var len1 = line1.Length; maxChangeWidth = Max(maxChangeWidth, len1); charDiffers1 += len1; } } if (!sr2.EndOfStream) { while (!sr2.EndOfStream) { var line2 = sr2.ReadLine(); ++totalLines2; ++lineDiffers2; var len2 = line2.Length; maxChangeWidth = Max(maxChangeWidth, len2); charDiffers2 += len2; } } var tblOut = new List <List <string> >(); if (showStats) { tblOut.Add(new List <string>() { "max changed chars per line", maxChangeWidth.ToString(), maxChangeWidth.ToString() }); tblOut.Add(new List <string>() { "size", filesize1.ToString(), filesize2.ToString() }); tblOut.Add(new List <string>() { "lines", totalLines1.ToString(), totalLines2.ToString() }); tblOut.Add(new List <string>() { "line differs", lineDiffers1.ToString(), lineDiffers2.ToString() }); tblOut.Add(new List <string>() { "line differs (%)", string.Format("{0:0.0}", (double)lineDiffers1 / totalLines1 * 100), string.Format("{0:0.0}", (double)lineDiffers2 / totalLines2 * 100) }); tblOut.Add(new List <string>() { "char differs", charDiffers1.ToString(), charDiffers2.ToString() }); tblOut.Add(new List <string>() { "char differs (%)", string.Format("{0:0.0}", (double)charDiffers1 / filesize1 * 100), string.Format("{0:0.0}", (double)charDiffers2 / filesize2 * 100) }); } if (tblOut.Count > 0) { System.Console.WriteLine(tblOut.TableFormat( new[] { "", "file1", "file2" }, new[] { ColumnAlignment.left, ColumnAlignment.right, ColumnAlignment.right })); } } } } #endregion #region show char changes if (showDiff || p.Items.Count(w => w.Type == CmdlineParseItemType.flag && w.Matches) == 0) { using (var sr1 = new StreamReader(file1)) { using (var sr2 = new StreamReader(file2)) { var W = Max(maxChangeWidth, "fileX".Length); var firstLine = true; while (!sr1.EndOfStream && !sr2.EndOfStream) { var line1 = sr1.ReadLine(); var line2 = sr2.ReadLine(); var len1 = line1.Length; var len2 = line2.Length; var lenmax = Max(len1, len2); var sb1 = new StringBuilder(); var sb2 = new StringBuilder(); int i1 = 0; int i2 = 0; while (true) { if (len1 == 0) { sb2.Append(line2.Substring(i2)); break; } else if (len2 == 0) { sb1.Append(line1.Substring(i1)); break; } if (line1[i1] != line2[i2]) { if (i1 < len1 - 1 && line1[i1 + 1] == line2[i2]) { sb1.Append(line1[i1]); ++i1; } else if (i2 < len2 - 1 && line2[i2 + 1] == line1[i1]) { sb1.Append(line2[i2]); ++i2; } else { ++i1; ++i2; } } else { ++i1; ++i2; } if (i1 >= len1 && i2 >= len2) { break; } else if (i1 >= len1) { sb2.Append(line2.Substring(i2)); break; } else if (i2 >= len2) { sb1.Append(line1.Substring(i1)); break; } } if (firstLine) { System.Console.WriteLine($"{"file1".Align(W)} | {"file2".Align(W)}"); firstLine = false; } var s1 = sb1.ToString(); var s2 = sb2.ToString(); if (!string.IsNullOrWhiteSpace(s1) || !string.IsNullOrWhiteSpace(s2)) { System.Console.WriteLine($"{s1.ToString().Align(W)} | {s2.ToString().Align(W)}"); } } if (!sr1.EndOfStream) { while (!sr1.EndOfStream) { var line1 = sr1.ReadLine(); System.Console.WriteLine($"{line1.Align(W)} |"); } } if (!sr2.EndOfStream) { while (!sr2.EndOfStream) { var line2 = sr2.ReadLine(); System.Console.WriteLine($"{(" ".Repeat(W))} | {line2}"); } } } } } #endregion }); p.Run(args); }); }