4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
12 ** This file contains C# code to perform regular expression replacements
13 ** using the standard input and output channels.
17 using System
.Diagnostics
;
19 using System
.Reflection
;
20 using System
.Runtime
.InteropServices
;
21 using System
.Text
.RegularExpressions
;
23 ///////////////////////////////////////////////////////////////////////////////
25 #region Assembly Metadata
26 [assembly
: AssemblyTitle("Replace Tool")]
27 [assembly
: AssemblyDescription("Replace text using standard input/output.")]
28 [assembly
: AssemblyCompany("SQLite Development Team")]
29 [assembly
: AssemblyProduct("SQLite")]
30 [assembly
: AssemblyCopyright("Public Domain")]
31 [assembly
: ComVisible(false)]
32 [assembly
: Guid("95a0513f-8863-48cd-a76f-cb80868cb578")]
33 [assembly
: AssemblyVersion("1.0.*")]
36 [assembly
: AssemblyConfiguration("Debug")]
38 [assembly
: AssemblyConfiguration("Release")]
42 ///////////////////////////////////////////////////////////////////////////////
47 /// This enumeration is used to represent all the possible exit codes from
50 internal enum ExitCode
53 /// The file download was a success.
58 /// The command line arguments are missing (i.e. null). Generally,
59 /// this should not happen.
64 /// The wrong number of command line arguments was supplied.
69 /// The "matchingOnly" flag could not be converted to a value of the
70 /// <see cref="Boolean"/> type.
72 BadMatchingOnlyFlag
= 3,
75 /// An exception was caught in <see cref="Main" />. Generally, this
76 /// should not happen.
81 ///////////////////////////////////////////////////////////////////////////
83 internal static class Replace
85 #region Private Support Methods
87 /// This method displays an error message to the console and/or
88 /// displays the command line usage information for this tool.
90 /// <param name="message">
91 /// The error message to display, if any.
93 /// <param name="usage">
94 /// Non-zero to display the command line usage information.
96 private static void Error(
102 Console
.WriteLine(message
);
104 string fileName
= Path
.GetFileName(
105 Process
.GetCurrentProcess().MainModule
.FileName
);
107 Console
.WriteLine(String
.Format(
108 "usage: {0} <regExPattern> <regExSubSpec> <matchingOnly>",
113 ///////////////////////////////////////////////////////////////////////
115 #region Program Entry Point
117 /// This is the entry-point for this tool. It handles processing the
118 /// command line arguments, reading from the standard input channel,
119 /// replacing any matching lines of text, and writing to the standard
122 /// <param name="args">
123 /// The command line arguments.
126 /// Zero upon success; non-zero on failure. This will be one of the
127 /// values from the <see cref="ExitCode" /> enumeration.
129 private static int Main(
134 // NOTE: Sanity check the command line arguments.
139 return (int)ExitCode
.MissingArgs
;
142 if (args
.Length
!= 3)
145 return (int)ExitCode
.WrongNumArgs
;
151 // NOTE: Create a regular expression from the first command
152 // line argument. Then, grab the replacement string,
153 // which is the second argument.
155 Regex regEx
= new Regex(args
[0]);
156 string replacement
= args
[1];
159 // NOTE: Attempt to convert the third argument to a boolean.
163 if (!bool.TryParse(args
[2], out matchingOnly
))
166 return (int)ExitCode
.BadMatchingOnlyFlag
;
170 // NOTE: Grab the standard input and output channels from the
173 TextReader inputTextReader
= Console
.In
;
174 TextWriter outputTextWriter
= Console
.Out
;
177 // NOTE: Loop until end-of-file is hit on the standard input
183 // NOTE: Read a line from the standard input channel. If
184 // null is returned here, there is no more input and
187 string inputLine
= inputTextReader
.ReadLine();
189 if (inputLine
== null)
193 // NOTE: Perform regular expression replacements on this
194 // line, if any. Then, write the modified line to
195 // the standard output channel.
197 string outputLine
= regEx
.Replace(inputLine
, replacement
);
199 if (!matchingOnly
|| !String
.Equals(
200 inputLine
, outputLine
, StringComparison
.Ordinal
))
202 outputTextWriter
.WriteLine(outputLine
);
207 // NOTE: At this point, everything has succeeded.
209 return (int)ExitCode
.Success
;
214 // NOTE: An exception was caught. Report it via the console
215 // and return failure.
217 Error(e
.ToString(), false);
218 return (int)ExitCode
.Exception
;