Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
gaoqiong
yaml-cpp
Commits
45322566
Commit
45322566
authored
Sep 03, 2008
by
Jesse Beder
Browse files
Set the eol style to native for all files.
parent
a45f083e
Changes
42
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1673 additions
and
1673 deletions
+1673
-1673
include/crt.h
include/crt.h
+11
-11
include/exceptions.h
include/exceptions.h
+59
-59
include/iterator.h
include/iterator.h
+30
-30
include/node.h
include/node.h
+92
-92
include/parser.h
include/parser.h
+42
-42
include/parserstate.h
include/parserstate.h
+20
-20
include/yaml.h
include/yaml.h
+8
-8
src/content.cpp
src/content.cpp
+13
-13
src/content.h
src/content.h
+55
-55
src/exp.cpp
src/exp.cpp
+113
-113
src/exp.h
src/exp.h
+71
-71
src/iterator.cpp
src/iterator.cpp
+108
-108
src/iterpriv.h
src/iterpriv.h
+25
-25
src/ltnode.h
src/ltnode.h
+10
-10
src/map.cpp
src/map.cpp
+196
-196
src/map.h
src/map.h
+38
-38
src/node.cpp
src/node.cpp
+317
-317
src/parser.cpp
src/parser.cpp
+133
-133
src/parserstate.cpp
src/parserstate.cpp
+26
-26
src/regex.cpp
src/regex.cpp
+306
-306
No files found.
include/crt.h
View file @
45322566
#pragma once
#pragma once
// for detecting memory leaks
// for detecting memory leaks
#ifdef _DEBUG
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <stdlib.h>
#include <crtdbg.h>
#include <crtdbg.h>
#endif // _DEBUG
#endif // _DEBUG
include/exceptions.h
View file @
45322566
#pragma once
#pragma once
#include <exception>
#include <exception>
#include <string>
#include <string>
namespace
YAML
namespace
YAML
{
{
class
Exception
:
public
std
::
exception
{};
class
Exception
:
public
std
::
exception
{};
class
ParserException
:
public
Exception
{
class
ParserException
:
public
Exception
{
public:
public:
ParserException
(
int
line_
,
int
column_
,
const
std
::
string
&
msg_
)
ParserException
(
int
line_
,
int
column_
,
const
std
::
string
&
msg_
)
:
line
(
line_
),
column
(
column_
),
msg
(
msg_
)
{}
:
line
(
line_
),
column
(
column_
),
msg
(
msg_
)
{}
virtual
~
ParserException
()
throw
()
{}
virtual
~
ParserException
()
throw
()
{}
int
line
,
column
;
int
line
,
column
;
std
::
string
msg
;
std
::
string
msg
;
};
};
class
RepresentationException
:
public
Exception
{};
class
RepresentationException
:
public
Exception
{};
// representation exceptions
// representation exceptions
class
InvalidScalar
:
public
RepresentationException
{};
class
InvalidScalar
:
public
RepresentationException
{};
class
BadDereference
:
public
RepresentationException
{};
class
BadDereference
:
public
RepresentationException
{};
// error messages
// error messages
namespace
ErrorMsg
namespace
ErrorMsg
{
{
const
std
::
string
YAML_DIRECTIVE_ARGS
=
"YAML directives must have exactly one argument"
;
const
std
::
string
YAML_DIRECTIVE_ARGS
=
"YAML directives must have exactly one argument"
;
const
std
::
string
YAML_VERSION
=
"bad YAML version: "
;
const
std
::
string
YAML_VERSION
=
"bad YAML version: "
;
const
std
::
string
YAML_MAJOR_VERSION
=
"YAML major version too large"
;
const
std
::
string
YAML_MAJOR_VERSION
=
"YAML major version too large"
;
const
std
::
string
TAG_DIRECTIVE_ARGS
=
"TAG directives must have exactly two arguments"
;
const
std
::
string
TAG_DIRECTIVE_ARGS
=
"TAG directives must have exactly two arguments"
;
const
std
::
string
END_OF_MAP
=
"end of map not found"
;
const
std
::
string
END_OF_MAP
=
"end of map not found"
;
const
std
::
string
END_OF_MAP_FLOW
=
"end of map flow not found"
;
const
std
::
string
END_OF_MAP_FLOW
=
"end of map flow not found"
;
const
std
::
string
END_OF_SEQ
=
"end of sequence not found"
;
const
std
::
string
END_OF_SEQ
=
"end of sequence not found"
;
const
std
::
string
END_OF_SEQ_FLOW
=
"end of sequence flow not found"
;
const
std
::
string
END_OF_SEQ_FLOW
=
"end of sequence flow not found"
;
const
std
::
string
MULTIPLE_TAGS
=
"cannot assign multiple tags to the same node"
;
const
std
::
string
MULTIPLE_TAGS
=
"cannot assign multiple tags to the same node"
;
const
std
::
string
MULTIPLE_ANCHORS
=
"cannot assign multiple anchors to the same node"
;
const
std
::
string
MULTIPLE_ANCHORS
=
"cannot assign multiple anchors to the same node"
;
const
std
::
string
MULTIPLE_ALIASES
=
"cannot assign multiple aliases to the same node"
;
const
std
::
string
MULTIPLE_ALIASES
=
"cannot assign multiple aliases to the same node"
;
const
std
::
string
ALIAS_CONTENT
=
"aliases can't have any content, *including* tags"
;
const
std
::
string
ALIAS_CONTENT
=
"aliases can't have any content, *including* tags"
;
const
std
::
string
INVALID_HEX
=
"bad character found while scanning hex number"
;
const
std
::
string
INVALID_HEX
=
"bad character found while scanning hex number"
;
const
std
::
string
INVALID_UNICODE
=
"invalid unicode: "
;
const
std
::
string
INVALID_UNICODE
=
"invalid unicode: "
;
const
std
::
string
INVALID_ESCAPE
=
"unknown escape character: "
;
const
std
::
string
INVALID_ESCAPE
=
"unknown escape character: "
;
const
std
::
string
UNKNOWN_TOKEN
=
"unknown token"
;
const
std
::
string
UNKNOWN_TOKEN
=
"unknown token"
;
const
std
::
string
DOC_IN_SCALAR
=
"illegal document indicator in scalar"
;
const
std
::
string
DOC_IN_SCALAR
=
"illegal document indicator in scalar"
;
const
std
::
string
EOF_IN_SCALAR
=
"illegal EOF in scalar"
;
const
std
::
string
EOF_IN_SCALAR
=
"illegal EOF in scalar"
;
const
std
::
string
CHAR_IN_SCALAR
=
"illegal character in scalar"
;
const
std
::
string
CHAR_IN_SCALAR
=
"illegal character in scalar"
;
const
std
::
string
TAB_IN_INDENTATION
=
"illegal tab when looking for indentation"
;
const
std
::
string
TAB_IN_INDENTATION
=
"illegal tab when looking for indentation"
;
const
std
::
string
FLOW_END
=
"illegal flow end"
;
const
std
::
string
FLOW_END
=
"illegal flow end"
;
const
std
::
string
BLOCK_ENTRY
=
"illegal block entry"
;
const
std
::
string
BLOCK_ENTRY
=
"illegal block entry"
;
const
std
::
string
MAP_KEY
=
"illegal map key"
;
const
std
::
string
MAP_KEY
=
"illegal map key"
;
const
std
::
string
MAP_VALUE
=
"illegal map value"
;
const
std
::
string
MAP_VALUE
=
"illegal map value"
;
const
std
::
string
ALIAS_NOT_FOUND
=
"alias not found after *"
;
const
std
::
string
ALIAS_NOT_FOUND
=
"alias not found after *"
;
const
std
::
string
ANCHOR_NOT_FOUND
=
"anchor not found after &"
;
const
std
::
string
ANCHOR_NOT_FOUND
=
"anchor not found after &"
;
const
std
::
string
CHAR_IN_ALIAS
=
"illegal character found while scanning alias"
;
const
std
::
string
CHAR_IN_ALIAS
=
"illegal character found while scanning alias"
;
const
std
::
string
CHAR_IN_ANCHOR
=
"illegal character found while scanning anchor"
;
const
std
::
string
CHAR_IN_ANCHOR
=
"illegal character found while scanning anchor"
;
const
std
::
string
ZERO_INDENT_IN_BLOCK
=
"cannot set zero indentation for a block scalar"
;
const
std
::
string
ZERO_INDENT_IN_BLOCK
=
"cannot set zero indentation for a block scalar"
;
const
std
::
string
CHAR_IN_BLOCK
=
"unexpected character in block scalar"
;
const
std
::
string
CHAR_IN_BLOCK
=
"unexpected character in block scalar"
;
}
}
}
}
include/iterator.h
View file @
45322566
#pragma once
#pragma once
namespace
YAML
namespace
YAML
{
{
class
Node
;
class
Node
;
struct
IterPriv
;
struct
IterPriv
;
class
Iterator
class
Iterator
{
{
public:
public:
Iterator
();
Iterator
();
Iterator
(
IterPriv
*
pData
);
Iterator
(
IterPriv
*
pData
);
Iterator
(
const
Iterator
&
rhs
);
Iterator
(
const
Iterator
&
rhs
);
~
Iterator
();
~
Iterator
();
Iterator
&
operator
=
(
const
Iterator
&
rhs
);
Iterator
&
operator
=
(
const
Iterator
&
rhs
);
Iterator
&
operator
++
();
Iterator
&
operator
++
();
Iterator
operator
++
(
int
);
Iterator
operator
++
(
int
);
const
Node
&
operator
*
()
const
;
const
Node
&
operator
*
()
const
;
const
Node
*
operator
->
()
const
;
const
Node
*
operator
->
()
const
;
const
Node
&
first
()
const
;
const
Node
&
first
()
const
;
const
Node
&
second
()
const
;
const
Node
&
second
()
const
;
friend
bool
operator
==
(
const
Iterator
&
it
,
const
Iterator
&
jt
);
friend
bool
operator
==
(
const
Iterator
&
it
,
const
Iterator
&
jt
);
friend
bool
operator
!=
(
const
Iterator
&
it
,
const
Iterator
&
jt
);
friend
bool
operator
!=
(
const
Iterator
&
it
,
const
Iterator
&
jt
);
private:
private:
IterPriv
*
m_pData
;
IterPriv
*
m_pData
;
};
};
}
}
include/node.h
View file @
45322566
#pragma once
#pragma once
#include <string>
#include <string>
#include <ios>
#include <ios>
#include <vector>
#include <vector>
#include <map>
#include <map>
#include "parserstate.h"
#include "parserstate.h"
#include "exceptions.h"
#include "exceptions.h"
#include "iterator.h"
#include "iterator.h"
namespace
YAML
namespace
YAML
{
{
class
Content
;
class
Content
;
class
Scanner
;
class
Scanner
;
enum
CONTENT_TYPE
{
CT_NONE
,
CT_SCALAR
,
CT_SEQUENCE
,
CT_MAP
};
enum
CONTENT_TYPE
{
CT_NONE
,
CT_SCALAR
,
CT_SEQUENCE
,
CT_MAP
};
class
Node
class
Node
{
{
public:
public:
Node
();
Node
();
~
Node
();
~
Node
();
void
Clear
();
void
Clear
();
void
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
const
;
void
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
const
;
CONTENT_TYPE
GetType
()
const
;
CONTENT_TYPE
GetType
()
const
;
// accessors
// accessors
Iterator
begin
()
const
;
Iterator
begin
()
const
;
Iterator
end
()
const
;
Iterator
end
()
const
;
unsigned
size
()
const
;
unsigned
size
()
const
;
template
<
typename
T
>
template
<
typename
T
>
const
Node
&
GetValue
(
const
T
&
key
)
const
{
const
Node
&
GetValue
(
const
T
&
key
)
const
{
if
(
!
m_pContent
)
if
(
!
m_pContent
)
throw
BadDereference
();
throw
BadDereference
();
for
(
Iterator
it
=
begin
();
it
!=
end
();
++
it
)
{
for
(
Iterator
it
=
begin
();
it
!=
end
();
++
it
)
{
T
t
;
T
t
;
try
{
try
{
it
.
first
()
>>
t
;
it
.
first
()
>>
t
;
if
(
key
==
t
)
if
(
key
==
t
)
return
it
.
second
();
return
it
.
second
();
}
catch
(
RepresentationException
&
)
{
}
catch
(
RepresentationException
&
)
{
}
}
}
}
throw
BadDereference
();
throw
BadDereference
();
}
}
template
<
typename
T
>
template
<
typename
T
>
const
Node
&
operator
[]
(
const
T
&
key
)
const
{
const
Node
&
operator
[]
(
const
T
&
key
)
const
{
return
GetValue
(
key
);
return
GetValue
(
key
);
}
}
const
Node
&
operator
[]
(
const
char
*
key
)
const
{
const
Node
&
operator
[]
(
const
char
*
key
)
const
{
return
GetValue
(
std
::
string
(
key
));
return
GetValue
(
std
::
string
(
key
));
}
}
const
Node
&
operator
[]
(
unsigned
u
)
const
;
const
Node
&
operator
[]
(
unsigned
u
)
const
;
const
Node
&
operator
[]
(
int
i
)
const
;
const
Node
&
operator
[]
(
int
i
)
const
;
// extraction
// extraction
friend
void
operator
>>
(
const
Node
&
node
,
std
::
string
&
s
);
friend
void
operator
>>
(
const
Node
&
node
,
std
::
string
&
s
);
friend
void
operator
>>
(
const
Node
&
node
,
int
&
i
);
friend
void
operator
>>
(
const
Node
&
node
,
int
&
i
);
friend
void
operator
>>
(
const
Node
&
node
,
unsigned
&
u
);
friend
void
operator
>>
(
const
Node
&
node
,
unsigned
&
u
);
friend
void
operator
>>
(
const
Node
&
node
,
long
&
l
);
friend
void
operator
>>
(
const
Node
&
node
,
long
&
l
);
friend
void
operator
>>
(
const
Node
&
node
,
float
&
f
);
friend
void
operator
>>
(
const
Node
&
node
,
float
&
f
);
friend
void
operator
>>
(
const
Node
&
node
,
double
&
d
);
friend
void
operator
>>
(
const
Node
&
node
,
double
&
d
);
friend
void
operator
>>
(
const
Node
&
node
,
char
&
c
);
friend
void
operator
>>
(
const
Node
&
node
,
char
&
c
);
// insertion
// insertion
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Node
&
node
);
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Node
&
node
);
// ordering
// ordering
int
Compare
(
const
Node
&
rhs
)
const
;
int
Compare
(
const
Node
&
rhs
)
const
;
friend
bool
operator
<
(
const
Node
&
n1
,
const
Node
&
n2
);
friend
bool
operator
<
(
const
Node
&
n1
,
const
Node
&
n2
);
private:
private:
void
ParseHeader
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseHeader
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseTag
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseTag
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseAnchor
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseAnchor
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseAlias
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseAlias
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
private:
private:
std
::
string
m_anchor
,
m_tag
;
std
::
string
m_anchor
,
m_tag
;
Content
*
m_pContent
;
Content
*
m_pContent
;
bool
m_alias
;
bool
m_alias
;
};
};
}
}
include/parser.h
View file @
45322566
#pragma once
#pragma once
#include <ios>
#include <ios>
#include <string>
#include <string>
#include <vector>
#include <vector>
#include <map>
#include <map>
#include "node.h"
#include "node.h"
#include "parserstate.h"
#include "parserstate.h"
namespace
YAML
namespace
YAML
{
{
class
Scanner
;
class
Scanner
;
struct
Token
;
struct
Token
;
class
Parser
class
Parser
{
{
public:
public:
Parser
(
std
::
istream
&
in
);
Parser
(
std
::
istream
&
in
);
~
Parser
();
~
Parser
();
operator
bool
()
const
;
operator
bool
()
const
;
void
Load
(
std
::
istream
&
in
);
void
Load
(
std
::
istream
&
in
);
void
GetNextDocument
(
Node
&
document
);
void
GetNextDocument
(
Node
&
document
);
void
PrintTokens
(
std
::
ostream
&
out
);
void
PrintTokens
(
std
::
ostream
&
out
);
private:
private:
void
ParseDirectives
();
void
ParseDirectives
();
void
HandleDirective
(
Token
*
pToken
);
void
HandleDirective
(
Token
*
pToken
);
void
HandleYamlDirective
(
Token
*
pToken
);
void
HandleYamlDirective
(
Token
*
pToken
);
void
HandleTagDirective
(
Token
*
pToken
);
void
HandleTagDirective
(
Token
*
pToken
);
private:
private:
// can't copy this
// can't copy this
Parser
(
const
Parser
&
rhs
)
{}
Parser
(
const
Parser
&
rhs
)
{}
Parser
&
operator
=
(
const
Parser
&
rhs
)
{
return
*
this
;
}
Parser
&
operator
=
(
const
Parser
&
rhs
)
{
return
*
this
;
}
private:
private:
Scanner
*
m_pScanner
;
Scanner
*
m_pScanner
;
ParserState
m_state
;
ParserState
m_state
;
};
};
}
}
include/parserstate.h
View file @
45322566
#pragma once
#pragma once
#include <string>
#include <string>
#include <map>
#include <map>
namespace
YAML
namespace
YAML
{
{
struct
Version
{
struct
Version
{
int
major
,
minor
;
int
major
,
minor
;
};
};
struct
ParserState
struct
ParserState
{
{
Version
version
;
Version
version
;
std
::
map
<
std
::
string
,
std
::
string
>
tags
;
std
::
map
<
std
::
string
,
std
::
string
>
tags
;
void
Reset
();
void
Reset
();
std
::
string
TranslateTag
(
const
std
::
string
&
handle
)
const
;
std
::
string
TranslateTag
(
const
std
::
string
&
handle
)
const
;
};
};
}
}
include/yaml.h
View file @
45322566
#pragma once
#pragma once
#include "crt.h"
#include "crt.h"
#include "parser.h"
#include "parser.h"
#include "node.h"
#include "node.h"
#include "iterator.h"
#include "iterator.h"
#include "exceptions.h"
#include "exceptions.h"
src/content.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "content.h"
#include "content.h"
namespace
YAML
namespace
YAML
{
{
Content
::
Content
()
Content
::
Content
()
{
{
}
}
Content
::~
Content
()
Content
::~
Content
()
{
{
}
}
}
}
src/content.h
View file @
45322566
#pragma once
#pragma once
#include <ios>
#include <ios>
#include <vector>
#include <vector>
#include <map>
#include <map>
#include "parserstate.h"
#include "parserstate.h"
#include "exceptions.h"
#include "exceptions.h"
#include "ltnode.h"
#include "ltnode.h"
namespace
YAML
namespace
YAML
{
{
class
Scanner
;
class
Scanner
;
class
Parser
;
class
Parser
;
class
Node
;
class
Node
;
class
Scalar
;
class
Scalar
;
class
Sequence
;
class
Sequence
;
class
Map
;
class
Map
;
class
Content
class
Content
{
{
public:
public:
Content
();
Content
();
virtual
~
Content
();
virtual
~
Content
();
virtual
void
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
=
0
;
virtual
void
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
=
0
;
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
=
0
;
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
=
0
;
virtual
bool
GetBegin
(
std
::
vector
<
Node
*>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
bool
GetBegin
(
std
::
vector
<
Node
*>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
bool
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
bool
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
bool
GetEnd
(
std
::
vector
<
Node
*>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
bool
GetEnd
(
std
::
vector
<
Node
*>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
bool
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
bool
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
{
return
false
;
}
virtual
Node
*
GetNode
(
unsigned
i
)
const
{
return
0
;
}
virtual
Node
*
GetNode
(
unsigned
i
)
const
{
return
0
;
}
virtual
unsigned
GetSize
()
const
{
return
0
;
}
virtual
unsigned
GetSize
()
const
{
return
0
;
}
virtual
bool
IsScalar
()
const
{
return
false
;
}
virtual
bool
IsScalar
()
const
{
return
false
;
}
virtual
bool
IsMap
()
const
{
return
false
;
}
virtual
bool
IsMap
()
const
{
return
false
;
}
virtual
bool
IsSequence
()
const
{
return
false
;
}
virtual
bool
IsSequence
()
const
{
return
false
;
}
// extraction
// extraction
virtual
void
Read
(
std
::
string
&
s
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
std
::
string
&
s
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
int
&
i
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
int
&
i
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
unsigned
&
u
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
unsigned
&
u
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
long
&
l
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
long
&
l
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
float
&
f
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
float
&
f
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
double
&
d
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
double
&
d
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
char
&
c
)
{
throw
InvalidScalar
();
}
virtual
void
Read
(
char
&
c
)
{
throw
InvalidScalar
();
}
// ordering
// ordering
virtual
int
Compare
(
Content
*
pContent
)
{
return
0
;
}
virtual
int
Compare
(
Content
*
pContent
)
{
return
0
;
}
virtual
int
Compare
(
Scalar
*
pScalar
)
{
return
0
;
}
virtual
int
Compare
(
Scalar
*
pScalar
)
{
return
0
;
}
virtual
int
Compare
(
Sequence
*
pSeq
)
{
return
0
;
}
virtual
int
Compare
(
Sequence
*
pSeq
)
{
return
0
;
}
virtual
int
Compare
(
Map
*
pMap
)
{
return
0
;
}
virtual
int
Compare
(
Map
*
pMap
)
{
return
0
;
}
protected:
protected:
};
};
}
}
src/exp.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "exp.h"
#include "exp.h"
#include "exceptions.h"
#include "exceptions.h"
#include <sstream>
#include <sstream>
namespace
YAML
namespace
YAML
{
{
namespace
Exp
namespace
Exp
{
{
unsigned
ParseHex
(
const
std
::
string
&
str
,
int
line
,
int
column
)
unsigned
ParseHex
(
const
std
::
string
&
str
,
int
line
,
int
column
)
{
{
unsigned
value
=
0
;
unsigned
value
=
0
;
for
(
unsigned
i
=
0
;
i
<
str
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
str
.
size
();
i
++
)
{
char
ch
=
str
[
i
];
char
ch
=
str
[
i
];
int
digit
=
0
;
int
digit
=
0
;
if
(
'a'
<=
ch
&&
ch
<=
'f'
)
if
(
'a'
<=
ch
&&
ch
<=
'f'
)
digit
=
ch
-
'a'
+
10
;
digit
=
ch
-
'a'
+
10
;
else
if
(
'A'
<=
ch
&&
ch
<=
'F'
)
else
if
(
'A'
<=
ch
&&
ch
<=
'F'
)
digit
=
ch
-
'A'
+
10
;
digit
=
ch
-
'A'
+
10
;
else
if
(
'0'
<=
ch
&&
ch
<=
'9'
)
else
if
(
'0'
<=
ch
&&
ch
<=
'9'
)
digit
=
ch
-
'0'
;
digit
=
ch
-
'0'
;
else
else
throw
ParserException
(
line
,
column
,
ErrorMsg
::
INVALID_HEX
);
throw
ParserException
(
line
,
column
,
ErrorMsg
::
INVALID_HEX
);
value
=
(
value
<<
4
)
+
digit
;
value
=
(
value
<<
4
)
+
digit
;
}
}
return
value
;
return
value
;
}
}
std
::
string
Str
(
char
ch
)
std
::
string
Str
(
char
ch
)
{
{
return
std
::
string
(
""
)
+
ch
;
return
std
::
string
(
""
)
+
ch
;
}
}
// Escape
// Escape
// . Translates the next 'codeLength' characters into a hex number and returns the result.
// . Translates the next 'codeLength' characters into a hex number and returns the result.
// . Throws if it's not actually hex.
// . Throws if it's not actually hex.
std
::
string
Escape
(
Stream
&
in
,
int
codeLength
)
std
::
string
Escape
(
Stream
&
in
,
int
codeLength
)
{
{
// grab string
// grab string
std
::
string
str
;
std
::
string
str
;
for
(
int
i
=
0
;
i
<
codeLength
;
i
++
)
for
(
int
i
=
0
;
i
<
codeLength
;
i
++
)
str
+=
in
.
get
();
str
+=
in
.
get
();
// get the value
// get the value
unsigned
value
=
ParseHex
(
str
,
in
.
line
,
in
.
column
);
unsigned
value
=
ParseHex
(
str
,
in
.
line
,
in
.
column
);
// legal unicode?
// legal unicode?
if
((
value
>=
0xD800
&&
value
<=
0xDFFF
)
||
value
>
0x10FFFF
)
{
if
((
value
>=
0xD800
&&
value
<=
0xDFFF
)
||
value
>
0x10FFFF
)
{
std
::
stringstream
msg
;
std
::
stringstream
msg
;
msg
<<
ErrorMsg
::
INVALID_UNICODE
<<
value
;
msg
<<
ErrorMsg
::
INVALID_UNICODE
<<
value
;
throw
ParserException
(
in
.
line
,
in
.
column
,
msg
.
str
());
throw
ParserException
(
in
.
line
,
in
.
column
,
msg
.
str
());
}
}
// now break it up into chars
// now break it up into chars
if
(
value
<=
0x7F
)
if
(
value
<=
0x7F
)
return
Str
(
value
);
return
Str
(
value
);
else
if
(
value
<=
0x7FF
)
else
if
(
value
<=
0x7FF
)
return
Str
(
0xC0
+
(
value
>>
6
))
+
Str
(
0x80
+
(
value
&
0x3F
));
return
Str
(
0xC0
+
(
value
>>
6
))
+
Str
(
0x80
+
(
value
&
0x3F
));
else
if
(
value
<=
0xFFFF
)
else
if
(
value
<=
0xFFFF
)
return
Str
(
0xE0
+
(
value
>>
12
))
+
Str
(
0x80
+
((
value
>>
6
)
&
0x3F
))
+
Str
(
0x80
+
(
value
&
0x3F
));
return
Str
(
0xE0
+
(
value
>>
12
))
+
Str
(
0x80
+
((
value
>>
6
)
&
0x3F
))
+
Str
(
0x80
+
(
value
&
0x3F
));
else
else
return
Str
(
0xF0
+
(
value
>>
18
))
+
Str
(
0x80
+
((
value
>>
12
)
&
0x3F
))
+
return
Str
(
0xF0
+
(
value
>>
18
))
+
Str
(
0x80
+
((
value
>>
12
)
&
0x3F
))
+
Str
(
0x80
+
((
value
>>
6
)
&
0x3F
))
+
Str
(
0x80
+
(
value
&
0x3F
));
Str
(
0x80
+
((
value
>>
6
)
&
0x3F
))
+
Str
(
0x80
+
(
value
&
0x3F
));
}
}
// Escape
// Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single quote)
// . Escapes the sequence starting 'in' (it must begin with a '\' or single quote)
// and returns the result.
// and returns the result.
// . Throws if it's an unknown escape character.
// . Throws if it's an unknown escape character.
std
::
string
Escape
(
Stream
&
in
)
std
::
string
Escape
(
Stream
&
in
)
{
{
// eat slash
// eat slash
char
escape
=
in
.
get
();
char
escape
=
in
.
get
();
// switch on escape character
// switch on escape character
char
ch
=
in
.
get
();
char
ch
=
in
.
get
();
// first do single quote, since it's easier
// first do single quote, since it's easier
if
(
escape
==
'\''
&&
ch
==
'\''
)
if
(
escape
==
'\''
&&
ch
==
'\''
)
return
"
\'
"
;
return
"
\'
"
;
// now do the slash (we're not gonna check if it's a slash - you better pass one!)
// now do the slash (we're not gonna check if it's a slash - you better pass one!)
switch
(
ch
)
{
switch
(
ch
)
{
case
'0'
:
return
"
\0
"
;
case
'0'
:
return
"
\0
"
;
case
'a'
:
return
"
\x07
"
;
case
'a'
:
return
"
\x07
"
;
case
'b'
:
return
"
\x08
"
;
case
'b'
:
return
"
\x08
"
;
case
't'
:
case
't'
:
case
'\t'
:
return
"
\x09
"
;
case
'\t'
:
return
"
\x09
"
;
case
'n'
:
return
"
\x0A
"
;
case
'n'
:
return
"
\x0A
"
;
case
'v'
:
return
"
\x0B
"
;
case
'v'
:
return
"
\x0B
"
;
case
'f'
:
return
"
\x0C
"
;
case
'f'
:
return
"
\x0C
"
;
case
'r'
:
return
"
\x0D
"
;
case
'r'
:
return
"
\x0D
"
;
case
'e'
:
return
"
\x1B
"
;
case
'e'
:
return
"
\x1B
"
;
case
' '
:
return
"
\x20
"
;
case
' '
:
return
"
\x20
"
;
case
'\"'
:
return
"
\"
"
;
case
'\"'
:
return
"
\"
"
;
case
'\''
:
return
"
\'
"
;
case
'\''
:
return
"
\'
"
;
case
'\\'
:
return
"
\\
"
;
case
'\\'
:
return
"
\\
"
;
case
'N'
:
return
"
\xC2\x85
"
;
// NEL (#x85)
case
'N'
:
return
"
\xC2\x85
"
;
// NEL (#x85)
case
'_'
:
return
"
\xC2\xA0
"
;
// #xA0
case
'_'
:
return
"
\xC2\xA0
"
;
// #xA0
case
'L'
:
return
"
\xE2\x80\xA8
"
;
// LS (#x2028)
case
'L'
:
return
"
\xE2\x80\xA8
"
;
// LS (#x2028)
case
'P'
:
return
"
\xE2\x80\xA9
"
;
// PS (#x2029)
case
'P'
:
return
"
\xE2\x80\xA9
"
;
// PS (#x2029)
case
'x'
:
return
Escape
(
in
,
2
);
case
'x'
:
return
Escape
(
in
,
2
);
case
'u'
:
return
Escape
(
in
,
4
);
case
'u'
:
return
Escape
(
in
,
4
);
case
'U'
:
return
Escape
(
in
,
8
);
case
'U'
:
return
Escape
(
in
,
8
);
}
}
std
::
stringstream
msg
;
std
::
stringstream
msg
;
throw
ParserException
(
in
.
line
,
in
.
column
,
ErrorMsg
::
INVALID_ESCAPE
+
ch
);
throw
ParserException
(
in
.
line
,
in
.
column
,
ErrorMsg
::
INVALID_ESCAPE
+
ch
);
}
}
}
}
}
}
src/exp.h
View file @
45322566
#pragma once
#pragma once
#include "regex.h"
#include "regex.h"
#include <string>
#include <string>
#include <ios>
#include <ios>
#include "stream.h"
#include "stream.h"
namespace
YAML
namespace
YAML
{
{
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Here we store a bunch of expressions for matching different parts of the file.
// Here we store a bunch of expressions for matching different parts of the file.
namespace
Exp
namespace
Exp
{
{
// misc
// misc
const
RegEx
Blank
=
RegEx
(
' '
)
||
RegEx
(
'\t'
);
const
RegEx
Blank
=
RegEx
(
' '
)
||
RegEx
(
'\t'
);
const
RegEx
Break
=
RegEx
(
'\n'
)
||
RegEx
(
"
\r\n
"
);
const
RegEx
Break
=
RegEx
(
'\n'
)
||
RegEx
(
"
\r\n
"
);
const
RegEx
BlankOrBreak
=
Blank
||
Break
;
const
RegEx
BlankOrBreak
=
Blank
||
Break
;
const
RegEx
Digit
=
RegEx
(
'0'
,
'9'
);
const
RegEx
Digit
=
RegEx
(
'0'
,
'9'
);
const
RegEx
Alpha
=
RegEx
(
'a'
,
'z'
)
||
RegEx
(
'A'
,
'Z'
);
const
RegEx
Alpha
=
RegEx
(
'a'
,
'z'
)
||
RegEx
(
'A'
,
'Z'
);
const
RegEx
AlphaNumeric
=
Alpha
||
Digit
;
const
RegEx
AlphaNumeric
=
Alpha
||
Digit
;
const
RegEx
Hex
=
Digit
||
RegEx
(
'A'
,
'F'
)
||
RegEx
(
'a'
,
'f'
);
const
RegEx
Hex
=
Digit
||
RegEx
(
'A'
,
'F'
)
||
RegEx
(
'a'
,
'f'
);
// actual tags
// actual tags
const
RegEx
DocStart
=
RegEx
(
"---"
)
+
(
BlankOrBreak
||
RegEx
(
EOF
)
||
RegEx
());
const
RegEx
DocStart
=
RegEx
(
"---"
)
+
(
BlankOrBreak
||
RegEx
(
EOF
)
||
RegEx
());
const
RegEx
DocEnd
=
RegEx
(
"..."
)
+
(
BlankOrBreak
||
RegEx
(
EOF
)
||
RegEx
());
const
RegEx
DocEnd
=
RegEx
(
"..."
)
+
(
BlankOrBreak
||
RegEx
(
EOF
)
||
RegEx
());
const
RegEx
DocIndicator
=
DocStart
||
DocEnd
;
const
RegEx
DocIndicator
=
DocStart
||
DocEnd
;
const
RegEx
BlockEntry
=
RegEx
(
'-'
)
+
(
BlankOrBreak
||
RegEx
(
EOF
));
const
RegEx
BlockEntry
=
RegEx
(
'-'
)
+
(
BlankOrBreak
||
RegEx
(
EOF
));
const
RegEx
Key
=
RegEx
(
'?'
),
const
RegEx
Key
=
RegEx
(
'?'
),
KeyInFlow
=
RegEx
(
'?'
)
+
BlankOrBreak
;
KeyInFlow
=
RegEx
(
'?'
)
+
BlankOrBreak
;
const
RegEx
Value
=
RegEx
(
':'
)
+
BlankOrBreak
,
const
RegEx
Value
=
RegEx
(
':'
)
+
BlankOrBreak
,
ValueInFlow
=
RegEx
(
':'
)
+
BlankOrBreak
;
ValueInFlow
=
RegEx
(
':'
)
+
BlankOrBreak
;
const
RegEx
Comment
=
RegEx
(
'#'
);
const
RegEx
Comment
=
RegEx
(
'#'
);
const
RegEx
AnchorEnd
=
RegEx
(
"?:,]}%@`"
,
REGEX_OR
)
||
BlankOrBreak
;
const
RegEx
AnchorEnd
=
RegEx
(
"?:,]}%@`"
,
REGEX_OR
)
||
BlankOrBreak
;
// Plain scalar rules:
// Plain scalar rules:
// . Cannot start with a blank.
// . Cannot start with a blank.
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . In the block context - ? : must be not be followed with a space.
// . In the block context - ? : must be not be followed with a space.
// . In the flow context ? is illegal and : and - must not be followed with a space.
// . In the flow context ? is illegal and : and - must not be followed with a space.
const
RegEx
PlainScalar
=
!
(
BlankOrBreak
||
RegEx
(
",[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-?:"
,
REGEX_OR
)
+
Blank
)),
const
RegEx
PlainScalar
=
!
(
BlankOrBreak
||
RegEx
(
",[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-?:"
,
REGEX_OR
)
+
Blank
)),
PlainScalarInFlow
=
!
(
BlankOrBreak
||
RegEx
(
"?,[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-:"
,
REGEX_OR
)
+
Blank
));
PlainScalarInFlow
=
!
(
BlankOrBreak
||
RegEx
(
"?,[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-:"
,
REGEX_OR
)
+
Blank
));
const
RegEx
EndScalar
=
RegEx
(
':'
)
+
BlankOrBreak
,
const
RegEx
EndScalar
=
RegEx
(
':'
)
+
BlankOrBreak
,
EndScalarInFlow
=
(
RegEx
(
':'
)
+
BlankOrBreak
)
||
RegEx
(
",?[]{}"
,
REGEX_OR
);
EndScalarInFlow
=
(
RegEx
(
':'
)
+
BlankOrBreak
)
||
RegEx
(
",?[]{}"
,
REGEX_OR
);
const
RegEx
EscSingleQuote
=
RegEx
(
"
\'\'
"
);
const
RegEx
EscSingleQuote
=
RegEx
(
"
\'\'
"
);
const
RegEx
EscBreak
=
RegEx
(
'\\'
)
+
Break
;
const
RegEx
EscBreak
=
RegEx
(
'\\'
)
+
Break
;
const
RegEx
ChompIndicator
=
RegEx
(
"+-"
,
REGEX_OR
);
const
RegEx
ChompIndicator
=
RegEx
(
"+-"
,
REGEX_OR
);
const
RegEx
Chomp
=
(
ChompIndicator
+
Digit
)
||
(
Digit
+
ChompIndicator
)
||
ChompIndicator
||
Digit
;
const
RegEx
Chomp
=
(
ChompIndicator
+
Digit
)
||
(
Digit
+
ChompIndicator
)
||
ChompIndicator
||
Digit
;
// and some functions
// and some functions
std
::
string
Escape
(
Stream
&
in
);
std
::
string
Escape
(
Stream
&
in
);
}
}
namespace
Keys
namespace
Keys
{
{
const
char
Directive
=
'%'
;
const
char
Directive
=
'%'
;
const
char
FlowSeqStart
=
'['
;
const
char
FlowSeqStart
=
'['
;
const
char
FlowSeqEnd
=
']'
;
const
char
FlowSeqEnd
=
']'
;
const
char
FlowMapStart
=
'{'
;
const
char
FlowMapStart
=
'{'
;
const
char
FlowMapEnd
=
'}'
;
const
char
FlowMapEnd
=
'}'
;
const
char
FlowEntry
=
','
;
const
char
FlowEntry
=
','
;
const
char
Alias
=
'*'
;
const
char
Alias
=
'*'
;
const
char
Anchor
=
'&'
;
const
char
Anchor
=
'&'
;
const
char
Tag
=
'!'
;
const
char
Tag
=
'!'
;
const
char
LiteralScalar
=
'|'
;
const
char
LiteralScalar
=
'|'
;
const
char
FoldedScalar
=
'>'
;
const
char
FoldedScalar
=
'>'
;
}
}
}
}
src/iterator.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "node.h"
#include "node.h"
#include "exceptions.h"
#include "exceptions.h"
#include "iterpriv.h"
#include "iterpriv.h"
namespace
YAML
namespace
YAML
{
{
Iterator
::
Iterator
()
:
m_pData
(
0
)
Iterator
::
Iterator
()
:
m_pData
(
0
)
{
{
m_pData
=
new
IterPriv
;
m_pData
=
new
IterPriv
;
}
}
Iterator
::
Iterator
(
IterPriv
*
pData
)
:
m_pData
(
pData
)
Iterator
::
Iterator
(
IterPriv
*
pData
)
:
m_pData
(
pData
)
{
{
}
}
Iterator
::
Iterator
(
const
Iterator
&
rhs
)
:
m_pData
(
0
)
Iterator
::
Iterator
(
const
Iterator
&
rhs
)
:
m_pData
(
0
)
{
{
m_pData
=
new
IterPriv
(
*
rhs
.
m_pData
);
m_pData
=
new
IterPriv
(
*
rhs
.
m_pData
);
}
}
Iterator
&
Iterator
::
operator
=
(
const
Iterator
&
rhs
)
Iterator
&
Iterator
::
operator
=
(
const
Iterator
&
rhs
)
{
{
if
(
this
==
&
rhs
)
if
(
this
==
&
rhs
)
return
*
this
;
return
*
this
;
delete
m_pData
;
delete
m_pData
;
m_pData
=
new
IterPriv
(
*
rhs
.
m_pData
);
m_pData
=
new
IterPriv
(
*
rhs
.
m_pData
);
return
*
this
;
return
*
this
;
}
}
Iterator
::~
Iterator
()
Iterator
::~
Iterator
()
{
{
delete
m_pData
;
delete
m_pData
;
}
}
Iterator
&
Iterator
::
operator
++
()
Iterator
&
Iterator
::
operator
++
()
{
{
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
++
m_pData
->
seqIter
;
++
m_pData
->
seqIter
;
else
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
else
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
++
m_pData
->
mapIter
;
++
m_pData
->
mapIter
;
return
*
this
;
return
*
this
;
}
}
Iterator
Iterator
::
operator
++
(
int
)
Iterator
Iterator
::
operator
++
(
int
)
{
{
Iterator
temp
=
*
this
;
Iterator
temp
=
*
this
;
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
++
m_pData
->
seqIter
;
++
m_pData
->
seqIter
;
else
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
else
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
++
m_pData
->
mapIter
;
++
m_pData
->
mapIter
;
return
temp
;
return
temp
;
}
}
const
Node
&
Iterator
::
operator
*
()
const
const
Node
&
Iterator
::
operator
*
()
const
{
{
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
return
**
m_pData
->
seqIter
;
return
**
m_pData
->
seqIter
;
throw
BadDereference
();
throw
BadDereference
();
}
}
const
Node
*
Iterator
::
operator
->
()
const
const
Node
*
Iterator
::
operator
->
()
const
{
{
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
if
(
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
return
*
m_pData
->
seqIter
;
return
*
m_pData
->
seqIter
;
throw
BadDereference
();
throw
BadDereference
();
}
}
const
Node
&
Iterator
::
first
()
const
const
Node
&
Iterator
::
first
()
const
{
{
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
return
*
m_pData
->
mapIter
->
first
;
return
*
m_pData
->
mapIter
->
first
;
throw
BadDereference
();
throw
BadDereference
();
}
}
const
Node
&
Iterator
::
second
()
const
const
Node
&
Iterator
::
second
()
const
{
{
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
if
(
m_pData
->
type
==
IterPriv
::
IT_MAP
)
return
*
m_pData
->
mapIter
->
second
;
return
*
m_pData
->
mapIter
->
second
;
throw
BadDereference
();
throw
BadDereference
();
}
}
bool
operator
==
(
const
Iterator
&
it
,
const
Iterator
&
jt
)
bool
operator
==
(
const
Iterator
&
it
,
const
Iterator
&
jt
)
{
{
if
(
it
.
m_pData
->
type
!=
jt
.
m_pData
->
type
)
if
(
it
.
m_pData
->
type
!=
jt
.
m_pData
->
type
)
return
false
;
return
false
;
if
(
it
.
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
if
(
it
.
m_pData
->
type
==
IterPriv
::
IT_SEQ
)
return
it
.
m_pData
->
seqIter
==
jt
.
m_pData
->
seqIter
;
return
it
.
m_pData
->
seqIter
==
jt
.
m_pData
->
seqIter
;
else
if
(
it
.
m_pData
->
type
==
IterPriv
::
IT_MAP
)
else
if
(
it
.
m_pData
->
type
==
IterPriv
::
IT_MAP
)
return
it
.
m_pData
->
mapIter
==
jt
.
m_pData
->
mapIter
;
return
it
.
m_pData
->
mapIter
==
jt
.
m_pData
->
mapIter
;
return
true
;
return
true
;
}
}
bool
operator
!=
(
const
Iterator
&
it
,
const
Iterator
&
jt
)
bool
operator
!=
(
const
Iterator
&
it
,
const
Iterator
&
jt
)
{
{
return
!
(
it
==
jt
);
return
!
(
it
==
jt
);
}
}
}
}
src/iterpriv.h
View file @
45322566
#pragma once
#pragma once
#include "ltnode.h"
#include "ltnode.h"
#include <vector>
#include <vector>
#include <map>
#include <map>
namespace
YAML
namespace
YAML
{
{
class
Node
;
class
Node
;
// IterPriv
// IterPriv
// . The implementation for iterators - essentially a union of sequence and map iterators.
// . The implementation for iterators - essentially a union of sequence and map iterators.
struct
IterPriv
struct
IterPriv
{
{
IterPriv
()
:
type
(
IT_NONE
)
{}
IterPriv
()
:
type
(
IT_NONE
)
{}
IterPriv
(
std
::
vector
<
Node
*>::
const_iterator
it
)
:
type
(
IT_SEQ
),
seqIter
(
it
)
{}
IterPriv
(
std
::
vector
<
Node
*>::
const_iterator
it
)
:
type
(
IT_SEQ
),
seqIter
(
it
)
{}
IterPriv
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
it
)
:
type
(
IT_MAP
),
mapIter
(
it
)
{}
IterPriv
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
it
)
:
type
(
IT_MAP
),
mapIter
(
it
)
{}
enum
ITER_TYPE
{
IT_NONE
,
IT_SEQ
,
IT_MAP
};
enum
ITER_TYPE
{
IT_NONE
,
IT_SEQ
,
IT_MAP
};
ITER_TYPE
type
;
ITER_TYPE
type
;
std
::
vector
<
Node
*>::
const_iterator
seqIter
;
std
::
vector
<
Node
*>::
const_iterator
seqIter
;
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
mapIter
;
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
mapIter
;
};
};
}
}
src/ltnode.h
View file @
45322566
#pragma once
#pragma once
namespace
YAML
namespace
YAML
{
{
class
Node
;
class
Node
;
struct
ltnode
{
struct
ltnode
{
bool
operator
()(
const
Node
*
pNode1
,
const
Node
*
pNode2
)
const
;
bool
operator
()(
const
Node
*
pNode1
,
const
Node
*
pNode2
)
const
;
};
};
}
}
src/map.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "map.h"
#include "map.h"
#include "node.h"
#include "node.h"
#include "scanner.h"
#include "scanner.h"
#include "token.h"
#include "token.h"
#include "exceptions.h"
#include "exceptions.h"
#include <iostream>
#include <iostream>
namespace
YAML
namespace
YAML
{
{
Map
::
Map
()
Map
::
Map
()
{
{
}
}
Map
::~
Map
()
Map
::~
Map
()
{
{
Clear
();
Clear
();
}
}
void
Map
::
Clear
()
void
Map
::
Clear
()
{
{
for
(
node_map
::
const_iterator
it
=
m_data
.
begin
();
it
!=
m_data
.
end
();
++
it
)
{
for
(
node_map
::
const_iterator
it
=
m_data
.
begin
();
it
!=
m_data
.
end
();
++
it
)
{
delete
it
->
first
;
delete
it
->
first
;
delete
it
->
second
;
delete
it
->
second
;
}
}
m_data
.
clear
();
m_data
.
clear
();
}
}
bool
Map
::
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
bool
Map
::
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
{
{
it
=
m_data
.
begin
();
it
=
m_data
.
begin
();
return
true
;
return
true
;
}
}
bool
Map
::
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
bool
Map
::
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
{
{
it
=
m_data
.
end
();
it
=
m_data
.
end
();
return
true
;
return
true
;
}
}
void
Map
::
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Map
::
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
Clear
();
Clear
();
// split based on start token
// split based on start token
switch
(
pScanner
->
peek
().
type
)
{
switch
(
pScanner
->
peek
().
type
)
{
case
TT_BLOCK_MAP_START
:
ParseBlock
(
pScanner
,
state
);
break
;
case
TT_BLOCK_MAP_START
:
ParseBlock
(
pScanner
,
state
);
break
;
case
TT_FLOW_MAP_START
:
ParseFlow
(
pScanner
,
state
);
break
;
case
TT_FLOW_MAP_START
:
ParseFlow
(
pScanner
,
state
);
break
;
}
}
}
}
void
Map
::
ParseBlock
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Map
::
ParseBlock
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
// eat start token
// eat start token
pScanner
->
pop
();
pScanner
->
pop
();
while
(
1
)
{
while
(
1
)
{
if
(
pScanner
->
empty
())
if
(
pScanner
->
empty
())
throw
ParserException
(
-
1
,
-
1
,
ErrorMsg
::
END_OF_MAP
);
throw
ParserException
(
-
1
,
-
1
,
ErrorMsg
::
END_OF_MAP
);
Token
token
=
pScanner
->
peek
();
Token
token
=
pScanner
->
peek
();
if
(
token
.
type
!=
TT_KEY
&&
token
.
type
!=
TT_BLOCK_END
)
if
(
token
.
type
!=
TT_KEY
&&
token
.
type
!=
TT_BLOCK_END
)
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
END_OF_MAP
);
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
END_OF_MAP
);
pScanner
->
pop
();
pScanner
->
pop
();
if
(
token
.
type
==
TT_BLOCK_END
)
if
(
token
.
type
==
TT_BLOCK_END
)
break
;
break
;
Node
*
pKey
=
new
Node
;
Node
*
pKey
=
new
Node
;
Node
*
pValue
=
new
Node
;
Node
*
pValue
=
new
Node
;
try
{
try
{
// grab key
// grab key
pKey
->
Parse
(
pScanner
,
state
);
pKey
->
Parse
(
pScanner
,
state
);
// now grab value (optional)
// now grab value (optional)
if
(
!
pScanner
->
empty
()
&&
pScanner
->
peek
().
type
==
TT_VALUE
)
{
if
(
!
pScanner
->
empty
()
&&
pScanner
->
peek
().
type
==
TT_VALUE
)
{
pScanner
->
pop
();
pScanner
->
pop
();
pValue
->
Parse
(
pScanner
,
state
);
pValue
->
Parse
(
pScanner
,
state
);
}
}
m_data
[
pKey
]
=
pValue
;
m_data
[
pKey
]
=
pValue
;
}
catch
(
Exception
&
e
)
{
}
catch
(
Exception
&
e
)
{
delete
pKey
;
delete
pKey
;
delete
pValue
;
delete
pValue
;
throw
e
;
throw
e
;
}
}
}
}
}
}
void
Map
::
ParseFlow
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Map
::
ParseFlow
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
// eat start token
// eat start token
pScanner
->
pop
();
pScanner
->
pop
();
while
(
1
)
{
while
(
1
)
{
if
(
pScanner
->
empty
())
if
(
pScanner
->
empty
())
throw
ParserException
(
-
1
,
-
1
,
ErrorMsg
::
END_OF_MAP_FLOW
);
throw
ParserException
(
-
1
,
-
1
,
ErrorMsg
::
END_OF_MAP_FLOW
);
Token
&
token
=
pScanner
->
peek
();
Token
&
token
=
pScanner
->
peek
();
// first check for end
// first check for end
if
(
token
.
type
==
TT_FLOW_MAP_END
)
{
if
(
token
.
type
==
TT_FLOW_MAP_END
)
{
pScanner
->
pop
();
pScanner
->
pop
();
break
;
break
;
}
}
// now it better be a key
// now it better be a key
if
(
token
.
type
!=
TT_KEY
)
if
(
token
.
type
!=
TT_KEY
)
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
END_OF_MAP_FLOW
);
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
END_OF_MAP_FLOW
);
pScanner
->
pop
();
pScanner
->
pop
();
Node
*
pKey
=
new
Node
;
Node
*
pKey
=
new
Node
;
Node
*
pValue
=
new
Node
;
Node
*
pValue
=
new
Node
;
try
{
try
{
// grab key
// grab key
pKey
->
Parse
(
pScanner
,
state
);
pKey
->
Parse
(
pScanner
,
state
);
// now grab value (optional)
// now grab value (optional)
if
(
!
pScanner
->
empty
()
&&
pScanner
->
peek
().
type
==
TT_VALUE
)
{
if
(
!
pScanner
->
empty
()
&&
pScanner
->
peek
().
type
==
TT_VALUE
)
{
pScanner
->
pop
();
pScanner
->
pop
();
pValue
->
Parse
(
pScanner
,
state
);
pValue
->
Parse
(
pScanner
,
state
);
}
}
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
Token
&
nextToken
=
pScanner
->
peek
();
Token
&
nextToken
=
pScanner
->
peek
();
if
(
nextToken
.
type
==
TT_FLOW_ENTRY
)
if
(
nextToken
.
type
==
TT_FLOW_ENTRY
)
pScanner
->
pop
();
pScanner
->
pop
();
else
if
(
nextToken
.
type
!=
TT_FLOW_MAP_END
)
else
if
(
nextToken
.
type
!=
TT_FLOW_MAP_END
)
throw
ParserException
(
nextToken
.
line
,
nextToken
.
column
,
ErrorMsg
::
END_OF_MAP_FLOW
);
throw
ParserException
(
nextToken
.
line
,
nextToken
.
column
,
ErrorMsg
::
END_OF_MAP_FLOW
);
m_data
[
pKey
]
=
pValue
;
m_data
[
pKey
]
=
pValue
;
}
catch
(
Exception
&
e
)
{
}
catch
(
Exception
&
e
)
{
// clean up and rethrow
// clean up and rethrow
delete
pKey
;
delete
pKey
;
delete
pValue
;
delete
pValue
;
throw
e
;
throw
e
;
}
}
}
}
}
}
void
Map
::
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
void
Map
::
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
{
{
if
(
startedLine
&&
!
onlyOneCharOnLine
)
if
(
startedLine
&&
!
onlyOneCharOnLine
)
out
<<
"
\n
"
;
out
<<
"
\n
"
;
for
(
node_map
::
const_iterator
it
=
m_data
.
begin
();
it
!=
m_data
.
end
();
++
it
)
{
for
(
node_map
::
const_iterator
it
=
m_data
.
begin
();
it
!=
m_data
.
end
();
++
it
)
{
if
((
startedLine
&&
!
onlyOneCharOnLine
)
||
it
!=
m_data
.
begin
())
{
if
((
startedLine
&&
!
onlyOneCharOnLine
)
||
it
!=
m_data
.
begin
())
{
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
out
<<
" "
;
out
<<
" "
;
}
}
out
<<
"? "
;
out
<<
"? "
;
it
->
first
->
Write
(
out
,
indent
+
1
,
true
,
it
!=
m_data
.
begin
()
||
!
startedLine
||
onlyOneCharOnLine
);
it
->
first
->
Write
(
out
,
indent
+
1
,
true
,
it
!=
m_data
.
begin
()
||
!
startedLine
||
onlyOneCharOnLine
);
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
out
<<
" "
;
out
<<
" "
;
out
<<
": "
;
out
<<
": "
;
it
->
second
->
Write
(
out
,
indent
+
1
,
true
,
true
);
it
->
second
->
Write
(
out
,
indent
+
1
,
true
,
true
);
}
}
if
(
m_data
.
empty
())
if
(
m_data
.
empty
())
out
<<
"
\n
"
;
out
<<
"
\n
"
;
}
}
int
Map
::
Compare
(
Content
*
pContent
)
int
Map
::
Compare
(
Content
*
pContent
)
{
{
return
-
pContent
->
Compare
(
this
);
return
-
pContent
->
Compare
(
this
);
}
}
int
Map
::
Compare
(
Map
*
pMap
)
int
Map
::
Compare
(
Map
*
pMap
)
{
{
node_map
::
const_iterator
it
=
m_data
.
begin
(),
jt
=
pMap
->
m_data
.
begin
();
node_map
::
const_iterator
it
=
m_data
.
begin
(),
jt
=
pMap
->
m_data
.
begin
();
while
(
1
)
{
while
(
1
)
{
if
(
it
==
m_data
.
end
())
{
if
(
it
==
m_data
.
end
())
{
if
(
jt
==
pMap
->
m_data
.
end
())
if
(
jt
==
pMap
->
m_data
.
end
())
return
0
;
return
0
;
else
else
return
-
1
;
return
-
1
;
}
}
if
(
jt
==
pMap
->
m_data
.
end
())
if
(
jt
==
pMap
->
m_data
.
end
())
return
1
;
return
1
;
int
cmp
=
it
->
first
->
Compare
(
*
jt
->
first
);
int
cmp
=
it
->
first
->
Compare
(
*
jt
->
first
);
if
(
cmp
!=
0
)
if
(
cmp
!=
0
)
return
cmp
;
return
cmp
;
cmp
=
it
->
second
->
Compare
(
*
jt
->
second
);
cmp
=
it
->
second
->
Compare
(
*
jt
->
second
);
if
(
cmp
!=
0
)
if
(
cmp
!=
0
)
return
cmp
;
return
cmp
;
}
}
return
0
;
return
0
;
}
}
}
}
src/map.h
View file @
45322566
#pragma once
#pragma once
#include "content.h"
#include "content.h"
#include <map>
#include <map>
namespace
YAML
namespace
YAML
{
{
class
Node
;
class
Node
;
class
Map
:
public
Content
class
Map
:
public
Content
{
{
public:
public:
Map
();
Map
();
virtual
~
Map
();
virtual
~
Map
();
void
Clear
();
void
Clear
();
virtual
bool
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
;
virtual
bool
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
;
virtual
bool
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
;
virtual
bool
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
it
)
const
;
virtual
void
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
virtual
void
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
);
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
);
virtual
bool
IsMap
()
const
{
return
true
;
}
virtual
bool
IsMap
()
const
{
return
true
;
}
// ordering
// ordering
virtual
int
Compare
(
Content
*
pContent
);
virtual
int
Compare
(
Content
*
pContent
);
virtual
int
Compare
(
Scalar
*
pScalar
)
{
return
1
;
}
virtual
int
Compare
(
Scalar
*
pScalar
)
{
return
1
;
}
virtual
int
Compare
(
Sequence
*
pSeq
)
{
return
1
;
}
virtual
int
Compare
(
Sequence
*
pSeq
)
{
return
1
;
}
virtual
int
Compare
(
Map
*
pMap
);
virtual
int
Compare
(
Map
*
pMap
);
private:
private:
void
ParseBlock
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseBlock
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseFlow
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
void
ParseFlow
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
protected:
protected:
typedef
std
::
map
<
Node
*
,
Node
*
,
ltnode
>
node_map
;
typedef
std
::
map
<
Node
*
,
Node
*
,
ltnode
>
node_map
;
node_map
m_data
;
node_map
m_data
;
};
};
}
}
src/node.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "node.h"
#include "node.h"
#include "token.h"
#include "token.h"
#include "scanner.h"
#include "scanner.h"
#include "content.h"
#include "content.h"
#include "parser.h"
#include "parser.h"
#include "scalar.h"
#include "scalar.h"
#include "sequence.h"
#include "sequence.h"
#include "map.h"
#include "map.h"
#include "iterpriv.h"
#include "iterpriv.h"
namespace
YAML
namespace
YAML
{
{
// the ordering!
// the ordering!
bool
ltnode
::
operator
()(
const
Node
*
pNode1
,
const
Node
*
pNode2
)
const
bool
ltnode
::
operator
()(
const
Node
*
pNode1
,
const
Node
*
pNode2
)
const
{
{
return
*
pNode1
<
*
pNode2
;
return
*
pNode1
<
*
pNode2
;
}
}
Node
::
Node
()
:
m_pContent
(
0
),
m_alias
(
false
)
Node
::
Node
()
:
m_pContent
(
0
),
m_alias
(
false
)
{
{
}
}
Node
::~
Node
()
Node
::~
Node
()
{
{
Clear
();
Clear
();
}
}
void
Node
::
Clear
()
void
Node
::
Clear
()
{
{
delete
m_pContent
;
delete
m_pContent
;
m_pContent
=
0
;
m_pContent
=
0
;
m_alias
=
false
;
m_alias
=
false
;
}
}
void
Node
::
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Node
::
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
Clear
();
Clear
();
ParseHeader
(
pScanner
,
state
);
ParseHeader
(
pScanner
,
state
);
// is this an alias? if so, it can have no content
// is this an alias? if so, it can have no content
if
(
m_alias
)
if
(
m_alias
)
return
;
return
;
// now split based on what kind of node we should be
// now split based on what kind of node we should be
switch
(
pScanner
->
peek
().
type
)
{
switch
(
pScanner
->
peek
().
type
)
{
case
TT_SCALAR
:
case
TT_SCALAR
:
m_pContent
=
new
Scalar
;
m_pContent
=
new
Scalar
;
m_pContent
->
Parse
(
pScanner
,
state
);
m_pContent
->
Parse
(
pScanner
,
state
);
break
;
break
;
case
TT_FLOW_SEQ_START
:
case
TT_FLOW_SEQ_START
:
case
TT_BLOCK_SEQ_START
:
case
TT_BLOCK_SEQ_START
:
case
TT_BLOCK_ENTRY
:
case
TT_BLOCK_ENTRY
:
m_pContent
=
new
Sequence
;
m_pContent
=
new
Sequence
;
m_pContent
->
Parse
(
pScanner
,
state
);
m_pContent
->
Parse
(
pScanner
,
state
);
break
;
break
;
case
TT_FLOW_MAP_START
:
case
TT_FLOW_MAP_START
:
case
TT_BLOCK_MAP_START
:
case
TT_BLOCK_MAP_START
:
m_pContent
=
new
Map
;
m_pContent
=
new
Map
;
m_pContent
->
Parse
(
pScanner
,
state
);
m_pContent
->
Parse
(
pScanner
,
state
);
break
;
break
;
}
}
}
}
// ParseHeader
// ParseHeader
// . Grabs any tag, alias, or anchor tokens and deals with them.
// . Grabs any tag, alias, or anchor tokens and deals with them.
void
Node
::
ParseHeader
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Node
::
ParseHeader
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
while
(
1
)
{
while
(
1
)
{
if
(
pScanner
->
empty
())
if
(
pScanner
->
empty
())
return
;
return
;
switch
(
pScanner
->
peek
().
type
)
{
switch
(
pScanner
->
peek
().
type
)
{
case
TT_TAG
:
ParseTag
(
pScanner
,
state
);
break
;
case
TT_TAG
:
ParseTag
(
pScanner
,
state
);
break
;
case
TT_ANCHOR
:
ParseAnchor
(
pScanner
,
state
);
break
;
case
TT_ANCHOR
:
ParseAnchor
(
pScanner
,
state
);
break
;
case
TT_ALIAS
:
ParseAlias
(
pScanner
,
state
);
break
;
case
TT_ALIAS
:
ParseAlias
(
pScanner
,
state
);
break
;
default:
return
;
default:
return
;
}
}
}
}
}
}
void
Node
::
ParseTag
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Node
::
ParseTag
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
Token
&
token
=
pScanner
->
peek
();
Token
&
token
=
pScanner
->
peek
();
if
(
m_tag
!=
""
)
if
(
m_tag
!=
""
)
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
MULTIPLE_TAGS
);
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
MULTIPLE_TAGS
);
m_tag
=
state
.
TranslateTag
(
token
.
value
);
m_tag
=
state
.
TranslateTag
(
token
.
value
);
for
(
unsigned
i
=
0
;
i
<
token
.
params
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
token
.
params
.
size
();
i
++
)
m_tag
+=
token
.
params
[
i
];
m_tag
+=
token
.
params
[
i
];
pScanner
->
pop
();
pScanner
->
pop
();
}
}
void
Node
::
ParseAnchor
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Node
::
ParseAnchor
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
Token
&
token
=
pScanner
->
peek
();
Token
&
token
=
pScanner
->
peek
();
if
(
m_anchor
!=
""
)
if
(
m_anchor
!=
""
)
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
MULTIPLE_ANCHORS
);
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
MULTIPLE_ANCHORS
);
m_anchor
=
token
.
value
;
m_anchor
=
token
.
value
;
m_alias
=
false
;
m_alias
=
false
;
pScanner
->
pop
();
pScanner
->
pop
();
}
}
void
Node
::
ParseAlias
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
void
Node
::
ParseAlias
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
{
Token
&
token
=
pScanner
->
peek
();
Token
&
token
=
pScanner
->
peek
();
if
(
m_anchor
!=
""
)
if
(
m_anchor
!=
""
)
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
MULTIPLE_ALIASES
);
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
MULTIPLE_ALIASES
);
if
(
m_tag
!=
""
)
if
(
m_tag
!=
""
)
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
ALIAS_CONTENT
);
throw
ParserException
(
token
.
line
,
token
.
column
,
ErrorMsg
::
ALIAS_CONTENT
);
m_anchor
=
token
.
value
;
m_anchor
=
token
.
value
;
m_alias
=
true
;
m_alias
=
true
;
pScanner
->
pop
();
pScanner
->
pop
();
}
}
void
Node
::
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
const
void
Node
::
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
const
{
{
// write anchor/alias
// write anchor/alias
if
(
m_anchor
!=
""
)
{
if
(
m_anchor
!=
""
)
{
if
(
m_alias
)
if
(
m_alias
)
out
<<
std
::
string
(
"*"
);
out
<<
std
::
string
(
"*"
);
else
else
out
<<
std
::
string
(
"&"
);
out
<<
std
::
string
(
"&"
);
out
<<
m_anchor
<<
std
::
string
(
" "
);
out
<<
m_anchor
<<
std
::
string
(
" "
);
startedLine
=
true
;
startedLine
=
true
;
onlyOneCharOnLine
=
false
;
onlyOneCharOnLine
=
false
;
}
}
// write tag
// write tag
if
(
m_tag
!=
""
)
{
if
(
m_tag
!=
""
)
{
out
<<
std
::
string
(
"!<"
)
<<
m_tag
<<
std
::
string
(
"> "
);
out
<<
std
::
string
(
"!<"
)
<<
m_tag
<<
std
::
string
(
"> "
);
startedLine
=
true
;
startedLine
=
true
;
onlyOneCharOnLine
=
false
;
onlyOneCharOnLine
=
false
;
}
}
if
(
!
m_pContent
)
{
if
(
!
m_pContent
)
{
out
<<
std
::
string
(
"
\n
"
);
out
<<
std
::
string
(
"
\n
"
);
}
else
{
}
else
{
m_pContent
->
Write
(
out
,
indent
,
startedLine
,
onlyOneCharOnLine
);
m_pContent
->
Write
(
out
,
indent
,
startedLine
,
onlyOneCharOnLine
);
}
}
}
}
CONTENT_TYPE
Node
::
GetType
()
const
CONTENT_TYPE
Node
::
GetType
()
const
{
{
if
(
!
m_pContent
)
if
(
!
m_pContent
)
return
CT_NONE
;
return
CT_NONE
;
if
(
m_pContent
->
IsScalar
())
if
(
m_pContent
->
IsScalar
())
return
CT_SCALAR
;
return
CT_SCALAR
;
else
if
(
m_pContent
->
IsSequence
())
else
if
(
m_pContent
->
IsSequence
())
return
CT_SEQUENCE
;
return
CT_SEQUENCE
;
else
if
(
m_pContent
->
IsMap
())
else
if
(
m_pContent
->
IsMap
())
return
CT_MAP
;
return
CT_MAP
;
return
CT_NONE
;
return
CT_NONE
;
}
}
// begin
// begin
// Returns an iterator to the beginning of this (sequence or map).
// Returns an iterator to the beginning of this (sequence or map).
Iterator
Node
::
begin
()
const
Iterator
Node
::
begin
()
const
{
{
if
(
!
m_pContent
)
if
(
!
m_pContent
)
return
Iterator
();
return
Iterator
();
std
::
vector
<
Node
*>::
const_iterator
seqIter
;
std
::
vector
<
Node
*>::
const_iterator
seqIter
;
if
(
m_pContent
->
GetBegin
(
seqIter
))
if
(
m_pContent
->
GetBegin
(
seqIter
))
return
Iterator
(
new
IterPriv
(
seqIter
));
return
Iterator
(
new
IterPriv
(
seqIter
));
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
mapIter
;
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
mapIter
;
if
(
m_pContent
->
GetBegin
(
mapIter
))
if
(
m_pContent
->
GetBegin
(
mapIter
))
return
Iterator
(
new
IterPriv
(
mapIter
));
return
Iterator
(
new
IterPriv
(
mapIter
));
return
Iterator
();
return
Iterator
();
}
}
// end
// end
// . Returns an iterator to the end of this (sequence or map).
// . Returns an iterator to the end of this (sequence or map).
Iterator
Node
::
end
()
const
Iterator
Node
::
end
()
const
{
{
if
(
!
m_pContent
)
if
(
!
m_pContent
)
return
Iterator
();
return
Iterator
();
std
::
vector
<
Node
*>::
const_iterator
seqIter
;
std
::
vector
<
Node
*>::
const_iterator
seqIter
;
if
(
m_pContent
->
GetEnd
(
seqIter
))
if
(
m_pContent
->
GetEnd
(
seqIter
))
return
Iterator
(
new
IterPriv
(
seqIter
));
return
Iterator
(
new
IterPriv
(
seqIter
));
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
mapIter
;
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
mapIter
;
if
(
m_pContent
->
GetEnd
(
mapIter
))
if
(
m_pContent
->
GetEnd
(
mapIter
))
return
Iterator
(
new
IterPriv
(
mapIter
));
return
Iterator
(
new
IterPriv
(
mapIter
));
return
Iterator
();
return
Iterator
();
}
}
// size
// size
// . Returns the size of this node, if it's a sequence node.
// . Returns the size of this node, if it's a sequence node.
// . Otherwise, returns zero.
// . Otherwise, returns zero.
unsigned
Node
::
size
()
const
unsigned
Node
::
size
()
const
{
{
if
(
!
m_pContent
)
if
(
!
m_pContent
)
return
0
;
return
0
;
return
m_pContent
->
GetSize
();
return
m_pContent
->
GetSize
();
}
}
const
Node
&
Node
::
operator
[]
(
unsigned
u
)
const
const
Node
&
Node
::
operator
[]
(
unsigned
u
)
const
{
{
if
(
!
m_pContent
)
if
(
!
m_pContent
)
throw
BadDereference
();
throw
BadDereference
();
Node
*
pNode
=
m_pContent
->
GetNode
(
u
);
Node
*
pNode
=
m_pContent
->
GetNode
(
u
);
if
(
pNode
)
if
(
pNode
)
return
*
pNode
;
return
*
pNode
;
return
GetValue
(
u
);
return
GetValue
(
u
);
}
}
const
Node
&
Node
::
operator
[]
(
int
i
)
const
const
Node
&
Node
::
operator
[]
(
int
i
)
const
{
{
if
(
!
m_pContent
)
if
(
!
m_pContent
)
throw
BadDereference
();
throw
BadDereference
();
Node
*
pNode
=
m_pContent
->
GetNode
(
i
);
Node
*
pNode
=
m_pContent
->
GetNode
(
i
);
if
(
pNode
)
if
(
pNode
)
return
*
pNode
;
return
*
pNode
;
return
GetValue
(
i
);
return
GetValue
(
i
);
}
}
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
// Extraction
// Extraction
void
operator
>>
(
const
Node
&
node
,
std
::
string
&
s
)
void
operator
>>
(
const
Node
&
node
,
std
::
string
&
s
)
{
{
if
(
!
node
.
m_pContent
)
if
(
!
node
.
m_pContent
)
throw
;
throw
;
node
.
m_pContent
->
Read
(
s
);
node
.
m_pContent
->
Read
(
s
);
}
}
void
operator
>>
(
const
Node
&
node
,
int
&
i
)
void
operator
>>
(
const
Node
&
node
,
int
&
i
)
{
{
if
(
!
node
.
m_pContent
)
if
(
!
node
.
m_pContent
)
throw
;
throw
;
node
.
m_pContent
->
Read
(
i
);
node
.
m_pContent
->
Read
(
i
);
}
}
void
operator
>>
(
const
Node
&
node
,
unsigned
&
u
)
void
operator
>>
(
const
Node
&
node
,
unsigned
&
u
)
{
{
if
(
!
node
.
m_pContent
)
if
(
!
node
.
m_pContent
)
throw
;
throw
;
node
.
m_pContent
->
Read
(
u
);
node
.
m_pContent
->
Read
(
u
);
}
}
void
operator
>>
(
const
Node
&
node
,
long
&
l
)
void
operator
>>
(
const
Node
&
node
,
long
&
l
)
{
{
if
(
!
node
.
m_pContent
)
if
(
!
node
.
m_pContent
)
throw
;
throw
;
node
.
m_pContent
->
Read
(
l
);
node
.
m_pContent
->
Read
(
l
);
}
}
void
operator
>>
(
const
Node
&
node
,
float
&
f
)
void
operator
>>
(
const
Node
&
node
,
float
&
f
)
{
{
if
(
!
node
.
m_pContent
)
if
(
!
node
.
m_pContent
)
throw
;
throw
;
node
.
m_pContent
->
Read
(
f
);
node
.
m_pContent
->
Read
(
f
);
}
}
void
operator
>>
(
const
Node
&
node
,
double
&
d
)
void
operator
>>
(
const
Node
&
node
,
double
&
d
)
{
{
if
(
!
node
.
m_pContent
)
if
(
!
node
.
m_pContent
)
throw
;
throw
;
node
.
m_pContent
->
Read
(
d
);
node
.
m_pContent
->
Read
(
d
);
}
}
void
operator
>>
(
const
Node
&
node
,
char
&
c
)
void
operator
>>
(
const
Node
&
node
,
char
&
c
)
{
{
if
(
!
node
.
m_pContent
)
if
(
!
node
.
m_pContent
)
throw
;
throw
;
node
.
m_pContent
->
Read
(
c
);
node
.
m_pContent
->
Read
(
c
);
}
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Node
&
node
)
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Node
&
node
)
{
{
node
.
Write
(
out
,
0
,
false
,
false
);
node
.
Write
(
out
,
0
,
false
,
false
);
return
out
;
return
out
;
}
}
int
Node
::
Compare
(
const
Node
&
rhs
)
const
int
Node
::
Compare
(
const
Node
&
rhs
)
const
{
{
// Step 1: no content is the smallest
// Step 1: no content is the smallest
if
(
!
m_pContent
)
{
if
(
!
m_pContent
)
{
if
(
rhs
.
m_pContent
)
if
(
rhs
.
m_pContent
)
return
-
1
;
return
-
1
;
else
else
return
0
;
return
0
;
}
}
if
(
!
rhs
.
m_pContent
)
if
(
!
rhs
.
m_pContent
)
return
1
;
return
1
;
return
m_pContent
->
Compare
(
rhs
.
m_pContent
);
return
m_pContent
->
Compare
(
rhs
.
m_pContent
);
}
}
bool
operator
<
(
const
Node
&
n1
,
const
Node
&
n2
)
bool
operator
<
(
const
Node
&
n1
,
const
Node
&
n2
)
{
{
return
n1
.
Compare
(
n2
)
<
0
;
return
n1
.
Compare
(
n2
)
<
0
;
}
}
}
}
src/parser.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "parser.h"
#include "parser.h"
#include "scanner.h"
#include "scanner.h"
#include "token.h"
#include "token.h"
#include "exceptions.h"
#include "exceptions.h"
#include <sstream>
#include <sstream>
namespace
YAML
namespace
YAML
{
{
Parser
::
Parser
(
std
::
istream
&
in
)
:
m_pScanner
(
0
)
Parser
::
Parser
(
std
::
istream
&
in
)
:
m_pScanner
(
0
)
{
{
Load
(
in
);
Load
(
in
);
}
}
Parser
::~
Parser
()
Parser
::~
Parser
()
{
{
delete
m_pScanner
;
delete
m_pScanner
;
}
}
Parser
::
operator
bool
()
const
Parser
::
operator
bool
()
const
{
{
return
!
m_pScanner
->
empty
();
return
!
m_pScanner
->
empty
();
}
}
void
Parser
::
Load
(
std
::
istream
&
in
)
void
Parser
::
Load
(
std
::
istream
&
in
)
{
{
delete
m_pScanner
;
delete
m_pScanner
;
m_pScanner
=
new
Scanner
(
in
);
m_pScanner
=
new
Scanner
(
in
);
m_state
.
Reset
();
m_state
.
Reset
();
}
}
// GetNextDocument
// GetNextDocument
// . Reads the next document in the queue (of tokens).
// . Reads the next document in the queue (of tokens).
// . Throws a ParserException on error.
// . Throws a ParserException on error.
void
Parser
::
GetNextDocument
(
Node
&
document
)
void
Parser
::
GetNextDocument
(
Node
&
document
)
{
{
// clear node
// clear node
document
.
Clear
();
document
.
Clear
();
// first read directives
// first read directives
ParseDirectives
();
ParseDirectives
();
// we better have some tokens in the queue
// we better have some tokens in the queue
if
(
m_pScanner
->
empty
())
if
(
m_pScanner
->
empty
())
return
;
return
;
// first eat doc start (optional)
// first eat doc start (optional)
if
(
m_pScanner
->
peek
().
type
==
TT_DOC_START
)
if
(
m_pScanner
->
peek
().
type
==
TT_DOC_START
)
m_pScanner
->
pop
();
m_pScanner
->
pop
();
// now parse our root node
// now parse our root node
document
.
Parse
(
m_pScanner
,
m_state
);
document
.
Parse
(
m_pScanner
,
m_state
);
// and finally eat any doc ends we see
// and finally eat any doc ends we see
while
(
!
m_pScanner
->
empty
()
&&
m_pScanner
->
peek
().
type
==
TT_DOC_END
)
while
(
!
m_pScanner
->
empty
()
&&
m_pScanner
->
peek
().
type
==
TT_DOC_END
)
m_pScanner
->
pop
();
m_pScanner
->
pop
();
}
}
// ParseDirectives
// ParseDirectives
// . Reads any directives that are next in the queue.
// . Reads any directives that are next in the queue.
void
Parser
::
ParseDirectives
()
void
Parser
::
ParseDirectives
()
{
{
bool
readDirective
=
false
;
bool
readDirective
=
false
;
while
(
1
)
{
while
(
1
)
{
if
(
m_pScanner
->
empty
())
if
(
m_pScanner
->
empty
())
break
;
break
;
Token
&
token
=
m_pScanner
->
peek
();
Token
&
token
=
m_pScanner
->
peek
();
if
(
token
.
type
!=
TT_DIRECTIVE
)
if
(
token
.
type
!=
TT_DIRECTIVE
)
break
;
break
;
// we keep the directives from the last document if none are specified;
// we keep the directives from the last document if none are specified;
// but if any directives are specific, then we reset them
// but if any directives are specific, then we reset them
if
(
!
readDirective
)
if
(
!
readDirective
)
m_state
.
Reset
();
m_state
.
Reset
();
readDirective
=
true
;
readDirective
=
true
;
HandleDirective
(
&
token
);
HandleDirective
(
&
token
);
m_pScanner
->
pop
();
m_pScanner
->
pop
();
}
}
}
}
void
Parser
::
HandleDirective
(
Token
*
pToken
)
void
Parser
::
HandleDirective
(
Token
*
pToken
)
{
{
if
(
pToken
->
value
==
"YAML"
)
if
(
pToken
->
value
==
"YAML"
)
HandleYamlDirective
(
pToken
);
HandleYamlDirective
(
pToken
);
else
if
(
pToken
->
value
==
"TAG"
)
else
if
(
pToken
->
value
==
"TAG"
)
HandleTagDirective
(
pToken
);
HandleTagDirective
(
pToken
);
}
}
// HandleYamlDirective
// HandleYamlDirective
// . Should be of the form 'major.minor' (like a version number)
// . Should be of the form 'major.minor' (like a version number)
void
Parser
::
HandleYamlDirective
(
Token
*
pToken
)
void
Parser
::
HandleYamlDirective
(
Token
*
pToken
)
{
{
if
(
pToken
->
params
.
size
()
!=
1
)
if
(
pToken
->
params
.
size
()
!=
1
)
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
YAML_DIRECTIVE_ARGS
);
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
YAML_DIRECTIVE_ARGS
);
std
::
stringstream
str
(
pToken
->
params
[
0
]);
std
::
stringstream
str
(
pToken
->
params
[
0
]);
str
>>
m_state
.
version
.
major
;
str
>>
m_state
.
version
.
major
;
str
.
get
();
str
.
get
();
str
>>
m_state
.
version
.
minor
;
str
>>
m_state
.
version
.
minor
;
if
(
!
str
||
str
.
peek
()
!=
EOF
)
if
(
!
str
||
str
.
peek
()
!=
EOF
)
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
YAML_VERSION
+
pToken
->
params
[
0
]);
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
YAML_VERSION
+
pToken
->
params
[
0
]);
if
(
m_state
.
version
.
major
>
1
)
if
(
m_state
.
version
.
major
>
1
)
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
YAML_MAJOR_VERSION
);
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
YAML_MAJOR_VERSION
);
// TODO: warning on major == 1, minor > 2?
// TODO: warning on major == 1, minor > 2?
}
}
// HandleTagDirective
// HandleTagDirective
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
void
Parser
::
HandleTagDirective
(
Token
*
pToken
)
void
Parser
::
HandleTagDirective
(
Token
*
pToken
)
{
{
if
(
pToken
->
params
.
size
()
!=
2
)
if
(
pToken
->
params
.
size
()
!=
2
)
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
TAG_DIRECTIVE_ARGS
);
throw
ParserException
(
pToken
->
line
,
pToken
->
column
,
ErrorMsg
::
TAG_DIRECTIVE_ARGS
);
std
::
string
handle
=
pToken
->
params
[
0
],
prefix
=
pToken
->
params
[
1
];
std
::
string
handle
=
pToken
->
params
[
0
],
prefix
=
pToken
->
params
[
1
];
m_state
.
tags
[
handle
]
=
prefix
;
m_state
.
tags
[
handle
]
=
prefix
;
}
}
void
Parser
::
PrintTokens
(
std
::
ostream
&
out
)
void
Parser
::
PrintTokens
(
std
::
ostream
&
out
)
{
{
while
(
1
)
{
while
(
1
)
{
if
(
m_pScanner
->
empty
())
if
(
m_pScanner
->
empty
())
break
;
break
;
out
<<
m_pScanner
->
peek
()
<<
"
\n
"
;
out
<<
m_pScanner
->
peek
()
<<
"
\n
"
;
m_pScanner
->
pop
();
m_pScanner
->
pop
();
}
}
}
}
}
}
src/parserstate.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "parserstate.h"
#include "parserstate.h"
namespace
YAML
namespace
YAML
{
{
void
ParserState
::
Reset
()
void
ParserState
::
Reset
()
{
{
// version
// version
version
.
major
=
1
;
version
.
major
=
1
;
version
.
minor
=
2
;
version
.
minor
=
2
;
// and tags
// and tags
tags
.
clear
();
tags
.
clear
();
tags
[
"!"
]
=
"!"
;
tags
[
"!"
]
=
"!"
;
tags
[
"!!"
]
=
"tag:yaml.org,2002:"
;
tags
[
"!!"
]
=
"tag:yaml.org,2002:"
;
}
}
std
::
string
ParserState
::
TranslateTag
(
const
std
::
string
&
handle
)
const
std
::
string
ParserState
::
TranslateTag
(
const
std
::
string
&
handle
)
const
{
{
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
tags
.
find
(
handle
);
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
tags
.
find
(
handle
);
if
(
it
==
tags
.
end
())
if
(
it
==
tags
.
end
())
return
handle
;
return
handle
;
return
it
->
second
;
return
it
->
second
;
}
}
}
}
src/regex.cpp
View file @
45322566
#include "crt.h"
#include "crt.h"
#include "regex.h"
#include "regex.h"
#include "stream.h"
#include "stream.h"
#include <iostream>
#include <iostream>
namespace
YAML
namespace
YAML
{
{
RegEx
::
RegEx
(
REGEX_OP
op
)
:
m_op
(
op
),
m_pOp
(
0
)
RegEx
::
RegEx
(
REGEX_OP
op
)
:
m_op
(
op
),
m_pOp
(
0
)
{
{
SetOp
();
SetOp
();
}
}
RegEx
::
RegEx
(
const
RegEx
&
rhs
)
:
m_pOp
(
0
)
RegEx
::
RegEx
(
const
RegEx
&
rhs
)
:
m_pOp
(
0
)
{
{
m_op
=
rhs
.
m_op
;
m_op
=
rhs
.
m_op
;
m_a
=
rhs
.
m_a
;
m_a
=
rhs
.
m_a
;
m_z
=
rhs
.
m_z
;
m_z
=
rhs
.
m_z
;
m_params
=
rhs
.
m_params
;
m_params
=
rhs
.
m_params
;
SetOp
();
SetOp
();
}
}
RegEx
::
RegEx
()
:
m_op
(
REGEX_EMPTY
),
m_pOp
(
0
)
RegEx
::
RegEx
()
:
m_op
(
REGEX_EMPTY
),
m_pOp
(
0
)
{
{
SetOp
();
SetOp
();
}
}
RegEx
::
RegEx
(
char
ch
)
:
m_op
(
REGEX_MATCH
),
m_pOp
(
0
),
m_a
(
ch
)
RegEx
::
RegEx
(
char
ch
)
:
m_op
(
REGEX_MATCH
),
m_pOp
(
0
),
m_a
(
ch
)
{
{
SetOp
();
SetOp
();
}
}
RegEx
::
RegEx
(
char
a
,
char
z
)
:
m_op
(
REGEX_RANGE
),
m_pOp
(
0
),
m_a
(
a
),
m_z
(
z
)
RegEx
::
RegEx
(
char
a
,
char
z
)
:
m_op
(
REGEX_RANGE
),
m_pOp
(
0
),
m_a
(
a
),
m_z
(
z
)
{
{
SetOp
();
SetOp
();
}
}
RegEx
::
RegEx
(
const
std
::
string
&
str
,
REGEX_OP
op
)
:
m_op
(
op
),
m_pOp
(
0
)
RegEx
::
RegEx
(
const
std
::
string
&
str
,
REGEX_OP
op
)
:
m_op
(
op
),
m_pOp
(
0
)
{
{
for
(
unsigned
i
=
0
;
i
<
str
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
str
.
size
();
i
++
)
m_params
.
push_back
(
RegEx
(
str
[
i
]));
m_params
.
push_back
(
RegEx
(
str
[
i
]));
SetOp
();
SetOp
();
}
}
RegEx
::~
RegEx
()
RegEx
::~
RegEx
()
{
{
delete
m_pOp
;
delete
m_pOp
;
}
}
RegEx
&
RegEx
::
operator
=
(
const
RegEx
&
rhs
)
RegEx
&
RegEx
::
operator
=
(
const
RegEx
&
rhs
)
{
{
delete
m_pOp
;
delete
m_pOp
;
m_pOp
=
0
;
m_pOp
=
0
;
m_op
=
rhs
.
m_op
;
m_op
=
rhs
.
m_op
;
m_a
=
rhs
.
m_a
;
m_a
=
rhs
.
m_a
;
m_z
=
rhs
.
m_z
;
m_z
=
rhs
.
m_z
;
m_params
=
rhs
.
m_params
;
m_params
=
rhs
.
m_params
;
SetOp
();
SetOp
();
return
*
this
;
return
*
this
;
}
}
void
RegEx
::
SetOp
()
void
RegEx
::
SetOp
()
{
{
delete
m_pOp
;
delete
m_pOp
;
m_pOp
=
0
;
m_pOp
=
0
;
switch
(
m_op
)
{
switch
(
m_op
)
{
case
REGEX_MATCH
:
m_pOp
=
new
MatchOperator
;
break
;
case
REGEX_MATCH
:
m_pOp
=
new
MatchOperator
;
break
;
case
REGEX_RANGE
:
m_pOp
=
new
RangeOperator
;
break
;
case
REGEX_RANGE
:
m_pOp
=
new
RangeOperator
;
break
;
case
REGEX_OR
:
m_pOp
=
new
OrOperator
;
break
;
case
REGEX_OR
:
m_pOp
=
new
OrOperator
;
break
;
case
REGEX_AND
:
m_pOp
=
new
AndOperator
;
break
;
case
REGEX_AND
:
m_pOp
=
new
AndOperator
;
break
;
case
REGEX_NOT
:
m_pOp
=
new
NotOperator
;
break
;
case
REGEX_NOT
:
m_pOp
=
new
NotOperator
;
break
;
case
REGEX_SEQ
:
m_pOp
=
new
SeqOperator
;
break
;
case
REGEX_SEQ
:
m_pOp
=
new
SeqOperator
;
break
;
}
}
}
}
bool
RegEx
::
Matches
(
char
ch
)
const
bool
RegEx
::
Matches
(
char
ch
)
const
{
{
std
::
string
str
;
std
::
string
str
;
str
+=
ch
;
str
+=
ch
;
return
Matches
(
str
);
return
Matches
(
str
);
}
}
bool
RegEx
::
Matches
(
const
std
::
string
&
str
)
const
bool
RegEx
::
Matches
(
const
std
::
string
&
str
)
const
{
{
return
Match
(
str
)
>=
0
;
return
Match
(
str
)
>=
0
;
}
}
bool
RegEx
::
Matches
(
std
::
istream
&
in
)
const
bool
RegEx
::
Matches
(
std
::
istream
&
in
)
const
{
{
return
Match
(
in
)
>=
0
;
return
Match
(
in
)
>=
0
;
}
}
bool
RegEx
::
Matches
(
Stream
&
in
)
const
bool
RegEx
::
Matches
(
Stream
&
in
)
const
{
{
return
Match
(
in
)
>=
0
;
return
Match
(
in
)
>=
0
;
}
}
// Match
// Match
// . Matches the given string against this regular expression.
// . Matches the given string against this regular expression.
// . Returns the number of characters matched.
// . Returns the number of characters matched.
// . Returns -1 if no characters were matched (the reason for
// . Returns -1 if no characters were matched (the reason for
// not returning zero is that we may have an empty regex
// not returning zero is that we may have an empty regex
// which is ALWAYS successful at matching zero characters).
// which is ALWAYS successful at matching zero characters).
int
RegEx
::
Match
(
const
std
::
string
&
str
)
const
int
RegEx
::
Match
(
const
std
::
string
&
str
)
const
{
{
if
(
!
m_pOp
)
if
(
!
m_pOp
)
return
0
;
return
0
;
return
m_pOp
->
Match
(
str
,
*
this
);
return
m_pOp
->
Match
(
str
,
*
this
);
}
}
// Match
// Match
int
RegEx
::
Match
(
Stream
&
in
)
const
int
RegEx
::
Match
(
Stream
&
in
)
const
{
{
return
Match
(
in
.
stream
());
return
Match
(
in
.
stream
());
}
}
// Match
// Match
// . The stream version does the same thing as the string version;
// . The stream version does the same thing as the string version;
// REMEMBER that we only match from the start of the stream!
// REMEMBER that we only match from the start of the stream!
// . Note: the istream is not a const reference, but we guarantee
// . Note: the istream is not a const reference, but we guarantee
// that the pointer will be in the same spot, and we'll clear its
// that the pointer will be in the same spot, and we'll clear its
// flags before we end.
// flags before we end.
int
RegEx
::
Match
(
std
::
istream
&
in
)
const
int
RegEx
::
Match
(
std
::
istream
&
in
)
const
{
{
if
(
!
m_pOp
)
if
(
!
m_pOp
)
return
-
1
;
return
-
1
;
int
pos
=
in
.
tellg
();
int
pos
=
in
.
tellg
();
int
ret
=
m_pOp
->
Match
(
in
,
*
this
);
int
ret
=
m_pOp
->
Match
(
in
,
*
this
);
// reset input stream!
// reset input stream!
in
.
clear
();
in
.
clear
();
in
.
seekg
(
pos
);
in
.
seekg
(
pos
);
return
ret
;
return
ret
;
}
}
RegEx
operator
!
(
const
RegEx
&
ex
)
RegEx
operator
!
(
const
RegEx
&
ex
)
{
{
RegEx
ret
(
REGEX_NOT
);
RegEx
ret
(
REGEX_NOT
);
ret
.
m_params
.
push_back
(
ex
);
ret
.
m_params
.
push_back
(
ex
);
return
ret
;
return
ret
;
}
}
RegEx
operator
||
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
RegEx
operator
||
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
{
RegEx
ret
(
REGEX_OR
);
RegEx
ret
(
REGEX_OR
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex2
);
ret
.
m_params
.
push_back
(
ex2
);
return
ret
;
return
ret
;
}
}
RegEx
operator
&&
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
RegEx
operator
&&
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
{
RegEx
ret
(
REGEX_AND
);
RegEx
ret
(
REGEX_AND
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex2
);
ret
.
m_params
.
push_back
(
ex2
);
return
ret
;
return
ret
;
}
}
RegEx
operator
+
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
RegEx
operator
+
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
{
RegEx
ret
(
REGEX_SEQ
);
RegEx
ret
(
REGEX_SEQ
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex2
);
ret
.
m_params
.
push_back
(
ex2
);
return
ret
;
return
ret
;
}
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Operators
// Operators
// MatchOperator
// MatchOperator
int
RegEx
::
MatchOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
int
RegEx
::
MatchOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
{
{
if
(
str
.
empty
()
||
str
[
0
]
!=
regex
.
m_a
)
if
(
str
.
empty
()
||
str
[
0
]
!=
regex
.
m_a
)
return
-
1
;
return
-
1
;
return
1
;
return
1
;
}
}
int
RegEx
::
MatchOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
int
RegEx
::
MatchOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
{
{
if
(
!
in
||
in
.
peek
()
!=
regex
.
m_a
)
if
(
!
in
||
in
.
peek
()
!=
regex
.
m_a
)
return
-
1
;
return
-
1
;
return
1
;
return
1
;
}
}
// RangeOperator
// RangeOperator
int
RegEx
::
RangeOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
int
RegEx
::
RangeOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
{
{
if
(
str
.
empty
()
||
regex
.
m_a
>
str
[
0
]
||
regex
.
m_z
<
str
[
0
])
if
(
str
.
empty
()
||
regex
.
m_a
>
str
[
0
]
||
regex
.
m_z
<
str
[
0
])
return
-
1
;
return
-
1
;
return
1
;
return
1
;
}
}
int
RegEx
::
RangeOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
int
RegEx
::
RangeOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
{
{
if
(
!
in
||
regex
.
m_a
>
in
.
peek
()
||
regex
.
m_z
<
in
.
peek
())
if
(
!
in
||
regex
.
m_a
>
in
.
peek
()
||
regex
.
m_z
<
in
.
peek
())
return
-
1
;
return
-
1
;
return
1
;
return
1
;
}
}
// OrOperator
// OrOperator
int
RegEx
::
OrOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
int
RegEx
::
OrOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
{
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
int
n
=
regex
.
m_params
[
i
].
Match
(
str
);
int
n
=
regex
.
m_params
[
i
].
Match
(
str
);
if
(
n
>=
0
)
if
(
n
>=
0
)
return
n
;
return
n
;
}
}
return
-
1
;
return
-
1
;
}
}
int
RegEx
::
OrOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
int
RegEx
::
OrOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
{
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
int
n
=
regex
.
m_params
[
i
].
Match
(
in
);
int
n
=
regex
.
m_params
[
i
].
Match
(
in
);
if
(
n
>=
0
)
if
(
n
>=
0
)
return
n
;
return
n
;
}
}
return
-
1
;
return
-
1
;
}
}
// AndOperator
// AndOperator
// Note: 'AND' is a little funny, since we may be required to match things
// Note: 'AND' is a little funny, since we may be required to match things
// of different lengths. If we find a match, we return the length of
// of different lengths. If we find a match, we return the length of
// the FIRST entry on the list.
// the FIRST entry on the list.
int
RegEx
::
AndOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
int
RegEx
::
AndOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
{
{
int
first
=
-
1
;
int
first
=
-
1
;
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
int
n
=
regex
.
m_params
[
i
].
Match
(
str
);
int
n
=
regex
.
m_params
[
i
].
Match
(
str
);
if
(
n
==
-
1
)
if
(
n
==
-
1
)
return
-
1
;
return
-
1
;
if
(
i
==
0
)
if
(
i
==
0
)
first
=
n
;
first
=
n
;
}
}
return
first
;
return
first
;
}
}
int
RegEx
::
AndOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
int
RegEx
::
AndOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
{
{
int
first
=
-
1
;
int
first
=
-
1
;
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
int
n
=
regex
.
m_params
[
i
].
Match
(
in
);
int
n
=
regex
.
m_params
[
i
].
Match
(
in
);
if
(
n
==
-
1
)
if
(
n
==
-
1
)
return
-
1
;
return
-
1
;
if
(
i
==
0
)
if
(
i
==
0
)
first
=
n
;
first
=
n
;
}
}
return
first
;
return
first
;
}
}
// NotOperator
// NotOperator
int
RegEx
::
NotOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
int
RegEx
::
NotOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
{
{
if
(
regex
.
m_params
.
empty
())
if
(
regex
.
m_params
.
empty
())
return
-
1
;
return
-
1
;
if
(
regex
.
m_params
[
0
].
Match
(
str
)
>=
0
)
if
(
regex
.
m_params
[
0
].
Match
(
str
)
>=
0
)
return
-
1
;
return
-
1
;
return
1
;
return
1
;
}
}
int
RegEx
::
NotOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
int
RegEx
::
NotOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
{
{
if
(
regex
.
m_params
.
empty
())
if
(
regex
.
m_params
.
empty
())
return
-
1
;
return
-
1
;
if
(
regex
.
m_params
[
0
].
Match
(
in
)
>=
0
)
if
(
regex
.
m_params
[
0
].
Match
(
in
)
>=
0
)
return
-
1
;
return
-
1
;
return
1
;
return
1
;
}
}
// SeqOperator
// SeqOperator
int
RegEx
::
SeqOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
int
RegEx
::
SeqOperator
::
Match
(
const
std
::
string
&
str
,
const
RegEx
&
regex
)
const
{
{
int
offset
=
0
;
int
offset
=
0
;
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
int
n
=
regex
.
m_params
[
i
].
Match
(
str
.
substr
(
offset
));
int
n
=
regex
.
m_params
[
i
].
Match
(
str
.
substr
(
offset
));
if
(
n
==
-
1
)
if
(
n
==
-
1
)
return
-
1
;
return
-
1
;
offset
+=
n
;
offset
+=
n
;
}
}
return
offset
;
return
offset
;
}
}
int
RegEx
::
SeqOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
int
RegEx
::
SeqOperator
::
Match
(
std
::
istream
&
in
,
const
RegEx
&
regex
)
const
{
{
int
offset
=
0
;
int
offset
=
0
;
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
regex
.
m_params
.
size
();
i
++
)
{
int
n
=
regex
.
m_params
[
i
].
Match
(
in
);
int
n
=
regex
.
m_params
[
i
].
Match
(
in
);
if
(
n
==
-
1
)
if
(
n
==
-
1
)
return
-
1
;
return
-
1
;
offset
+=
n
;
offset
+=
n
;
in
.
ignore
(
n
);
in
.
ignore
(
n
);
}
}
return
offset
;
return
offset
;
}
}
}
}
Prev
1
2
3
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment