Example #1
0
 private void C_Append(LineReader reader, string args)
 {
     string[] parts = Chop(args);
     if (parts[0] != "-r" && parts.Length >= 2)
     {
         string key = parts[0];
         var sb = new StringBuilder();
         string contents;
         if (TryGetMacro(key, out contents))
         {
             sb.Append(contents);
         }
         for (int i = 1; i < parts.Length; i++)
         {
             string val = parts[i];
             sb.AppendLine().Append(GetMacro(val));
         }
         SetMacro(key, sb.ToString());
         SendMessage("@append {0}", args);
     }
     else
     {
         var append = ReadHereString(reader, false);
         string key = args;
         bool ok = false;
         string contents;
         if (TryGetMacro(key, out contents))
         {
             SetMacro(key, contents + Expand(append));
             ok = true;
         }
         else
         {
             string[] paths = GetFiles(args);
             if (paths.Length != 0)
             {
                 append = Expand(append);
                 foreach (var p in paths)
                 {
                     SetFile(p);
                     if (Write) File.AppendAllText(p, Generate(append));
                     ok = true;
                 }
             }
         }
         if (ok) SendMessage("@append {0}", args);
         else SendMessage("@skip append {0}");
     }
 }
Example #2
0
 private void C_Ask(LineReader reader, string args)
 {
     string[] nv = Chop(args, 2, '=');
     string key = nv[0];
     string text;
     if (!TryGetMacro(key, out text)) text = "";
     if (Interactive)
     {
         if (nv.Length > 1)
         {
             text = Input(nv[1], true, text);
         }
         else
         {
             string contents = ReadHereString(reader);
             string[] lines = contents.Split(new[] { "\r\n" }, StringSplitOptions.None);
             var sb = new StringBuilder();
             int i;
             for (i = 0; i < lines.Length; i++)
             {
                 string s = lines[i];
                 if (s == "-") break;
                 sb.AppendLine(s);
             }
             i++;
             var parts = new string[lines.Length - i];
             Array.Copy(lines, i, parts, 0, parts.Length);
             text = Input(sb.ToString(), true, text, parts);
         }
         //Cancel->null, OK without selection -> ""
         if (text == null)
         {
             SendMessage("@ask -> cancel");
             _Run = false;
         }
         else
         {
             SetMacro(key, text);
             SendKeyValueMessage(key, text);
         }
     }
     else if (nv.Length == 1) ReadCData(reader, "#end");
 }
Example #3
0
 private void C_Udp(LineReader reader, string args)
 {
     string[] parts = Chop(args);
     string contents = ReadHereString(reader);
     using (var u = new UdpClient(parts[0], Convert.ToInt32(parts[1])))
     {
         if (Write)
         {
             byte[] bytes = Encoding.UTF8.GetBytes(contents);
             u.Send(bytes, bytes.Length);
         }
         SendMessage("@udp {0}:{1} {2}", parts[0], parts[1], Truncate(contents, 70));
     }
 }
Example #4
0
        private void C_Post(LineReader reader, string args)
        {
            string[] parts = Chop(args, 2, '=');
            string contents = ReadHereString(reader);
            if (Write && contents.Length > 0)
            {
                var request = (HttpWebRequest)WebRequest.Create(parts[1]);
                byte[] buf = Encoding.UTF8.GetBytes(contents);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = buf.Length;
                request.Credentials = CredentialCache.DefaultCredentials;
                request.UserAgent = "RecipeTool";

                using (Stream st = request.GetRequestStream())
                {
                    st.Write(buf, 0, buf.Length);
                }
                using (var response = request.GetResponse())
                {
                    using (Stream st = response.GetResponseStream())
                    {
                        using (var sr = new StreamReader(st))
                        {
                            _Macros[parts[0]] = sr.ReadToEnd();
                        }
                    }
                }
            }
        }
Example #5
0
 private void C_Output(LineReader reader, string args, string cmd, string rawArgs)
 {
     // info mbox warn write
     string text = (rawArgs == string.Empty) ? ReadHereString(reader) : args;
     if (cmd == "write" || cmd == "print") SendMessage("~{0}", text);
     else SendMessage("@{0} {1}", cmd, text);
 }
Example #6
0
 private string C_Mkdir(LineReader reader, string args)
 {
     args = args.Trim();
     bool force = args.StartsWith("-f");
     string key = force ? args.Substring(3).TrimStart() : args;
     string contents = ReadHereString(reader);
     string[] parts = contents.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
     if (Write) Directory.CreateDirectory(key);
     foreach (string part in parts)
     {
         bool copy = part.StartsWith("+");
         string text = copy ? "copy" : "move";
         var file = (copy ? part.Substring(1) : part).Trim();
         string[] paths = GetFiles(file);
         foreach (string p in paths)
         {
             string dest = Path.Combine(key, Path.GetFileName(p));
             if (force || !File.Exists(dest))
             {
                 if (Write)
                 {
                     if (File.Exists(dest))
                     {
                         File.Delete(dest);
                         text = "repl";
                     }
                     if (copy) File.Copy(p, dest);
                     else File.Move(p, dest);
                 }
                 SendMessage("@file{0} {1}", text, dest);
             }
             else
             {
                 SendMessage("@skip file{0}, already exists: {1}", text, dest);
             }
         }
     }
     return args;
 }
Example #7
0
 private void C_Line(LineReader reader)
 {
     SendMessage(GetLine(reader));
 }
Example #8
0
 private void C_For(LineReader reader, string args)
 {
     string[] parts = Chop(args);
     string fmt = parts[0];
     int min = Convert.ToInt32(parts[1]);
     int step = Convert.ToInt32(parts[2]);
     int max = Convert.ToInt32(parts[3]);
     string contents = ReadCData(reader, "#next");
     SendMessage("@for {0}, {1}..{3} step {2}", fmt, min, step, max);
     for (int i = min; i <= max; i += step)
     {
         SetMacro("_", i.ToString(fmt, CultureInfo.InvariantCulture));
         string text = Expand(contents);
         using (var sr = new LineReader(text, args))
         {
             if (Run(sr) == null && !_Run) break;
         }
     }
 }
Example #9
0
 private void C_CData(LineReader reader, string args)
 {
     string key = args;
     string contents = ReadCData(reader, "#end " + key);
     SetMacro(key, contents);
     SendKeyValueMessage(key, contents);
 }
Example #10
0
 private void C_Write(LineReader reader, string args)
 {
     if (Write)
     {
         string script = ReadCData(reader, null);
         string[] parts = args.Split(':');
         string host = parts[0] == string.Empty ? "0.0.0.0" : parts[0];
         int port = parts.Length < 2 || string.IsNullOrEmpty(parts[1]) ? DefaultPort : Convert.ToInt32(parts[1]);
         if (_Server != null) throw new Exception("Can run only one instance of a server at port " + port);
         _Server = new RecipeServer(host, port, this, script);
         new Thread(_Server.Listen).Start();
         SendMessage("@server {0}", port);
     }
 }
Example #11
0
        private void C_CallExternal(LineReader reader, string args, string cmd)
        {
            if (cmd == "xcopy")
            {
                args = "{xcopy} " + args;
                cmd = "cmd";
            }

            string fmt = "@{0} {1} -> {2}";
            string key, script, text;
            string[] nv;
            if (cmd == "ps" && args.Contains("="))
            {
                nv = Chop(args, 2, '=');
                key = nv[0];
                script = nv[1] + " | Out-String";
                int exitCode = RunPowerShell(script, out text);
                SetMacro("exitcode", exitCode.ToString());
                if (key != string.Empty) SetMacro(key, text);
                SendMessage(fmt, "run here", script, exitCode);
            }
            else if ((cmd == "call" || cmd == "cmd" || cmd == "ps") && !args.Contains("{"))
            {
                script = ReadHereString(reader);
                int exitCode = cmd == "ps" ? RunPowerShell(script, out text) : RunShell(script, out text);
                SetMacro("exitcode", exitCode.ToString());
                key = args;
                if (key != string.Empty) SetMacro(key, text);
                SendMessage(fmt, "run here", script, exitCode);
            }
            else if (cmd == "git")
            {
                if (args.Contains("="))
                {
                    nv = Chop(args, 2, '=');
                    key = nv[0];
                    script = "git.exe " + nv[1]; //"C:\Program Files (x86)\Git\cmd\"
                }
                else
                {
                    key = args;
                    script = ReadHereString(reader);
                    string[] parts = script.Split(new string[] { Environment.NewLine }, StringSplitOptions.None).Select(s => "git.exe " + s).ToArray();
                    script = string.Join(Environment.NewLine, parts);
                }
                string macro = GetMacro("repo");
                if (macro == "")
                {
                    SendMessage("@git -> unknown repo, use #put repo=<drive>:<folder>");
                    SetMacro("exitcode", "test only");
                    throw new Exception("git repo name missing");
                }
                script = "cd \"" + macro + "\"" + Environment.NewLine + script;
                if (macro.Length > 1 && macro[1] == ':') script = macro.Substring(0, 2) + Environment.NewLine + script;
                int exitCode = RunShell(script, out text);
                SetMacro("exitcode", exitCode.ToString());
                text = Regex.Replace(text, @"(?<!\r)\n", "\r\n");
                if (key != string.Empty) SetMacro(key, text);
                SendMessage(fmt, "run git: ", script, exitCode);
            }
            else
            {
                var match = Regex.Match(args, @"\{([^}]+)\}\s*(.*)$"); // #cmd/#run {program} arg1 arg2 arg3 ...
                string prog = match.Groups[1].Value;
                string progArgs = match.Groups[2].Value;
                Process p = Process.Start(prog, progArgs);
                if (cmd == "run")
                {
                    SendMessage(fmt, cmd, args, "async");
                }
                else if (p != null)
                {
                    p.WaitForExit();
                    SetMacro("exitcode", p.ExitCode.ToString());
                    SendMessage(fmt, cmd, args, p.ExitCode);
                }
            }
        }
Example #12
0
 private void C_With(LineReader reader, string args)
 {
     if (!string.IsNullOrEmpty(args))
     {
         string[] parts = Chop(args, 2, '=');
         string key = parts[0];
         string script = parts.Length == 2 ? parts[1].TrimStart() : ReadHereString(reader);
         string text;
         string[] paths;
         if (TryGetMacro(key, out text))
         {
             text = Apply(script, text);
             SetMacro(key, text);
             SendKeyValueMessage(key, script);
         }
         else
         {
             paths = GetFiles(args);
             foreach (string p in paths)
             {
                 text = File.ReadAllText(p);
                 text = Apply(script, text);
                 if (Write) File.WriteAllText(p, text);
                 SendMessage("@with {0}", p);
             }
         }
     }
 }
Example #13
0
 private void C_While_Until(LineReader reader, string args, string cmd)
 {
     string[] parts = Chop(args, 2, ' ');
     string macro = parts[0];
     string rx = parts[1];
     bool not = cmd == "until";
     string contents = ReadCData(reader, "#loop");
     SendMessage("@{0} {1} {2}", cmd, macro, rx);
     string text;
     while (not ^ (TryGetMacro(macro, out text) && Regex.IsMatch(text, rx)))
     {
         text = Expand(contents);
         using (var sr = new LineReader(text, name: args))
         {
             if (Run(sr) == null && !_Run) break;
         }
     }
 }
Example #14
0
 private void C_Watch(LineReader reader, string args)
 {
     if (Write)
     {
         string script = ReadCData(reader, null);
         string[] parts = Chop(args, 2, ' ');
         _Watcher = new Watcher(this, script);
         new Thread(() => _Watcher.ExecutionLoop(parts[0], parts[1])).Start();
         SendMessage("@watch {0}", args);
     }
 }
Example #15
0
        private void C_Expn(LineReader reader, string args)
        {
            /* compare #expn vs. #with template
                #put a
                one|two|three
                four|five|six
                #end

                #with a
                template insert $1 into $2 yield $3
                #end

                #info `a`

                ---

                #cdata b
                insert `1` into `2` yield `3`...

                #end b

                #expn b
                one|two|three
                four|five|six
                #end

                #info `b`
             */
            string key = args;
            string text;
            if (TryGetMacro(key, out text))
            {
                string contents = ReadHereString(reader, true);
                var sb = new StringBuilder();
                string[] parts = contents.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string s in new TemplateExpander(text, parts, Put, Expand).Instances())
                {
                    sb.Append(s);
                }
                SetMacro(key, sb.ToString());
            }
        }
Example #16
0
 private void C_Csharp(LineReader reader, string args)
 {
     string script = ReadHereString(reader);
     var result = CSharp.Build(script);
     string text;
     if (result.Errors.HasErrors)
     {
         text = string.Join(Environment.NewLine, CSharp.Errors(result));
         SendMessage("@csharp {0}", text);
     }
     else if (Write)
     {
         string[] parts = Chop(args);
         string key = parts[0];
         parts = parts.Where((s, i) => i > 0).Select(s => GetMacro(s)).ToArray();
         text = CSharp.Execute(result.CompiledAssembly, parts);
         if (key != string.Empty) SetMacro(key, text);
     }
     else SendMessage("@csharp skip (test mode)");
 }
Example #17
0
 private void C_Extract(LineReader reader, string args, string cmd)
 {
     string rx, macro;
     string[] paths;
     if (GetRxLine(args, out rx, out paths, out macro))
     {
         string text, contents;
         if (macro != null && TryGetMacro(macro, out text))
         {
             contents = ReadHereString(reader);
             text = Replace(contents, text, rx);
             _Macros[macro] = text;
             SendKeyValueMessage(macro, text);
         }
         else
         {
             if (paths.Length == 0)
             {
                 ReadHereString(reader, false);
                 SendMessage("@skip {0} {1}", cmd, args);
             }
             else
             {
                 contents = ReadHereString(reader, false);
                 foreach (string p in paths)
                 {
                     SetFile(p);
                     string inst = Expand(contents);
                     text = File.ReadAllText(p);
                     text = Replace(inst, text, rx);
                     if (Write)
                     {
                         File.WriteAllText(p, text);
                     }
                     SendMessage("@{0} {1}", cmd, p);
                 }
             }
         }
     }
     else
     {
         ReadHereString(reader, false);
         SendMessage("@nomatch {0}: {1}", cmd, args);
     }
 }
Example #18
0
 /// <summary>
 /// Converts dates found in the macro text or files, using the given spec.
 /// </summary>
 /// <param name="spec">4 lines: 1. input format (*=any), 2. input time zone (*=UTC), 3. output time zone. (*=same as input), 4. output format (*=same as input)</param>
 /// <param name="args">rxline: rx macro/paths</param>
 private void C_Date(LineReader reader, string args)
 {
     string spec = ReadHereString(reader);
     string srx, macro;
     string[] paths;
     if (GetRxLine(args, out srx, out paths, out macro))
     {
         Regex rx = new Regex(srx, RegexOptions.CultureInvariant | RegexOptions.Compiled);
         if (macro != null)
         {
             string text;
             if (TryGetMacro(macro, out text))
             {
                 string text1 = ConvertDateTime(text, rx, spec);
                 SetMacro(macro, text1);
             }
         }
         else
         {
             foreach (string p in paths)
             {
                 string text = File.ReadAllText(p);
                 string text1 = ConvertDateTime(text, rx, spec);
                 File.WriteAllText(p, text1);
             }
         }
     }
 }
Example #19
0
 private bool C_If_Ifnot(LineReader reader, string args, string cmd, out string val)
 {
     string[] parts = Chop(args, 2, ' ');
     string macro = parts[0];
     string rx = parts[1];
     bool isElse;
     bool not = cmd == "ifnot";
     string text, contents;
     if (not ^ (TryGetMacro(macro, out text) && Regex.IsMatch(text, rx)))
     {
         contents = Expand(ReadConditionalBlock(reader, out isElse));
         using (var sr = new LineReader(contents, args + " (then)"))
         {
             SendMessage("@{0} ({1})->then", cmd, macro);
             val = Run(sr);
             if (val != null) return true;
         }
         if (isElse) ReadCData(reader, "#endif");
     }
     else
     {
         ReadConditionalBlock(reader, out isElse);
         if (isElse)
         {
             contents = Expand(ReadCData(reader, "#endif"));
             using (var sr = new LineReader(contents, args + " (else)"))
             {
                 SendMessage("@{0} ({1})->else", cmd, macro);
                 val = Run(sr);
                 if (val != null) return true;
             }
         }
     }
     val = null;
     return false;
 }
Example #20
0
 private void C_Def(LineReader reader, string args)
 {
     string[] parts = Chop(args);
     string key = parts[0];
     if (key.Length < 1 || key[0] < 'A' || key[0] > 'Z') throw new ArgumentException("#def name must start with capital A..Z");
     string text = ReadCData(reader, "#enddef");
     string[] arr = new string[parts.Length - 1];
     Array.Copy(parts, 1, arr, 0, parts.Length - 1);
     _CustomCommands[key] = new CustomCommand(key, text, arr);
 }
Example #21
0
 private void C_Iter(LineReader reader, string args)
 {
     string[] parts = Chop(args, 3, ' ');
     string key, text, contents;
     if (parts.Length >= 3)
     {
         // #iter list recipe i
         key = parts[2];
         text = GetMacro(parts[1]); // recipe
         contents = GetMacro(parts[0]);
         SetMacro(key, contents);
     }
     else if (parts.Length == 2)
     {
         // #putv i=list
         // #iter i recipe
         key = parts[0];
         text = GetMacro(parts[1]); // recipe
         contents = GetMacro(key);
     }
     else
     {
         // #iter list
         // ... `_` ...
         // #next
         key = "_";
         text = ReadCData(reader, "#next"); // recipe
         contents = GetMacro(parts[0]);
     }
     string[] items = contents.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
     string itemKey = key;
     int n = 0;
     foreach (string item in items)
     {
         n++;
         SendMessage("@iter {0} = {1}", key, item);
         using (var sr = new LineReader(text, string.Format("{0} #{1}", args, n)))
         {
             _Macros[itemKey] = item;
             if (Run(sr) == null && !_Run) break;
         }
     }
     _Macros.Remove(itemKey);
 }
Example #22
0
 private void C_Default(LineReader reader, string args, string cmd)
 {
     string key = args.Trim();
     CustomCommand cc;
     if (_CustomCommands.TryGetValue(cmd, out cc))
     {
         string text = ReadHereString(reader, true);
         string val = ExecuteCustomCommand(cc, text);
         if (key != "") SetMacro(key, val);
     }
     else if (cmd != "tags" && cmd != "auto")
     {
         throw new Exception("Unknown command: #" + cmd);
     }
 }
Example #23
0
 private void C_MakeXml(LineReader reader, string args)
 {
     if (string.IsNullOrEmpty(args)) throw new Exception("#makexml needs key and here-text");
     var contents = ReadHereString(reader, true);
     string xml = LightXml.ToNormalXml(contents);
     SetMacro(args, xml);
     SendMessage("@makexml {0}", args);
 }
Example #24
0
 private void C_Email(LineReader reader, string args)
 {
     string[] ra = Chop(args, 2, ' ');
     if (ra.Length > 0)
     {
         string recip = ra[0];
         string body = ReadHereString(reader);
         string[] att = ra.Length > 1 ? ra[1].Trim().Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries) : new string[0];
         string sender;
         if (!TryGetMacro("smtp-sender", out sender))
         {
             SendMessage("@skip email: macro smtp-sender not defined");
         }
         else
         {
             var mm = new MailMessage(sender, recip, _MarkerName, body);
             foreach (string file in att)
             {
                 mm.Attachments.Add(new Attachment(file));
             }
             SmtpClient client = GetSmtpClient();
             if (client == null)
             {
                 SendMessage("@skip email: macro smtp-host not defined");
             }
             else
             {
                 if (Write)
                 {
                     try
                     {
                         client.Send(mm);
                     }
                     catch
                     {
                         // email doesn't work, just write it out
                         SendMessage("~{0}", body);
                     }
                 }
                 SendMessage("@email " + recip);
             }
         }
     }
 }
Example #25
0
 private void C_New_Newer(LineReader reader, string args, string cmd)
 {
     string path;
     SetFile(path = args);
     string contents = ReadHereString(reader);
     string directory = Path.GetDirectoryName(path);
     if (string.IsNullOrEmpty(directory))
     {
         SendMessage("@skip new {0} -> directory missing", path);
     }
     else
     {
         if (!Directory.Exists(directory))
         {
             if (Write) Directory.CreateDirectory(directory);
             SendMessage("@new {0}", directory);
         }
         if (cmd == "newer" || !File.Exists(path))
         {
             if (Write) File.WriteAllText(path, contents);
             SendMessage("@{0} {1}", cmd, path);
         }
         else
         {
             SendMessage("@skip new {0}", path);
         }
     }
 }
Example #26
0
 private void C_Esc(LineReader reader, string args)
 {
     string[] nv = Chop(args, 2, '=');
     string rx = Regex.Escape(nv.Length == 2 ? nv[1] : ReadHereString(reader));
     SetMacro(nv[0], rx);
     SendMessage("@esc {0}", rx);
 }
Example #27
0
 private void C_Path(LineReader reader, string args)
 {
     string key = args;
     string contents = ReadHereString(reader);
     string[] parts = contents.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
     string text = Path.Combine(parts);
     SetMacro(key, text);
 }
Example #28
0
 private void C_EscXml(LineReader reader, string args)
 {
     string[] nv = Chop(args, 2, '=');
     string xml = SecurityElement.Escape(nv.Length == 2 ? nv[1] : ReadHereString(reader));
     SetMacro(nv[0], xml);
     SendMessage("@escxml {0}", nv[0]);
 }
Example #29
0
        private void InitializeRecipe()
        {
            try
            {
                ConfigUtils.RefreshAppSettings();
                string recipePath = ConfigUtils.GetString("Path", @"~prog\Main.rcp");
                recipePath = ExpandPath(recipePath);
                _LogLevel = ConfigUtils.GetValue("LogLevel", 1);

                var macros = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
                // add all environment variables to the dictionary
                IDictionary env = Environment.GetEnvironmentVariables();
                foreach (string key in env.Keys) macros.Add(key, (string)env[key]);

                // parse config file arguments and add to dictionary
                string[] args = ConfigUtils.GetArray("Macros", "");
                var sb = new StringBuilder();
                if (args != null)
                {
                    foreach (string t in args)
                    {
                        string[] nv = t.Split('=');
                        if (nv.Length == 2)
                        {
                            string key = nv[0].Trim();
                            string value = ExpandPath(nv[1].Trim());
                            macros[key] = value;
                            sb.Append(key).Append('=').Append(value).Append('|');
                        }
                        else throw new Exception("Invalid argument: " + t);
                    }
                }
                Log(0, "Macros from configuration: [{0}]", sb.ToString().TrimEnd('|'));
                _RecipeExec = new Recipe { Write = true };
                _RecipeExec.ClearHandlers();
                _RecipeExec.Message += HandleMessage;
                _RecipeExec.SetRootPath(recipePath);

                using (LineReader sr = new LineReader(File.OpenText(recipePath), name: recipePath))
                {
                    Log(0, "Running: [{0}] LogLevel: {1}", recipePath, _LogLevel);
                    _RecipeExec.Run(sr, macros, string.Empty);
                }
            }
            catch (ApplicationException)
            {
                Log(0, "Recipe Exit {0}");
            }
            catch (Exception ex)
            {
                Log(1, "{0}", ex);
            }
        }
Example #30
0
        private void C_Before_Subs_After(LineReader reader, string args, string cmd)
        {
            string rx, macro;
            string[] paths;
            if (GetRxLine(args, out rx, out paths, out macro))
            {
                string text;
                string contents;
                if (macro != null && TryGetMacro(macro, out text))
                {
                    contents = ReadHereString(reader);
                    string repl =
                        cmd == "subs"
                            ? contents
                            : cmd == "before" ? contents + "$0" : "$0" + contents;
                    text = Regex.Replace(text, rx, repl);
                    _Macros[macro] = text;
                    SendKeyValueMessage(macro, text);
                }
                else
                {
                    if (paths.Length == 0)
                    {
                        ReadHereString(reader, false);
                        SendMessage("@skip {0} {1}", cmd, args);
                    }
                    else
                    {
                        contents = ReadHereString(reader, false);
                        foreach (string p in paths)
                        {
                            SetFile(p);
                            string inst = Expand(Generate(contents));
                            string repl =
                                cmd == "subs"
                                    ? inst
                                    : cmd == "before" ? inst + "$0" : "$0" + inst;

                            text = File.ReadAllText(p);
                            var text1 = Regex.Replace(text, rx, repl);
                            if (Write && text != text1)
                            {
                                File.WriteAllText(p, text1);
                                SendMessage("@{0} {1}", cmd, p);
                            }
                        }
                    }
                }
            }
            else
            {
                ReadHereString(reader, false);
                SendMessage("@nomatch {0}: {1}", cmd, args);
            }
        }