public override State PushChar (char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek () as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) throw new InvalidOperationException ("Invalid state"); Debug.Assert (context.CurrentStateLength > 1 || char.IsLetter (c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert (context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError ("Unexpected ':' in name."); return Parent; } namedObject.Name = new XName (context.KeywordBuilder.ToString ()); context.KeywordBuilder.Length = 0; return null; } if (XmlChar.IsWhitespace (c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError ("Zero-length name."); } else if (namedObject.Name.Name != null) { //add prefix (and move current "name" to prefix) namedObject.Name = new XName (namedObject.Name.Name, context.KeywordBuilder.ToString ()); } else { namedObject.Name = new XName (context.KeywordBuilder.ToString ()); } //note: parent's MalformedTagState logs an error, so skip this //if (c == '<') //context.LogError ("Unexpected '<' in name."); return Parent; } if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError ("Unexpected ':' in name."); return Parent; } namedObject.Name = new XName (context.KeywordBuilder.ToString ()); context.KeywordBuilder.Length = 0; return null; } if (XmlChar.IsNameChar (c)) { context.KeywordBuilder.Append (c); return null; } rollback = string.Empty; context.LogError ("Unexpected character '" + c +"'"); return Parent; }
public override State PushChar(char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek() as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) { throw new InvalidOperationException("Invalid state"); } Debug.Assert(context.CurrentStateLength > 1 || char.IsLetter(c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert(context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (XmlChar.IsWhitespace(c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError("Zero-length name."); } else { string s = context.KeywordBuilder.ToString(); int i = s.IndexOf(':'); if (i < 0) { namedObject.Name = new XName(s); } else { namedObject.Name = new XName(s.Substring(0, i), s.Substring(i + 1)); } } return(Parent); } if (c == ':') { if (context.KeywordBuilder.ToString().IndexOf(':') > 0) { context.LogError("Unexpected ':' in name."); } context.KeywordBuilder.Append(c); return(null); } if (XmlChar.IsNameChar(c)) { context.KeywordBuilder.Append(c); return(null); } rollback = string.Empty; context.LogError("Unexpected character '" + c + "' in name"); return(Parent); }
public override State PushChar (char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek () as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) throw new InvalidOperationException ("Invalid state"); Debug.Assert (context.CurrentStateLength > 1 || char.IsLetter (c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert (context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError ("Unexpected ':' in name."); return Parent; } namedObject.Name = new XName (context.KeywordBuilder.ToString ()); context.KeywordBuilder.Length = 0; return null; } if (XmlChar.IsWhitespace (c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError ("Zero-length name."); } else { string s = context.KeywordBuilder.ToString (); int i = s.IndexOf (':'); if (i < 0) { namedObject.Name = new XName (s); } else { namedObject.Name = new XName (s.Substring (0, i), s.Substring (i + 1)); } } return Parent; } if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.ToString ().IndexOf (':') <= 0) { context.LogError ("Unexpected ':' in name."); return Parent; } return null; } if (XmlChar.IsNameChar (c)) { context.KeywordBuilder.Append (c); return null; } rollback = string.Empty; context.LogError ("Unexpected character '" + c +"' in name"); return Parent; }
public override State PushChar (char c, IParseContext context, ref string rollback) { System.Diagnostics.Debug.Assert (((XAttribute) context.Nodes.Peek ()).Value == null); if (c == '<') { //the parent state should report the error rollback = string.Empty; return Parent; } else if (c == '>' && context.KeywordBuilder.Length > 0) { string fullName = ((XAttribute) context.Nodes.Peek ()).Name.FullName; context.LogError ("The value of attribute '" + fullName + "' ended unexpectedly."); rollback = string.Empty; return Parent; } else if (char.IsLetterOrDigit (c) || c == '_' || c == '.') { context.KeywordBuilder.Append (c); return null; } else if (char.IsWhiteSpace (c) || c == '>' || c == '\\') { //ending the value XAttribute att = (XAttribute) context.Nodes.Peek (); att.Value = context.KeywordBuilder.ToString (); } else { //MalformedTagState handles error reporting //context.LogWarning ("Unexpected character '" + c + "' getting attribute value"); return MalformedTagState; } rollback = string.Empty; return Parent; }
public override State PushChar (char c, IParseContext context, ref string rollback) { switch (context.StateTag) { case INCOMING: if (c == '<' && context.PreviousState != ExpressionState && context.PreviousState != CommentState) { context.StateTag = BRACKET; return null; } else if (context.PreviousState == ExpressionState || context.PreviousState == CommentState) { //expression has successfully been collected //we should go back to the AttributeValueState or the TagState, not the AttributeState rollback = string.Empty; return Parent is XmlAttributeState ? Parent.Parent : Parent; } break; case BRACKET: if (c == '%') { context.StateTag = PERCENT; return null; } else { context.StateTag = MALFORMED; context.LogError ("Unexpected tag start"); rollback = "<"; } break; case PERCENT: if (c == '-') { context.StateTag = PERCENT_DASH; return null; } else if (c == '@') { context.StateTag = MALFORMED; context.LogError ("Invalid directive location"); rollback = "<%"; } else { rollback = string.Empty; return ExpressionState; } break; case PERCENT_DASH: if (c == '-') { return CommentState; } else { context.StateTag = MALFORMED; context.LogError ("Malformed server comment"); rollback = "<%-"; } break; case MALFORMED: break; } return base.PushChar (c, context, ref rollback); }
public override State PushChar (char c, IParseContext context, ref string rollback) { AspNetDirective directive = context.Nodes.Peek () as AspNetDirective; if (directive == null || directive.IsComplete) { directive = new AspNetDirective (context.LocationMinus (4)); // 4 == <%@ + current char context.Nodes.Push (directive); } if (c == '<') { context.LogError ("Unexpected '<' in directive."); rollback = string.Empty; return MalformedTagState; } Debug.Assert (!directive.IsComplete); if (context.StateTag != ENDING && c == '%') { context.StateTag = ENDING; return null; } if (context.StateTag == ENDING) { if (c == '>') { //have already checked that directive is not null, i.e. top of stack is our directive context.Nodes.Pop (); if (!directive.IsNamed) { context.LogError ("Directive closed prematurely."); } else { directive.End (context.Location); if (context.BuildTree) { XContainer container = (XContainer) context.Nodes.Peek (); container.AddChildNode (directive); } } return Parent; } //ending but not '>'? Error; go to end. } else if (char.IsLetter (c)) { rollback = string.Empty; if (!directive.IsNamed) { return NameState; } else { return AttributeState; } } else if (char.IsWhiteSpace (c)) return null; rollback = string.Empty; context.LogError ("Unexpected character '" + c + "' in tag."); return MalformedTagState; }
public override State PushChar (char c, IParseContext context, ref string rollback) { //ensure that we don't drop any nodes or leave them un-ended if (context.CurrentStateLength == 1) { context.LogError ("Malformed tag: unexpected '" + c + "' character."); if (context.BuildTree) context.ConnectAll (); context.EndAll (true); } if (c == '<' || c == '>') { if (c == '<') rollback = string.Empty; return RootState; } return null; }
State BuildUnquotedValue (char c, IParseContext context, ref string rollback) { if (c == '>' && context.KeywordBuilder.Length > 0) { string fullName = ((XAttribute)context.Nodes.Peek ()).Name.FullName; context.LogError ("The value of attribute '" + fullName + "' ended unexpectedly."); rollback = string.Empty; return Parent; } if (char.IsLetterOrDigit(c) || c == '_' || c == '.') { context.KeywordBuilder.Append (c); return null; } var att = (XAttribute)context.Nodes.Peek (); att.Value = context.KeywordBuilder.ToString (); rollback = string.Empty; return Parent; }
State BuildUnquotedValue(char c, IParseContext context, ref string rollback) { if (c == '>' && context.KeywordBuilder.Length > 0) { string fullName = ((XAttribute)context.Nodes.Peek()).Name.FullName; context.LogError("The value of attribute '" + fullName + "' ended unexpectedly."); rollback = string.Empty; return(Parent); } if (char.IsLetterOrDigit(c) || c == '_' || c == '.') { context.KeywordBuilder.Append(c); return(null); } var att = (XAttribute)context.Nodes.Peek(); att.Value = context.KeywordBuilder.ToString(); rollback = string.Empty; return(Parent); }
public override State PushChar(char c, IParseContext context, ref string rollback) { System.Diagnostics.Debug.Assert(((XAttribute)context.Nodes.Peek()).Value == null); if (c == '<') { //the parent state should report the error rollback = string.Empty; return(Parent); } else if (c == '>' && context.KeywordBuilder.Length > 0) { string fullName = ((XAttribute)context.Nodes.Peek()).Name.FullName; context.LogError("The value of attribute '" + fullName + "' ended unexpectedly."); rollback = string.Empty; return(Parent); } else if (char.IsLetterOrDigit(c) || c == '_' || c == '.') { context.KeywordBuilder.Append(c); return(null); } else if (char.IsWhiteSpace(c) || c == '>' || c == '\\') { //ending the value XAttribute att = (XAttribute)context.Nodes.Peek(); att.Value = context.KeywordBuilder.ToString(); } else { //MalformedTagState handles error reporting //context.LogWarning ("Unexpected character '" + c + "' getting attribute value"); return(MalformedTagState); } rollback = string.Empty; return(Parent); }
public override State PushChar(char c, IParseContext context, ref string rollback) { //ensure that we don't drop any nodes or leave them un-ended if (context.CurrentStateLength == 1) { context.LogError("Malformed tag: unexpected '" + c + "' character."); if (context.BuildTree) { context.ConnectAll(); } context.EndAll(true); } if (c == '<' || c == '>') { if (c == '<') { rollback = string.Empty; } return(RootState); } return(null); }
public override State PushChar (char c, IParseContext context, ref string rollback) { if (c == '<') { if (context.StateTag != FREE) context.LogError ("Incomplete tag opening; encountered unexpected '<'.", new MonoDevelop.Projects.Dom.DomRegion ( context.LocationMinus (LengthFromOpenBracket (context) + 1), context.LocationMinus (1))); context.StateTag = BRACKET; return null; } switch (context.StateTag) { case FREE: //FIXME: handle entities? return null; case BRACKET: if (c == '?') { rollback = string.Empty; return this.ProcessingInstructionState; } else if (c == '!') { context.StateTag = BRACKET_EXCLAM; return null; } else if (c == '/') { return this.ClosingTagState; } else if (char.IsLetter (c) || c == '_') { rollback = string.Empty; return TagState; } break; case BRACKET_EXCLAM: if (c == '[') { context.StateTag = CDATA; return null; } else if (c == '-') { context.StateTag = COMMENT; return null; } else if (c == 'D') { context.StateTag = DOCTYPE; return null; } break; case COMMENT: if (c == '-') return CommentState; break; case CDATA: string cdataStr = "CDATA["; if (c == cdataStr [context.KeywordBuilder.Length]) { context.KeywordBuilder.Append (c); if (context.KeywordBuilder.Length < cdataStr.Length) return null; else return CDataState; } else { context.KeywordBuilder.Length = 0; } break; case DOCTYPE: string docTypeStr = "OCTYPE"; if (c == docTypeStr [context.KeywordBuilder.Length]) { context.KeywordBuilder.Append (c); if (context.KeywordBuilder.Length < docTypeStr.Length) return null; else return DocTypeState; } else { context.KeywordBuilder.Length = 0; } break; } context.LogError ("Incomplete tag opening; encountered unexpected character '" + c + "'.", new MonoDevelop.Projects.Dom.DomRegion ( context.LocationMinus (LengthFromOpenBracket (context)), context.Location)); context.StateTag = FREE; return null; }
public override State PushChar(char c, IParseContext context, ref string rollback) { XElement element = context.Nodes.Peek() as XElement; if (element == null || element.IsComplete) { element = new XElement(context.LocationMinus(2)); // 2 == < + current char context.Nodes.Push(element); } if (c == '<') { if (element.IsNamed) { context.LogError("Unexpected '<' in tag '" + element.Name.FullName + "'."); Close(element, context, context.LocationMinus(1)); } else { context.LogError("Unexpected '<' in unnamed tag."); } rollback = string.Empty; return(Parent); } Debug.Assert(!element.IsComplete); if (element.IsClosed && c != '>') { if (char.IsWhiteSpace(c)) { context.LogWarning("Unexpected whitespace after '/' in self-closing tag."); return(null); } context.LogError("Unexpected character '" + c + "' after '/' in self-closing tag."); context.Nodes.Pop(); return(Parent); } //if tag closed if (c == '>') { if (context.StateTag == MAYBE_SELF_CLOSING) { element.Close(element); } if (!element.IsNamed) { context.LogError("Tag closed prematurely."); } else { Close(element, context, context.Location); } return(Parent); } if (c == '/') { context.StateTag = MAYBE_SELF_CLOSING; return(null); } if (context.StateTag == ATTEMPT_RECOVERY) { if (XmlChar.IsWhitespace(c)) { context.StateTag = RECOVERY_FOUND_WHITESPACE; } return(null); } if (context.StateTag == RECOVERY_FOUND_WHITESPACE) { if (!XmlChar.IsFirstNameChar(c)) { return(null); } } context.StateTag = OK; if (!element.IsNamed && XmlChar.IsFirstNameChar(c)) { rollback = string.Empty; return(NameState); } if (context.CurrentStateLength > 1 && XmlChar.IsFirstNameChar(c)) { rollback = string.Empty; return(AttributeState); } if (XmlChar.IsWhitespace(c)) { return(null); } context.LogError("Unexpected character '" + c + "' in tag.", context.LocationMinus(1)); context.StateTag = ATTEMPT_RECOVERY; return(null); }
public override State PushChar(char c, IParseContext context, ref string rollback) { XAttribute att = context.Nodes.Peek() as XAttribute; //state has just been entered if (context.CurrentStateLength == 1) { if (context.PreviousState is XmlNameState) { //error parsing name if (!att.IsNamed) { context.Nodes.Pop(); rollback = string.Empty; return(Parent); } context.StateTag = GETTINGEQ; } else if (context.PreviousState is XmlAttributeValueState) { //Got value, so end attribute context.Nodes.Pop(); att.End(context.LocationMinus(1)); IAttributedXObject element = (IAttributedXObject)context.Nodes.Peek(); element.Attributes.AddAttribute(att); rollback = string.Empty; return(Parent); } else { //starting a new attribute Debug.Assert(att == null); Debug.Assert(context.StateTag == NAMING); att = new XAttribute(context.LocationMinus(1)); context.Nodes.Push(att); rollback = string.Empty; return(XmlNameState); } } if (context.StateTag == GETTINGEQ) { if (char.IsWhiteSpace(c)) { return(null); } if (c == '=') { context.StateTag = GETTINGVAL; return(null); } context.LogError("Expecting = in attribute, got '" + c + "'."); } else if (context.StateTag == GETTINGVAL) { if (char.IsWhiteSpace(c)) { return(null); } rollback = string.Empty; return(AttributeValueState); } else if (c != '<') { //parent handles message for '<' context.LogError("Unexpected character '" + c + "' in attribute."); } if (att != null) { context.Nodes.Pop(); } rollback = string.Empty; return(Parent); }
public override State PushChar (char c, IParseContext context, ref string rollback) { XClosingTag ct = context.Nodes.Peek () as XClosingTag; if (ct == null) { Debug.Assert (context.CurrentStateLength == 1, "IncompleteNode must not be an XClosingTag when CurrentStateLength is 1"); Debug.Assert (context.Nodes.Peek () is XElement); ct = new XClosingTag (context.LocationMinus (3)); //3 = </ and the current char context.Nodes.Push (ct); } //if tag closed if (c == '>') { context.Nodes.Pop (); if (ct.IsNamed) { ct.End (context.Location); // walk up tree of parents looking for matching tag int popCount = 0; bool found = false; foreach (XObject node in context.Nodes) { popCount++; XElement element = node as XElement; if (element != null && element.Name == ct.Name) { found = true; break; } } if (!found) popCount = 0; //clear the stack of intermediate unclosed tags while (popCount > 1) { XElement el = context.Nodes.Pop () as XElement; if (el != null) context.LogError (string.Format ( "Unclosed tag '{0}' at line {1}, column {2}.", el.Name.FullName, el.Region.Start.Line, el.Region.Start.Column), ct.Region); popCount--; } //close the start tag, if we found it if (popCount > 0) { if (context.BuildTree) ((XElement) context.Nodes.Pop ()).Close (ct); else context.Nodes.Pop (); } else { context.LogError ( "Closing tag '" + ct.Name.FullName + "' does not match any currently open tag."); } } else { context.LogError ("Closing tag ended prematurely."); } return Parent; } if (c == '<') { context.LogError ("Unexpected '<' in tag."); rollback = string.Empty; return Parent; } if (!ct.IsNamed && (char.IsLetter (c) || c == '_')) { rollback = string.Empty; return NameState; } rollback = string.Empty; //note: MalformedTagState logs an error, so skip this //context.LogError ("Unexpected character '" + c + "' in closing tag."); return MalformedTagState; }
public override State PushChar(char c, IParseContext context, ref string rollback) { XClosingTag ct = context.Nodes.Peek() as XClosingTag; if (ct == null) { Debug.Assert(context.CurrentStateLength == 1, "IncompleteNode must not be an XClosingTag when CurrentStateLength is 1"); Debug.Assert(context.Nodes.Peek() is XElement); ct = new XClosingTag(context.LocationMinus(3)); //3 = </ and the current char context.Nodes.Push(ct); } //if tag closed if (c == '>') { context.Nodes.Pop(); if (ct.IsNamed) { ct.End(context.Location); // walk up tree of parents looking for matching tag int popCount = 0; bool found = false; foreach (XObject node in context.Nodes) { popCount++; XElement element = node as XElement; if (element != null && element.Name == ct.Name) { found = true; break; } } if (!found) { popCount = 0; } //clear the stack of intermediate unclosed tags while (popCount > 1) { XElement el = context.Nodes.Pop() as XElement; if (el != null) { context.LogError(string.Format( "Unclosed tag '{0}' at line {1}, column {2}.", el.Name.FullName, el.Region.BeginLine, el.Region.BeginColumn), ct.Region); } popCount--; } //close the start tag, if we found it if (popCount > 0) { if (context.BuildTree) { ((XElement)context.Nodes.Pop()).Close(ct); } else { context.Nodes.Pop(); } } else { context.LogError( "Closing tag '" + ct.Name.FullName + "' does not match any currently open tag."); } } else { context.LogError("Closing tag ended prematurely."); } return(Parent); } if (c == '<') { context.LogError("Unexpected '<' in tag."); rollback = string.Empty; return(Parent); } if (!ct.IsNamed && (char.IsLetter(c) || c == '_')) { rollback = string.Empty; return(NameState); } rollback = string.Empty; //note: MalformedTagState logs an error, so skip this //context.LogError ("Unexpected character '" + c + "' in closing tag."); return(MalformedTagState); }
public override State PushChar (char c, IParseContext context, ref string rollback) { XAttribute att = context.Nodes.Peek () as XAttribute; if (c == '<') { //parent handles message if (att != null) context.Nodes.Pop (); rollback = string.Empty; return Parent; } //state has just been entered if (context.CurrentStateLength == 1) { if (context.PreviousState is XmlNameState) { Debug.Assert (att.IsNamed); context.StateTag = GETTINGEQ; } else if (context.PreviousState is XmlAttributeValueState) { //Got value, so end attribute context.Nodes.Pop (); att.End (context.LocationMinus (1)); IAttributedXObject element = (IAttributedXObject) context.Nodes.Peek (); element.Attributes.AddAttribute (att); rollback = string.Empty; return Parent; } else { //starting a new attribute Debug.Assert (att == null); Debug.Assert (context.StateTag == NAMING); att = new XAttribute (context.LocationMinus (1)); context.Nodes.Push (att); rollback = string.Empty; return XmlNameState; } } if (c == '>') { context.LogWarning ("Attribute ended unexpectedly with '>' character."); if (att != null) context.Nodes.Pop (); rollback = string.Empty; return Parent; } if (context.StateTag == GETTINGEQ) { if (char.IsWhiteSpace (c)) { return null; } else if (c == '=') { context.StateTag = GETTINGVAL; return null; } } else if (context.StateTag == GETTINGVAL) { if (char.IsWhiteSpace (c)) { return null; } else if (c== '"') { return DoubleQuotedAttributeValueState; } else if (c == '\'') { return SingleQuotedAttributeValueState; } else if (char.IsLetterOrDigit (c)) { rollback = string.Empty; return UnquotedAttributeValueState; } } if (Char.IsLetterOrDigit (c) || char.IsPunctuation (c) || char.IsWhiteSpace (c)) { string err; if (context.StateTag == GETTINGEQ) context.LogError ("Expecting = in attribute, got " + c + "."); else if (context.StateTag == GETTINGVAL) context.LogError ("Expecting attribute value, got " + c + "."); else context.LogError ("Unexpected character '" + c + "' in attribute."); if (att != null) context.Nodes.Pop (); rollback = string.Empty; return Parent; } rollback = string.Empty; return Parent; }
public override State PushChar(char c, IParseContext context, ref string rollback) { INamedXObject namedObject = context.Nodes.Peek() as INamedXObject; if (namedObject == null || namedObject.Name.Prefix != null) { throw new InvalidOperationException("Invalid state"); } Debug.Assert(context.CurrentStateLength > 1 || char.IsLetter(c) || c == '_', "First character pushed to a XmlTagNameState must be a letter."); Debug.Assert(context.CurrentStateLength > 1 || context.KeywordBuilder.Length == 0, "Keyword builder must be empty when state begins."); if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError("Unexpected ':' in name."); return(Parent); } namedObject.Name = new XName(context.KeywordBuilder.ToString()); context.KeywordBuilder.Length = 0; return(null); } if (XmlChar.IsWhitespace(c) || c == '<' || c == '>' || c == '/' || c == '=') { rollback = string.Empty; if (context.KeywordBuilder.Length == 0) { context.LogError("Zero-length name."); } else if (namedObject.Name.Name != null) { //add prefix (and move current "name" to prefix) namedObject.Name = new XName(namedObject.Name.Name, context.KeywordBuilder.ToString()); } else { namedObject.Name = new XName(context.KeywordBuilder.ToString()); } //note: parent's MalformedTagState logs an error, so skip this //if (c == '<') //context.LogError ("Unexpected '<' in name."); return(Parent); } if (c == ':') { if (namedObject.Name.Name != null || context.KeywordBuilder.Length == 0) { context.LogError("Unexpected ':' in name."); return(Parent); } namedObject.Name = new XName(context.KeywordBuilder.ToString()); context.KeywordBuilder.Length = 0; return(null); } if (XmlChar.IsNameChar(c)) { context.KeywordBuilder.Append(c); return(null); } rollback = string.Empty; context.LogError("Unexpected character '" + c + "' in name"); return(Parent); }
public override State PushChar (char c, IParseContext context, ref string rollback) { var maskedTag = (AttState) ((context.StateTag & TagMask) >> XmlAttributeValueState.TagShift); switch (maskedTag) { case AttState.Incoming: if (c == '<') { SetTag (context, AttState.Bracket); return null; } return base.PushChar (c, context, ref rollback); case AttState.Bracket: if (c == '%') { SetTag (context, AttState.Percent); return null; } rollback = "<"; return Parent; case AttState.Percent: if (c == '-') { SetTag (context, AttState.PercentDash); return null; } if (c == '@') { context.LogError ("Invalid directive location"); rollback = "<%"; return Parent; } AspNetExpressionState.AddExpressionNode (c, context); SetTag (context, AttState.Expression); return null; case AttState.PercentDash: if (c == '-') { context.Nodes.Push (new AspNetServerComment (context.LocationMinus (4))); SetTag (context, AttState.Comment); return null; } context.LogError ("Malformed server comment"); rollback = "<%-"; return Parent; case AttState.Expression: if (c == '%') SetTag (context, AttState.EndPercent); return null; case AttState.EndPercent: if (c == '>') { //TODO: attach nodes var n = context.Nodes.Pop (); n.End (context.Location); SetTag (context, AttState.Incoming); //ensure attribute get closed if value is unquoted var baseState = (context.StateTag & XmlAttributeValueState.TagMask); if (baseState == FREE || baseState == UNQUOTED) { var att = (XAttribute)context.Nodes.Peek (); att.Value = ""; return Parent; } return null; } SetTag (context, AttState.Expression); return null; case AttState.Comment: if (c == '-') SetTag (context, AttState.EndDash); return null; case AttState.EndDash: if (c == '-') SetTag (context, AttState.EndDashDash); else SetTag (context, AttState.Comment); return null; case AttState.EndDashDash: if (c == '%') SetTag (context, AttState.EndDashDashPercent); else if (c != '-') SetTag (context, AttState.Comment); return null; case AttState.EndDashDashPercent: if (c == '>') { //TODO: attach nodes var n = context.Nodes.Pop (); n.End (context.Location); SetTag (context, AttState.Incoming); return null; } SetTag (context, AttState.Comment); return null; default: return base.PushChar (c, context, ref rollback); } }
public override State PushChar (char c, IParseContext context, ref string rollback) { XAttribute att = context.Nodes.Peek () as XAttribute; //state has just been entered if (context.CurrentStateLength == 1) { if (context.PreviousState is XmlNameState) { //error parsing name if (!att.IsNamed) { context.Nodes.Pop (); rollback = string.Empty; return Parent; } context.StateTag = GETTINGEQ; } else if (context.PreviousState is XmlAttributeValueState) { //Got value, so end attribute context.Nodes.Pop (); att.End (context.LocationMinus (1)); IAttributedXObject element = (IAttributedXObject) context.Nodes.Peek (); element.Attributes.AddAttribute (att); rollback = string.Empty; return Parent; } else { //starting a new attribute Debug.Assert (att == null); Debug.Assert (context.StateTag == NAMING); att = new XAttribute (context.LocationMinus (1)); context.Nodes.Push (att); rollback = string.Empty; return XmlNameState; } } if (context.StateTag == GETTINGEQ) { if (char.IsWhiteSpace (c)) { return null; } if (c == '=') { context.StateTag = GETTINGVAL; return null; } context.LogError ("Expecting = in attribute, got '" + c + "'."); } else if (context.StateTag == GETTINGVAL) { if (char.IsWhiteSpace (c)) { return null; } rollback = string.Empty; return AttributeValueState; } else if (c != '<') { //parent handles message for '<' context.LogError ("Unexpected character '" + c + "' in attribute."); } if (att != null) context.Nodes.Pop (); rollback = string.Empty; return Parent; }
public override State PushChar (char c, IParseContext context, ref string rollback) { XElement element = context.Nodes.Peek () as XElement; if (element == null || element.IsComplete) { element = new XElement (context.LocationMinus (2)); // 2 == < + current char context.Nodes.Push (element); } if (c == '<') { if (element.IsNamed) { context.LogError ("Unexpected '<' in tag '" + element.Name.FullName + "'."); Close (element, context); } else { context.LogError ("Unexpected '<' in unnamed tag."); } rollback = string.Empty; return Parent; } Debug.Assert (!element.IsComplete); if (element.IsClosed && c != '>') { if (char.IsWhiteSpace (c)) { context.LogWarning ("Unexpected whitespace after '/' in self-closing tag."); return null; } else { context.LogError ("Unexpected character '" + c + "' after '/' in self-closing tag."); context.Nodes.Pop (); return Parent; } } //if tag closed if (c == '>') { if (!element.IsNamed) { context.LogError ("Tag closed prematurely."); } else { Close (element, context); } return Parent; } if (XmlChar.IsFirstNameChar (c)) { rollback = string.Empty; if (!element.IsNamed) { return NameState; } else { return AttributeState; } } if (c == '/') { element.Close (element); return null; } if (XmlChar.IsWhitespace (c)) return null; if (element.IsNamed) Close (element, context); context.LogError ("Unexpected character '" + c + "' in tag."); rollback = string.Empty; return Parent; }
public override State PushChar(char c, IParseContext context, ref string rollback) { XDocType doc = context.Nodes.Peek() as XDocType; if (doc == null) { doc = new XDocType(context.LocationMinus("<!DOCTYPE".Length + 1)); context.Nodes.Push(doc); } if (!doc.RootElement.IsValid) { if (XmlChar.IsWhitespace(c)) { return(null); } else if (XmlChar.IsFirstNameChar(c)) { rollback = ""; return(nameState); } } else if (doc.PublicFpi == null) { if (context.StateTag == 0) { if (c == 's' || c == 'S') { context.StateTag = 1; return(null); } else if (c == 'p' || c == 'P') { context.StateTag = -1; return(null); } if (XmlChar.IsWhitespace(c)) { return(null); } } else if (Math.Abs(context.StateTag) < 6) { if (context.StateTag > 0) { if ("YSTEM"[context.StateTag - 1] == c || "ystem"[context.StateTag - 1] == c) { context.StateTag++; if (context.StateTag == 6) { context.StateTag = 0; doc.PublicFpi = ""; } return(null); } } else { int absState = Math.Abs(context.StateTag) - 1; if ("UBLIC"[absState] == c || "ublic"[absState] == c) { context.StateTag--; return(null); } } } else { if (context.KeywordBuilder.Length == 0) { if (XmlChar.IsWhitespace(c)) { return(null); } else if (c == '"') { context.KeywordBuilder.Append(c); return(null); } } else { if (c == '"') { context.KeywordBuilder.Remove(0, 1); doc.PublicFpi = context.KeywordBuilder.ToString(); context.KeywordBuilder.Length = 0; context.StateTag = 0; } else { context.KeywordBuilder.Append(c); } return(null); } } } else if (doc.Uri == null) { if (context.KeywordBuilder.Length == 0) { if (XmlChar.IsWhitespace(c)) { return(null); } else if (c == '"') { context.KeywordBuilder.Append(c); return(null); } } else { if (c == '"') { context.KeywordBuilder.Remove(0, 1); doc.Uri = context.KeywordBuilder.ToString(); context.KeywordBuilder.Length = 0; } else { context.KeywordBuilder.Append(c); } return(null); } } else if (doc.InternalDeclarationRegion.EndLine <= 0) { if (XmlChar.IsWhitespace(c)) { return(null); } switch (context.StateTag) { case 0: if (c == '[') { doc.InternalDeclarationRegion = new DomRegion(context.Location, TextLocation.Empty); context.StateTag = 1; return(null); } break; case 1: if (c == '<') { context.StateTag = 2; return(null); } else if (c == ']') { context.StateTag = 0; doc.InternalDeclarationRegion = new DomRegion(doc.InternalDeclarationRegion.Begin, context.Location); return(null); } break; case 2: if (c == '>') { context.StateTag = 1; } return(null); default: throw new InvalidOperationException(); } } doc = (XDocType)context.Nodes.Pop(); if (c == '<') { rollback = string.Empty; context.LogError("Doctype ended prematurely."); } else if (c != '>') { context.LogError("Unexpected character '" + c + "' in doctype."); } if (context.BuildTree) { doc.End(context.Location); ((XContainer)context.Nodes.Peek()).AddChildNode(doc); } return(Parent); }
public override State PushChar(char c, IParseContext context, ref string rollback) { var maskedTag = (AttState)((context.StateTag & TagMask) >> XmlAttributeValueState.TagShift); switch (maskedTag) { case AttState.Incoming: if (c == '<') { SetTag(context, AttState.Bracket); return(null); } return(base.PushChar(c, context, ref rollback)); case AttState.Bracket: if (c == '%') { SetTag(context, AttState.Percent); return(null); } rollback = "<"; return(Parent); case AttState.Percent: if (c == '-') { SetTag(context, AttState.PercentDash); return(null); } if (c == '@') { context.LogError("Invalid directive location"); rollback = "<%"; return(Parent); } AspNetExpressionState.AddExpressionNode(c, context); SetTag(context, AttState.Expression); return(null); case AttState.PercentDash: if (c == '-') { context.Nodes.Push(new AspNetServerComment(context.LocationMinus(4))); SetTag(context, AttState.Comment); return(null); } context.LogError("Malformed server comment"); rollback = "<%-"; return(Parent); case AttState.Expression: if (c == '%') { SetTag(context, AttState.EndPercent); } return(null); case AttState.EndPercent: if (c == '>') { //TODO: attach nodes var n = context.Nodes.Pop(); n.End(context.Location); SetTag(context, AttState.Incoming); //ensure attribute get closed if value is unquoted var baseState = (context.StateTag & XmlAttributeValueState.TagMask); if (baseState == FREE || baseState == UNQUOTED) { var att = (XAttribute)context.Nodes.Peek(); att.Value = ""; return(Parent); } return(null); } SetTag(context, AttState.Expression); return(null); case AttState.Comment: if (c == '-') { SetTag(context, AttState.EndDash); } return(null); case AttState.EndDash: if (c == '-') { SetTag(context, AttState.EndDashDash); } else { SetTag(context, AttState.Comment); } return(null); case AttState.EndDashDash: if (c == '%') { SetTag(context, AttState.EndDashDashPercent); } else if (c != '-') { SetTag(context, AttState.Comment); } return(null); case AttState.EndDashDashPercent: if (c == '>') { //TODO: attach nodes var n = context.Nodes.Pop(); n.End(context.Location); SetTag(context, AttState.Incoming); return(null); } SetTag(context, AttState.Comment); return(null); default: return(base.PushChar(c, context, ref rollback)); } }
public override State PushChar (char c, IParseContext context, ref string rollback) { XElement element = context.Nodes.Peek () as XElement; if (element == null || element.IsComplete) { element = new XElement (context.LocationMinus (2)); // 2 == < + current char context.Nodes.Push (element); } if (c == '<') { if (element.IsNamed) { context.LogError ("Unexpected '<' in tag '" + element.Name.FullName + "'."); Close (element, context, context.LocationMinus (1)); } else { context.LogError ("Unexpected '<' in unnamed tag."); } rollback = string.Empty; return Parent; } Debug.Assert (!element.IsComplete); if (element.IsClosed && c != '>') { if (char.IsWhiteSpace (c)) { context.LogWarning ("Unexpected whitespace after '/' in self-closing tag."); return null; } context.LogError ("Unexpected character '" + c + "' after '/' in self-closing tag."); context.Nodes.Pop (); return Parent; } //if tag closed if (c == '>') { if (context.StateTag == MAYBE_SELF_CLOSING) { element.Close (element); } if (!element.IsNamed) { context.LogError ("Tag closed prematurely."); } else { Close (element, context, context.Location); } return Parent; } if (c == '/') { context.StateTag = MAYBE_SELF_CLOSING; return null; } if (context.StateTag == ATTEMPT_RECOVERY) { if (XmlChar.IsWhitespace (c)) { context.StateTag = RECOVERY_FOUND_WHITESPACE; } return null; } if (context.StateTag == RECOVERY_FOUND_WHITESPACE) { if (!XmlChar.IsFirstNameChar (c)) return null; } context.StateTag = OK; if (!element.IsNamed && XmlChar.IsFirstNameChar (c)) { rollback = string.Empty; return NameState; } if (context.CurrentStateLength > 1 && XmlChar.IsFirstNameChar (c)) { rollback = string.Empty; return AttributeState; } if (XmlChar.IsWhitespace (c)) return null; context.LogError ("Unexpected character '" + c + "' in tag.", context.LocationMinus (1)); context.StateTag = ATTEMPT_RECOVERY; return null; }
public override State PushChar (char c, IParseContext context, ref string rollback) { XDocType doc = context.Nodes.Peek () as XDocType; if (doc == null) { doc = new XDocType (context.LocationMinus ("<!DOCTYPE".Length + 1)); context.Nodes.Push (doc); } if (!doc.RootElement.IsValid) { if (XmlChar.IsWhitespace (c)) return null; else if (XmlChar.IsFirstNameChar (c)) { rollback = ""; return nameState; } } else if (doc.PublicFpi == null) { if (context.StateTag == 0) { if (c == 's' || c == 'S') { context.StateTag = 1; return null; } else if (c == 'p' || c == 'P') { context.StateTag = -1; return null; } if (XmlChar.IsWhitespace (c)) { return null; } } else if (Math.Abs (context.StateTag) < 6) { if (context.StateTag > 0) { if ("YSTEM"[context.StateTag - 1] == c || "ystem"[context.StateTag - 1] == c) { context.StateTag++; if (context.StateTag == 6) { context.StateTag = 0; doc.PublicFpi = ""; } return null; } } else { int absState = Math.Abs (context.StateTag) - 1; if ("UBLIC"[absState] == c || "ublic"[absState] == c) { context.StateTag--; return null; } } } else { if (context.KeywordBuilder.Length == 0) { if (XmlChar.IsWhitespace (c)) return null; else if (c == '"') { context.KeywordBuilder.Append (c); return null; } } else { if (c == '"') { context.KeywordBuilder.Remove (0,1); doc.PublicFpi = context.KeywordBuilder.ToString (); context.KeywordBuilder.Length = 0; context.StateTag = 0; } else { context.KeywordBuilder.Append (c); } return null; } } } else if (doc.Uri == null) { if (context.KeywordBuilder.Length == 0) { if (XmlChar.IsWhitespace (c)) return null; else if (c == '"') { context.KeywordBuilder.Append (c); return null; } } else { if (c == '"') { context.KeywordBuilder.Remove (0,1); doc.Uri = context.KeywordBuilder.ToString (); context.KeywordBuilder.Length = 0; } else { context.KeywordBuilder.Append (c); } return null; } } else if (doc.InternalDeclarationRegion.End.Line <= 0) { if (XmlChar.IsWhitespace (c)) return null; switch (context.StateTag) { case 0: if (c == '[') { doc.InternalDeclarationRegion = new DomRegion (context.Location, DomLocation.Empty); context.StateTag = 1; return null; } break; case 1: if (c == '<') { context.StateTag = 2; return null; } else if (c == ']') { context.StateTag = 0; doc.InternalDeclarationRegion = new DomRegion (doc.InternalDeclarationRegion.Start, context.Location); return null; } break; case 2: if (c == '>') { context.StateTag = 1; } return null; default: throw new InvalidOperationException (); } } doc = (XDocType)context.Nodes.Pop (); if (c == '<') { rollback = string.Empty; context.LogError ("Doctype ended prematurely."); } else if (c != '>') { context.LogError ("Unexpected character '" + c +"' in doctype."); } if (context.BuildTree) { doc.End (context.Location); ((XContainer) context.Nodes.Peek ()).AddChildNode (doc); } return Parent; }
public override State PushChar(char c, IParseContext context, ref string rollback) { XAttribute att = context.Nodes.Peek() as XAttribute; if (c == '<') { //parent handles message if (att != null) { context.Nodes.Pop(); } rollback = string.Empty; return(Parent); } //state has just been entered if (context.CurrentStateLength == 1) { if (context.PreviousState is XmlNameState) { Debug.Assert(att.IsNamed); context.StateTag = GETTINGEQ; } else if (context.PreviousState is XmlAttributeValueState) { //Got value, so end attribute context.Nodes.Pop(); att.End(context.LocationMinus(1)); IAttributedXObject element = (IAttributedXObject)context.Nodes.Peek(); element.Attributes.AddAttribute(att); rollback = string.Empty; return(Parent); } else { //starting a new attribute Debug.Assert(att == null); Debug.Assert(context.StateTag == NAMING); att = new XAttribute(context.LocationMinus(1)); context.Nodes.Push(att); rollback = string.Empty; return(XmlNameState); } } if (c == '>') { context.LogWarning("Attribute ended unexpectedly with '>' character."); if (att != null) { context.Nodes.Pop(); } rollback = string.Empty; return(Parent); } if (context.StateTag == GETTINGEQ) { if (char.IsWhiteSpace(c)) { return(null); } else if (c == '=') { context.StateTag = GETTINGVAL; return(null); } } else if (context.StateTag == GETTINGVAL) { if (char.IsWhiteSpace(c)) { return(null); } else if (c == '"') { return(DoubleQuotedAttributeValueState); } else if (c == '\'') { return(SingleQuotedAttributeValueState); } else if (char.IsLetterOrDigit(c)) { rollback = string.Empty; return(UnquotedAttributeValueState); } } if (char.IsLetterOrDigit(c) || char.IsPunctuation(c) || char.IsWhiteSpace(c)) { if (context.StateTag == GETTINGEQ) { context.LogError("Expecting = in attribute, got " + c + "."); } else if (context.StateTag == GETTINGVAL) { context.LogError("Expecting attribute value, got " + c + "."); } else { context.LogError("Unexpected character '" + c + "' in attribute."); } if (att != null) { context.Nodes.Pop(); } rollback = string.Empty; return(Parent); } rollback = string.Empty; return(Parent); }
public override State PushChar(char c, IParseContext context, ref string rollback) { AspNetDirective directive = context.Nodes.Peek() as AspNetDirective; if (directive == null || directive.IsComplete) { directive = new AspNetDirective(context.LocationMinus(4)); // 4 == <%@ + current char context.Nodes.Push(directive); } if (c == '<') { context.LogError("Unexpected '<' in directive."); rollback = string.Empty; return(Parent); } Debug.Assert(!directive.IsComplete); if (context.StateTag != ENDING && c == '%') { context.StateTag = ENDING; return(null); } if (context.StateTag == ENDING) { if (c == '>') { //have already checked that directive is not null, i.e. top of stack is our directive context.Nodes.Pop(); if (!directive.IsNamed) { context.LogError("Directive closed prematurely."); } else { directive.End(context.Location); if (context.BuildTree) { XContainer container = (XContainer)context.Nodes.Peek(); container.AddChildNode(directive); } } return(Parent); } //ending but not '>'? Error; go to end. } else if (char.IsLetter(c)) { rollback = string.Empty; if (!directive.IsNamed) { return(NameState); } else { return(AttributeState); } } else if (char.IsWhiteSpace(c)) { return(null); } rollback = string.Empty; context.LogError("Unexpected character '" + c + "' in tag."); return(Parent); }
public override State PushChar(char c, IParseContext context, ref string rollback) { switch (context.StateTag) { case INCOMING: if (c == '<' && context.PreviousState != ExpressionState && context.PreviousState != CommentState) { context.StateTag = BRACKET; return(null); } else if (context.PreviousState == ExpressionState || context.PreviousState == CommentState) { //expression has successfully been collected //we should go back to the AttributeValueState or the TagState, not the AttributeState rollback = string.Empty; return(Parent is XmlAttributeState ? Parent.Parent : Parent); } break; case BRACKET: if (c == '%') { context.StateTag = PERCENT; return(null); } else { context.StateTag = MALFORMED; context.LogError("Unexpected tag start"); rollback = "<"; } break; case PERCENT: if (c == '-') { context.StateTag = PERCENT_DASH; return(null); } else if (c == '@') { context.StateTag = MALFORMED; context.LogError("Invalid directive location"); rollback = "<%"; } else { rollback = string.Empty; return(ExpressionState); } break; case PERCENT_DASH: if (c == '-') { return(CommentState); } else { context.StateTag = MALFORMED; context.LogError("Malformed server comment"); rollback = "<%-"; } break; case MALFORMED: break; } return(base.PushChar(c, context, ref rollback)); }
public override State PushChar(char c, IParseContext context, ref string rollback) { if (c == '<') { if (context.StateTag != FREE) { context.LogError("Incomplete tag opening; encountered unexpected '<'.", new MonoDevelop.Projects.Dom.DomRegion( context.LocationMinus(LengthFromOpenBracket(context) + 1), context.LocationMinus(1))); } context.StateTag = BRACKET; return(null); } switch (context.StateTag) { case FREE: //FIXME: handle entities? return(null); case BRACKET: if (c == '?') { rollback = string.Empty; return(this.ProcessingInstructionState); } else if (c == '!') { context.StateTag = BRACKET_EXCLAM; return(null); } else if (c == '/') { return(this.ClosingTagState); } else if (char.IsLetter(c) || c == '_') { rollback = string.Empty; return(TagState); } break; case BRACKET_EXCLAM: if (c == '[') { context.StateTag = CDATA; return(null); } else if (c == '-') { context.StateTag = COMMENT; return(null); } else if (c == 'D') { context.StateTag = DOCTYPE; return(null); } break; case COMMENT: if (c == '-') { return(CommentState); } break; case CDATA: string cdataStr = "CDATA["; if (c == cdataStr [context.KeywordBuilder.Length]) { context.KeywordBuilder.Append(c); if (context.KeywordBuilder.Length < cdataStr.Length) { return(null); } else { return(CDataState); } } else { context.KeywordBuilder.Length = 0; } break; case DOCTYPE: string docTypeStr = "OCTYPE"; if (c == docTypeStr [context.KeywordBuilder.Length]) { context.KeywordBuilder.Append(c); if (context.KeywordBuilder.Length < docTypeStr.Length) { return(null); } else { return(DocTypeState); } } else { context.KeywordBuilder.Length = 0; } break; } context.LogError("Incomplete tag opening; encountered unexpected character '" + c + "'.", new MonoDevelop.Projects.Dom.DomRegion( context.LocationMinus(LengthFromOpenBracket(context)), context.Location)); context.StateTag = FREE; return(null); }