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
b3a5a519
Commit
b3a5a519
authored
May 22, 2009
by
Jesse Beder
Browse files
Merged aliases branch into trunk, changes r100:150
parent
9d0e0c6a
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
308 additions
and
18 deletions
+308
-18
include/exceptions.h
include/exceptions.h
+2
-0
include/node.h
include/node.h
+7
-0
src/CMakeLists.txt
src/CMakeLists.txt
+1
-1
src/alias.cpp
src/alias.cpp
+125
-0
src/alias.h
src/alias.h
+42
-0
src/node.cpp
src/node.cpp
+54
-16
src/parser.cpp
src/parser.cpp
+3
-0
src/scanner.cpp
src/scanner.cpp
+50
-1
src/scanner.h
src/scanner.h
+10
-0
src/stream.cpp
src/stream.cpp
+1
-0
yaml-reader/tests.cpp
yaml-reader/tests.cpp
+1
-0
yaml-reader/tests/aliased.yaml
yaml-reader/tests/aliased.yaml
+4
-0
yamlcpp.vcproj
yamlcpp.vcproj
+8
-0
No files found.
include/exceptions.h
View file @
b3a5a519
...
...
@@ -38,6 +38,8 @@ namespace YAML
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
CHAR_IN_BLOCK
=
"unexpected character in block scalar"
;
const
std
::
string
AMBIGUOUS_ANCHOR
=
"cannot assign the same alias to multiple nodes"
;
const
std
::
string
UNKNOWN_ANCHOR
=
"the referenced anchor is not defined"
;
const
std
::
string
INVALID_SCALAR
=
"invalid scalar"
;
const
std
::
string
KEY_NOT_FOUND
=
"key not found"
;
...
...
include/node.h
View file @
b3a5a519
...
...
@@ -66,6 +66,11 @@ namespace YAML
const
Node
&
operator
[]
(
unsigned
u
)
const
;
const
Node
&
operator
[]
(
int
i
)
const
;
// for anchors/aliases
const
Node
*
Identity
()
const
{
return
m_pIdentity
;
}
bool
IsAlias
()
const
{
return
m_alias
;
}
bool
IsReferenced
()
const
{
return
m_referenced
;
}
// insertion
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
out
,
const
Node
&
node
);
...
...
@@ -89,6 +94,8 @@ namespace YAML
std
::
string
m_anchor
,
m_tag
;
Content
*
m_pContent
;
bool
m_alias
;
const
Node
*
m_pIdentity
;
mutable
bool
m_referenced
;
};
// templated things we need to keep inline in the header
...
...
src/CMakeLists.txt
View file @
b3a5a519
set
(
FILES content.cpp iterator.cpp node.cpp parserstate.cpp
set
(
FILES
alias.cpp
content.cpp iterator.cpp node.cpp parserstate.cpp
scalar.cpp scanscalar.cpp sequence.cpp stream.cpp
exp.cpp map.cpp parser.cpp regex.cpp scanner.cpp
scantoken.cpp simplekey.cpp
)
...
...
src/alias.cpp
0 → 100644
View file @
b3a5a519
#include "crt.h"
#include "alias.h"
#include <iostream>
namespace
YAML
{
Alias
::
Alias
(
Content
*
pNodeContent
)
:
m_pRef
(
pNodeContent
)
{
}
void
Alias
::
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
{
}
void
Alias
::
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
{
out
<<
"
\n
"
;
}
bool
Alias
::
GetBegin
(
std
::
vector
<
Node
*>::
const_iterator
&
i
)
const
{
return
m_pRef
->
GetBegin
(
i
);
}
bool
Alias
::
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
i
)
const
{
return
m_pRef
->
GetBegin
(
i
);
}
bool
Alias
::
GetEnd
(
std
::
vector
<
Node
*>::
const_iterator
&
i
)
const
{
return
m_pRef
->
GetEnd
(
i
);
}
bool
Alias
::
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
i
)
const
{
return
m_pRef
->
GetEnd
(
i
);
}
Node
*
Alias
::
GetNode
(
unsigned
n
)
const
{
return
m_pRef
->
GetNode
(
n
);
}
unsigned
Alias
::
GetSize
()
const
{
return
m_pRef
->
GetSize
();
}
bool
Alias
::
IsScalar
()
const
{
return
m_pRef
->
IsScalar
();
}
bool
Alias
::
IsMap
()
const
{
return
m_pRef
->
IsMap
();
}
bool
Alias
::
IsSequence
()
const
{
return
m_pRef
->
IsSequence
();
}
bool
Alias
::
Read
(
std
::
string
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
bool
Alias
::
Read
(
int
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
bool
Alias
::
Read
(
unsigned
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
bool
Alias
::
Read
(
long
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
bool
Alias
::
Read
(
float
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
bool
Alias
::
Read
(
double
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
bool
Alias
::
Read
(
char
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
bool
Alias
::
Read
(
bool
&
v
)
const
{
return
m_pRef
->
Read
(
v
);
}
int
Alias
::
Compare
(
Content
*
pContent
)
{
return
m_pRef
->
Compare
(
pContent
);
}
int
Alias
::
Compare
(
Scalar
*
pScalar
)
{
return
m_pRef
->
Compare
(
pScalar
);
}
int
Alias
::
Compare
(
Sequence
*
pSequence
)
{
return
m_pRef
->
Compare
(
pSequence
);
}
int
Alias
::
Compare
(
Map
*
pMap
)
{
return
m_pRef
->
Compare
(
pMap
);
}
}
src/alias.h
0 → 100644
View file @
b3a5a519
#pragma once
#include "content.h"
namespace
YAML
{
class
Alias
:
public
Content
{
public:
Alias
(
Content
*
pNodeContent
);
virtual
void
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
);
virtual
void
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
);
virtual
bool
GetBegin
(
std
::
vector
<
Node
*>::
const_iterator
&
)
const
;
virtual
bool
GetBegin
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
)
const
;
virtual
bool
GetEnd
(
std
::
vector
<
Node
*>::
const_iterator
&
)
const
;
virtual
bool
GetEnd
(
std
::
map
<
Node
*
,
Node
*
,
ltnode
>::
const_iterator
&
)
const
;
virtual
Node
*
GetNode
(
unsigned
)
const
;
virtual
unsigned
GetSize
()
const
;
virtual
bool
IsScalar
()
const
;
virtual
bool
IsMap
()
const
;
virtual
bool
IsSequence
()
const
;
virtual
bool
Read
(
std
::
string
&
)
const
;
virtual
bool
Read
(
int
&
)
const
;
virtual
bool
Read
(
unsigned
&
)
const
;
virtual
bool
Read
(
long
&
)
const
;
virtual
bool
Read
(
float
&
)
const
;
virtual
bool
Read
(
double
&
)
const
;
virtual
bool
Read
(
char
&
)
const
;
virtual
bool
Read
(
bool
&
)
const
;
virtual
int
Compare
(
Content
*
);
virtual
int
Compare
(
Scalar
*
);
virtual
int
Compare
(
Sequence
*
);
virtual
int
Compare
(
Map
*
);
private:
Content
*
m_pRef
;
};
}
src/node.cpp
View file @
b3a5a519
...
...
@@ -7,7 +7,9 @@
#include "scalar.h"
#include "sequence.h"
#include "map.h"
#include "alias.h"
#include "iterpriv.h"
#include <iostream>
namespace
YAML
{
...
...
@@ -17,7 +19,7 @@ namespace YAML
return
*
pNode1
<
*
pNode2
;
}
Node
::
Node
()
:
m_pContent
(
0
),
m_alias
(
false
)
Node
::
Node
()
:
m_pContent
(
0
),
m_alias
(
false
)
,
m_pIdentity
(
this
),
m_referenced
(
true
)
{
}
...
...
@@ -31,6 +33,9 @@ namespace YAML
delete
m_pContent
;
m_pContent
=
0
;
m_alias
=
false
;
m_referenced
=
false
;
m_anchor
.
clear
();
m_tag
.
clear
();
}
void
Node
::
Parse
(
Scanner
*
pScanner
,
const
ParserState
&
state
)
...
...
@@ -47,30 +52,50 @@ namespace YAML
ParseHeader
(
pScanner
,
state
);
// is this an alias? if so, it can have no content
if
(
m_alias
)
// is this an alias? if so, its contents are an alias to
// a previously defined anchor
if
(
m_alias
)
{
// the scanner throws an exception if it doesn't know this anchor name
const
Node
*
pReferencedNode
=
pScanner
->
Retrieve
(
m_anchor
);
m_pIdentity
=
pReferencedNode
;
// mark the referenced node for the sake of the client code
pReferencedNode
->
m_referenced
=
true
;
// use of an Alias object keeps the referenced content from
// being deleted twice
Content
*
pAliasedContent
=
pReferencedNode
->
m_pContent
;
if
(
pAliasedContent
)
m_pContent
=
new
Alias
(
pAliasedContent
);
return
;
}
// now split based on what kind of node we should be
switch
(
pScanner
->
peek
().
type
)
{
case
TT_SCALAR
:
m_pContent
=
new
Scalar
;
m_pContent
->
Parse
(
pScanner
,
state
);
break
;
case
TT_FLOW_SEQ_START
:
case
TT_BLOCK_SEQ_START
:
case
TT_BLOCK_ENTRY
:
m_pContent
=
new
Sequence
;
m_pContent
->
Parse
(
pScanner
,
state
);
break
;
case
TT_FLOW_MAP_START
:
case
TT_BLOCK_MAP_START
:
m_pContent
=
new
Map
;
m_pContent
->
Parse
(
pScanner
,
state
);
break
;
default:
break
;
}
// Have to save anchor before parsing to allow for aliases as
// contained node (recursive structure)
if
(
!
m_anchor
.
empty
())
pScanner
->
Save
(
m_anchor
,
this
);
if
(
m_pContent
)
m_pContent
->
Parse
(
pScanner
,
state
);
}
// ParseHeader
...
...
@@ -129,33 +154,46 @@ namespace YAML
void
Node
::
Write
(
std
::
ostream
&
out
,
int
indent
,
bool
startedLine
,
bool
onlyOneCharOnLine
)
const
{
// If using an anchor or tag for the whole document, document start
// must be explicit
bool
indicateDocStart
=
(
indent
==
0
);
// write anchor/alias
if
(
m_anchor
!=
""
)
{
if
(
indicateDocStart
)
{
out
<<
"--- "
;
indicateDocStart
=
false
;
}
if
(
m_alias
)
out
<<
std
::
string
(
"*"
)
;
out
<<
"*"
;
else
out
<<
std
::
string
(
"&"
)
;
out
<<
m_anchor
<<
std
::
string
(
" "
)
;
out
<<
"&"
;
out
<<
m_anchor
<<
" "
;
startedLine
=
true
;
onlyOneCharOnLine
=
false
;
}
// write tag
if
(
m_tag
!=
""
)
{
if
(
indicateDocStart
)
{
out
<<
"--- "
;
indicateDocStart
=
false
;
}
// put the tag in the "proper" brackets
if
(
m_tag
.
substr
(
0
,
2
)
==
"!<"
&&
m_tag
.
substr
(
m_tag
.
size
()
-
1
)
==
">"
)
out
<<
m_tag
;
if
(
m_tag
.
substr
(
0
,
2
)
==
std
::
string
(
"!<"
)
&&
m_tag
.
substr
(
m_tag
.
size
()
-
1
)
==
std
::
string
(
">"
)
)
out
<<
m_tag
<<
" "
;
else
out
<<
std
::
string
(
"!<"
)
<<
m_tag
<<
std
::
string
(
"> "
)
;
out
<<
"!<"
<<
m_tag
<<
"> "
;
startedLine
=
true
;
onlyOneCharOnLine
=
false
;
}
if
(
!
m_pContent
)
{
out
<<
std
::
string
(
"
\n
"
)
;
}
else
{
if
(
!
m_pContent
)
out
<<
"
\n
"
;
else
m_pContent
->
Write
(
out
,
indent
,
startedLine
,
onlyOneCharOnLine
);
}
}
CONTENT_TYPE
Node
::
GetType
()
const
...
...
src/parser.cpp
View file @
b3a5a519
...
...
@@ -55,6 +55,9 @@ namespace YAML
// and finally eat any doc ends we see
while
(
!
m_pScanner
->
empty
()
&&
m_pScanner
->
peek
().
type
==
TT_DOC_END
)
m_pScanner
->
pop
();
// clear anchors from the scanner, which are no longer relevant
m_pScanner
->
ClearAnchors
();
}
// ParseDirectives
...
...
src/scanner.cpp
View file @
b3a5a519
...
...
@@ -29,8 +29,13 @@ namespace YAML
void
Scanner
::
pop
()
{
EnsureTokensInQueue
();
if
(
!
m_tokens
.
empty
())
if
(
!
m_tokens
.
empty
())
{
// Saved anchors shouldn't survive popping the document end marker
if
(
m_tokens
.
front
().
type
==
TT_DOC_END
)
{
ClearAnchors
();
}
m_tokens
.
pop
();
}
}
// peek
...
...
@@ -217,6 +222,7 @@ namespace YAML
m_startedStream
=
true
;
m_simpleKeyAllowed
=
true
;
m_indents
.
push
(
-
1
);
m_anchors
.
clear
();
}
// EndStream
...
...
@@ -273,4 +279,47 @@ namespace YAML
m_tokens
.
push
(
Token
(
TT_BLOCK_END
,
INPUT
.
line
,
INPUT
.
column
));
}
}
// Save
// . Saves a pointer to the Node object referenced by a particular anchor
// name.
void
Scanner
::
Save
(
const
std
::
string
&
anchor
,
Node
*
value
)
{
m_anchors
[
anchor
]
=
value
;
}
// Retrieve
// . Retrieves a pointer previously saved for an anchor name.
// . Throws an exception if the anchor has not been defined.
const
Node
*
Scanner
::
Retrieve
(
const
std
::
string
&
anchor
)
const
{
typedef
std
::
map
<
std
::
string
,
const
Node
*>
map
;
map
::
const_iterator
itNode
=
m_anchors
.
find
(
anchor
);
if
(
m_anchors
.
end
()
==
itNode
)
ThrowParserException
(
ErrorMsg
::
UNKNOWN_ANCHOR
);
return
itNode
->
second
;
}
// ThrowParserException
// . Throws a ParserException with the current token location
// (if available).
// . Does not parse any more tokens.
void
Scanner
::
ThrowParserException
(
const
std
::
string
&
msg
)
const
{
int
line
=
-
1
,
column
=
-
1
;
if
(
!
m_tokens
.
empty
())
{
const
Token
&
token
=
m_tokens
.
front
();
line
=
token
.
line
;
column
=
token
.
column
;
}
throw
ParserException
(
line
,
column
,
msg
);
}
void
Scanner
::
ClearAnchors
()
{
m_anchors
.
clear
();
}
}
src/scanner.h
View file @
b3a5a519
...
...
@@ -5,11 +5,14 @@
#include <queue>
#include <stack>
#include <set>
#include <map>
#include "stream.h"
#include "token.h"
namespace
YAML
{
class
Node
;
class
Scanner
{
public:
...
...
@@ -21,6 +24,11 @@ namespace YAML
void
pop
();
Token
&
peek
();
// anchor management
void
Save
(
const
std
::
string
&
anchor
,
Node
*
value
);
const
Node
*
Retrieve
(
const
std
::
string
&
anchor
)
const
;
void
ClearAnchors
();
private:
// scanning
void
EnsureTokensInQueue
();
...
...
@@ -35,6 +43,7 @@ namespace YAML
void
InsertSimpleKey
();
bool
VerifySimpleKey
(
bool
force
=
false
);
void
VerifyAllSimpleKeys
();
void
ThrowParserException
(
const
std
::
string
&
msg
)
const
;
bool
IsWhitespaceToBeEaten
(
char
ch
);
...
...
@@ -81,5 +90,6 @@ namespace YAML
bool
m_isLastKeyValid
;
std
::
stack
<
SimpleKey
>
m_simpleKeys
;
std
::
stack
<
int
>
m_indents
;
std
::
map
<
std
::
string
,
const
Node
*>
m_anchors
;
};
}
src/stream.cpp
View file @
b3a5a519
...
...
@@ -55,6 +55,7 @@ namespace YAML
std
::
string
Stream
::
get
(
int
n
)
{
std
::
string
ret
;
ret
.
reserve
(
n
);
for
(
int
i
=
0
;
i
<
n
;
i
++
)
ret
+=
get
();
return
ret
;
...
...
yaml-reader/tests.cpp
View file @
b3a5a519
...
...
@@ -16,6 +16,7 @@ namespace Test
files
.
push_back
(
"tests/mixed.yaml"
);
files
.
push_back
(
"tests/scalars.yaml"
);
files
.
push_back
(
"tests/directives.yaml"
);
files
.
push_back
(
"tests/aliased.yaml"
);
bool
passed
=
true
;
for
(
unsigned
i
=
0
;
i
<
files
.
size
();
i
++
)
{
...
...
yaml-reader/tests/aliased.yaml
0 → 100644
View file @
b3a5a519
---
&list
-
This document contains a recursive list.
-
*list
...
yamlcpp.vcproj
View file @
b3a5a519
...
...
@@ -167,6 +167,10 @@
<Filter
Name=
"Representation"
>
<File
RelativePath=
".\src\alias.cpp"
>
</File>
<File
RelativePath=
".\src\content.cpp"
>
...
...
@@ -257,6 +261,10 @@
<Filter
Name=
"Representation"
>
<File
RelativePath=
".\include\alias.h"
>
</File>
<File
RelativePath=
".\src\content.h"
>
...
...
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