예제 #1
0
        // The pipe that is being called.

        /// <summary>
        /// Compiles the filter.
        /// </summary>
        public override void Compile(string cmdLineText, int initialCharPos)
        {
            // Parse the filter's command line:

            LoggingEnabled = true;
            LogWrite("Call.Compile: begin");
            CmdLine.Text = cmdLineText;
            CmdLine.IgnoringExtraneousText = true;
            CmdLine.Parse(initialCharPos, true);

            // Load and compile the contents of the saved-to-disk pipe:

            string pipePath = (string)CmdLine.GetArg(0).Value;

            LogWrite("Call.Compile: Called pipe: \"" + pipePath + "\"");

            if (System.IO.File.Exists(pipePath))
            {
                // The pipe file exists.  Create a new pipe object from the pipe file's contents:

                string tempStr    = System.IO.Path.GetFullPath(pipePath);
                string pipeFolder = System.IO.Path.GetDirectoryName(tempStr);
                string pipeName   = System.IO.Path.GetFileName(tempStr);
                string pipeScript = System.IO.File.ReadAllText(pipePath);
                CalledPipe = new Pipe(pipeScript, (Engine)Eng, pipeFolder, pipeName,
                                      ((Filter)Host).CoreLoggingEnabled, false);
                CalledPipe.DebugFile = ((Filter)Host).DebugFile;
                CalledPipe.Errors    = ((Filter)Host).Errors;

                // Save the current folder because Pipe.Compile() may change it:

                string savedFolder = System.Environment.CurrentDirectory;

                // Compile the pipe using the CALL filter's
                // "extraneous" command line parameters:

                CalledPipe.Compile(CmdLine.Text, ((CommandLine)CmdLine).CmdLinePtr, Source, PipeLineNo);

                // Restore the prior-saved current folder:

                Directory.SetCurrentDirectory(savedFolder);
            }
            else
            {
                // Pipe file doesn't exist.

                PipeWrenchCompileException ex = new PipeWrenchCompileException("Pipe file not found.");
                ex.Data.Add("CharPos", ((CommandLine)CmdLine).CmdLinePtr);
                ex.Data.Add("CmdLine", CmdLine.Text);
                throw ex;
            }

            LogWrite("Call.Compile: end");
        }
예제 #2
0
        /// <summary>
        /// This routine converts all 2-digit hexadecimal numbers preceded
        /// by a pound character found in the given string into the characters
        /// represented by each three-character sequence. Two pound characters
        /// found together are interpreted as meaning a single one.
        /// </summary>
        public string XlatPoundSigns(string TheStr)
        {
            string methodName = "CommandLine.XlatPoundSigns";
             LogWrite(methodName + ": Start");
             LogWrite(methodName + ": Input string: " + TheStr);
             char keyChar = '#';
             int charPos = 0;
             string result = string.Empty;
             bool done = false;
             char ch;
             string hexStr = string.Empty;
             int state = 0;
             ToState(ref state, 1, methodName);

             // Translate the string:

             while (!done)
             {
            switch (state)
            {
               case 1:
                  ch = GetNextChar(TheStr, ref charPos);

                  if (ch != '\0')
                  {
                     // Got a character.

                     if (ch == keyChar)
                        ToState(ref state, 2, methodName);
                     else
                        result += ch;
                  }
                  else
                  {
                     // String processed successfully.

                     done = true;
                  }
                  break;

               case 2:
                  ch = GetNextChar(TheStr, ref charPos);

                  if (ch != '\0')
                  {
                     // Got a character.

                     if (IsHexDigit(ch))
                     {
                        // First hex digit scanned.

                        hexStr = ch.ToString();
                        ToState(ref state, 3, methodName);
                     }
                     else
                     {
                        if (ch == keyChar)
                        {
                           // Insert a # character:

                           result += keyChar;
                           ToState(ref state, 1, methodName);
                        }
                        else
                        {
                           // # or hex digit expected.

                           PipeWrenchCompileException ex = new PipeWrenchCompileException("# or hex digit expected.");
                           ex.Data.Add("Offset", charPos-1);
                           throw ex;
                        }
                     }
                  }
                  else
                  {
                     // Abrupt end-of-data.

                     PipeWrenchCompileException ex =
                     new PipeWrenchCompileException("# or hex digit expected but end-of-string encountered.");
                     ex.Data.Add("Offset", charPos);
                     throw ex;
                  }

                  break;

               case 3:
                  ch = GetNextChar(TheStr, ref charPos);

                  if (ch != '\0')
                  {
                     // Got a character.

                     if (IsHexDigit(ch))
                     {
                        // 2nd hex digit scanned.  Insert
                        // the actual represented character:

                        hexStr += ch;
                        result += (char) Convert.ToInt32(hexStr, 16);
                        ToState(ref state, 1, methodName);
                     }
                     else
                     {
                        // Hex digit expected.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException("Hex digit expected.");
                        ex.Data.Add("Offset", charPos-1);
                        throw ex;
                     }
                  }
                  else
                  {
                     // Abrupt end-of-data.

                     PipeWrenchCompileException ex =
                     new PipeWrenchCompileException("Hex digit expected but end-of-string encountered.");
                     ex.Data.Add("Offset", charPos);
                     throw ex;
                  }
                  break;
            }
             }

             LogWrite(methodName + ": Result string: " + result);
             LogWrite(methodName + ": Finish");
             return result;
        }
예제 #3
0
        /// <summary>
        /// This routine interprets all backslash
        /// escape sequences in the given string.
        /// </summary>
        public string XlatBackslashes(string TheStr)
        {
            string methodName = "CommandLine.XlatBackslashes";
             LogWrite(methodName + ": Start");
             LogWrite(methodName + ": Input string: " + TheStr);
             char backslashChar = '\\';
             int charPos = 0;
             string result = string.Empty;
             bool done = false;
             char ch = '\0';
             string hexStr = string.Empty;
             int state = 0;
             ToState(ref state, 1, methodName);

             // Translate the string:

             while (!done)
             {
            switch (state)
            {
               case 1:
                  ch = GetNextChar(TheStr, ref charPos);

                  if (ch != '\0')
                  {
                     // Got a character.

                     if (ch == backslashChar)
                        ToState(ref state, 2, methodName);
                     else
                        result += ch;
                  }
                  else
                  {
                     // String processed successfully.

                     done = true;
                  }

                  break;

               case 2:
                  ch = GetNextChar(TheStr, ref charPos);

                  if (ch != '\0')
                  {
                     // Got a character following a backslash.

                     switch (ch.ToString().ToUpper())
                     {
                        case "0":
                           result += '\0';
                           ToState(ref state, 1, methodName);
                           break;

                        case "A":
                           result += '\a';
                           ToState(ref state, 1, methodName);
                           break;

                        case "B":
                           result += '\b';
                           ToState(ref state, 1, methodName);
                           break;

                        case "E":

                           // This escape isn't recognized as a standard. I've added it in order
                           // to represent an end-of-line sequence regardless of what system PipeWrench
                           // is executing on.

                           result += System.Environment.NewLine;
                           ToState(ref state, 1, methodName);
                           break;

                        case "F":
                           result += '\f';
                           ToState(ref state, 1, methodName);
                           break;

                        case "N":
                           result += '\n';
                           ToState(ref state, 1, methodName);
                           break;

                        case "R":
                           result += '\r';
                           ToState(ref state, 1, methodName);
                           break;

                        case "T":
                           result += '\t';
                           ToState(ref state, 1, methodName);
                           break;

                        case "V":
                           result += '\v';
                           ToState(ref state, 1, methodName);
                           break;

                        case "\'":
                           result += '\'';
                           ToState(ref state, 1, methodName);
                           break;

                        case "\"":
                           result += '"';
                           ToState(ref state, 1, methodName);
                           break;

                        case "\\":
                           result += '\\';
                           ToState(ref state, 1, methodName);
                           break;

                        case "X":
                           ToState(ref state, 3, methodName);
                           break;

                        default:
                           result += ch;
                           ToState(ref state, 1, methodName);
                           break;
                     }
                  }
                  else
                  {
                     // Abrupt end-of-data.

                     PipeWrenchCompileException ex = new PipeWrenchCompileException(
                     "Abrupt end-of-data.");
                     ex.Data.Add("Offset", charPos-1);
                     throw ex;
                  }

                  break;

               case 3:

                  // Have "\x".

                  ch = GetNextChar(TheStr, ref charPos);

                  if (ch != '\0')
                  {
                     // Got a character.

                     if (IsHexDigit(ch))
                     {
                        // First hex digit scanned.

                        hexStr = ch.ToString();
                        ToState(ref state, 4, methodName);
                     }
                     else
                     {
                        // Character is not a hex digit.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException(
                        "Hex digit expected.");
                        ex.Data.Add("Offset", charPos-1);
                        throw ex;
                     }
                  }
                  else
                  {
                     // Abrupt end-of-data.

                     PipeWrenchCompileException ex = new PipeWrenchCompileException(
                     "Abrupt end-of-data.");
                     ex.Data.Add("Offset", charPos-1);
                     throw ex;
                  }

                  break;

               case 4:

                  // Have "\xn".

                  ch = GetNextChar(TheStr, ref charPos);

                  if (ch != '\0')
                  {
                     // Got a character.

                     if (IsHexDigit(ch))
                     {
                        // 2nd hex digit scanned.  Insert the actual represented
                        // character and continue scanning the string:

                        hexStr += ch;
                        result += (char) Convert.ToInt32(hexStr, 16);
                        ToState(ref state, 1, methodName);
                     }
                     else
                     {
                        // Character is not a hex digit.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException(
                        "Hex digit expected.");
                        ex.Data.Add("Offset", charPos-1);
                        throw ex;
                     }
                  }
                  else
                  {
                     // Abrupt end-of-data.

                     PipeWrenchCompileException ex = new PipeWrenchCompileException(
                     "Abrupt end-of-data.");
                     ex.Data.Add("Offset", charPos-1);
                     throw ex;
                  }

                  break;
            }
             }

             LogWrite(methodName + ": Result string: " + result);
             LogWrite(methodName + ": Finish");
             return result;
        }
예제 #4
0
        /// <summary>
        /// Parses the command line arguments.
        /// </summary>
        public void Parse(int initPos, bool xlatStrings)
        {
            string MethodName = "CommandLine.Parse";
             bool Done = false;
             char Ch;
             bool ParamIsOptional = false;
             int TemplPtr = 0;
             CmdLinePtr = initPos;
             LogWrite(MethodName + ": Parsing \"" + this.Text + "\" using template, \"" + Template +
             "\" starting at CharPos " + initPos.ToString() + ".");
             LogWrite(MethodName + ": IgnoringExtraneousText = " + IgnoringExtraneousText);
             LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
             int State = 0;
             ToState(ref State, 1, MethodName);

             while (!Done)
             {
            switch (State)
            {
               case 1:
                  Ch = GetNextChar(Template, ref TemplPtr);

                  switch (Ch)
                  {
                     case 'n':
                        ToState(ref State, 2, MethodName);
                        break;

                     case 's':
                        ToState(ref State, 3, MethodName);
                        break;

                     case '[':
                        ParamIsOptional = true;
                        LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                        break;

                     case ']':

                        // do nothing

                        break;

                     case '.':
                        ToState(ref State, 4, MethodName);
                        break;

                     case '/':

                        // switch encountered

                        ToState(ref State, 7, MethodName);
                        break;

                     case '\0':

                        // end of template encountered

                        ToState(ref State, 5, MethodName);
                        break;

                     case ' ':

                        // Ignore and keep scanning...

                        break;

                     case '\t':

                        // Ignore and keep scanning...

                        break;

                     default:

                        // Invalid template character.

                        throw new PipeWrenchEngineException("Template is invalid.");
                  }
                  break;

               case 2:

                  // An integer is expected according to the template.

                  Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                  if ("0123456789-+".IndexOf(Ch) != -1)
                  {
                     // Found an integer.  Back up a character and parse it:

                     CmdLinePtr--;
                     string Token = "";

                     while ((CmdLinePtr < this.Text.Length) && (this.Text[CmdLinePtr] != ' ') &&
                     (this.Text[CmdLinePtr] != '\t'))
                     {
                        Token += this.Text[CmdLinePtr];
                        CmdLinePtr++;
                     }

                     try
                     {
                        // Convert the token to an integer value:

                        int Value = Convert.ToInt32(Token);
                        LogWrite(MethodName + ": IntArg value = " + Value.ToString());
                        Argument arg = new Argument(Value, CmdLinePtr);
                        Args.Add(arg);
                     }
                     catch (Exception)
                     {
                        PipeWrenchCompileException ex = new PipeWrenchCompileException("Integer value is invalid.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                     }

                     if (ParamIsOptional)
                     {
                        // Found first parameter in optional
                        // sequence.  Now all other parameters
                        // to end of sequence are required.

                        ParamIsOptional = false;
                        LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                     }

                     ToState(ref State, 1, MethodName);
                  }
                  else
                  {
                     if (Ch == '\'')
                     {
                        // String encountered instead of an integer.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException("Integer expected for this parameter.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                     }
                     else
                     {
                        if (Ch == '/')
                        {
                           // Switch encountered instead of an integer.

                           if (ParamIsOptional)
                           {
                              ToState(ref State, 6, MethodName);
                           }
                           else
                           {
                              // Expected integer value was not found.

                              PipeWrenchCompileException ex =
                              new PipeWrenchCompileException("Expected an integer parameter but switch was encountered.");
                              ex.Data.Add("CharPos", CmdLinePtr);
                              ex.Data.Add("CmdLine", this.Text);
                              throw ex;
                           }
                        }
                        else
                        {
                           if (Ch == '\0')
                           {
                              // Reached the end of the command line.

                              if (ParamIsOptional)
                              {
                                 Done = true;
                              }
                              else
                              {
                                 // Expected integer value was not found.

                                 PipeWrenchCompileException ex =
                                 new PipeWrenchCompileException("Expected an integer parameter but end-of-line was encountered.");
                                 ex.Data.Add("CharPos", CmdLinePtr);
                                 ex.Data.Add("CmdLine", this.Text);
                                 throw ex;
                              }
                           }
                           else
                           {
                              if ((Ch == ' ') || (Ch == '\t'))
                              {
                                 // It's a whitespace character.  Just ignore it and keep scanning...
                              }
                              else
                              {
                                 // Expected integer value was not found.

                                 PipeWrenchCompileException ex =
                                 new PipeWrenchCompileException("Integer expected for this parameter.");
                                 ex.Data.Add("CharPos", CmdLinePtr);
                                 ex.Data.Add("CmdLine", this.Text);
                                 throw ex;
                              }
                           }
                        }
                     }
                  }

                  break;

               case 3:

                  // A string is expected according to the template.

                  Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                  if (Ch == '\'')
                  {
                     // Found a string.  Back up and parse it:

                     CmdLinePtr--;
                     string Token;

                     if (xlatStrings)
                     {
                        string tempStr = GetString(this.Text, ref iCmdLinePtr, '\'', true);

                        try
                        {
                           Token = XlatEscapes(tempStr);
                        }

                        catch (PipeWrenchCompileException ex)
                        {
                           ex.Data.Add("CmdLine", this.Text);
                           ex.Data["CharPos"] = CmdLinePtr - tempStr.Length + (int) ex.Data["Offset"];
                           throw ex;
                        }
                     }
                     else
                     {
                        Token = GetString(this.Text, ref iCmdLinePtr, '\'', false);
                     }

                     Argument arg = new Argument(Token, iCmdLinePtr);
                     Args.Add(arg);

                     if (ParamIsOptional)
                     {
                        // Found first parameter in optional sequence.  Now all other
                        // parameters to end of sequence are required.

                        ParamIsOptional = false;
                        LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                     }

                     ToState(ref State, 1, MethodName);
                  }
                  else
                  {
                     if ("0123456789-+".IndexOf(Ch) != -1)
                     {
                        // An integer was encountered.

                        PipeWrenchCompileException ex =
                        new PipeWrenchCompileException("String expected for this parameter.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                     }
                     else
                     {
                        if (Ch == '/')
                        {
                           // A switch was encountered.

                           if (ParamIsOptional)
                           {
                              ToState(ref State, 6, MethodName);
                           }
                           else
                           {
                              PipeWrenchCompileException ex =
                              new PipeWrenchCompileException("Expected a string parameter but switch was encountered.");
                              ex.Data.Add("CharPos", CmdLinePtr);
                              ex.Data.Add("CmdLine", this.Text);
                              throw ex;
                           }
                        }
                        else
                        {
                           if (Ch == '\0')
                           {
                              // Reached the end of the command line.

                              if (ParamIsOptional)
                              {
                                 Done = true;
                              }
                              else
                              {
                                 // Expected string value was not found.

                                 PipeWrenchCompileException ex =
                                 new PipeWrenchCompileException("Expected a string parameter but end-of-line was encountered.");
                                 ex.Data.Add("CharPos", CmdLinePtr);
                                 ex.Data.Add("CmdLine", this.Text);
                                 throw ex;
                              }
                           }
                           else
                           {
                              if ((Ch == ' ') || (Ch == '\t'))
                              {
                                 // It's a whitespace character.  Just ignore it and keep scanning...
                              }
                              else
                              {
                                 // Expected string value was not found.

                                 PipeWrenchCompileException ex =
                                 new PipeWrenchCompileException("String expected for this parameter.");
                                 ex.Data.Add("CharPos", CmdLinePtr);
                                 ex.Data.Add("CmdLine", this.Text);
                                 throw ex;
                              }
                           }
                        }
                     }
                  }

                  break;

               case 4:

                  // Backtracking through optional sequence.

                  int savedTemplPtr = TemplPtr;

                  try
                  {
                     while (Template[TemplPtr] != '[')
                     {
                        TemplPtr--;
                     }
                  }

                  catch (Exception)
                  {
                     PipeWrenchTemplateException ex =
                     new PipeWrenchTemplateException(
                     "Template error: Repeating group (...) is only allowed inside \"[]\".");
                     ex.Data.Add("CharPos", savedTemplPtr);
                     ex.Data.Add("Template", Template);
                     throw ex;
                  }

                  TemplPtr++;
                  ParamIsOptional = true;
                  LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                  ToState(ref State, 1, MethodName);
                  break;

               case 5:

                  // End of template encountered.

                  if (!IgnoringExtraneousText)
                  {
                     // Be sure that remainder of command line is clear
                     // as additional parameters, (including switches)
                     // are not expected:

                     Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                     if (Ch == '\0')
                     {
                        Done = true;
                     }
                     else
                     {
                        if ((Ch == ' ') || (Ch == '\t'))
                        {
                           // It's a whitespace character.  Just ignore it and keep scanning...
                        }
                        else
                        {
                           PipeWrenchCompileException ex =
                           new PipeWrenchCompileException("Parameter or switch is extraneous.");
                           ex.Data.Add("CharPos", CmdLinePtr);
                           ex.Data.Add("CmdLine", this.Text);
                           throw ex;
                        }
                     }
                  }
                  else
                  {
                     Done = true;
                  }

                  break;

               case 6:

                  // Switch encountered.

                  if (CmdLinePtr < this.Text.Length)
                  {
                     // Not yet to the end of the command line.

                     string SwitchID = "/" + Char.ToUpper(this.Text[CmdLinePtr]);
                     CmdLinePtr++;
                     ParseSwitch(SwitchID, ref iCmdLinePtr, ref TemplPtr, xlatStrings);
                     ToState(ref State, 7, MethodName);
                  }
                  else
                  {
                     // End of command line was encountered.  Switch
                     // character, (/) was found without a succeeding
                     // ID character.

                     PipeWrenchCompileException ex =
                     new PipeWrenchCompileException("Switch is incomplete.");
                     ex.Data.Add("CharPos", CmdLinePtr);
                     ex.Data.Add("CmdLine", this.Text);
                     throw ex;
                  }

                  break;

               case 7:

                  // Locate the next switch on the command line:

                  Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                  switch (Ch)
                  {
                     case '/':

                        // Found it.

                        ToState(ref State, 6, MethodName);
                        break;

                     case '\0':
                        Done = true;
                        break;

                     case ' ':

                        // Whitespace character.  Just ignore it and keep scanning...

                        break;

                     case '\t':

                        // Whitespace character.  Just ignore it and keep scanning...

                        break;

                     default:
                        PipeWrenchCompileException ex =
                        new PipeWrenchCompileException("A switch was expected.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                  }

                  break;

               default:
                  throw new PipeWrenchEngineException(MethodName +
                  ": Invalid state (" + State.ToString() + ").");
            }
             }
        }
예제 #5
0
        /// <summary>
        /// Parses a switch.
        /// </summary>
        private void ParseSwitch(string SwitchID, ref int CmdLinePtr, ref int TemplPtr, bool xlatStrings)
        {
            string MethodName = "CommandLine.ParseSwitch";
             LogWrite(MethodName + ": SwitchID = " + SwitchID);
             char SwitchType;
             int i = Template.ToUpper().IndexOf(SwitchID.ToUpper());

             if (i > -1)
             {
            // The switch is expected.  Set the template
            // pointer to point to the switch's type:

            TemplPtr = i + 2;

            // Determine the type of switch:

            if (TemplPtr < Template.Length)
            {
               // Not yet to end-of-template.

               if ((Template[TemplPtr] == 'n') || (Template[TemplPtr] == 's'))
               {
                  SwitchType = Template[TemplPtr];
               }
               else
               {
                  SwitchType = 'b';
               }
            }
            else
            {
               // Reached the end of the template.

               SwitchType = 'b';
            }

            // Parse the switch's setting: }

            LogWrite(MethodName + ": SwitchType = \"" + SwitchType + "\"");
            switch (SwitchType)
            {
               case 'n':
                  if ((CmdLinePtr < this.Text.Length) && ("0123456789-+".IndexOf(this.Text[CmdLinePtr]) != -1))
                  {
                     // The first character is part of an integer.  Parse it:

                     string Token = "";

                     while ((CmdLinePtr < this.Text.Length) && (this.Text[CmdLinePtr] != ' ') &&
                     (this.Text[CmdLinePtr] != '\t'))
                     {
                        Token += this.Text[CmdLinePtr];
                        CmdLinePtr++;
                     }

                     try
                     {
                        // Convert the token to an integer value:

                        int Value = Convert.ToInt32(Token);
                        Switch TheSwitch = new Switch(SwitchID, Value, CmdLinePtr);
                        LogWrite(MethodName + ": IntSwitch value = " + Value.ToString());
                        Switches.Add(TheSwitch);
                     }
                     catch (Exception)
                     {
                        PipeWrenchCompileException ex =
                        new PipeWrenchCompileException("Integer value is invalid");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                     }
                  }
                  else
                  {
                     // The first character is not part of an integer.

                     PipeWrenchCompileException ex =
                     new PipeWrenchCompileException("Expected an integer immediately following this switch.");
                     ex.Data.Add("CharPos", CmdLinePtr);
                     ex.Data.Add("CmdLine", this.Text);
                     throw ex;
                  }

                  break;

               case 's':
                  if ((CmdLinePtr < this.Text.Length) && (this.Text[CmdLinePtr] == '\''))
                  {
                     // The first character is a quote.  Parse the string:

                     string Value;

                     if (xlatStrings)
                     {
                        string tempStr = GetString(this.Text, ref CmdLinePtr, '\'', true);

                        try
                        {
                           Value = XlatEscapes(tempStr);
                        }
                        catch (PipeWrenchCompileException ex)
                        {
                           ex.Data.Add("CmdLine", this.Text);
                           ex.Data["CharPos"] = CmdLinePtr - tempStr.Length + (int) ex.Data["Offset"];
                           throw ex;
                        }
                     }
                     else
                     {
                        Value = GetString(this.Text, ref CmdLinePtr, '\'', false);
                     }

                     Switch TheSwitch = new Switch(SwitchID, Value, CmdLinePtr);
                     LogWrite(MethodName + ": StrSwitch value = " + Value);
                     Switches.Add(TheSwitch);
                  }
                  else
                  {
                     // The first character is not a quote.

                     PipeWrenchCompileException ex =
                     new PipeWrenchCompileException("Expected a string immediately following this switch.");
                     ex.Data.Add("CharPos", CmdLinePtr);
                     ex.Data.Add("CmdLine", this.Text);
                     throw ex;
                  }

                  break;

               case 'b':
                  bool SwitchIsValid = (CmdLinePtr == this.Text.Length) ||
                  (this.Text[CmdLinePtr] == ' ') || (this.Text[CmdLinePtr] == '\t');

                  if (SwitchIsValid)
                  {
                     Switch TheSwitch = new Switch(SwitchID, null, CmdLinePtr);
                     LogWrite(MethodName + ": BoolSwitch value = true");
                     Switches.Add(TheSwitch);
                  }
                  else
                  {
                     // Switch is invalid.

                     PipeWrenchCompileException ex = new PipeWrenchCompileException("Boolean switch is invalid.");
                     ex.Data.Add("CharPos", CmdLinePtr);
                     ex.Data.Add("CmdLine", this.Text);
                     throw ex;
                  }

                  break;
            }
             }
             else
             {
            // The switch was not expected.

            PipeWrenchCompileException ex = new PipeWrenchCompileException("Switch is unexpected.");
            ex.Data.Add("CharPos", CmdLinePtr);
            ex.Data.Add("CmdLine", this.Text);
            throw ex;
             }
        }
예제 #6
0
        /// <summary>
        /// This routine searches the source string, "CmdLine" for a string
        /// delimited by single or double quotes, (specify one).  Searching begins
        /// at the given character position, "CmdLinePtr".  If a complete delimited
        /// string is not found, then "RCode" is returned non-zero, (see below).
        /// Embedded delimiters are allowed by placing two of them together within
        /// the string.
        /// </summary>
        private string GetString(string CmdLine, ref int CmdLinePtr, char QuoteChar,
      bool InterpretingQuotes)
        {
            string MethodName = "CommandLine.GetString";
             char Ch;
             string Str = string.Empty;
             bool Done = false;
             int State = 0;
             ToState(ref State, 1, MethodName);

             // Parse the string:

             do
             {
            switch (State)
            {
               case 1:
                  Ch = GetNextChar(CmdLine, ref CmdLinePtr);

                  if (Ch != '\0')
                  {
                     if (Ch == QuoteChar)
                     {
                        // Found beginning delimiter.

                        ToState(ref State, 2, MethodName);
                     }
                     else
                     {
                        if ((Ch == ' ') || (Ch == '\t'))
                        {
                           // Whitespace character.  Remain in this state.
                        }
                        else
                        {
                           // First non-whitespace character is not a delimiter.

                           PipeWrenchCompileException ex =
                           new PipeWrenchCompileException("Expected beginning of string.");
                           ex.Data.Add("CharPos", CmdLinePtr);
                           ex.Data.Add("CmdLine", CmdLine);
                           throw ex;
                        }
                     }
                  }
                  else
                  {
                     // Reached End-Of-String.  Beginning delimiter not found.

                     PipeWrenchCompileException ex =
                     new PipeWrenchCompileException("Expected string not found.");
                     ex.Data.Add("CharPos", CmdLinePtr);
                     ex.Data.Add("CmdLine", CmdLine);
                     throw ex;
                  }
                  break;

               case 2:
                  Ch = GetNextChar(CmdLine, ref CmdLinePtr);

                  if (Ch != '\0')
                  {
                     if (Ch == QuoteChar)
                     {
                        // Found another delimiter.

                        ToState(ref State, 3, MethodName);
                     }
                     else
                     {
                        // Remain in this state.

                        Str += Ch;
                     }
                  }
                  else
                  {
                     // Reached End-Of-String.  Ending delimiter not found.

                     PipeWrenchCompileException ex =
                     new PipeWrenchCompileException("String is not terminated with a quote.");
                     ex.Data.Add("CharPos", CmdLinePtr);
                     ex.Data.Add("CmdLine", CmdLine);
                     throw ex;
                  }
                  break;

               case 3:
                  Ch = GetNextChar(CmdLine, ref CmdLinePtr);

                  if (Ch != '\0')
                  {
                     if (Ch == QuoteChar)
                     {
                        // This delimiter is part of the
                        // string.  Add it to the string:

                        Str += Ch;
                        if (!InterpretingQuotes) Str += Ch;
                        ToState(ref State, 2, MethodName);
                     }
                     else
                     {
                        // Next char is not an ajacent delimiter;
                        // therefore, we're done.  Back up:

                        CmdLinePtr--;
                        Done = true;
                     }
                  }
                  else
                  {
                     // Done.  Reached End-Of-String.

                     Done = true;
                  }
                  break;
            }
             }
             while (!Done);

             return Str;
        }
예제 #7
0
 public void Add(PipeWrenchCompileException ex)
 {
     Items.Add(ex);
 }
예제 #8
0
파일: Call.cs 프로젝트: bblock/PipeWrench
        // The pipe that is being called.
        /// <summary>
        /// Compiles the filter.
        /// </summary>
        public override void Compile(string cmdLineText, int initialCharPos)
        {
            // Parse the filter's command line:

             LoggingEnabled = true;
             LogWrite("Call.Compile: begin");
             CmdLine.Text = cmdLineText;
             CmdLine.IgnoringExtraneousText = true;
             CmdLine.Parse(initialCharPos, true);

             // Load and compile the contents of the saved-to-disk pipe:

             string pipePath = (string) CmdLine.GetArg(0).Value;
             LogWrite("Call.Compile: Called pipe: \"" + pipePath + "\"");

             if (System.IO.File.Exists(pipePath))
             {
            // The pipe file exists.  Create a new pipe object from the pipe file's contents:

            string tempStr = System.IO.Path.GetFullPath(pipePath);
            string pipeFolder = System.IO.Path.GetDirectoryName(tempStr);
            string pipeName = System.IO.Path.GetFileName(tempStr);
            string pipeScript = System.IO.File.ReadAllText(pipePath);
            CalledPipe = new Pipe(pipeScript, (Engine) Eng, pipeFolder, pipeName,
            ((Filter) Host).CoreLoggingEnabled, false);
            CalledPipe.DebugFile = ((Filter) Host).DebugFile;
            CalledPipe.Errors = ((Filter) Host).Errors;

            // Save the current folder because Pipe.Compile() may change it:

            string savedFolder = System.Environment.CurrentDirectory;

            // Compile the pipe using the CALL filter's
            // "extraneous" command line parameters:

            CalledPipe.Compile(CmdLine.Text, ((CommandLine) CmdLine).CmdLinePtr, Source, PipeLineNo);

            // Restore the prior-saved current folder:

            Directory.SetCurrentDirectory(savedFolder);
             }
             else
             {
            // Pipe file doesn't exist.

            PipeWrenchCompileException ex = new PipeWrenchCompileException("Pipe file not found.");
            ex.Data.Add("CharPos", ((CommandLine) CmdLine).CmdLinePtr);
            ex.Data.Add("CmdLine", CmdLine.Text);
            throw ex;
             }

             LogWrite("Call.Compile: end");
        }
예제 #9
0
        /// <summary>
        /// This routine searches the source string, "CmdLine" for a string
        /// delimited by single or double quotes, (specify one). Searching begins
        /// at the given character position, "CmdLinePtr".  Embedded delimiters
        /// are allowed by placing two of them together within the string.
        /// </summary>
        private string GetString(string CmdLine, ref int CmdLinePtr, char QuoteChar,
                                 bool InterpretingQuotes)
        {
            char   Ch;
            string Str   = string.Empty;
            bool   Done  = false;
            int    State = 0;

            ToState(ref State, 1);

            // Parse the string:

            do
            {
                switch (State)
                {
                case 1:
                    Ch = GetNextChar(CmdLine, ref CmdLinePtr);

                    if (Ch != '\0')
                    {
                        if (Ch == QuoteChar)
                        {
                            // Found beginning delimiter.

                            ToState(ref State, 2);
                        }
                        else
                        {
                            if ((Ch == ' ') || (Ch == '\t'))
                            {
                                // Whitespace character.  Remain in this state.
                            }
                            else
                            {
                                // First non-whitespace character is not a delimiter.

                                PipeWrenchCompileException ex =
                                    new PipeWrenchCompileException("Expected beginning of string.");
                                ex.Data.Add("CharPos", CmdLinePtr);
                                ex.Data.Add("CmdLine", CmdLine);
                                throw ex;
                            }
                        }
                    }
                    else
                    {
                        // Reached End-Of-String.  Beginning delimiter not found.

                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("Expected string not found.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", CmdLine);
                        throw ex;
                    }
                    break;

                case 2:
                    Ch = GetNextChar(CmdLine, ref CmdLinePtr);

                    if (Ch != '\0')
                    {
                        if (Ch == QuoteChar)
                        {
                            // Found another delimiter.

                            ToState(ref State, 3);
                        }
                        else
                        {
                            // Remain in this state.

                            Str += Ch;
                        }
                    }
                    else
                    {
                        // Reached End-Of-String.  Ending delimiter not found.

                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("String is not terminated with a quote.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", CmdLine);
                        throw ex;
                    }
                    break;

                case 3:
                    Ch = GetNextChar(CmdLine, ref CmdLinePtr);

                    if (Ch != '\0')
                    {
                        if (Ch == QuoteChar)
                        {
                            // This delimiter is part of the
                            // string.  Add it to the string:

                            Str += Ch;
                            if (!InterpretingQuotes)
                            {
                                Str += Ch;
                            }
                            ToState(ref State, 2);
                        }
                        else
                        {
                            // Next char is not an ajacent delimiter;
                            // therefore, we're done.  Back up:

                            CmdLinePtr--;
                            Done = true;
                        }
                    }
                    else
                    {
                        // Done.  Reached End-Of-String.

                        Done = true;
                    }
                    break;
                }
            }while (!Done);

            return(Str);
        }
예제 #10
0
 public void Add(PipeWrenchCompileException ex)
 {
     Items.Add(ex);
 }
예제 #11
0
        /// <summary>
        /// Compiles the pipe given its command line.  Normally, InitialCharPos is set to 0 unless
        /// the CALL filter is compiling a pipe in which case the CALL filter's original command
        /// line is passed in and InitialCharPos is passed a value > 0 so that command line parsing
        /// can begin where the CALL filter's command line parsing left off.
        /// </summary>
        public void Compile(string PipeArgs, int InitialCharPos, string ParentSource, int ParentLineNo)
        {
            int    CmdLinePtr;
            string MethodName = "Pipe.Compile";
            int    LineNo     = 0;
            string TempStr;

            LogWrite(MethodName + ": begin");

            if (this.Folder != string.Empty)
            {
                // Set the currently logged folder to this pipe's folder:

                Directory.SetCurrentDirectory(this.Folder);
            }

            CmdLine.Text = PipeArgs;

            try
            {
                // Parse the pipe's arguments (note: a pipe's string
                // arguments should never be interpreted, hence the
                // xlatStrings parameter is passed as false):

                CmdLine.Parse(InitialCharPos, false);

                // Process each script line:

                string[] ScriptLines = Script.Split(new string[] { System.Environment.NewLine },
                                                    StringSplitOptions.None);

                foreach (string ScriptLn in ScriptLines)
                {
                    LineNo++;
                    LogWrite(MethodName + ": Raw Script Line = \"" + ScriptLn + "\"");
                    TempStr = ScriptLn.Trim();

                    if ((TempStr != String.Empty) && (TempStr[0] != CommentChar))
                    {
                        // The line isn't blank or a comment.

                        string ScriptLine = ScriptLn;

                        if (Template != string.Empty)
                        {
                            // Replace all placeholders in the line
                            // with their respective pipe arguments:

                            try
                            {
                                ScriptLine = ReplacePlaceholders(ScriptLine);
                            }

                            catch (PipeWrenchCompileException ex)
                            {
                                ex.Data.Add("Source", this.Name);
                                ex.Data.Add("LineNo", LineNo);
                                Errors.Add(ex);
                            }
                        }

                        // Get the filter's name:

                        string FilterName = ParseFilterName(ScriptLine, out CmdLinePtr);

                        // Determine if the filter is registered:

                        int i = Eng.CmdSpecs.IndexOf(FilterName);

                        if (i > -1)
                        {
                            // The filter is registered.

                            string TypeName = Eng.CmdSpecs[i].TypeName;
                            LogWrite(MethodName + ": Filter TypeName: \"" + TypeName + "\"");
                            string AssyPath = Eng.CmdSpecs[i].AssyPath;
                            LogWrite(MethodName + ": Filter AssyPath: \"" + AssyPath + "\"");

                            Filter TheFilter = new Filter(FilterName, TypeName, AssyPath, this, LineNo);

                            try
                            {
                                // "Compile" the filter:

                                TheFilter.Compile(ScriptLine, CmdLinePtr);
                            }

                            catch (PipeWrenchCompileException ex)
                            {
                                ex.Data.Add("Source", this.Name);
                                ex.Data.Add("LineNo", LineNo);
                                Errors.Add(ex);
                            }

                            // Add the filter container to the pipe:

                            AddFilter(TheFilter);
                        }
                        else
                        {
                            // The filter is not registered.

                            PipeWrenchCompileException ex = new PipeWrenchCompileException("Filter " +
                                                                                           FilterName + " is unknown.");
                            ex.Data.Add("CmdLine", ScriptLine);
                            ex.Data.Add("CharPos", CmdLinePtr);
                            ex.Data.Add("LineNo", LineNo);
                            ex.Data.Add("Source", this.Name);
                            Errors.Add(ex);
                        }
                    }
                }
            }

            catch (PipeWrenchCompileException ex)
            {
                ex.Data.Add("Source", ParentSource);
                ex.Data.Add("LineNo", ParentLineNo);
                Errors.Add(ex);
            }

            LogWrite(MethodName + ": end");
        }
예제 #12
0
        /// <summary>
        /// Parses the command line arguments.
        /// </summary>
        public void Parse(int initPos, bool xlatStrings)
        {
            string MethodName = "CommandLine.Parse";
            bool   Done       = false;
            char   Ch;
            bool   ParamIsOptional = false;
            int    TemplPtr        = 0;

            CmdLinePtr = initPos;
            LogWrite(MethodName + ": Parsing \"" + this.Text + "\" using template, \"" + Template +
                     "\" starting at CharPos " + initPos.ToString() + ".");
            LogWrite(MethodName + ": IgnoringExtraneousText = " + IgnoringExtraneousText);
            LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
            int State = 0;

            ToState(ref State, 1, MethodName);

            while (!Done)
            {
                switch (State)
                {
                case 1:
                    Ch = GetNextChar(Template, ref TemplPtr);

                    switch (Ch)
                    {
                    case 'n':
                        ToState(ref State, 2, MethodName);
                        break;

                    case 's':
                        ToState(ref State, 3, MethodName);
                        break;

                    case '[':
                        ParamIsOptional = true;
                        LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                        break;

                    case ']':

                        // do nothing

                        break;

                    case '.':
                        ToState(ref State, 4, MethodName);
                        break;

                    case '/':

                        // switch encountered

                        ToState(ref State, 7, MethodName);
                        break;

                    case '\0':

                        // end of template encountered

                        ToState(ref State, 5, MethodName);
                        break;

                    case ' ':

                        // Ignore and keep scanning...

                        break;

                    case '\t':

                        // Ignore and keep scanning...

                        break;

                    default:

                        // Invalid template character.

                        throw new PipeWrenchEngineException("Template is invalid.");
                    }
                    break;

                case 2:

                    // An integer is expected according to the template.

                    Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                    if ("0123456789-+".IndexOf(Ch) != -1)
                    {
                        // Found an integer.  Back up a character and parse it:

                        CmdLinePtr--;
                        string Token = "";

                        while ((CmdLinePtr < this.Text.Length) && (this.Text[CmdLinePtr] != ' ') &&
                               (this.Text[CmdLinePtr] != '\t'))
                        {
                            Token += this.Text[CmdLinePtr];
                            CmdLinePtr++;
                        }

                        try
                        {
                            // Convert the token to an integer value:

                            int Value = Convert.ToInt32(Token);
                            LogWrite(MethodName + ": IntArg value = " + Value.ToString());
                            Argument arg = new Argument(Value, CmdLinePtr);
                            Args.Add(arg);
                        }
                        catch (Exception)
                        {
                            PipeWrenchCompileException ex = new PipeWrenchCompileException("Integer value is invalid.");
                            ex.Data.Add("CharPos", CmdLinePtr);
                            ex.Data.Add("CmdLine", this.Text);
                            throw ex;
                        }

                        if (ParamIsOptional)
                        {
                            // Found first parameter in optional
                            // sequence.  Now all other parameters
                            // to end of sequence are required.

                            ParamIsOptional = false;
                            LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                        }

                        ToState(ref State, 1, MethodName);
                    }
                    else
                    {
                        if (Ch == '\'')
                        {
                            // String encountered instead of an integer.

                            PipeWrenchCompileException ex = new PipeWrenchCompileException("Integer expected for this parameter.");
                            ex.Data.Add("CharPos", CmdLinePtr);
                            ex.Data.Add("CmdLine", this.Text);
                            throw ex;
                        }
                        else
                        {
                            if (Ch == '/')
                            {
                                // Switch encountered instead of an integer.

                                if (ParamIsOptional)
                                {
                                    ToState(ref State, 6, MethodName);
                                }
                                else
                                {
                                    // Expected integer value was not found.

                                    PipeWrenchCompileException ex =
                                        new PipeWrenchCompileException("Expected an integer parameter but switch was encountered.");
                                    ex.Data.Add("CharPos", CmdLinePtr);
                                    ex.Data.Add("CmdLine", this.Text);
                                    throw ex;
                                }
                            }
                            else
                            {
                                if (Ch == '\0')
                                {
                                    // Reached the end of the command line.

                                    if (ParamIsOptional)
                                    {
                                        Done = true;
                                    }
                                    else
                                    {
                                        // Expected integer value was not found.

                                        PipeWrenchCompileException ex =
                                            new PipeWrenchCompileException("Expected an integer parameter but end-of-line was encountered.");
                                        ex.Data.Add("CharPos", CmdLinePtr);
                                        ex.Data.Add("CmdLine", this.Text);
                                        throw ex;
                                    }
                                }
                                else
                                {
                                    if ((Ch == ' ') || (Ch == '\t'))
                                    {
                                        // It's a whitespace character.  Just ignore it and keep scanning...
                                    }
                                    else
                                    {
                                        // Expected integer value was not found.

                                        PipeWrenchCompileException ex =
                                            new PipeWrenchCompileException("Integer expected for this parameter.");
                                        ex.Data.Add("CharPos", CmdLinePtr);
                                        ex.Data.Add("CmdLine", this.Text);
                                        throw ex;
                                    }
                                }
                            }
                        }
                    }

                    break;

                case 3:

                    // A string is expected according to the template.

                    Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                    if (Ch == '\'')
                    {
                        // Found a string.  Back up and parse it:

                        CmdLinePtr--;
                        string Token;

                        if (xlatStrings)
                        {
                            string tempStr = GetString(this.Text, ref iCmdLinePtr, '\'', true);

                            try
                            {
                                Token = XlatEscapes(tempStr);
                            }

                            catch (PipeWrenchCompileException ex)
                            {
                                ex.Data.Add("CmdLine", this.Text);
                                ex.Data["CharPos"] = CmdLinePtr - tempStr.Length + (int)ex.Data["Offset"];
                                throw ex;
                            }
                        }
                        else
                        {
                            Token = GetString(this.Text, ref iCmdLinePtr, '\'', false);
                        }

                        Argument arg = new Argument(Token, iCmdLinePtr);
                        Args.Add(arg);

                        if (ParamIsOptional)
                        {
                            // Found first parameter in optional sequence.  Now all other
                            // parameters to end of sequence are required.

                            ParamIsOptional = false;
                            LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                        }

                        ToState(ref State, 1, MethodName);
                    }
                    else
                    {
                        if ("0123456789-+".IndexOf(Ch) != -1)
                        {
                            // An integer was encountered.

                            PipeWrenchCompileException ex =
                                new PipeWrenchCompileException("String expected for this parameter.");
                            ex.Data.Add("CharPos", CmdLinePtr);
                            ex.Data.Add("CmdLine", this.Text);
                            throw ex;
                        }
                        else
                        {
                            if (Ch == '/')
                            {
                                // A switch was encountered.

                                if (ParamIsOptional)
                                {
                                    ToState(ref State, 6, MethodName);
                                }
                                else
                                {
                                    PipeWrenchCompileException ex =
                                        new PipeWrenchCompileException("Expected a string parameter but switch was encountered.");
                                    ex.Data.Add("CharPos", CmdLinePtr);
                                    ex.Data.Add("CmdLine", this.Text);
                                    throw ex;
                                }
                            }
                            else
                            {
                                if (Ch == '\0')
                                {
                                    // Reached the end of the command line.

                                    if (ParamIsOptional)
                                    {
                                        Done = true;
                                    }
                                    else
                                    {
                                        // Expected string value was not found.

                                        PipeWrenchCompileException ex =
                                            new PipeWrenchCompileException("Expected a string parameter but end-of-line was encountered.");
                                        ex.Data.Add("CharPos", CmdLinePtr);
                                        ex.Data.Add("CmdLine", this.Text);
                                        throw ex;
                                    }
                                }
                                else
                                {
                                    if ((Ch == ' ') || (Ch == '\t'))
                                    {
                                        // It's a whitespace character.  Just ignore it and keep scanning...
                                    }
                                    else
                                    {
                                        // Expected string value was not found.

                                        PipeWrenchCompileException ex =
                                            new PipeWrenchCompileException("String expected for this parameter.");
                                        ex.Data.Add("CharPos", CmdLinePtr);
                                        ex.Data.Add("CmdLine", this.Text);
                                        throw ex;
                                    }
                                }
                            }
                        }
                    }

                    break;

                case 4:

                    // Backtracking through optional sequence.

                    int savedTemplPtr = TemplPtr;

                    try
                    {
                        while (Template[TemplPtr] != '[')
                        {
                            TemplPtr--;
                        }
                    }

                    catch (Exception)
                    {
                        PipeWrenchTemplateException ex =
                            new PipeWrenchTemplateException(
                                "Template error: Repeating group (...) is only allowed inside \"[]\".");
                        ex.Data.Add("CharPos", savedTemplPtr);
                        ex.Data.Add("Template", Template);
                        throw ex;
                    }

                    TemplPtr++;
                    ParamIsOptional = true;
                    LogWrite(MethodName + ": ParamIsOptional = " + ParamIsOptional);
                    ToState(ref State, 1, MethodName);
                    break;

                case 5:

                    // End of template encountered.

                    if (!IgnoringExtraneousText)
                    {
                        // Be sure that remainder of command line is clear
                        // as additional parameters, (including switches)
                        // are not expected:

                        Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                        if (Ch == '\0')
                        {
                            Done = true;
                        }
                        else
                        {
                            if ((Ch == ' ') || (Ch == '\t'))
                            {
                                // It's a whitespace character.  Just ignore it and keep scanning...
                            }
                            else
                            {
                                PipeWrenchCompileException ex =
                                    new PipeWrenchCompileException("Parameter or switch is extraneous.");
                                ex.Data.Add("CharPos", CmdLinePtr);
                                ex.Data.Add("CmdLine", this.Text);
                                throw ex;
                            }
                        }
                    }
                    else
                    {
                        Done = true;
                    }

                    break;

                case 6:

                    // Switch encountered.

                    if (CmdLinePtr < this.Text.Length)
                    {
                        // Not yet to the end of the command line.

                        string SwitchID = "/" + Char.ToUpper(this.Text[CmdLinePtr]);
                        CmdLinePtr++;
                        ParseSwitch(SwitchID, ref iCmdLinePtr, ref TemplPtr, xlatStrings);
                        ToState(ref State, 7, MethodName);
                    }
                    else
                    {
                        // End of command line was encountered.  Switch
                        // character, (/) was found without a succeeding
                        // ID character.

                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("Switch is incomplete.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                    }

                    break;

                case 7:

                    // Locate the next switch on the command line:

                    Ch = GetNextChar(this.Text, ref iCmdLinePtr);

                    switch (Ch)
                    {
                    case '/':

                        // Found it.

                        ToState(ref State, 6, MethodName);
                        break;

                    case '\0':
                        Done = true;
                        break;

                    case ' ':

                        // Whitespace character.  Just ignore it and keep scanning...

                        break;

                    case '\t':

                        // Whitespace character.  Just ignore it and keep scanning...

                        break;

                    default:
                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("A switch was expected.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                    }

                    break;

                default:
                    throw new PipeWrenchEngineException(MethodName +
                                                        ": Invalid state (" + State.ToString() + ").");
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Parses a switch.
        /// </summary>
        private void ParseSwitch(string SwitchID, ref int CmdLinePtr, ref int TemplPtr, bool xlatStrings)
        {
            string MethodName = "CommandLine.ParseSwitch";

            LogWrite(MethodName + ": SwitchID = " + SwitchID);
            char SwitchType;
            int  i = Template.ToUpper().IndexOf(SwitchID.ToUpper());

            if (i > -1)
            {
                // The switch is expected.  Set the template
                // pointer to point to the switch's type:

                TemplPtr = i + 2;

                // Determine the type of switch:

                if (TemplPtr < Template.Length)
                {
                    // Not yet to end-of-template.

                    if ((Template[TemplPtr] == 'n') || (Template[TemplPtr] == 's'))
                    {
                        SwitchType = Template[TemplPtr];
                    }
                    else
                    {
                        SwitchType = 'b';
                    }
                }
                else
                {
                    // Reached the end of the template.

                    SwitchType = 'b';
                }

                // Parse the switch's setting: }

                LogWrite(MethodName + ": SwitchType = \"" + SwitchType + "\"");
                switch (SwitchType)
                {
                case 'n':
                    if ((CmdLinePtr < this.Text.Length) && ("0123456789-+".IndexOf(this.Text[CmdLinePtr]) != -1))
                    {
                        // The first character is part of an integer.  Parse it:

                        string Token = "";

                        while ((CmdLinePtr < this.Text.Length) && (this.Text[CmdLinePtr] != ' ') &&
                               (this.Text[CmdLinePtr] != '\t'))
                        {
                            Token += this.Text[CmdLinePtr];
                            CmdLinePtr++;
                        }

                        try
                        {
                            // Convert the token to an integer value:

                            int    Value     = Convert.ToInt32(Token);
                            Switch TheSwitch = new Switch(SwitchID, Value, CmdLinePtr);
                            LogWrite(MethodName + ": IntSwitch value = " + Value.ToString());
                            Switches.Add(TheSwitch);
                        }
                        catch (Exception)
                        {
                            PipeWrenchCompileException ex =
                                new PipeWrenchCompileException("Integer value is invalid");
                            ex.Data.Add("CharPos", CmdLinePtr);
                            ex.Data.Add("CmdLine", this.Text);
                            throw ex;
                        }
                    }
                    else
                    {
                        // The first character is not part of an integer.

                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("Expected an integer immediately following this switch.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                    }

                    break;

                case 's':
                    if ((CmdLinePtr < this.Text.Length) && (this.Text[CmdLinePtr] == '\''))
                    {
                        // The first character is a quote.  Parse the string:

                        string Value;

                        if (xlatStrings)
                        {
                            string tempStr = GetString(this.Text, ref CmdLinePtr, '\'', true);

                            try
                            {
                                Value = XlatEscapes(tempStr);
                            }
                            catch (PipeWrenchCompileException ex)
                            {
                                ex.Data.Add("CmdLine", this.Text);
                                ex.Data["CharPos"] = CmdLinePtr - tempStr.Length + (int)ex.Data["Offset"];
                                throw ex;
                            }
                        }
                        else
                        {
                            Value = GetString(this.Text, ref CmdLinePtr, '\'', false);
                        }

                        Switch TheSwitch = new Switch(SwitchID, Value, CmdLinePtr);
                        LogWrite(MethodName + ": StrSwitch value = " + Value);
                        Switches.Add(TheSwitch);
                    }
                    else
                    {
                        // The first character is not a quote.

                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("Expected a string immediately following this switch.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                    }

                    break;

                case 'b':
                    bool SwitchIsValid = (CmdLinePtr == this.Text.Length) ||
                                         (this.Text[CmdLinePtr] == ' ') || (this.Text[CmdLinePtr] == '\t');

                    if (SwitchIsValid)
                    {
                        Switch TheSwitch = new Switch(SwitchID, null, CmdLinePtr);
                        LogWrite(MethodName + ": BoolSwitch value = true");
                        Switches.Add(TheSwitch);
                    }
                    else
                    {
                        // Switch is invalid.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException("Boolean switch is invalid.");
                        ex.Data.Add("CharPos", CmdLinePtr);
                        ex.Data.Add("CmdLine", this.Text);
                        throw ex;
                    }

                    break;
                }
            }
            else
            {
                // The switch was not expected.

                PipeWrenchCompileException ex = new PipeWrenchCompileException("Switch is unexpected.");
                ex.Data.Add("CharPos", CmdLinePtr);
                ex.Data.Add("CmdLine", this.Text);
                throw ex;
            }
        }
예제 #14
0
        /// <summary>
        /// This routine converts all 2-digit hexadecimal numbers preceded
        /// by a pound character found in the given string into the characters
        /// represented by each three-character sequence. Two pound characters
        /// found together are interpreted as meaning a single one.
        /// </summary>
        public string XlatPoundSigns(string TheStr)
        {
            string methodName = "CommandLine.XlatPoundSigns";

            LogWrite(methodName + ": Start");
            LogWrite(methodName + ": Input string: " + TheStr);
            char   keyChar = '#';
            int    charPos = 0;
            string result  = string.Empty;
            bool   done    = false;
            char   ch;
            string hexStr = string.Empty;
            int    state  = 0;

            ToState(ref state, 1, methodName);

            // Translate the string:

            while (!done)
            {
                switch (state)
                {
                case 1:
                    ch = GetNextChar(TheStr, ref charPos);

                    if (ch != '\0')
                    {
                        // Got a character.

                        if (ch == keyChar)
                        {
                            ToState(ref state, 2, methodName);
                        }
                        else
                        {
                            result += ch;
                        }
                    }
                    else
                    {
                        // String processed successfully.

                        done = true;
                    }
                    break;

                case 2:
                    ch = GetNextChar(TheStr, ref charPos);

                    if (ch != '\0')
                    {
                        // Got a character.

                        if (IsHexDigit(ch))
                        {
                            // First hex digit scanned.

                            hexStr = ch.ToString();
                            ToState(ref state, 3, methodName);
                        }
                        else
                        {
                            if (ch == keyChar)
                            {
                                // Insert a # character:

                                result += keyChar;
                                ToState(ref state, 1, methodName);
                            }
                            else
                            {
                                // # or hex digit expected.

                                PipeWrenchCompileException ex = new PipeWrenchCompileException("# or hex digit expected.");
                                ex.Data.Add("Offset", charPos - 1);
                                throw ex;
                            }
                        }
                    }
                    else
                    {
                        // Abrupt end-of-data.

                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("# or hex digit expected but end-of-string encountered.");
                        ex.Data.Add("Offset", charPos);
                        throw ex;
                    }

                    break;

                case 3:
                    ch = GetNextChar(TheStr, ref charPos);

                    if (ch != '\0')
                    {
                        // Got a character.

                        if (IsHexDigit(ch))
                        {
                            // 2nd hex digit scanned.  Insert
                            // the actual represented character:

                            hexStr += ch;
                            result += (char)Convert.ToInt32(hexStr, 16);
                            ToState(ref state, 1, methodName);
                        }
                        else
                        {
                            // Hex digit expected.

                            PipeWrenchCompileException ex = new PipeWrenchCompileException("Hex digit expected.");
                            ex.Data.Add("Offset", charPos - 1);
                            throw ex;
                        }
                    }
                    else
                    {
                        // Abrupt end-of-data.

                        PipeWrenchCompileException ex =
                            new PipeWrenchCompileException("Hex digit expected but end-of-string encountered.");
                        ex.Data.Add("Offset", charPos);
                        throw ex;
                    }
                    break;
                }
            }

            LogWrite(methodName + ": Result string: " + result);
            LogWrite(methodName + ": Finish");
            return(result);
        }
예제 #15
0
        /// <summary>
        /// This routine interprets all backslash
        /// escape sequences in the given string.
        /// </summary>
        public string XlatBackslashes(string TheStr)
        {
            string methodName = "CommandLine.XlatBackslashes";

            LogWrite(methodName + ": Start");
            LogWrite(methodName + ": Input string: " + TheStr);
            char   backslashChar = '\\';
            int    charPos       = 0;
            string result        = string.Empty;
            bool   done          = false;
            char   ch            = '\0';
            string hexStr        = string.Empty;
            int    state         = 0;

            ToState(ref state, 1, methodName);

            // Translate the string:

            while (!done)
            {
                switch (state)
                {
                case 1:
                    ch = GetNextChar(TheStr, ref charPos);

                    if (ch != '\0')
                    {
                        // Got a character.

                        if (ch == backslashChar)
                        {
                            ToState(ref state, 2, methodName);
                        }
                        else
                        {
                            result += ch;
                        }
                    }
                    else
                    {
                        // String processed successfully.

                        done = true;
                    }

                    break;

                case 2:
                    ch = GetNextChar(TheStr, ref charPos);

                    if (ch != '\0')
                    {
                        // Got a character following a backslash.

                        switch (ch.ToString().ToUpper())
                        {
                        case "0":
                            result += '\0';
                            ToState(ref state, 1, methodName);
                            break;

                        case "A":
                            result += '\a';
                            ToState(ref state, 1, methodName);
                            break;

                        case "B":
                            result += '\b';
                            ToState(ref state, 1, methodName);
                            break;

                        case "E":

                            // This escape isn't recognized as a standard. I've added it in order
                            // to represent an end-of-line sequence regardless of what system PipeWrench
                            // is executing on.

                            result += System.Environment.NewLine;
                            ToState(ref state, 1, methodName);
                            break;

                        case "F":
                            result += '\f';
                            ToState(ref state, 1, methodName);
                            break;

                        case "N":
                            result += '\n';
                            ToState(ref state, 1, methodName);
                            break;

                        case "R":
                            result += '\r';
                            ToState(ref state, 1, methodName);
                            break;

                        case "T":
                            result += '\t';
                            ToState(ref state, 1, methodName);
                            break;

                        case "V":
                            result += '\v';
                            ToState(ref state, 1, methodName);
                            break;

                        case "\'":
                            result += '\'';
                            ToState(ref state, 1, methodName);
                            break;

                        case "\"":
                            result += '"';
                            ToState(ref state, 1, methodName);
                            break;

                        case "\\":
                            result += '\\';
                            ToState(ref state, 1, methodName);
                            break;

                        case "X":
                            ToState(ref state, 3, methodName);
                            break;

                        default:
                            result += ch;
                            ToState(ref state, 1, methodName);
                            break;
                        }
                    }
                    else
                    {
                        // Abrupt end-of-data.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException(
                            "Abrupt end-of-data.");
                        ex.Data.Add("Offset", charPos - 1);
                        throw ex;
                    }

                    break;

                case 3:

                    // Have "\x".

                    ch = GetNextChar(TheStr, ref charPos);

                    if (ch != '\0')
                    {
                        // Got a character.

                        if (IsHexDigit(ch))
                        {
                            // First hex digit scanned.

                            hexStr = ch.ToString();
                            ToState(ref state, 4, methodName);
                        }
                        else
                        {
                            // Character is not a hex digit.

                            PipeWrenchCompileException ex = new PipeWrenchCompileException(
                                "Hex digit expected.");
                            ex.Data.Add("Offset", charPos - 1);
                            throw ex;
                        }
                    }
                    else
                    {
                        // Abrupt end-of-data.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException(
                            "Abrupt end-of-data.");
                        ex.Data.Add("Offset", charPos - 1);
                        throw ex;
                    }

                    break;

                case 4:

                    // Have "\xn".

                    ch = GetNextChar(TheStr, ref charPos);

                    if (ch != '\0')
                    {
                        // Got a character.

                        if (IsHexDigit(ch))
                        {
                            // 2nd hex digit scanned.  Insert the actual represented
                            // character and continue scanning the string:

                            hexStr += ch;
                            result += (char)Convert.ToInt32(hexStr, 16);
                            ToState(ref state, 1, methodName);
                        }
                        else
                        {
                            // Character is not a hex digit.

                            PipeWrenchCompileException ex = new PipeWrenchCompileException(
                                "Hex digit expected.");
                            ex.Data.Add("Offset", charPos - 1);
                            throw ex;
                        }
                    }
                    else
                    {
                        // Abrupt end-of-data.

                        PipeWrenchCompileException ex = new PipeWrenchCompileException(
                            "Abrupt end-of-data.");
                        ex.Data.Add("Offset", charPos - 1);
                        throw ex;
                    }

                    break;
                }
            }

            LogWrite(methodName + ": Result string: " + result);
            LogWrite(methodName + ": Finish");
            return(result);
        }
예제 #16
0
파일: Pipe.cs 프로젝트: bblock/PipeWrench
        /// <summary>
        /// Compiles the pipe given its command line.  Normally, InitialCharPos is set to 0 unless
        /// the CALL filter is compiling a pipe in which case the CALL filter's original command
        /// line is passed in and InitialCharPos is passed a value > 0 so that command line parsing
        /// can begin where the CALL filter's command line parsing left off.
        /// </summary>
        public void Compile(string PipeArgs, int InitialCharPos, string ParentSource, int ParentLineNo)
        {
            int CmdLinePtr;
             string MethodName = "Pipe.Compile";
             int LineNo = 0;
             string TempStr;

             LogWrite(MethodName + ": begin");

             if (this.Folder != string.Empty)
             {
            // Set the currently logged folder to this pipe's folder:

            Directory.SetCurrentDirectory(this.Folder);
             }

             CmdLine.Text = PipeArgs;

             try
             {
            // Parse the pipe's arguments (note: a pipe's string
            // arguments should never be interpreted, hence the
            // xlatStrings parameter is passed as false):

            CmdLine.Parse(InitialCharPos, false);

            // Process each script line:

            string[] ScriptLines = Script.Split(new string[] { System.Environment.NewLine },
            StringSplitOptions.None);

            foreach (string ScriptLn in ScriptLines)
            {
               LineNo++;
               LogWrite(MethodName + ": Raw Script Line = \"" + ScriptLn + "\"");
               TempStr = ScriptLn.Trim();

               if ((TempStr != String.Empty) && (TempStr[0] != CommentChar))
               {
                  // The line isn't blank or a comment.

                  string ScriptLine = ScriptLn;

                  if (Template != string.Empty)
                  {
                     // Replace all placeholders in the line
                     // with their respective pipe arguments:

                     try
                     {
                        ScriptLine = ReplacePlaceholders(ScriptLine);
                     }

                     catch (PipeWrenchCompileException ex)
                     {
                        ex.Data.Add("Source", this.Name);
                        ex.Data.Add("LineNo", LineNo);
                        Errors.Add(ex);
                     }
                  }

                  // Get the filter's name:

                  string FilterName = ParseFilterName(ScriptLine, out CmdLinePtr);

                  // Determine if the filter is registered:

                  int i = Eng.CmdSpecs.IndexOf(FilterName);

                  if (i > -1)
                  {
                     // The filter is registered.

                     string TypeName = Eng.CmdSpecs[i].TypeName;
                     LogWrite(MethodName + ": Filter TypeName: \"" + TypeName + "\"");
                     string AssyPath = Eng.CmdSpecs[i].AssyPath;
                     LogWrite(MethodName + ": Filter AssyPath: \"" + AssyPath + "\"");

                     Filter TheFilter = new Filter(FilterName, TypeName, AssyPath, this, LineNo);

                     try
                     {
                        // "Compile" the filter:

                        TheFilter.Compile(ScriptLine, CmdLinePtr);
                     }

                     catch (PipeWrenchCompileException ex)
                     {
                        ex.Data.Add("Source", this.Name);
                        ex.Data.Add("LineNo", LineNo);
                        Errors.Add(ex);
                     }

                     // Add the filter container to the pipe:

                     AddFilter(TheFilter);
                  }
                  else
                  {
                     // The filter is not registered.

                     PipeWrenchCompileException ex = new PipeWrenchCompileException("Filter " +
                     FilterName + " is unknown.");
                     ex.Data.Add("CmdLine", ScriptLine);
                     ex.Data.Add("CharPos", CmdLinePtr);
                     ex.Data.Add("LineNo", LineNo);
                     ex.Data.Add("Source", this.Name);
                     Errors.Add(ex);
                  }
               }
            }
             }

             catch (PipeWrenchCompileException ex)
             {
            ex.Data.Add("Source", ParentSource);
            ex.Data.Add("LineNo", ParentLineNo);
            Errors.Add(ex);
             }

             LogWrite(MethodName + ": end");
        }