private bool ProcessChar(int i, char lineChar, out string errorText) { result = true; errorText = null; switch (parseState) { case ParseState.NotInParam: if (lineChar == quoteChar) { parseState = ParseState.TextParam; textParamIdx++; startIdx = i; textBldr.Clear(); quoted = true; } else { if (Array.IndexOf <char>(optionParamAnnouncerChars, lineChar) >= 0) { parseState = ParseState.OptionParam; parseOptionState = ParseOptionState.Announced; startIdx = i + 1; } else { if (Array.IndexOf <char>(parseTerminateChars, lineChar) >= 0) { ignoreRestOfLine = true; } else { if (!char.IsWhiteSpace(lineChar)) { parseState = ParseState.TextParam; textParamIdx++; startIdx = i; textBldr.Clear(); textBldr.Append(lineChar); quoted = false; } } } } break; case ParseState.TextParam: if (!quoted) { if (!char.IsWhiteSpace(lineChar)) { textBldr.Append(lineChar); } else { result = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText); parseState = ParseState.NotInParam; } } else { if (lineChar != QuoteChar) { textBldr.Append(lineChar); } else { parseState = ParseState.TextParamPossibleEndQuote; } } break; case ParseState.TextParamPossibleEndQuote: if (lineChar == QuoteChar) { textBldr.Append(lineChar); parseState = ParseState.TextParam; } else { if (char.IsWhiteSpace(lineChar)) { result = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText); parseState = ParseState.NotInParam; } else { result = PrepareErrorText(CLParserError.Id.InvalidQuoteCharacterInTextParameter, textBldr.ToString(), out errorText); } } break; case ParseState.OptionParam: switch (parseOptionState) { case ParseOptionState.Announced: if (char.IsWhiteSpace(lineChar) || Array.IndexOf <char>(optionTerminationChars, lineChar) >= 0) { result = PrepareErrorText(CLParserError.Id.OptionNotSpecifiedAtLinePosition, i.ToString(), out errorText); } else { parseOptionState = ParseOptionState.Name; } break; case ParseOptionState.Name: bool optionValueAnnounced = lineChar == optionParamValueAnnouncerChar; if (optionValueAnnounced || char.IsWhiteSpace(lineChar) || Array.IndexOf <char>(optionTerminationChars, lineChar) >= 0) { optionName = parseLine.Substring(startIdx, i - startIdx); if (optionName == "") { result = PrepareErrorText(CLParserError.Id.OptionNotSpecifiedAtLinePosition, i.ToString(), out errorText); } else { if (optionValueAnnounced) { if (optionParamValueAnnouncerIsWhiteSpace) { parseOptionState = ParseOptionState.ValuePossible; } else { parseOptionState = ParseOptionState.ValueAnnounced; } } else { result = ProcessOption(optionName, null, out errorText); if (result) { parseState = ParseState.NotInParam; } } } } break; case ParseOptionState.ValuePossible: if (!char.IsWhiteSpace(lineChar)) { if ( Array.IndexOf <char>(optionParamAnnouncerChars, lineChar) < 0 // not a new option && CanOptionHaveValue(optionName) // option can have values ) { parseOptionState = ParseOptionState.ValueAnnounced; result = ProcessChar(i, lineChar, out errorText); // process first char of value } else { result = ProcessOption(optionName, null, out errorText); // process current option if (result) { parseState = ParseState.NotInParam; result = ProcessChar(i, lineChar, out errorText); // will handle new option/text param } } } break; case ParseOptionState.ValueAnnounced: startIdx = i; textBldr.Clear(); if (char.IsWhiteSpace(lineChar)) { result = ProcessOption(optionName, "", out errorText); parseState = ParseState.NotInParam; } else { if (lineChar == QuoteChar) { quoted = true; } else { quoted = false; textBldr.Append(lineChar); } parseOptionState = ParseOptionState.Value; } break; case ParseOptionState.Value: if (!quoted) { if (!char.IsWhiteSpace(lineChar)) { textBldr.Append(lineChar); } else { result = ProcessOption(optionName, textBldr.ToString(), out errorText); parseState = ParseState.NotInParam; } } else { if (lineChar != QuoteChar) { textBldr.Append(lineChar); } else { parseOptionState = ParseOptionState.ValuePossibleEndQuote; } } break; case ParseOptionState.ValuePossibleEndQuote: if (lineChar == QuoteChar) { textBldr.Append(lineChar); parseOptionState = ParseOptionState.Value; } else { if (char.IsWhiteSpace(lineChar)) { result = ProcessOption(optionName, textBldr.ToString(), out errorText); parseState = ParseState.NotInParam; } else { result = PrepareErrorText(CLParserError.Id.InvalidQuoteCharacterInOptionValue, optionName, out errorText); } } break; } break; } return(result); }
public virtual bool Parse(string line, out string errorText) { parseLine = line; textParamIdx = -1; parseState = ParseState.NotInParam; parseOptionState = ParseOptionState.Announced; startIdx = -1; optionName = null; quoted = false; ignoreRestOfLine = false; textBldr = new StringBuilder(30); optionTerminationChars = CreateOptionTerminationCharArray(); errorText = null; for (int i = 0; i < line.Length; i++) { result = ProcessChar(i, line[i], out errorText); if (!result || ignoreRestOfLine) { break; } } if (result && !ignoreRestOfLine) { switch (parseState) { case ParseState.NotInParam: break; case ParseState.TextParam: if (quoted) { result = PrepareErrorText(CLParserError.Id.TextMissingClosingQuoteCharacter, null, out errorText); } else { result = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText); } break; case ParseState.TextParamPossibleEndQuote: result = ProcessTextParam(textParamIdx, textBldr.ToString(), startIdx, out errorText); break; case ParseState.OptionParam: switch (parseOptionState) { case ParseOptionState.Announced: result = PrepareErrorText(CLParserError.Id.OptionNotSpecifiedAtLinePosition, line.Length.ToString(), out errorText); break; case ParseOptionState.Name: optionName = line.Substring(startIdx, line.Length - startIdx); result = ProcessOption(optionName, null, out errorText); break; case ParseOptionState.ValuePossible: result = ProcessOption(optionName, null, out errorText); break; case ParseOptionState.ValueAnnounced: result = ProcessOption(optionName, "", out errorText); break; case ParseOptionState.Value: if (quoted) { result = PrepareErrorText(CLParserError.Id.OptionMissingClosingQuoteCharacter, optionName, out errorText); } else { result = ProcessOption(optionName, textBldr.ToString(), out errorText); } break; case ParseOptionState.ValuePossibleEndQuote: result = ProcessOption(optionName, textBldr.ToString(), out errorText); break; } break; default: Debug.Assert(false, "False"); break; } } return(result); }