226 changes: 112 additions & 114 deletions std/xml.d
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ enum cdata = "<![CDATA[";
* Params:
* c = the character to be tested
*/
bool isChar(dchar c) @safe // rule 2
bool isChar(dchar c) @safe @nogc pure nothrow // rule 2
{
if (c <= 0xD7FF)
{
Expand All @@ -165,10 +165,8 @@ bool isChar(dchar c) @safe // rule 2
return false;
}

@safe unittest
@safe @nogc nothrow pure unittest
{
// const CharTable=[0x9,0x9,0xA,0xA,0xD,0xD,0x20,0xD7FF,0xE000,0xFFFD,
// 0x10000,0x10FFFF];
assert(!isChar(cast(dchar)0x8));
assert( isChar(cast(dchar)0x9));
assert( isChar(cast(dchar)0xA));
Expand Down Expand Up @@ -208,7 +206,7 @@ bool isChar(dchar c) @safe // rule 2
* Params:
* c = the character to be tested
*/
bool isSpace(dchar c)
bool isSpace(dchar c) @safe @nogc pure nothrow
{
return c == '\u0020' || c == '\u0009' || c == '\u000A' || c == '\u000D';
}
Expand All @@ -221,15 +219,15 @@ bool isSpace(dchar c)
* Params:
* c = the character to be tested
*/
bool isDigit(dchar c)
bool isDigit(dchar c) @safe @nogc pure nothrow
{
if (c <= 0x0039 && c >= 0x0030)
return true;
else
return lookup(DigitTable,c);
}

@safe unittest
@safe @nogc nothrow pure unittest
{
debug (stdxml_TestHardcodedChecks)
{
Expand All @@ -246,7 +244,7 @@ bool isDigit(dchar c)
* Params:
* c = the character to be tested
*/
bool isLetter(dchar c) // rule 84
bool isLetter(dchar c) @safe @nogc nothrow pure // rule 84
{
return isIdeographic(c) || isBaseChar(c);
}
Expand All @@ -260,7 +258,7 @@ bool isLetter(dchar c) // rule 84
* Params:
* c = the character to be tested
*/
bool isIdeographic(dchar c) @safe
bool isIdeographic(dchar c) @safe @nogc nothrow pure
{
if (c == 0x3007)
return true;
Expand All @@ -271,7 +269,7 @@ bool isIdeographic(dchar c) @safe
return false;
}

@safe unittest
@safe @nogc nothrow pure unittest
{
assert(isIdeographic('\u4E00'));
assert(isIdeographic('\u9FA5'));
Expand All @@ -295,7 +293,7 @@ bool isIdeographic(dchar c) @safe
* Params:
* c = the character to be tested
*/
bool isBaseChar(dchar c)
bool isBaseChar(dchar c) @safe @nogc nothrow pure
{
return lookup(BaseCharTable,c);
}
Expand All @@ -309,7 +307,7 @@ bool isBaseChar(dchar c)
* Params:
* c = the character to be tested
*/
bool isCombiningChar(dchar c)
bool isCombiningChar(dchar c) @safe @nogc nothrow pure
{
return lookup(CombiningCharTable,c);
}
Expand All @@ -322,7 +320,7 @@ bool isCombiningChar(dchar c)
* Params:
* c = the character to be tested
*/
bool isExtender(dchar c)
bool isExtender(dchar c) @safe @nogc nothrow pure
{
return lookup(ExtenderTable,c);
}
Expand Down Expand Up @@ -436,7 +434,7 @@ enum DecodeMode
* writefln(decode("a &gt; b")); // writes "a > b"
* --------------
*/
string decode(string s, DecodeMode mode=DecodeMode.LOOSE) @system
string decode(string s, DecodeMode mode=DecodeMode.LOOSE) @system pure
{
if (mode == DecodeMode.NONE) return s;

Expand Down Expand Up @@ -489,9 +487,9 @@ string decode(string s, DecodeMode mode=DecodeMode.LOOSE) @system
return (buffer.length == 0) ? s : cast(string)buffer;
}

@system unittest
@system pure unittest
{
void assertNot(string s)
void assertNot(string s) pure
{
bool b = false;
try { decode(s,DecodeMode.STRICT); }
Expand Down Expand Up @@ -577,7 +575,7 @@ class Document : Element
* Params:
* tag = the start tag of the document.
*/
this(const(Tag) tag) @safe
this(const(Tag) tag)
{
super(tag);
}
Expand Down Expand Up @@ -694,7 +692,7 @@ class Element : Item
* // constructs the element <title>Serenity</title>
* -------------------------------------------------------
*/
this(string name, string interior=null)
this(string name, string interior=null) @safe pure
{
this(new Tag(name));
if (interior.length != 0) opCatAssign(new Text(interior));
Expand All @@ -706,7 +704,7 @@ class Element : Item
* Params:
* tag_ = the start or empty tag of the element.
*/
this(const(Tag) tag_) @safe
this(const(Tag) tag_) @safe pure
{
this.tag = new Tag(tag_.name);
tag.type = TagType.EMPTY;
Expand All @@ -726,7 +724,7 @@ class Element : Item
* element ~= new Text("hello");
* --------------
*/
void opCatAssign(Text item)
void opCatAssign(Text item) @safe pure
{
texts ~= item;
appendItem(item);
Expand All @@ -744,7 +742,7 @@ class Element : Item
* element ~= new CData("hello");
* --------------
*/
void opCatAssign(CData item)
void opCatAssign(CData item) @safe pure
{
cdatas ~= item;
appendItem(item);
Expand All @@ -762,7 +760,7 @@ class Element : Item
* element ~= new Comment("hello");
* --------------
*/
void opCatAssign(Comment item)
void opCatAssign(Comment item) @safe pure
{
comments ~= item;
appendItem(item);
Expand All @@ -780,7 +778,7 @@ class Element : Item
* element ~= new ProcessingInstruction("hello");
* --------------
*/
void opCatAssign(ProcessingInstruction item)
void opCatAssign(ProcessingInstruction item) @safe pure
{
pis ~= item;
appendItem(item);
Expand All @@ -800,13 +798,13 @@ class Element : Item
* // appends element representing <br />
* --------------
*/
void opCatAssign(Element item)
void opCatAssign(Element item) @safe pure
{
elements ~= item;
appendItem(item);
}

private void appendItem(Item item)
private void appendItem(Item item) @safe pure
{
items ~= item;
if (tag.type == TagType.EMPTY && !item.isEmptyXML)
Expand Down Expand Up @@ -968,7 +966,7 @@ class Element : Item
return buffer;
}

override @property bool isEmptyXML() { return items.length == 0; }
override @property @safe pure @nogc nothrow bool isEmptyXML() { return items.length == 0; }
}
}

Expand Down Expand Up @@ -1040,7 +1038,7 @@ class Tag
* tag.attr["src"] = "http://example.com/example.jpg";
* --------------
*/
this(string name, TagType type=TagType.START) @safe
this(string name, TagType type=TagType.START) @safe pure
{
this.name = name;
this.type = type;
Expand Down Expand Up @@ -1189,7 +1187,7 @@ class Tag
* if (tag.isStart) { }
* --------------
*/
@property bool isStart() { return type == TagType.START; }
@property bool isStart() @safe @nogc pure nothrow { return type == TagType.START; }

/**
* Returns true if the Tag is an end tag
Expand All @@ -1199,7 +1197,7 @@ class Tag
* if (tag.isEnd) { }
* --------------
*/
@property bool isEnd() { return type == TagType.END; }
@property bool isEnd() @safe @nogc pure nothrow { return type == TagType.END; }

/**
* Returns true if the Tag is an empty tag
Expand All @@ -1209,7 +1207,7 @@ class Tag
* if (tag.isEmpty) { }
* --------------
*/
@property bool isEmpty() { return type == TagType.EMPTY; }
@property bool isEmpty() @safe @nogc pure nothrow { return type == TagType.EMPTY; }
}
}

Expand All @@ -1235,7 +1233,7 @@ class Comment : Item
* // constructs <!--This is a comment-->
* --------------
*/
this(string content)
this(string content) @safe pure
{
if (content == "-" || content.indexOf("--") != -1)
throw new CommentException(content);
Expand Down Expand Up @@ -1284,14 +1282,14 @@ class Comment : Item
* You should rarely need to call this function. It exists so that Comments
* can be used as associative array keys.
*/
override size_t toHash() const { return hash(content); }
override size_t toHash() const nothrow { return hash(content); }

/**
* Returns a string representation of this comment
*/
override string toString() const { return "<!--" ~ content ~ "-->"; }
override string toString() const @safe pure nothrow { return "<!--" ~ content ~ "-->"; }

override @property bool isEmptyXML() const { return false; } /// Returns false always
override @property @safe @nogc pure nothrow bool isEmptyXML() const { return false; } /// Returns false always
}

unittest // issue 16241
Expand Down Expand Up @@ -1323,7 +1321,7 @@ class CData : Item
* // constructs <![CDATA[<b>hello</b>]]>
* --------------
*/
this(string content)
this(string content) @safe pure
{
if (content.indexOf("]]>") != -1) throw new CDataException(content);
this.content = content;
Expand Down Expand Up @@ -1371,14 +1369,14 @@ class CData : Item
* You should rarely need to call this function. It exists so that CDatas
* can be used as associative array keys.
*/
override size_t toHash() const { return hash(content); }
override size_t toHash() const nothrow { return hash(content); }

/**
* Returns a string representation of this CData section
*/
override string toString() const { return cdata ~ content ~ "]]>"; }
override string toString() const @safe pure nothrow { return cdata ~ content ~ "]]>"; }

override @property bool isEmptyXML() const { return false; } /// Returns false always
override @property @safe @nogc pure nothrow bool isEmptyXML() const { return false; } /// Returns false always
}

/**
Expand All @@ -1401,7 +1399,7 @@ class Text : Item
* // constructs a &lt; b
* --------------
*/
this(string content)
this(string content) @safe pure
{
this.content = encode(content);
}
Expand Down Expand Up @@ -1448,17 +1446,17 @@ class Text : Item
* You should rarely need to call this function. It exists so that Texts
* can be used as associative array keys.
*/
override size_t toHash() const { return hash(content); }
override size_t toHash() const nothrow { return hash(content); }

/**
* Returns a string representation of this Text section
*/
override string toString() const { return content; }
override string toString() const @safe @nogc pure nothrow { return content; }

/**
* Returns true if the content is the empty string
*/
override @property bool isEmptyXML() const { return content.length == 0; }
override @property @safe @nogc pure nothrow bool isEmptyXML() const { return content.length == 0; }
}

/**
Expand All @@ -1482,7 +1480,7 @@ class XMLInstruction : Item
* // constructs <!ATTLIST>
* --------------
*/
this(string content)
this(string content) @safe pure
{
if (content.indexOf(">") != -1) throw new XIException(content);
this.content = content;
Expand Down Expand Up @@ -1530,14 +1528,14 @@ class XMLInstruction : Item
* You should rarely need to call this function. It exists so that
* XmlInstructions can be used as associative array keys.
*/
override size_t toHash() const { return hash(content); }
override size_t toHash() const nothrow { return hash(content); }

/**
* Returns a string representation of this XmlInstruction
*/
override string toString() const { return "<!" ~ content ~ ">"; }
override string toString() const @safe pure nothrow { return "<!" ~ content ~ ">"; }

override @property bool isEmptyXML() const { return false; } /// Returns false always
override @property @safe @nogc pure nothrow bool isEmptyXML() const { return false; } /// Returns false always
}

/**
Expand All @@ -1561,7 +1559,7 @@ class ProcessingInstruction : Item
* // constructs <?php?>
* --------------
*/
this(string content)
this(string content) @safe pure
{
if (content.indexOf("?>") != -1) throw new PIException(content);
this.content = content;
Expand Down Expand Up @@ -1609,14 +1607,14 @@ class ProcessingInstruction : Item
* You should rarely need to call this function. It exists so that
* ProcessingInstructions can be used as associative array keys.
*/
override size_t toHash() const { return hash(content); }
override size_t toHash() const nothrow { return hash(content); }

/**
* Returns a string representation of this ProcessingInstruction
*/
override string toString() const { return "<?" ~ content ~ "?>"; }
override string toString() const @safe pure nothrow { return "<?" ~ content ~ "?>"; }

override @property bool isEmptyXML() const { return false; } /// Returns false always
override @property @safe @nogc pure nothrow bool isEmptyXML() const { return false; } /// Returns false always
}

/**
Expand Down Expand Up @@ -1649,7 +1647,7 @@ abstract class Item
}

/// Returns true if the item represents empty XML text
abstract @property bool isEmptyXML() const;
abstract @property @safe @nogc pure nothrow bool isEmptyXML() const;
}

/**
Expand Down Expand Up @@ -1735,15 +1733,15 @@ class ElementParser
Handler textHandler = null;

// Private constructor for start tags
this(ElementParser parent) @safe
this(ElementParser parent) @safe @nogc pure nothrow
{
s = parent.s;
this();
tag_ = parent.tag_;
}

// Private constructor for empty tags
this(Tag tag, string* t)
this(Tag tag, string* t) @safe @nogc pure nothrow
{
s = t;
this();
Expand All @@ -1755,7 +1753,7 @@ class ElementParser
* The Tag at the start of the element being parsed. You can read this to
* determine the tag's name and attributes.
*/
@property @safe const(Tag) tag() const { return tag_; }
@property @safe @nogc pure nothrow const(Tag) tag() const { return tag_; }

/**
* Register a handler which will be called whenever a start tag is
Expand Down Expand Up @@ -1824,7 +1822,7 @@ class ElementParser
*/
ElementHandler[string] onEndTag;

protected this() @safe
protected this() @safe @nogc pure nothrow
{
elementStart = *s;
}
Expand All @@ -1847,7 +1845,7 @@ class ElementParser
* };
* --------------
*/
@property @safe void onText(Handler handler) { textHandler = handler; }
@property @safe @nogc pure nothrow void onText(Handler handler) { textHandler = handler; }

/**
* Register an alternative handler which will be called whenever text
Expand All @@ -1873,7 +1871,7 @@ class ElementParser
* };
* --------------
*/
@safe void onTextRaw(Handler handler) { rawTextHandler = handler; }
@safe @nogc pure nothrow void onTextRaw(Handler handler) { rawTextHandler = handler; }

/**
* Register a handler which will be called whenever a character data
Expand All @@ -1894,7 +1892,7 @@ class ElementParser
* };
* --------------
*/
@property @safe void onCData(Handler handler) { cdataHandler = handler; }
@property @safe @nogc pure nothrow void onCData(Handler handler) { cdataHandler = handler; }

/**
* Register a handler which will be called whenever a comment is
Expand All @@ -1915,7 +1913,7 @@ class ElementParser
* };
* --------------
*/
@property @safe void onComment(Handler handler) { commentHandler = handler; }
@property @safe @nogc pure nothrow void onComment(Handler handler) { commentHandler = handler; }

/**
* Register a handler which will be called whenever a processing
Expand All @@ -1936,7 +1934,7 @@ class ElementParser
* };
* --------------
*/
@property @safe void onPI(Handler handler) { piHandler = handler; }
@property @safe @nogc pure nothrow void onPI(Handler handler) { piHandler = handler; }

/**
* Register a handler which will be called whenever an XML instruction is
Expand All @@ -1959,7 +1957,7 @@ class ElementParser
* };
* --------------
*/
@property @safe void onXI(Handler handler) { xiHandler = handler; }
@property @safe @nogc pure nothrow void onXI(Handler handler) { xiHandler = handler; }

/**
* Parse an XML element.
Expand Down Expand Up @@ -2096,7 +2094,7 @@ class ElementParser
/**
* Returns that part of the element which has already been parsed
*/
override string toString() const
override string toString() const @nogc @safe pure nothrow
{
assert(elementStart.length >= s.length);
return elementStart[0 .. elementStart.length - s.length];
Expand All @@ -2110,25 +2108,25 @@ private
{
string old = s;

void fail() @safe
void fail() @safe pure
{
s = old;
throw new Err(s,msg);
}

void fail(Err e)
void fail(Err e) @safe pure
{
s = old;
throw new Err(s,msg,e);
}

void fail(string msg2)
void fail(string msg2) @safe pure
{
fail(new Err(s,msg2));
}
}

void checkMisc(ref string s) // rule 27
void checkMisc(ref string s) @safe pure // rule 27
{
mixin Check!("Misc");

Expand All @@ -2141,7 +2139,7 @@ private
catch (Err e) { fail(e); }
}

void checkDocument(ref string s) // rule 1
void checkDocument(ref string s) @safe pure // rule 1
{
mixin Check!("Document");
try
Expand All @@ -2153,7 +2151,7 @@ private
catch (Err e) { fail(e); }
}

void checkChars(ref string s) @safe // rule 2
void checkChars(ref string s) @safe pure // rule 2
{
// TO DO - Fix std.utf stride and decode functions, then use those
// instead
Expand All @@ -2178,14 +2176,14 @@ private
}
}

void checkSpace(ref string s) // rule 3
void checkSpace(ref string s) @safe pure // rule 3
{
mixin Check!("Whitespace");
munch(s,"\u0020\u0009\u000A\u000D");
if (s is old) fail();
}

void checkName(ref string s, out string name) // rule 5
void checkName(ref string s, out string name) @safe pure // rule 5
{
mixin Check!("Name");

Expand All @@ -2204,7 +2202,7 @@ private
s = s[n..$];
}

void checkAttValue(ref string s) // rule 10
void checkAttValue(ref string s) @safe pure // rule 10
{
mixin Check!("AttValue");

Expand All @@ -2224,7 +2222,7 @@ private
s = s[1..$];
}

void checkCharData(ref string s) // rule 14
void checkCharData(ref string s) @safe pure // rule 14
{
mixin Check!("CharData");

Expand All @@ -2237,7 +2235,7 @@ private
}
}

void checkComment(ref string s) // rule 15
void checkComment(ref string s) @safe pure // rule 15
{
mixin Check!("Comment");

Expand All @@ -2248,7 +2246,7 @@ private
try { checkLiteral("-->",s); } catch (Err e) { fail(e); }
}

void checkPI(ref string s) // rule 16
void checkPI(ref string s) @safe pure // rule 16
{
mixin Check!("PI");

Expand All @@ -2260,7 +2258,7 @@ private
catch (Err e) { fail(e); }
}

void checkCDSect(ref string s) // rule 18
void checkCDSect(ref string s) @safe pure // rule 18
{
mixin Check!("CDSect");

Expand All @@ -2272,7 +2270,7 @@ private
catch (Err e) { fail(e); }
}

void checkProlog(ref string s) // rule 22
void checkProlog(ref string s) @safe pure // rule 22
{
mixin Check!("Prolog");

Expand All @@ -2289,7 +2287,7 @@ private
catch (Err e) { fail(e); }
}

void checkXMLDecl(ref string s) // rule 23
void checkXMLDecl(ref string s) @safe pure // rule 23
{
mixin Check!("XMLDecl");

Expand All @@ -2305,7 +2303,7 @@ private
catch (Err e) { fail(e); }
}

void checkVersionInfo(ref string s) // rule 24
void checkVersionInfo(ref string s) @safe pure // rule 24
{
mixin Check!("VersionInfo");

Expand All @@ -2319,7 +2317,7 @@ private
catch (Err e) { fail(e); }
}

void checkEq(ref string s) // rule 25
void checkEq(ref string s) @safe pure // rule 25
{
mixin Check!("Eq");

Expand All @@ -2332,15 +2330,15 @@ private
catch (Err e) { fail(e); }
}

void checkVersionNum(ref string s) // rule 26
void checkVersionNum(ref string s) @safe pure // rule 26
{
mixin Check!("VersionNum");

munch(s,"a-zA-Z0-9_.:-");
if (s is old) fail();
}

void checkDocTypeDecl(ref string s) // rule 28
void checkDocTypeDecl(ref string s) @safe pure // rule 28
{
mixin Check!("DocTypeDecl");

Expand All @@ -2356,7 +2354,7 @@ private
catch (Err e) { fail(e); }
}

void checkSDDecl(ref string s) // rule 32
void checkSDDecl(ref string s) @safe pure // rule 32
{
mixin Check!("SDDecl");

Expand All @@ -2376,7 +2374,7 @@ private
s = s[n..$];
}

void checkElement(ref string s) // rule 39
void checkElement(ref string s) @safe pure // rule 39
{
mixin Check!("Element");

Expand All @@ -2403,7 +2401,7 @@ private
}

// rules 40 and 44
void checkTag(ref string s, out string type, out string name)
void checkTag(ref string s, out string type, out string name) @safe pure
{
mixin Check!("Tag");

Expand All @@ -2424,7 +2422,7 @@ private
catch (Err e) { fail(e); }
}

void checkAttribute(ref string s) // rule 41
void checkAttribute(ref string s) @safe pure // rule 41
{
mixin Check!("Attribute");

Expand All @@ -2438,7 +2436,7 @@ private
catch (Err e) { fail(e); }
}

void checkETag(ref string s, out string name) // rule 42
void checkETag(ref string s, out string name) @safe pure // rule 42
{
mixin Check!("ETag");

Expand All @@ -2452,7 +2450,7 @@ private
catch (Err e) { fail(e); }
}

void checkContent(ref string s) // rule 43
void checkContent(ref string s) @safe pure // rule 43
{
mixin Check!("Content");

Expand All @@ -2473,7 +2471,7 @@ private
catch (Err e) { fail(e); }
}

void checkCharRef(ref string s, out dchar c) @safe // rule 66
void checkCharRef(ref string s, out dchar c) @safe pure // rule 66
{
mixin Check!("CharRef");

Expand Down Expand Up @@ -2522,7 +2520,7 @@ private
else s = s[1..$];
}

void checkReference(ref string s) // rule 67
void checkReference(ref string s) @safe pure // rule 67
{
mixin Check!("Reference");

Expand All @@ -2535,7 +2533,7 @@ private
catch (Err e) { fail(e); }
}

void checkEntityRef(ref string s) // rule 68
void checkEntityRef(ref string s) @safe pure // rule 68
{
mixin Check!("EntityRef");

Expand All @@ -2549,7 +2547,7 @@ private
catch (Err e) { fail(e); }
}

void checkEncName(ref string s) // rule 81
void checkEncName(ref string s) @safe pure // rule 81
{
mixin Check!("EncName");

Expand All @@ -2558,7 +2556,7 @@ private
munch(s,"a-zA-Z0-9_.-");
}

void checkEncodingDecl(ref string s) // rule 80
void checkEncodingDecl(ref string s) @safe pure // rule 80
{
mixin Check!("EncodingDecl");

Expand All @@ -2574,15 +2572,15 @@ private

// Helper functions

void checkLiteral(string literal,ref string s) @safe
void checkLiteral(string literal,ref string s) @safe pure
{
mixin Check!("Literal");

if (!s.startsWith(literal)) fail("Expected literal \""~literal~"\"");
s = s[literal.length..$];
}

void checkEnd(string end,ref string s)
void checkEnd(string end,ref string s) @safe pure
{
// Deliberately no mixin Check here.

Expand Down Expand Up @@ -2649,7 +2647,7 @@ private
* parse failure (the XML equivalent of a stack trace), giving the line and
* column number of every failure at every level.
*/
void check(string s)
void check(string s) pure
{
try
{
Expand All @@ -2664,7 +2662,7 @@ void check(string s)
}
}

@system unittest
@system pure unittest
{
try
{
Expand Down Expand Up @@ -2778,41 +2776,41 @@ EOS";
}

/** The base class for exceptions thrown by this module */
class XMLException : Exception { this(string msg) @safe { super(msg); } }
class XMLException : Exception { this(string msg) @safe pure { super(msg); } }

// Other exceptions

/// Thrown during Comment constructor
class CommentException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/// Thrown during CData constructor
class CDataException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/// Thrown during XMLInstruction constructor
class XIException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/// Thrown during ProcessingInstruction constructor
class PIException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/// Thrown during Text constructor
class TextException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/// Thrown during decode()
class DecodeException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/// Thrown if comparing with wrong type
class InvalidTypeException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/// Thrown when parsing for Tags
class TagException : XMLException
{ private this(string msg) @safe { super(msg); } }
{ private this(string msg) @safe pure { super(msg); } }

/**
* Thrown during check()
Expand All @@ -2829,15 +2827,15 @@ class CheckException : XMLException
size_t line = 0; /// Line number at which parse failure occurred
size_t column = 0; /// Column number at which parse failure occurred

private this(string tail,string msg,Err err=null) @safe
private this(string tail,string msg,Err err=null) @safe pure
{
super(null);
this.tail = tail;
this.msg = msg;
this.err = err;
}

private void complete(string entire)
private void complete(string entire) pure
{
string head = entire[0..$-tail.length];
ptrdiff_t n = head.lastIndexOf('\n') + 1;
Expand All @@ -2848,7 +2846,7 @@ class CheckException : XMLException
if (err !is null) err.complete(entire);
}

override string toString() const @safe
override string toString() const @safe pure
{
string s;
if (line != 0) s = format("Line %d, column %d: ",line,column);
Expand Down Expand Up @@ -2876,28 +2874,28 @@ private
return t;
}

string chop(ref string s, size_t n) @safe
string chop(ref string s, size_t n) @safe pure nothrow
{
if (n == -1) n = s.length;
string t = s[0..n];
s = s[n..$];
return t;
}

bool optc(ref string s, char c) @safe
bool optc(ref string s, char c) @safe pure nothrow
{
bool b = s.length != 0 && s[0] == c;
if (b) s = s[1..$];
return b;
}

void reqc(ref string s, char c) @safe
void reqc(ref string s, char c) @safe pure
{
if (s.length == 0 || s[0] != c) throw new TagException("");
s = s[1..$];
}

char requireOneOf(ref string s, string chars) @safe
char requireOneOf(ref string s, string chars) @safe pure
{
if (s.length == 0 || indexOf(chars,s[0]) == -1)
throw new TagException("");
Expand Down Expand Up @@ -2984,7 +2982,7 @@ private
0x0387,0x0640,0x0640,0x0E46,0x0E46,0x0EC6,0x0EC6,0x3005,0x3005,0x3031,
0x3035,0x309D,0x309E,0x30FC,0x30FE];

bool lookup(const(int)[] table, int c)
bool lookup(const(int)[] table, int c) @safe @nogc nothrow pure
{
while (table.length != 0)
{
Expand All @@ -3002,7 +3000,7 @@ private
return false;
}

string startOf(string s)
string startOf(string s) @safe nothrow pure
{
string r;
foreach (char c;s)
Expand Down