public virtual string ParseValue(string name, bool foldCase, MutableBoolean isempty, MutableInteger pdelim)
{
int len;
int start;
short map;
bool seenGt = false;
bool munge = true;
int c;
int delim, quotewarning;
string val;
delim = 0;
pdelim.Val = '"';
/*
Henry Zrepa reports that some folk are using the
embed element with script attributes where newlines
are significant and must be preserved
*/
if (Options.LiteralAttribs)
munge = false;
/* skip white space before the '=' */
for (;;)
{
c = Input.ReadChar();
if (c == StreamIn.END_OF_STREAM)
{
Input.UngetChar(c);
break;
}
map = Map((char) c);
if ((map & WHITE) == 0)
{
break;
}
}
/*
c should be '=' if there is a value
other legal possibilities are white
space, '/' and '>'
*/
if (c != '=')
{
Input.UngetChar(c);
return null;
}
/* skip white space after '=' */
for (;;)
{
c = Input.ReadChar();
if (c == StreamIn.END_OF_STREAM)
{
Input.UngetChar(c);
break;
}
map = Map((char) c);
if ((map & WHITE) == 0)
break;
}
/* check for quote marks */
if (c == '"' || c == '\'')
delim = c;
else if (c == '<')
{
start = Lexsize;
AddCharToLexer(c);
pdelim.Val = ParseServerInstruction();
len = Lexsize - start;
Lexsize = start;
return (len > 0 ? GetString(Lexbuf, start, len) : null);
}
else
{
Input.UngetChar(c);
}
/*
and read the value string
check for quote mark if needed
*/
quotewarning = 0;
start = Lexsize;
c = '\x0000';
for (;;)
{
int lastc = c;
c = Input.ReadChar();
if (c == StreamIn.END_OF_STREAM)
{
Report.AttrError(this, Token, null, Report.UNEXPECTED_END_OF_FILE);
Input.UngetChar(c);
break;
}
if (delim == (char) 0)
{
if (c == '>')
{
Input.UngetChar(c);
break;
}
if (c == '"' || c == '\'')
{
Report.AttrError(this, Token, null, Report.UNEXPECTED_QUOTEMARK);
break;
}
if (c == '<')
{
/* in.UngetChar(c); */
Report.AttrError(this, Token, null, Report.UNEXPECTED_GT);
/* break; */
}
/*
For cases like <br clear=all/> need to avoid treating /> as
part of the attribute value, however care is needed to avoid
so treating <a href=http://www.acme.com/> in this way, which
would map the <a> tag to <a href="http://www.acme.com"/>
*/
if (c == '/')
{
/* peek ahead in case of /> */
c = Input.ReadChar();
if (c == '>' && !AttributeTable.DefaultAttributeTable.IsUrl(name))
{
isempty.Val = true;
Input.UngetChar(c);
break;
}
/* unget peeked char */
Input.UngetChar(c);
c = '/';
}
}
/* delim is '\'' or '"' */
else
{
if (c == delim)
{
break;
}
/* treat CRLF, CR and LF as single line break */
if (c == '\r')
{
c = Input.ReadChar();
if (c != '\n')
{
Input.UngetChar(c);
}
c = '\n';
}
if (c == '\n' || c == '<' || c == '>')
++quotewarning;
if (c == '>')
seenGt = true;
}
if (c == '&')
{
AddCharToLexer(c);
ParseEntity(0);
continue;
}
/*
kludge for JavaScript attribute values
with line continuations in string literals
*/
if (c == '\\')
{
c = Input.ReadChar();
if (c != '\n')
{
Input.UngetChar(c);
c = '\\';
}
}
map = Map((char) c);
if ((map & WHITE) != 0)
{
if (delim == (char) 0)
break;
if (munge)
{
c = ' ';
if (lastc == ' ')
continue;
}
}
else if (foldCase && (map & UPPERCASE) != 0)
c += ('a' - 'A');
AddCharToLexer(c);
}
if (quotewarning > 10 && seenGt && munge)
{
/*
there is almost certainly a missing trailling quote mark
as we have see too many newlines, < or > characters.
an exception is made for Javascript attributes and the
javascript URL scheme which may legitimately include < and >
*/
if (!AttributeTable.DefaultAttributeTable.IsScript(name) &&
!(AttributeTable.DefaultAttributeTable.IsUrl(name) &&
(GetString(Lexbuf, start, 11)).Equals("javascript:")))
Report.Error(this, null, null, Report.SUSPECTED_MISSING_QUOTE);
}
len = Lexsize - start;
Lexsize = start;
if (len > 0 || delim != 0)
{
val = GetString(Lexbuf, start, len);
}
else
{
val = null;
}
/* note delimiter if given */
pdelim.Val = delim != 0 ? delim : '"';
return val;
}