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
3355bbb3
Commit
3355bbb3
authored
Mar 22, 2014
by
Jesse Beder
Browse files
Merge clang-format from core
parents
5b889311
9b4db068
Changes
72
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
3213 additions
and
3245 deletions
+3213
-3245
src/contrib/graphbuilderadapter.h
src/contrib/graphbuilderadapter.h
+55
-57
src/directives.cpp
src/directives.cpp
+19
-21
src/directives.h
src/directives.h
+17
-17
src/emitfromevents.cpp
src/emitfromevents.cpp
+80
-93
src/emitter.cpp
src/emitter.cpp
+879
-924
src/emitterstate.cpp
src/emitterstate.cpp
+341
-378
src/emitterstate.h
src/emitterstate.h
+196
-172
src/emitterutils.cpp
src/emitterutils.cpp
+431
-413
src/emitterutils.h
src/emitterutils.h
+36
-23
src/exp.cpp
src/exp.cpp
+113
-96
src/exp.h
src/exp.h
+187
-175
src/indentation.h
src/indentation.h
+26
-25
src/null.cpp
src/null.cpp
+2
-3
src/parser.cpp
src/parser.cpp
+115
-129
src/ptr_stack.h
src/ptr_stack.h
+37
-34
src/ptr_vector.h
src/ptr_vector.h
+33
-32
src/regex.cpp
src/regex.cpp
+41
-56
src/regex.h
src/regex.h
+65
-47
src/regeximpl.h
src/regeximpl.h
+176
-176
src/scanner.cpp
src/scanner.cpp
+364
-374
No files found.
src/contrib/graphbuilderadapter.h
View file @
3355bbb3
#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
...
...
@@ -12,45 +14,41 @@
#include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h"
namespace
YAML
{
class
GraphBuilderAdapter
:
public
EventHandler
{
namespace
YAML
{
class
GraphBuilderAdapter
:
public
EventHandler
{
public:
GraphBuilderAdapter
(
GraphBuilderInterface
&
builder
)
:
m_builder
(
builder
),
m_pRootNode
(
NULL
),
m_pKeyNode
(
NULL
)
{
}
:
m_builder
(
builder
),
m_pRootNode
(
NULL
),
m_pKeyNode
(
NULL
)
{}
virtual
void
OnDocumentStart
(
const
Mark
&
mark
)
{(
void
)
mark
;}
virtual
void
OnDocumentStart
(
const
Mark
&
mark
)
{
(
void
)
mark
;
}
virtual
void
OnDocumentEnd
()
{}
virtual
void
OnNull
(
const
Mark
&
mark
,
anchor_t
anchor
);
virtual
void
OnAlias
(
const
Mark
&
mark
,
anchor_t
anchor
);
virtual
void
OnScalar
(
const
Mark
&
mark
,
const
std
::
string
&
tag
,
anchor_t
anchor
,
const
std
::
string
&
value
);
virtual
void
OnScalar
(
const
Mark
&
mark
,
const
std
::
string
&
tag
,
anchor_t
anchor
,
const
std
::
string
&
value
);
virtual
void
OnSequenceStart
(
const
Mark
&
mark
,
const
std
::
string
&
tag
,
anchor_t
anchor
);
virtual
void
OnSequenceStart
(
const
Mark
&
mark
,
const
std
::
string
&
tag
,
anchor_t
anchor
);
virtual
void
OnSequenceEnd
();
virtual
void
OnMapStart
(
const
Mark
&
mark
,
const
std
::
string
&
tag
,
anchor_t
anchor
);
virtual
void
OnMapStart
(
const
Mark
&
mark
,
const
std
::
string
&
tag
,
anchor_t
anchor
);
virtual
void
OnMapEnd
();
void
*
RootNode
()
const
{
return
m_pRootNode
;}
void
*
RootNode
()
const
{
return
m_pRootNode
;
}
private:
struct
ContainerFrame
{
ContainerFrame
(
void
*
pSequence
)
:
pContainer
(
pSequence
),
pPrevKeyNode
(
&
sequenceMarker
)
{}
ContainerFrame
(
void
*
pMap
,
void
*
pPrevKeyNode
)
:
pContainer
(
pMap
),
pPrevKeyNode
(
pPrevKeyNode
)
{}
struct
ContainerFrame
{
ContainerFrame
(
void
*
pSequence
)
:
pContainer
(
pSequence
),
pPrevKeyNode
(
&
sequenceMarker
)
{}
ContainerFrame
(
void
*
pMap
,
void
*
pPrevKeyNode
)
:
pContainer
(
pMap
),
pPrevKeyNode
(
pPrevKeyNode
)
{}
void
*
pContainer
;
void
*
pPrevKeyNode
;
void
*
pContainer
;
void
*
pPrevKeyNode
;
bool
isMap
()
const
{
return
pPrevKeyNode
!=
&
sequenceMarker
;}
bool
isMap
()
const
{
return
pPrevKeyNode
!=
&
sequenceMarker
;
}
private:
static
int
sequenceMarker
;
...
...
@@ -61,13 +59,13 @@ namespace YAML
GraphBuilderInterface
&
m_builder
;
ContainerStack
m_containers
;
AnchorMap
m_anchors
;
void
*
m_pRootNode
;
void
*
m_pKeyNode
;
void
*
m_pRootNode
;
void
*
m_pKeyNode
;
void
*
GetCurrentParent
()
const
;
void
RegisterAnchor
(
anchor_t
anchor
,
void
*
pNode
);
void
DispositionNode
(
void
*
pNode
);
};
void
*
GetCurrentParent
()
const
;
void
RegisterAnchor
(
anchor_t
anchor
,
void
*
pNode
);
void
DispositionNode
(
void
*
pNode
);
};
}
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/directives.cpp
View file @
3355bbb3
#include "directives.h"
namespace
YAML
{
Directives
::
Directives
()
{
namespace
YAML
{
Directives
::
Directives
()
{
// version
version
.
isDefault
=
true
;
version
.
major
=
1
;
version
.
minor
=
2
;
}
}
const
std
::
string
Directives
::
TranslateTagHandle
(
const
std
::
string
&
handle
)
const
{
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
tags
.
find
(
handle
);
if
(
it
==
tags
.
end
())
{
if
(
handle
==
"!!"
)
const
std
::
string
Directives
::
TranslateTagHandle
(
const
std
::
string
&
handle
)
const
{
std
::
map
<
std
::
string
,
std
::
string
>::
const_iterator
it
=
tags
.
find
(
handle
);
if
(
it
==
tags
.
end
())
{
if
(
handle
==
"!!"
)
return
"tag:yaml.org,2002:"
;
return
handle
;
}
return
it
->
second
;
}
}
}
src/directives.h
View file @
3355bbb3
#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include <string>
#include <map>
namespace
YAML
{
struct
Version
{
namespace
YAML
{
struct
Version
{
bool
isDefault
;
int
major
,
minor
;
};
};
struct
Directives
{
struct
Directives
{
Directives
();
const
std
::
string
TranslateTagHandle
(
const
std
::
string
&
handle
)
const
;
Version
version
;
std
::
map
<
std
::
string
,
std
::
string
>
tags
;
};
};
}
#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/emitfromevents.cpp
View file @
3355bbb3
...
...
@@ -5,83 +5,71 @@
#include <sstream>
namespace
{
std
::
string
ToString
(
YAML
::
anchor_t
anchor
)
{
std
::
string
ToString
(
YAML
::
anchor_t
anchor
)
{
std
::
stringstream
stream
;
stream
<<
anchor
;
return
stream
.
str
();
}
}
}
namespace
YAML
{
EmitFromEvents
::
EmitFromEvents
(
Emitter
&
emitter
)
:
m_emitter
(
emitter
)
{
}
namespace
YAML
{
EmitFromEvents
::
EmitFromEvents
(
Emitter
&
emitter
)
:
m_emitter
(
emitter
)
{}
void
EmitFromEvents
::
OnDocumentStart
(
const
Mark
&
)
{
}
void
EmitFromEvents
::
OnDocumentStart
(
const
Mark
&
)
{}
void
EmitFromEvents
::
OnDocumentEnd
()
{
}
void
EmitFromEvents
::
OnDocumentEnd
()
{}
void
EmitFromEvents
::
OnNull
(
const
Mark
&
,
anchor_t
anchor
)
{
void
EmitFromEvents
::
OnNull
(
const
Mark
&
,
anchor_t
anchor
)
{
BeginNode
();
EmitProps
(
""
,
anchor
);
m_emitter
<<
Null
;
}
}
void
EmitFromEvents
::
OnAlias
(
const
Mark
&
,
anchor_t
anchor
)
{
void
EmitFromEvents
::
OnAlias
(
const
Mark
&
,
anchor_t
anchor
)
{
BeginNode
();
m_emitter
<<
Alias
(
ToString
(
anchor
));
}
}
void
EmitFromEvents
::
OnScalar
(
const
Mark
&
,
const
std
::
string
&
tag
,
anchor_t
anchor
,
const
std
::
string
&
value
)
{
void
EmitFromEvents
::
OnScalar
(
const
Mark
&
,
const
std
::
string
&
tag
,
anchor_t
anchor
,
const
std
::
string
&
value
)
{
BeginNode
();
EmitProps
(
tag
,
anchor
);
m_emitter
<<
value
;
}
}
void
EmitFromEvents
::
OnSequenceStart
(
const
Mark
&
,
const
std
::
string
&
tag
,
anchor_t
anchor
)
{
void
EmitFromEvents
::
OnSequenceStart
(
const
Mark
&
,
const
std
::
string
&
tag
,
anchor_t
anchor
)
{
BeginNode
();
EmitProps
(
tag
,
anchor
);
m_emitter
<<
BeginSeq
;
m_stateStack
.
push
(
State
::
WaitingForSequenceEntry
);
}
}
void
EmitFromEvents
::
OnSequenceEnd
()
{
void
EmitFromEvents
::
OnSequenceEnd
()
{
m_emitter
<<
EndSeq
;
assert
(
m_stateStack
.
top
()
==
State
::
WaitingForSequenceEntry
);
m_stateStack
.
pop
();
}
}
void
EmitFromEvents
::
OnMapStart
(
const
Mark
&
,
const
std
::
string
&
tag
,
anchor_t
anchor
)
{
void
EmitFromEvents
::
OnMapStart
(
const
Mark
&
,
const
std
::
string
&
tag
,
anchor_t
anchor
)
{
BeginNode
();
EmitProps
(
tag
,
anchor
);
m_emitter
<<
BeginMap
;
m_stateStack
.
push
(
State
::
WaitingForKey
);
}
}
void
EmitFromEvents
::
OnMapEnd
()
{
void
EmitFromEvents
::
OnMapEnd
()
{
m_emitter
<<
EndMap
;
assert
(
m_stateStack
.
top
()
==
State
::
WaitingForKey
);
m_stateStack
.
pop
();
}
}
void
EmitFromEvents
::
BeginNode
()
{
if
(
m_stateStack
.
empty
())
void
EmitFromEvents
::
BeginNode
()
{
if
(
m_stateStack
.
empty
())
return
;
switch
(
m_stateStack
.
top
())
{
switch
(
m_stateStack
.
top
())
{
case
State
::
WaitingForKey
:
m_emitter
<<
Key
;
m_stateStack
.
top
()
=
State
::
WaitingForValue
;
...
...
@@ -93,13 +81,12 @@ namespace YAML
default:
break
;
}
}
}
void
EmitFromEvents
::
EmitProps
(
const
std
::
string
&
tag
,
anchor_t
anchor
)
{
if
(
!
tag
.
empty
()
&&
tag
!=
"?"
)
void
EmitFromEvents
::
EmitProps
(
const
std
::
string
&
tag
,
anchor_t
anchor
)
{
if
(
!
tag
.
empty
()
&&
tag
!=
"?"
)
m_emitter
<<
VerbatimTag
(
tag
);
if
(
anchor
)
if
(
anchor
)
m_emitter
<<
Anchor
(
ToString
(
anchor
));
}
}
}
src/emitter.cpp
View file @
3355bbb3
...
...
@@ -5,117 +5,89 @@
#include "yaml-cpp/exceptions.h"
#include <sstream>
namespace
YAML
{
Emitter
::
Emitter
()
:
m_pState
(
new
EmitterState
)
{
}
namespace
YAML
{
Emitter
::
Emitter
()
:
m_pState
(
new
EmitterState
)
{}
Emitter
::
Emitter
(
std
::
ostream
&
stream
)
:
m_pState
(
new
EmitterState
),
m_stream
(
stream
)
{
}
Emitter
::
Emitter
(
std
::
ostream
&
stream
)
:
m_pState
(
new
EmitterState
),
m_stream
(
stream
)
{}
Emitter
::~
Emitter
()
{
}
Emitter
::~
Emitter
()
{}
const
char
*
Emitter
::
c_str
()
const
{
return
m_stream
.
str
();
}
const
char
*
Emitter
::
c_str
()
const
{
return
m_stream
.
str
();
}
std
::
size_t
Emitter
::
size
()
const
{
return
m_stream
.
pos
();
}
std
::
size_t
Emitter
::
size
()
const
{
return
m_stream
.
pos
();
}
// state checking
bool
Emitter
::
good
()
const
{
return
m_pState
->
good
();
}
// state checking
bool
Emitter
::
good
()
const
{
return
m_pState
->
good
();
}
const
std
::
string
Emitter
::
GetLastError
()
const
{
const
std
::
string
Emitter
::
GetLastError
()
const
{
return
m_pState
->
GetLastError
();
}
}
// global setters
bool
Emitter
::
SetOutputCharset
(
EMITTER_MANIP
value
)
{
// global setters
bool
Emitter
::
SetOutputCharset
(
EMITTER_MANIP
value
)
{
return
m_pState
->
SetOutputCharset
(
value
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetStringFormat
(
EMITTER_MANIP
value
)
{
bool
Emitter
::
SetStringFormat
(
EMITTER_MANIP
value
)
{
return
m_pState
->
SetStringFormat
(
value
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetBoolFormat
(
EMITTER_MANIP
value
)
{
bool
Emitter
::
SetBoolFormat
(
EMITTER_MANIP
value
)
{
bool
ok
=
false
;
if
(
m_pState
->
SetBoolFormat
(
value
,
FmtScope
::
Global
))
if
(
m_pState
->
SetBoolFormat
(
value
,
FmtScope
::
Global
))
ok
=
true
;
if
(
m_pState
->
SetBoolCaseFormat
(
value
,
FmtScope
::
Global
))
if
(
m_pState
->
SetBoolCaseFormat
(
value
,
FmtScope
::
Global
))
ok
=
true
;
if
(
m_pState
->
SetBoolLengthFormat
(
value
,
FmtScope
::
Global
))
if
(
m_pState
->
SetBoolLengthFormat
(
value
,
FmtScope
::
Global
))
ok
=
true
;
return
ok
;
}
}
bool
Emitter
::
SetIntBase
(
EMITTER_MANIP
value
)
{
bool
Emitter
::
SetIntBase
(
EMITTER_MANIP
value
)
{
return
m_pState
->
SetIntFormat
(
value
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetSeqFormat
(
EMITTER_MANIP
value
)
{
bool
Emitter
::
SetSeqFormat
(
EMITTER_MANIP
value
)
{
return
m_pState
->
SetFlowType
(
GroupType
::
Seq
,
value
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetMapFormat
(
EMITTER_MANIP
value
)
{
bool
Emitter
::
SetMapFormat
(
EMITTER_MANIP
value
)
{
bool
ok
=
false
;
if
(
m_pState
->
SetFlowType
(
GroupType
::
Map
,
value
,
FmtScope
::
Global
))
if
(
m_pState
->
SetFlowType
(
GroupType
::
Map
,
value
,
FmtScope
::
Global
))
ok
=
true
;
if
(
m_pState
->
SetMapKeyFormat
(
value
,
FmtScope
::
Global
))
if
(
m_pState
->
SetMapKeyFormat
(
value
,
FmtScope
::
Global
))
ok
=
true
;
return
ok
;
}
}
bool
Emitter
::
SetIndent
(
unsigned
n
)
{
bool
Emitter
::
SetIndent
(
unsigned
n
)
{
return
m_pState
->
SetIndent
(
n
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetPreCommentIndent
(
unsigned
n
)
{
bool
Emitter
::
SetPreCommentIndent
(
unsigned
n
)
{
return
m_pState
->
SetPreCommentIndent
(
n
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetPostCommentIndent
(
unsigned
n
)
{
bool
Emitter
::
SetPostCommentIndent
(
unsigned
n
)
{
return
m_pState
->
SetPostCommentIndent
(
n
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetFloatPrecision
(
unsigned
n
)
{
bool
Emitter
::
SetFloatPrecision
(
unsigned
n
)
{
return
m_pState
->
SetFloatPrecision
(
n
,
FmtScope
::
Global
);
}
}
bool
Emitter
::
SetDoublePrecision
(
unsigned
n
)
{
bool
Emitter
::
SetDoublePrecision
(
unsigned
n
)
{
return
m_pState
->
SetDoublePrecision
(
n
,
FmtScope
::
Global
);
}
}
// SetLocalValue
// . Either start/end a group, or set a modifier locally
Emitter
&
Emitter
::
SetLocalValue
(
EMITTER_MANIP
value
)
{
if
(
!
good
())
// SetLocalValue
// . Either start/end a group, or set a modifier locally
Emitter
&
Emitter
::
SetLocalValue
(
EMITTER_MANIP
value
)
{
if
(
!
good
())
return
*
this
;
switch
(
value
)
{
switch
(
value
)
{
case
BeginDoc
:
EmitBeginDoc
();
break
;
...
...
@@ -149,152 +121,139 @@ namespace YAML
break
;
}
return
*
this
;
}
}
Emitter
&
Emitter
::
SetLocalIndent
(
const
_Indent
&
indent
)
{
Emitter
&
Emitter
::
SetLocalIndent
(
const
_Indent
&
indent
)
{
m_pState
->
SetIndent
(
indent
.
value
,
FmtScope
::
Local
);
return
*
this
;
}
}
Emitter
&
Emitter
::
SetLocalPrecision
(
const
_Precision
&
precision
)
{
if
(
precision
.
floatPrecision
>=
0
)
Emitter
&
Emitter
::
SetLocalPrecision
(
const
_Precision
&
precision
)
{
if
(
precision
.
floatPrecision
>=
0
)
m_pState
->
SetFloatPrecision
(
precision
.
floatPrecision
,
FmtScope
::
Local
);
if
(
precision
.
doublePrecision
>=
0
)
if
(
precision
.
doublePrecision
>=
0
)
m_pState
->
SetDoublePrecision
(
precision
.
doublePrecision
,
FmtScope
::
Local
);
return
*
this
;
}
}
// EmitBeginDoc
void
Emitter
::
EmitBeginDoc
()
{
if
(
!
good
())
// EmitBeginDoc
void
Emitter
::
EmitBeginDoc
()
{
if
(
!
good
())
return
;
if
(
m_pState
->
CurGroupType
()
!=
GroupType
::
None
)
{
if
(
m_pState
->
CurGroupType
()
!=
GroupType
::
None
)
{
m_pState
->
SetError
(
"Unexpected begin document"
);
return
;
}
if
(
m_pState
->
HasAnchor
()
||
m_pState
->
HasTag
())
{
if
(
m_pState
->
HasAnchor
()
||
m_pState
->
HasTag
())
{
m_pState
->
SetError
(
"Unexpected begin document"
);
return
;
}
if
(
m_stream
.
col
()
>
0
)
if
(
m_stream
.
col
()
>
0
)
m_stream
<<
"
\n
"
;
m_stream
<<
"---
\n
"
;
m_pState
->
StartedDoc
();
}
}
// EmitEndDoc
void
Emitter
::
EmitEndDoc
()
{
if
(
!
good
())
// EmitEndDoc
void
Emitter
::
EmitEndDoc
()
{
if
(
!
good
())
return
;
if
(
m_pState
->
CurGroupType
()
!=
GroupType
::
None
)
{
if
(
m_pState
->
CurGroupType
()
!=
GroupType
::
None
)
{
m_pState
->
SetError
(
"Unexpected begin document"
);
return
;
}
if
(
m_pState
->
HasAnchor
()
||
m_pState
->
HasTag
())
{
if
(
m_pState
->
HasAnchor
()
||
m_pState
->
HasTag
())
{
m_pState
->
SetError
(
"Unexpected begin document"
);
return
;
}
if
(
m_stream
.
col
()
>
0
)
if
(
m_stream
.
col
()
>
0
)
m_stream
<<
"
\n
"
;
m_stream
<<
"...
\n
"
;
}
}
// EmitBeginSeq
void
Emitter
::
EmitBeginSeq
()
{
if
(
!
good
())
// EmitBeginSeq
void
Emitter
::
EmitBeginSeq
()
{
if
(
!
good
())
return
;
PrepareNode
(
m_pState
->
NextGroupType
(
GroupType
::
Seq
));
m_pState
->
StartedGroup
(
GroupType
::
Seq
);
}
}
// EmitEndSeq
void
Emitter
::
EmitEndSeq
()
{
if
(
!
good
())
// EmitEndSeq
void
Emitter
::
EmitEndSeq
()
{
if
(
!
good
())
return
;
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
m_pState
->
ForceFlow
();
if
(
m_pState
->
CurGroupFlowType
()
==
FlowType
::
Flow
)
{
if
(
m_stream
.
comment
())
if
(
m_pState
->
CurGroupFlowType
()
==
FlowType
::
Flow
)
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
m_pState
->
CurIndent
());
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
m_stream
<<
"["
;
m_stream
<<
"]"
;
}
m_pState
->
EndedGroup
(
GroupType
::
Seq
);
}
}
// EmitBeginMap
void
Emitter
::
EmitBeginMap
()
{
if
(
!
good
())
// EmitBeginMap
void
Emitter
::
EmitBeginMap
()
{
if
(
!
good
())
return
;
PrepareNode
(
m_pState
->
NextGroupType
(
GroupType
::
Map
));
m_pState
->
StartedGroup
(
GroupType
::
Map
);
}
}
// EmitEndMap
void
Emitter
::
EmitEndMap
()
{
if
(
!
good
())
// EmitEndMap
void
Emitter
::
EmitEndMap
()
{
if
(
!
good
())
return
;
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
m_pState
->
ForceFlow
();
if
(
m_pState
->
CurGroupFlowType
()
==
FlowType
::
Flow
)
{
if
(
m_stream
.
comment
())
if
(
m_pState
->
CurGroupFlowType
()
==
FlowType
::
Flow
)
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
m_pState
->
CurIndent
());
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
m_stream
<<
"{"
;
m_stream
<<
"}"
;
}
m_pState
->
EndedGroup
(
GroupType
::
Map
);
}
}
// EmitNewline
void
Emitter
::
EmitNewline
()
{
if
(
!
good
())
// EmitNewline
void
Emitter
::
EmitNewline
()
{
if
(
!
good
())
return
;
PrepareNode
(
EmitterNodeType
::
None
);
m_stream
<<
"
\n
"
;
m_pState
->
SetNonContent
();
}
}
bool
Emitter
::
CanEmitNewline
()
const
{
return
true
;
}
bool
Emitter
::
CanEmitNewline
()
const
{
return
true
;
}
// Put the stream in a state so we can simply write the next node
// E.g., if we're in a sequence, write the "- "
void
Emitter
::
PrepareNode
(
EmitterNodeType
::
value
child
)
{
switch
(
m_pState
->
CurGroupNodeType
())
{
// Put the stream in a state so we can simply write the next node
// E.g., if we're in a sequence, write the "- "
void
Emitter
::
PrepareNode
(
EmitterNodeType
::
value
child
)
{
switch
(
m_pState
->
CurGroupNodeType
())
{
case
EmitterNodeType
::
None
:
PrepareTopNode
(
child
);
break
;
...
...
@@ -315,19 +274,18 @@ namespace YAML
assert
(
false
);
break
;
}
}
}
void
Emitter
::
PrepareTopNode
(
EmitterNodeType
::
value
child
)
{
if
(
child
==
EmitterNodeType
::
None
)
void
Emitter
::
PrepareTopNode
(
EmitterNodeType
::
value
child
)
{
if
(
child
==
EmitterNodeType
::
None
)
return
;
if
(
m_pState
->
CurGroupChildCount
()
>
0
&&
m_stream
.
col
()
>
0
)
{
if
(
child
!=
EmitterNodeType
::
None
)
if
(
m_pState
->
CurGroupChildCount
()
>
0
&&
m_stream
.
col
()
>
0
)
{
if
(
child
!=
EmitterNodeType
::
None
)
EmitBeginDoc
();
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
...
...
@@ -340,59 +298,59 @@ namespace YAML
break
;
case
EmitterNodeType
::
BlockSeq
:
case
EmitterNodeType
::
BlockMap
:
if
(
m_pState
->
HasBegunNode
())
if
(
m_pState
->
HasBegunNode
())
m_stream
<<
"
\n
"
;
break
;
}
}
}
void
Emitter
::
FlowSeqPrepareNode
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
FlowSeqPrepareNode
(
EmitterNodeType
::
value
child
)
{
const
unsigned
lastIndent
=
m_pState
->
LastIndent
();
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
lastIndent
);
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
m_stream
<<
"["
;
else
m_stream
<<
","
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
case
EmitterNodeType
::
Scalar
:
case
EmitterNodeType
::
FlowSeq
:
case
EmitterNodeType
::
FlowMap
:
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
break
;
case
EmitterNodeType
::
BlockSeq
:
case
EmitterNodeType
::
BlockMap
:
assert
(
false
);
break
;
}
}
}
void
Emitter
::
BlockSeqPrepareNode
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
BlockSeqPrepareNode
(
EmitterNodeType
::
value
child
)
{
const
unsigned
curIndent
=
m_pState
->
CurIndent
();
const
unsigned
nextIndent
=
curIndent
+
m_pState
->
CurGroupIndent
();
if
(
child
==
EmitterNodeType
::
None
)
if
(
child
==
EmitterNodeType
::
None
)
return
;
if
(
!
m_pState
->
HasBegunContent
())
{
if
(
m_pState
->
CurGroupChildCount
()
>
0
||
m_stream
.
comment
())
{
if
(
!
m_pState
->
HasBegunContent
())
{
if
(
m_pState
->
CurGroupChildCount
()
>
0
||
m_stream
.
comment
())
{
m_stream
<<
"
\n
"
;
}
m_stream
<<
IndentTo
(
curIndent
);
m_stream
<<
"-"
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
...
...
@@ -405,184 +363,186 @@ namespace YAML
m_stream
<<
"
\n
"
;
break
;
case
EmitterNodeType
::
BlockMap
:
if
(
m_pState
->
HasBegunContent
()
||
m_stream
.
comment
())
if
(
m_pState
->
HasBegunContent
()
||
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
break
;
}
}
}
void
Emitter
::
FlowMapPrepareNode
(
EmitterNodeType
::
value
child
)
{
if
(
m_pState
->
CurGroupChildCount
()
%
2
==
0
)
{
if
(
m_pState
->
GetMapKeyFormat
()
==
LongKey
)
void
Emitter
::
FlowMapPrepareNode
(
EmitterNodeType
::
value
child
)
{
if
(
m_pState
->
CurGroupChildCount
()
%
2
==
0
)
{
if
(
m_pState
->
GetMapKeyFormat
()
==
LongKey
)
m_pState
->
SetLongKey
();
if
(
m_pState
->
CurGroupLongKey
())
if
(
m_pState
->
CurGroupLongKey
())
FlowMapPrepareLongKey
(
child
);
else
FlowMapPrepareSimpleKey
(
child
);
}
else
{
if
(
m_pState
->
CurGroupLongKey
())
if
(
m_pState
->
CurGroupLongKey
())
FlowMapPrepareLongKeyValue
(
child
);
else
FlowMapPrepareSimpleKeyValue
(
child
);
}
}
}
void
Emitter
::
FlowMapPrepareLongKey
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
FlowMapPrepareLongKey
(
EmitterNodeType
::
value
child
)
{
const
unsigned
lastIndent
=
m_pState
->
LastIndent
();
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
lastIndent
);
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
m_stream
<<
"{ ?"
;
else
m_stream
<<
", ?"
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
case
EmitterNodeType
::
Scalar
:
case
EmitterNodeType
::
FlowSeq
:
case
EmitterNodeType
::
FlowMap
:
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
break
;
case
EmitterNodeType
::
BlockSeq
:
case
EmitterNodeType
::
BlockMap
:
assert
(
false
);
break
;
}
}
}
void
Emitter
::
FlowMapPrepareLongKeyValue
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
FlowMapPrepareLongKeyValue
(
EmitterNodeType
::
value
child
)
{
const
unsigned
lastIndent
=
m_pState
->
LastIndent
();
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
lastIndent
);
m_stream
<<
":"
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
case
EmitterNodeType
::
Scalar
:
case
EmitterNodeType
::
FlowSeq
:
case
EmitterNodeType
::
FlowMap
:
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
break
;
case
EmitterNodeType
::
BlockSeq
:
case
EmitterNodeType
::
BlockMap
:
assert
(
false
);
break
;
}
}
}
void
Emitter
::
FlowMapPrepareSimpleKey
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
FlowMapPrepareSimpleKey
(
EmitterNodeType
::
value
child
)
{
const
unsigned
lastIndent
=
m_pState
->
LastIndent
();
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
lastIndent
);
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
if
(
m_pState
->
CurGroupChildCount
()
==
0
)
m_stream
<<
"{"
;
else
m_stream
<<
","
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
case
EmitterNodeType
::
Scalar
:
case
EmitterNodeType
::
FlowSeq
:
case
EmitterNodeType
::
FlowMap
:
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
break
;
case
EmitterNodeType
::
BlockSeq
:
case
EmitterNodeType
::
BlockMap
:
assert
(
false
);
break
;
}
}
}
void
Emitter
::
FlowMapPrepareSimpleKeyValue
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
FlowMapPrepareSimpleKeyValue
(
EmitterNodeType
::
value
child
)
{
const
unsigned
lastIndent
=
m_pState
->
LastIndent
();
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
lastIndent
);
m_stream
<<
":"
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
case
EmitterNodeType
::
Scalar
:
case
EmitterNodeType
::
FlowSeq
:
case
EmitterNodeType
::
FlowMap
:
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
SpaceOrIndentTo
(
m_pState
->
HasBegunContent
()
||
m_pState
->
CurGroupChildCount
()
>
0
,
lastIndent
);
break
;
case
EmitterNodeType
::
BlockSeq
:
case
EmitterNodeType
::
BlockMap
:
assert
(
false
);
break
;
}
}
}
void
Emitter
::
BlockMapPrepareNode
(
EmitterNodeType
::
value
child
)
{
if
(
m_pState
->
CurGroupChildCount
()
%
2
==
0
)
{
if
(
m_pState
->
GetMapKeyFormat
()
==
LongKey
)
void
Emitter
::
BlockMapPrepareNode
(
EmitterNodeType
::
value
child
)
{
if
(
m_pState
->
CurGroupChildCount
()
%
2
==
0
)
{
if
(
m_pState
->
GetMapKeyFormat
()
==
LongKey
)
m_pState
->
SetLongKey
();
if
(
child
==
EmitterNodeType
::
BlockSeq
||
child
==
EmitterNodeType
::
BlockMap
)
if
(
child
==
EmitterNodeType
::
BlockSeq
||
child
==
EmitterNodeType
::
BlockMap
)
m_pState
->
SetLongKey
();
if
(
m_pState
->
CurGroupLongKey
())
if
(
m_pState
->
CurGroupLongKey
())
BlockMapPrepareLongKey
(
child
);
else
BlockMapPrepareSimpleKey
(
child
);
}
else
{
if
(
m_pState
->
CurGroupLongKey
())
if
(
m_pState
->
CurGroupLongKey
())
BlockMapPrepareLongKeyValue
(
child
);
else
BlockMapPrepareSimpleKeyValue
(
child
);
}
}
}
void
Emitter
::
BlockMapPrepareLongKey
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
BlockMapPrepareLongKey
(
EmitterNodeType
::
value
child
)
{
const
unsigned
curIndent
=
m_pState
->
CurIndent
();
const
std
::
size_t
childCount
=
m_pState
->
CurGroupChildCount
();
if
(
child
==
EmitterNodeType
::
None
)
if
(
child
==
EmitterNodeType
::
None
)
return
;
if
(
!
m_pState
->
HasBegunContent
())
{
if
(
childCount
>
0
)
{
if
(
!
m_pState
->
HasBegunContent
())
{
if
(
childCount
>
0
)
{
m_stream
<<
"
\n
"
;
}
if
(
m_stream
.
comment
())
{
if
(
m_stream
.
comment
())
{
m_stream
<<
"
\n
"
;
}
m_stream
<<
IndentTo
(
curIndent
);
m_stream
<<
"?"
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
...
...
@@ -595,22 +555,21 @@ namespace YAML
case
EmitterNodeType
::
BlockMap
:
break
;
}
}
}
void
Emitter
::
BlockMapPrepareLongKeyValue
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
BlockMapPrepareLongKeyValue
(
EmitterNodeType
::
value
child
)
{
const
unsigned
curIndent
=
m_pState
->
CurIndent
();
if
(
child
==
EmitterNodeType
::
None
)
if
(
child
==
EmitterNodeType
::
None
)
return
;
if
(
!
m_pState
->
HasBegunContent
())
{
if
(
!
m_pState
->
HasBegunContent
())
{
m_stream
<<
"
\n
"
;
m_stream
<<
IndentTo
(
curIndent
);
m_stream
<<
":"
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
...
...
@@ -622,23 +581,22 @@ namespace YAML
SpaceOrIndentTo
(
true
,
curIndent
+
1
);
break
;
}
}
}
void
Emitter
::
BlockMapPrepareSimpleKey
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
BlockMapPrepareSimpleKey
(
EmitterNodeType
::
value
child
)
{
const
unsigned
curIndent
=
m_pState
->
CurIndent
();
const
std
::
size_t
childCount
=
m_pState
->
CurGroupChildCount
();
if
(
child
==
EmitterNodeType
::
None
)
if
(
child
==
EmitterNodeType
::
None
)
return
;
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
childCount
>
0
)
{
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
childCount
>
0
)
{
m_stream
<<
"
\n
"
;
}
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
...
...
@@ -651,18 +609,17 @@ namespace YAML
case
EmitterNodeType
::
BlockMap
:
break
;
}
}
}
void
Emitter
::
BlockMapPrepareSimpleKeyValue
(
EmitterNodeType
::
value
child
)
{
void
Emitter
::
BlockMapPrepareSimpleKeyValue
(
EmitterNodeType
::
value
child
)
{
const
unsigned
curIndent
=
m_pState
->
CurIndent
();
const
unsigned
nextIndent
=
curIndent
+
m_pState
->
CurGroupIndent
();
if
(
!
m_pState
->
HasBegunNode
())
{
if
(
!
m_pState
->
HasBegunNode
())
{
m_stream
<<
":"
;
}
switch
(
child
)
{
switch
(
child
)
{
case
EmitterNodeType
::
None
:
break
;
case
EmitterNodeType
::
Property
:
...
...
@@ -676,23 +633,21 @@ namespace YAML
m_stream
<<
"
\n
"
;
break
;
}
}
}
// SpaceOrIndentTo
// . Prepares for some more content by proper spacing
void
Emitter
::
SpaceOrIndentTo
(
bool
requireSpace
,
unsigned
indent
)
{
if
(
m_stream
.
comment
())
// SpaceOrIndentTo
// . Prepares for some more content by proper spacing
void
Emitter
::
SpaceOrIndentTo
(
bool
requireSpace
,
unsigned
indent
)
{
if
(
m_stream
.
comment
())
m_stream
<<
"
\n
"
;
if
(
m_stream
.
col
()
>
0
&&
requireSpace
)
if
(
m_stream
.
col
()
>
0
&&
requireSpace
)
m_stream
<<
" "
;
m_stream
<<
IndentTo
(
indent
);
}
}
void
Emitter
::
PrepareIntegralStream
(
std
::
stringstream
&
stream
)
const
{
void
Emitter
::
PrepareIntegralStream
(
std
::
stringstream
&
stream
)
const
{
switch
(
m_pState
->
GetIntFormat
())
{
switch
(
m_pState
->
GetIntFormat
())
{
case
Dec
:
stream
<<
std
::
dec
;
break
;
...
...
@@ -707,30 +662,28 @@ namespace YAML
default:
assert
(
false
);
}
}
}
void
Emitter
::
StartedScalar
()
{
m_pState
->
StartedScalar
();
}
void
Emitter
::
StartedScalar
()
{
m_pState
->
StartedScalar
();
}
// *******************************************************************************************
// overloads of Write
// *******************************************************************************************
// overloads of Write
Emitter
&
Emitter
::
Write
(
const
std
::
string
&
str
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
const
std
::
string
&
str
)
{
if
(
!
good
())
return
*
this
;
const
bool
escapeNonAscii
=
m_pState
->
GetOutputCharset
()
==
EscapeNonAscii
;
const
StringFormat
::
value
strFormat
=
Utils
::
ComputeStringFormat
(
str
,
m_pState
->
GetStringFormat
(),
m_pState
->
CurGroupFlowType
(),
escapeNonAscii
);
const
StringFormat
::
value
strFormat
=
Utils
::
ComputeStringFormat
(
str
,
m_pState
->
GetStringFormat
(),
m_pState
->
CurGroupFlowType
(),
escapeNonAscii
);
if
(
strFormat
==
StringFormat
::
Literal
)
if
(
strFormat
==
StringFormat
::
Literal
)
m_pState
->
SetMapKeyFormat
(
YAML
::
LongKey
,
FmtScope
::
Local
);
PrepareNode
(
EmitterNodeType
::
Scalar
);
switch
(
strFormat
)
{
switch
(
strFormat
)
{
case
StringFormat
::
Plain
:
m_stream
<<
str
;
break
;
...
...
@@ -741,69 +694,81 @@ namespace YAML
Utils
::
WriteDoubleQuotedString
(
m_stream
,
str
,
escapeNonAscii
);
break
;
case
StringFormat
::
Literal
:
Utils
::
WriteLiteralString
(
m_stream
,
str
,
m_pState
->
CurIndent
()
+
m_pState
->
GetIndent
());
Utils
::
WriteLiteralString
(
m_stream
,
str
,
m_pState
->
CurIndent
()
+
m_pState
->
GetIndent
());
break
;
}
StartedScalar
();
return
*
this
;
}
}
unsigned
Emitter
::
GetFloatPrecision
()
const
{
unsigned
Emitter
::
GetFloatPrecision
()
const
{
return
m_pState
->
GetFloatPrecision
();
}
}
unsigned
Emitter
::
GetDoublePrecision
()
const
{
unsigned
Emitter
::
GetDoublePrecision
()
const
{
return
m_pState
->
GetDoublePrecision
();
}
}
const
char
*
Emitter
::
ComputeFullBoolName
(
bool
b
)
const
{
const
EMITTER_MANIP
mainFmt
=
(
m_pState
->
GetBoolLengthFormat
()
==
ShortBool
?
YesNoBool
:
m_pState
->
GetBoolFormat
());
const
char
*
Emitter
::
ComputeFullBoolName
(
bool
b
)
const
{
const
EMITTER_MANIP
mainFmt
=
(
m_pState
->
GetBoolLengthFormat
()
==
ShortBool
?
YesNoBool
:
m_pState
->
GetBoolFormat
());
const
EMITTER_MANIP
caseFmt
=
m_pState
->
GetBoolCaseFormat
();
switch
(
mainFmt
)
{
switch
(
mainFmt
)
{
case
YesNoBool
:
switch
(
caseFmt
)
{
case
UpperCase
:
return
b
?
"YES"
:
"NO"
;
case
CamelCase
:
return
b
?
"Yes"
:
"No"
;
case
LowerCase
:
return
b
?
"yes"
:
"no"
;
default:
break
;
switch
(
caseFmt
)
{
case
UpperCase
:
return
b
?
"YES"
:
"NO"
;
case
CamelCase
:
return
b
?
"Yes"
:
"No"
;
case
LowerCase
:
return
b
?
"yes"
:
"no"
;
default:
break
;
}
break
;
case
OnOffBool
:
switch
(
caseFmt
)
{
case
UpperCase
:
return
b
?
"ON"
:
"OFF"
;
case
CamelCase
:
return
b
?
"On"
:
"Off"
;
case
LowerCase
:
return
b
?
"on"
:
"off"
;
default:
break
;
switch
(
caseFmt
)
{
case
UpperCase
:
return
b
?
"ON"
:
"OFF"
;
case
CamelCase
:
return
b
?
"On"
:
"Off"
;
case
LowerCase
:
return
b
?
"on"
:
"off"
;
default:
break
;
}
break
;
case
TrueFalseBool
:
switch
(
caseFmt
)
{
case
UpperCase
:
return
b
?
"TRUE"
:
"FALSE"
;
case
CamelCase
:
return
b
?
"True"
:
"False"
;
case
LowerCase
:
return
b
?
"true"
:
"false"
;
default:
break
;
switch
(
caseFmt
)
{
case
UpperCase
:
return
b
?
"TRUE"
:
"FALSE"
;
case
CamelCase
:
return
b
?
"True"
:
"False"
;
case
LowerCase
:
return
b
?
"true"
:
"false"
;
default:
break
;
}
break
;
default:
break
;
}
return
b
?
"y"
:
"n"
;
// should never get here, but it can't hurt to give these answers
}
return
b
?
"y"
:
"n"
;
// should never get here, but it can't hurt to give
// these answers
}
Emitter
&
Emitter
::
Write
(
bool
b
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
bool
b
)
{
if
(
!
good
())
return
*
this
;
PrepareNode
(
EmitterNodeType
::
Scalar
);
const
char
*
name
=
ComputeFullBoolName
(
b
);
if
(
m_pState
->
GetBoolLengthFormat
()
==
ShortBool
)
const
char
*
name
=
ComputeFullBoolName
(
b
);
if
(
m_pState
->
GetBoolLengthFormat
()
==
ShortBool
)
m_stream
<<
name
[
0
];
else
m_stream
<<
name
;
...
...
@@ -811,11 +776,10 @@ namespace YAML
StartedScalar
();
return
*
this
;
}
}
Emitter
&
Emitter
::
Write
(
char
ch
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
char
ch
)
{
if
(
!
good
())
return
*
this
;
PrepareNode
(
EmitterNodeType
::
Scalar
);
...
...
@@ -823,21 +787,20 @@ namespace YAML
StartedScalar
();
return
*
this
;
}
}
Emitter
&
Emitter
::
Write
(
const
_Alias
&
alias
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
const
_Alias
&
alias
)
{
if
(
!
good
())
return
*
this
;
if
(
m_pState
->
HasAnchor
()
||
m_pState
->
HasTag
())
{
if
(
m_pState
->
HasAnchor
()
||
m_pState
->
HasTag
())
{
m_pState
->
SetError
(
ErrorMsg
::
INVALID_ALIAS
);
return
*
this
;
}
PrepareNode
(
EmitterNodeType
::
Scalar
);
if
(
!
Utils
::
WriteAlias
(
m_stream
,
alias
.
content
))
{
if
(
!
Utils
::
WriteAlias
(
m_stream
,
alias
.
content
))
{
m_pState
->
SetError
(
ErrorMsg
::
INVALID_ALIAS
);
return
*
this
;
}
...
...
@@ -845,21 +808,20 @@ namespace YAML
StartedScalar
();
return
*
this
;
}
}
Emitter
&
Emitter
::
Write
(
const
_Anchor
&
anchor
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
const
_Anchor
&
anchor
)
{
if
(
!
good
())
return
*
this
;
if
(
m_pState
->
HasAnchor
())
{
if
(
m_pState
->
HasAnchor
())
{
m_pState
->
SetError
(
ErrorMsg
::
INVALID_ANCHOR
);
return
*
this
;
}
PrepareNode
(
EmitterNodeType
::
Property
);
if
(
!
Utils
::
WriteAnchor
(
m_stream
,
anchor
.
content
))
{
if
(
!
Utils
::
WriteAnchor
(
m_stream
,
anchor
.
content
))
{
m_pState
->
SetError
(
ErrorMsg
::
INVALID_ANCHOR
);
return
*
this
;
}
...
...
@@ -867,14 +829,13 @@ namespace YAML
m_pState
->
SetAnchor
();
return
*
this
;
}
}
Emitter
&
Emitter
::
Write
(
const
_Tag
&
tag
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
const
_Tag
&
tag
)
{
if
(
!
good
())
return
*
this
;
if
(
m_pState
->
HasTag
())
{
if
(
m_pState
->
HasTag
())
{
m_pState
->
SetError
(
ErrorMsg
::
INVALID_TAG
);
return
*
this
;
}
...
...
@@ -882,14 +843,14 @@ namespace YAML
PrepareNode
(
EmitterNodeType
::
Property
);
bool
success
=
false
;
if
(
tag
.
type
==
_Tag
::
Type
::
Verbatim
)
if
(
tag
.
type
==
_Tag
::
Type
::
Verbatim
)
success
=
Utils
::
WriteTag
(
m_stream
,
tag
.
content
,
true
);
else
if
(
tag
.
type
==
_Tag
::
Type
::
PrimaryHandle
)
else
if
(
tag
.
type
==
_Tag
::
Type
::
PrimaryHandle
)
success
=
Utils
::
WriteTag
(
m_stream
,
tag
.
content
,
false
);
else
success
=
Utils
::
WriteTagWithPrefix
(
m_stream
,
tag
.
prefix
,
tag
.
content
);
if
(
!
success
)
{
if
(
!
success
)
{
m_pState
->
SetError
(
ErrorMsg
::
INVALID_TAG
);
return
*
this
;
}
...
...
@@ -897,32 +858,28 @@ namespace YAML
m_pState
->
SetTag
();
return
*
this
;
}
}
void
Emitter
::
EmitKindTag
()
{
Write
(
LocalTag
(
""
));
}
void
Emitter
::
EmitKindTag
()
{
Write
(
LocalTag
(
""
));
}
Emitter
&
Emitter
::
Write
(
const
_Comment
&
comment
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
const
_Comment
&
comment
)
{
if
(
!
good
())
return
*
this
;
PrepareNode
(
EmitterNodeType
::
None
);
if
(
m_stream
.
col
()
>
0
)
if
(
m_stream
.
col
()
>
0
)
m_stream
<<
Indentation
(
m_pState
->
GetPreCommentIndent
());
Utils
::
WriteComment
(
m_stream
,
comment
.
content
,
m_pState
->
GetPostCommentIndent
());
Utils
::
WriteComment
(
m_stream
,
comment
.
content
,
m_pState
->
GetPostCommentIndent
());
m_pState
->
SetNonContent
();
return
*
this
;
}
}
Emitter
&
Emitter
::
Write
(
const
_Null
&
/*null*/
)
{
if
(
!
good
())
Emitter
&
Emitter
::
Write
(
const
_Null
&
/*null*/
)
{
if
(
!
good
())
return
*
this
;
PrepareNode
(
EmitterNodeType
::
Scalar
);
...
...
@@ -932,13 +889,12 @@ namespace YAML
StartedScalar
();
return
*
this
;
}
}
Emitter
&
Emitter
::
Write
(
const
Binary
&
binary
)
{
Emitter
&
Emitter
::
Write
(
const
Binary
&
binary
)
{
Write
(
SecondaryTag
(
"binary"
));
if
(
!
good
())
if
(
!
good
())
return
*
this
;
PrepareNode
(
EmitterNodeType
::
Scalar
);
...
...
@@ -946,6 +902,5 @@ namespace YAML
StartedScalar
();
return
*
this
;
}
}
}
src/emitterstate.cpp
View file @
3355bbb3
...
...
@@ -2,10 +2,14 @@
#include "yaml-cpp/exceptions.h"
#include <limits>
namespace
YAML
{
EmitterState
::
EmitterState
()
:
m_isGood
(
true
),
m_curIndent
(
0
),
m_hasAnchor
(
false
),
m_hasTag
(
false
),
m_hasNonContent
(
false
),
m_docCount
(
0
)
{
namespace
YAML
{
EmitterState
::
EmitterState
()
:
m_isGood
(
true
),
m_curIndent
(
0
),
m_hasAnchor
(
false
),
m_hasTag
(
false
),
m_hasNonContent
(
false
),
m_docCount
(
0
)
{
// set default global manipulators
m_charset
.
set
(
EmitNonAscii
);
m_strFmt
.
set
(
Auto
);
...
...
@@ -21,17 +25,14 @@ namespace YAML
m_mapKeyFmt
.
set
(
Auto
);
m_floatPrecision
.
set
(
std
::
numeric_limits
<
float
>::
digits10
+
1
);
m_doublePrecision
.
set
(
std
::
numeric_limits
<
double
>::
digits10
+
1
);
}
}
EmitterState
::~
EmitterState
()
{
}
EmitterState
::~
EmitterState
()
{}
// SetLocalValue
// . We blindly tries to set all possible formatters to this value
// . Only the ones that make sense will be accepted
void
EmitterState
::
SetLocalValue
(
EMITTER_MANIP
value
)
{
// SetLocalValue
// . We blindly tries to set all possible formatters to this value
// . Only the ones that make sense will be accepted
void
EmitterState
::
SetLocalValue
(
EMITTER_MANIP
value
)
{
SetOutputCharset
(
value
,
FmtScope
::
Local
);
SetStringFormat
(
value
,
FmtScope
::
Local
);
SetBoolFormat
(
value
,
FmtScope
::
Local
);
...
...
@@ -41,66 +42,54 @@ namespace YAML
SetFlowType
(
GroupType
::
Seq
,
value
,
FmtScope
::
Local
);
SetFlowType
(
GroupType
::
Map
,
value
,
FmtScope
::
Local
);
SetMapKeyFormat
(
value
,
FmtScope
::
Local
);
}
}
void
EmitterState
::
SetAnchor
()
{
m_hasAnchor
=
true
;
}
void
EmitterState
::
SetAnchor
()
{
m_hasAnchor
=
true
;
}
void
EmitterState
::
SetTag
()
{
m_hasTag
=
true
;
}
void
EmitterState
::
SetTag
()
{
m_hasTag
=
true
;
}
void
EmitterState
::
SetNonContent
()
{
m_hasNonContent
=
true
;
}
void
EmitterState
::
SetNonContent
()
{
m_hasNonContent
=
true
;
}
void
EmitterState
::
SetLongKey
()
{
void
EmitterState
::
SetLongKey
()
{
assert
(
!
m_groups
.
empty
());
if
(
m_groups
.
empty
())
if
(
m_groups
.
empty
())
return
;
assert
(
m_groups
.
top
().
type
==
GroupType
::
Map
);
m_groups
.
top
().
longKey
=
true
;
}
}
void
EmitterState
::
ForceFlow
()
{
void
EmitterState
::
ForceFlow
()
{
assert
(
!
m_groups
.
empty
());
if
(
m_groups
.
empty
())
if
(
m_groups
.
empty
())
return
;
m_groups
.
top
().
flowType
=
FlowType
::
Flow
;
}
}
void
EmitterState
::
StartedNode
()
{
if
(
m_groups
.
empty
())
{
void
EmitterState
::
StartedNode
()
{
if
(
m_groups
.
empty
())
{
m_docCount
++
;
}
else
{
m_groups
.
top
().
childCount
++
;
if
(
m_groups
.
top
().
childCount
%
2
==
0
)
if
(
m_groups
.
top
().
childCount
%
2
==
0
)
m_groups
.
top
().
longKey
=
false
;
}
m_hasAnchor
=
false
;
m_hasTag
=
false
;
m_hasNonContent
=
false
;
}
}
EmitterNodeType
::
value
EmitterState
::
NextGroupType
(
GroupType
::
value
type
)
const
{
if
(
type
==
GroupType
::
Seq
)
{
if
(
GetFlowType
(
type
)
==
Block
)
EmitterNodeType
::
value
EmitterState
::
NextGroupType
(
GroupType
::
value
type
)
const
{
if
(
type
==
GroupType
::
Seq
)
{
if
(
GetFlowType
(
type
)
==
Block
)
return
EmitterNodeType
::
BlockSeq
;
else
return
EmitterNodeType
::
FlowSeq
;
}
else
{
if
(
GetFlowType
(
type
)
==
Block
)
if
(
GetFlowType
(
type
)
==
Block
)
return
EmitterNodeType
::
BlockMap
;
else
return
EmitterNodeType
::
FlowMap
;
...
...
@@ -109,30 +98,26 @@ namespace YAML
// can't happen
assert
(
false
);
return
EmitterNodeType
::
None
;
}
}
void
EmitterState
::
StartedDoc
()
{
void
EmitterState
::
StartedDoc
()
{
m_hasAnchor
=
false
;
m_hasTag
=
false
;
m_hasNonContent
=
false
;
}
}
void
EmitterState
::
EndedDoc
()
{
void
EmitterState
::
EndedDoc
()
{
m_hasAnchor
=
false
;
m_hasTag
=
false
;
m_hasNonContent
=
false
;
}
}
void
EmitterState
::
StartedScalar
()
{
void
EmitterState
::
StartedScalar
()
{
StartedNode
();
ClearModifiedSettings
();
}
}
void
EmitterState
::
StartedGroup
(
GroupType
::
value
type
)
{
void
EmitterState
::
StartedGroup
(
GroupType
::
value
type
)
{
StartedNode
();
const
int
lastGroupIndent
=
(
m_groups
.
empty
()
?
0
:
m_groups
.
top
().
indent
);
...
...
@@ -144,19 +129,18 @@ namespace YAML
pGroup
->
modifiedSettings
=
m_modifiedSettings
;
// set up group
if
(
GetFlowType
(
type
)
==
Block
)
if
(
GetFlowType
(
type
)
==
Block
)
pGroup
->
flowType
=
FlowType
::
Block
;
else
pGroup
->
flowType
=
FlowType
::
Flow
;
pGroup
->
indent
=
GetIndent
();
m_groups
.
push
(
pGroup
);
}
}
void
EmitterState
::
EndedGroup
(
GroupType
::
value
type
)
{
if
(
m_groups
.
empty
())
{
if
(
type
==
GroupType
::
Seq
)
void
EmitterState
::
EndedGroup
(
GroupType
::
value
type
)
{
if
(
m_groups
.
empty
())
{
if
(
type
==
GroupType
::
Seq
)
return
SetError
(
ErrorMsg
::
UNEXPECTED_END_SEQ
);
else
return
SetError
(
ErrorMsg
::
UNEXPECTED_END_MAP
);
...
...
@@ -165,7 +149,7 @@ namespace YAML
// get rid of the current group
{
std
::
auto_ptr
<
Group
>
pFinishedGroup
=
m_groups
.
pop
();
if
(
pFinishedGroup
->
type
!=
type
)
if
(
pFinishedGroup
->
type
!=
type
)
return
SetError
(
ErrorMsg
::
UNMATCHED_GROUP_TAG
);
}
...
...
@@ -179,57 +163,47 @@ namespace YAML
m_globalModifiedSettings
.
restore
();
ClearModifiedSettings
();
}
}
EmitterNodeType
::
value
EmitterState
::
CurGroupNodeType
()
const
{
if
(
m_groups
.
empty
())
EmitterNodeType
::
value
EmitterState
::
CurGroupNodeType
()
const
{
if
(
m_groups
.
empty
())
return
EmitterNodeType
::
None
;
return
m_groups
.
top
().
NodeType
();
}
}
GroupType
::
value
EmitterState
::
CurGroupType
()
const
{
GroupType
::
value
EmitterState
::
CurGroupType
()
const
{
return
m_groups
.
empty
()
?
GroupType
::
None
:
m_groups
.
top
().
type
;
}
}
FlowType
::
value
EmitterState
::
CurGroupFlowType
()
const
{
FlowType
::
value
EmitterState
::
CurGroupFlowType
()
const
{
return
m_groups
.
empty
()
?
FlowType
::
None
:
m_groups
.
top
().
flowType
;
}
}
int
EmitterState
::
CurGroupIndent
()
const
{
int
EmitterState
::
CurGroupIndent
()
const
{
return
m_groups
.
empty
()
?
0
:
m_groups
.
top
().
indent
;
}
}
std
::
size_t
EmitterState
::
CurGroupChildCount
()
const
{
std
::
size_t
EmitterState
::
CurGroupChildCount
()
const
{
return
m_groups
.
empty
()
?
m_docCount
:
m_groups
.
top
().
childCount
;
}
}
bool
EmitterState
::
CurGroupLongKey
()
const
{
bool
EmitterState
::
CurGroupLongKey
()
const
{
return
m_groups
.
empty
()
?
false
:
m_groups
.
top
().
longKey
;
}
}
int
EmitterState
::
LastIndent
()
const
{
if
(
m_groups
.
size
()
<=
1
)
int
EmitterState
::
LastIndent
()
const
{
if
(
m_groups
.
size
()
<=
1
)
return
0
;
return
m_curIndent
-
m_groups
.
top
(
-
1
).
indent
;
}
}
void
EmitterState
::
ClearModifiedSettings
()
{
m_modifiedSettings
.
clear
();
}
void
EmitterState
::
ClearModifiedSettings
()
{
m_modifiedSettings
.
clear
();
}
bool
EmitterState
::
SetOutputCharset
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetOutputCharset
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
EmitNonAscii
:
case
EscapeNonAscii
:
_Set
(
m_charset
,
value
,
scope
);
...
...
@@ -237,11 +211,10 @@ namespace YAML
default:
return
false
;
}
}
}
bool
EmitterState
::
SetStringFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetStringFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
Auto
:
case
SingleQuoted
:
case
DoubleQuoted
:
...
...
@@ -251,11 +224,10 @@ namespace YAML
default:
return
false
;
}
}
}
bool
EmitterState
::
SetBoolFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetBoolFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
OnOffBool
:
case
TrueFalseBool
:
case
YesNoBool
:
...
...
@@ -264,11 +236,11 @@ namespace YAML
default:
return
false
;
}
}
}
bool
EmitterState
::
SetBoolLengthFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetBoolLengthFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
LongBool
:
case
ShortBool
:
_Set
(
m_boolLengthFmt
,
value
,
scope
);
...
...
@@ -276,11 +248,11 @@ namespace YAML
default:
return
false
;
}
}
}
bool
EmitterState
::
SetBoolCaseFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetBoolCaseFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
UpperCase
:
case
LowerCase
:
case
CamelCase
:
...
...
@@ -289,11 +261,10 @@ namespace YAML
default:
return
false
;
}
}
}
bool
EmitterState
::
SetIntFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetIntFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
Dec
:
case
Hex
:
case
Oct
:
...
...
@@ -302,38 +273,35 @@ namespace YAML
default:
return
false
;
}
}
}
bool
EmitterState
::
SetIndent
(
unsigned
value
,
FmtScope
::
value
scope
)
{
if
(
value
<=
1
)
bool
EmitterState
::
SetIndent
(
unsigned
value
,
FmtScope
::
value
scope
)
{
if
(
value
<=
1
)
return
false
;
_Set
(
m_indent
,
value
,
scope
);
return
true
;
}
}
bool
EmitterState
::
SetPreCommentIndent
(
unsigned
value
,
FmtScope
::
value
scope
)
{
if
(
value
==
0
)
bool
EmitterState
::
SetPreCommentIndent
(
unsigned
value
,
FmtScope
::
value
scope
)
{
if
(
value
==
0
)
return
false
;
_Set
(
m_preCommentIndent
,
value
,
scope
);
return
true
;
}
}
bool
EmitterState
::
SetPostCommentIndent
(
unsigned
value
,
FmtScope
::
value
scope
)
{
if
(
value
==
0
)
bool
EmitterState
::
SetPostCommentIndent
(
unsigned
value
,
FmtScope
::
value
scope
)
{
if
(
value
==
0
)
return
false
;
_Set
(
m_postCommentIndent
,
value
,
scope
);
return
true
;
}
}
bool
EmitterState
::
SetFlowType
(
GroupType
::
value
groupType
,
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetFlowType
(
GroupType
::
value
groupType
,
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
Block
:
case
Flow
:
_Set
(
groupType
==
GroupType
::
Seq
?
m_seqFmt
:
m_mapFmt
,
value
,
scope
);
...
...
@@ -341,21 +309,19 @@ namespace YAML
default:
return
false
;
}
}
}
EMITTER_MANIP
EmitterState
::
GetFlowType
(
GroupType
::
value
groupType
)
const
{
EMITTER_MANIP
EmitterState
::
GetFlowType
(
GroupType
::
value
groupType
)
const
{
// force flow style if we're currently in a flow
if
(
CurGroupFlowType
()
==
FlowType
::
Flow
)
if
(
CurGroupFlowType
()
==
FlowType
::
Flow
)
return
Flow
;
// otherwise, go with what's asked of us
return
(
groupType
==
GroupType
::
Seq
?
m_seqFmt
.
get
()
:
m_mapFmt
.
get
());
}
}
bool
EmitterState
::
SetMapKeyFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
bool
EmitterState
::
SetMapKeyFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
)
{
switch
(
value
)
{
case
Auto
:
case
LongKey
:
_Set
(
m_mapKeyFmt
,
value
,
scope
);
...
...
@@ -363,22 +329,19 @@ namespace YAML
default:
return
false
;
}
}
}
bool
EmitterState
::
SetFloatPrecision
(
int
value
,
FmtScope
::
value
scope
)
{
if
(
value
<
0
||
value
>
std
::
numeric_limits
<
float
>::
digits10
+
1
)
bool
EmitterState
::
SetFloatPrecision
(
int
value
,
FmtScope
::
value
scope
)
{
if
(
value
<
0
||
value
>
std
::
numeric_limits
<
float
>::
digits10
+
1
)
return
false
;
_Set
(
m_floatPrecision
,
value
,
scope
);
return
true
;
}
}
bool
EmitterState
::
SetDoublePrecision
(
int
value
,
FmtScope
::
value
scope
)
{
if
(
value
<
0
||
value
>
std
::
numeric_limits
<
double
>::
digits10
+
1
)
bool
EmitterState
::
SetDoublePrecision
(
int
value
,
FmtScope
::
value
scope
)
{
if
(
value
<
0
||
value
>
std
::
numeric_limits
<
double
>::
digits10
+
1
)
return
false
;
_Set
(
m_doublePrecision
,
value
,
scope
);
return
true
;
}
}
}
src/emitterstate.h
View file @
3355bbb3
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "ptr_stack.h"
#include "setting.h"
#include "yaml-cpp/emitterdef.h"
...
...
@@ -16,14 +17,29 @@
#include <memory>
#include <stdexcept>
namespace
YAML
{
struct
FmtScope
{
enum
value
{
Local
,
Global
};
};
struct
GroupType
{
enum
value
{
None
,
Seq
,
Map
};
};
struct
FlowType
{
enum
value
{
None
,
Flow
,
Block
};
};
namespace
YAML
{
struct
FmtScope
{
enum
value
{
Local
,
Global
};
};
struct
GroupType
{
enum
value
{
None
,
Seq
,
Map
};
};
struct
FlowType
{
enum
value
{
None
,
Flow
,
Block
};
};
class
EmitterState
{
class
EmitterState
{
public:
EmitterState
();
~
EmitterState
();
...
...
@@ -31,7 +47,10 @@ namespace YAML
// basic state checking
bool
good
()
const
{
return
m_isGood
;
}
const
std
::
string
GetLastError
()
const
{
return
m_lastError
;
}
void
SetError
(
const
std
::
string
&
error
)
{
m_isGood
=
false
;
m_lastError
=
error
;
}
void
SetError
(
const
std
::
string
&
error
)
{
m_isGood
=
false
;
m_lastError
=
error
;
}
// node handling
void
SetAnchor
();
...
...
@@ -58,7 +77,9 @@ namespace YAML
int
CurIndent
()
const
{
return
m_curIndent
;
}
bool
HasAnchor
()
const
{
return
m_hasAnchor
;
}
bool
HasTag
()
const
{
return
m_hasTag
;
}
bool
HasBegunNode
()
const
{
return
m_hasAnchor
||
m_hasTag
||
m_hasNonContent
;
}
bool
HasBegunNode
()
const
{
return
m_hasAnchor
||
m_hasTag
||
m_hasNonContent
;
}
bool
HasBegunContent
()
const
{
return
m_hasAnchor
||
m_hasTag
;
}
void
ClearModifiedSettings
();
...
...
@@ -92,7 +113,8 @@ namespace YAML
bool
SetPostCommentIndent
(
unsigned
value
,
FmtScope
::
value
scope
);
int
GetPostCommentIndent
()
const
{
return
m_postCommentIndent
.
get
();
}
bool
SetFlowType
(
GroupType
::
value
groupType
,
EMITTER_MANIP
value
,
FmtScope
::
value
scope
);
bool
SetFlowType
(
GroupType
::
value
groupType
,
EMITTER_MANIP
value
,
FmtScope
::
value
scope
);
EMITTER_MANIP
GetFlowType
(
GroupType
::
value
groupType
)
const
;
bool
SetMapKeyFormat
(
EMITTER_MANIP
value
,
FmtScope
::
value
scope
);
...
...
@@ -133,7 +155,8 @@ namespace YAML
SettingChanges
m_globalModifiedSettings
;
struct
Group
{
explicit
Group
(
GroupType
::
value
type_
)
:
type
(
type_
),
indent
(
0
),
childCount
(
0
),
longKey
(
false
)
{}
explicit
Group
(
GroupType
::
value
type_
)
:
type
(
type_
),
indent
(
0
),
childCount
(
0
),
longKey
(
false
)
{}
GroupType
::
value
type
;
FlowType
::
value
flowType
;
...
...
@@ -144,13 +167,13 @@ namespace YAML
SettingChanges
modifiedSettings
;
EmitterNodeType
::
value
NodeType
()
const
{
if
(
type
==
GroupType
::
Seq
)
{
if
(
flowType
==
FlowType
::
Flow
)
if
(
type
==
GroupType
::
Seq
)
{
if
(
flowType
==
FlowType
::
Flow
)
return
EmitterNodeType
::
FlowSeq
;
else
return
EmitterNodeType
::
BlockSeq
;
}
else
{
if
(
flowType
==
FlowType
::
Flow
)
if
(
flowType
==
FlowType
::
Flow
)
return
EmitterNodeType
::
FlowMap
;
else
return
EmitterNodeType
::
BlockMap
;
...
...
@@ -168,23 +191,24 @@ namespace YAML
bool
m_hasTag
;
bool
m_hasNonContent
;
std
::
size_t
m_docCount
;
};
};
template
<
typename
T
>
void
EmitterState
::
_Set
(
Setting
<
T
>&
fmt
,
T
value
,
FmtScope
::
value
scope
)
{
switch
(
scope
)
{
template
<
typename
T
>
void
EmitterState
::
_Set
(
Setting
<
T
>&
fmt
,
T
value
,
FmtScope
::
value
scope
)
{
switch
(
scope
)
{
case
FmtScope
::
Local
:
m_modifiedSettings
.
push
(
fmt
.
set
(
value
));
break
;
case
FmtScope
::
Global
:
fmt
.
set
(
value
);
m_globalModifiedSettings
.
push
(
fmt
.
set
(
value
));
// this pushes an identity set, so when we restore,
m_globalModifiedSettings
.
push
(
fmt
.
set
(
value
));
// this pushes an identity set, so when we restore,
// it restores to the value here, and not the previous one
break
;
default:
assert
(
false
);
}
}
}
}
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/emitterutils.cpp
View file @
3355bbb3
...
...
@@ -7,19 +7,25 @@
#include <sstream>
#include <iomanip>
namespace
YAML
{
namespace
Utils
{
namespace
{
enum
{
REPLACEMENT_CHARACTER
=
0xFFFD
};
bool
IsAnchorChar
(
int
ch
)
{
// test for ns-anchor-char
namespace
YAML
{
namespace
Utils
{
namespace
{
enum
{
REPLACEMENT_CHARACTER
=
0xFFFD
};
bool
IsAnchorChar
(
int
ch
)
{
// test for ns-anchor-char
switch
(
ch
)
{
case
','
:
case
'['
:
case
']'
:
case
'{'
:
case
'}'
:
// c-flow-indicator
case
' '
:
case
'\t'
:
// s-white
case
','
:
case
'['
:
case
']'
:
case
'{'
:
case
'}'
:
// c-flow-indicator
case
' '
:
case
'\t'
:
// s-white
case
0xFEFF
:
// c-byte-order-mark
case
0xA
:
case
0xD
:
// b-char
case
0xA
:
case
0xD
:
// b-char
return
false
;
case
0x85
:
return
true
;
...
...
@@ -43,14 +49,22 @@ namespace YAML
return
false
;
return
true
;
}
}
int
Utf8BytesIndicated
(
char
ch
)
{
int
Utf8BytesIndicated
(
char
ch
)
{
int
byteVal
=
static_cast
<
unsigned
char
>
(
ch
);
switch
(
byteVal
>>
4
)
{
case
0
:
case
1
:
case
2
:
case
3
:
case
4
:
case
5
:
case
6
:
case
7
:
case
0
:
case
1
:
case
2
:
case
3
:
case
4
:
case
5
:
case
6
:
case
7
:
return
1
;
case
12
:
case
13
:
case
12
:
case
13
:
return
2
;
case
14
:
return
3
;
...
...
@@ -59,13 +73,13 @@ namespace YAML
default:
return
-
1
;
}
}
}
bool
IsTrailingByte
(
char
ch
)
{
return
(
ch
&
0xC0
)
==
0x80
;
}
bool
IsTrailingByte
(
char
ch
)
{
return
(
ch
&
0xC0
)
==
0x80
;
}
bool
GetNextCodePointAndAdvance
(
int
&
codePoint
,
std
::
string
::
const_iterator
&
first
,
std
::
string
::
const_iterator
last
)
{
bool
GetNextCodePointAndAdvance
(
int
&
codePoint
,
std
::
string
::
const_iterator
&
first
,
std
::
string
::
const_iterator
last
)
{
if
(
first
==
last
)
return
false
;
...
...
@@ -105,9 +119,9 @@ namespace YAML
else
if
(
codePoint
>=
0xFDD0
&&
codePoint
<=
0xFDEF
)
codePoint
=
REPLACEMENT_CHARACTER
;
return
true
;
}
}
void
WriteCodePoint
(
ostream_wrapper
&
out
,
int
codePoint
)
{
void
WriteCodePoint
(
ostream_wrapper
&
out
,
int
codePoint
)
{
if
(
codePoint
<
0
||
codePoint
>
0x10FFFF
)
{
codePoint
=
REPLACEMENT_CHARACTER
;
}
...
...
@@ -126,74 +140,75 @@ namespace YAML
<<
static_cast
<
char
>
(
0x80
|
((
codePoint
>>
6
)
&
0x3F
))
<<
static_cast
<
char
>
(
0x80
|
(
codePoint
&
0x3F
));
}
}
}
bool
IsValidPlainScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
allowOnlyAscii
)
{
if
(
str
.
empty
())
bool
IsValidPlainScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
allowOnlyAscii
)
{
if
(
str
.
empty
())
return
false
;
// first check the start
const
RegEx
&
start
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
PlainScalarInFlow
()
:
Exp
::
PlainScalar
());
if
(
!
start
.
Matches
(
str
))
const
RegEx
&
start
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
PlainScalarInFlow
()
:
Exp
::
PlainScalar
());
if
(
!
start
.
Matches
(
str
))
return
false
;
// and check the end for plain whitespace (which can't be faithfully kept in a plain scalar)
if
(
!
str
.
empty
()
&&
*
str
.
rbegin
()
==
' '
)
// and check the end for plain whitespace (which can't be faithfully kept in a
// plain scalar)
if
(
!
str
.
empty
()
&&
*
str
.
rbegin
()
==
' '
)
return
false
;
// then check until something is disallowed
const
RegEx
&
disallowed
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
EndScalarInFlow
()
:
Exp
::
EndScalar
())
||
(
Exp
::
BlankOrBreak
()
+
Exp
::
Comment
())
||
Exp
::
NotPrintable
()
||
Exp
::
Utf8_ByteOrderMark
()
||
Exp
::
Break
()
||
Exp
::
Tab
();
const
RegEx
&
disallowed
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
EndScalarInFlow
()
:
Exp
::
EndScalar
())
||
(
Exp
::
BlankOrBreak
()
+
Exp
::
Comment
())
||
Exp
::
NotPrintable
()
||
Exp
::
Utf8_ByteOrderMark
()
||
Exp
::
Break
()
||
Exp
::
Tab
();
StringCharSource
buffer
(
str
.
c_str
(),
str
.
size
());
while
(
buffer
)
{
if
(
disallowed
.
Matches
(
buffer
))
while
(
buffer
)
{
if
(
disallowed
.
Matches
(
buffer
))
return
false
;
if
(
allowOnlyAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
buffer
[
0
])))
if
(
allowOnlyAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
buffer
[
0
])))
return
false
;
++
buffer
;
}
return
true
;
}
}
bool
IsValidSingleQuotedScalar
(
const
std
::
string
&
str
,
bool
escapeNonAscii
)
{
bool
IsValidSingleQuotedScalar
(
const
std
::
string
&
str
,
bool
escapeNonAscii
)
{
// TODO: check for non-printable characters?
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
return
false
;
if
(
str
[
i
]
==
'\n'
)
if
(
str
[
i
]
==
'\n'
)
return
false
;
}
return
true
;
}
}
bool
IsValidLiteralScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
escapeNonAscii
)
{
if
(
flowType
==
FlowType
::
Flow
)
bool
IsValidLiteralScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
escapeNonAscii
)
{
if
(
flowType
==
FlowType
::
Flow
)
return
false
;
// TODO: check for non-printable characters?
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
return
false
;
}
return
true
;
}
}
void
WriteDoubleQuoteEscapeSequence
(
ostream_wrapper
&
out
,
int
codePoint
)
{
void
WriteDoubleQuoteEscapeSequence
(
ostream_wrapper
&
out
,
int
codePoint
)
{
static
const
char
hexDigits
[]
=
"0123456789abcdef"
;
out
<<
"
\\
"
;
int
digits
=
8
;
if
(
codePoint
<
0xFF
)
{
if
(
codePoint
<
0xFF
)
{
out
<<
"x"
;
digits
=
2
;
}
else
if
(
codePoint
<
0xFFFF
)
{
}
else
if
(
codePoint
<
0xFFFF
)
{
out
<<
"u"
;
digits
=
4
;
}
else
{
...
...
@@ -204,38 +219,38 @@ namespace YAML
// Write digits into the escape sequence
for
(;
digits
>
0
;
--
digits
)
out
<<
hexDigits
[(
codePoint
>>
(
4
*
(
digits
-
1
)))
&
0xF
];
}
}
bool
WriteAliasName
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
bool
WriteAliasName
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());
)
{
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
if
(
!
IsAnchorChar
(
codePoint
))
return
false
;
WriteCodePoint
(
out
,
codePoint
);
}
return
true
;
}
}
}
}
StringFormat
::
value
ComputeStringFormat
(
const
std
::
string
&
str
,
EMITTER_MANIP
strFormat
,
FlowType
::
value
flowType
,
bool
escapeNonAscii
)
{
switch
(
strFormat
)
{
StringFormat
::
value
ComputeStringFormat
(
const
std
::
string
&
str
,
EMITTER_MANIP
strFormat
,
FlowType
::
value
flowType
,
bool
escapeNonAscii
)
{
switch
(
strFormat
)
{
case
Auto
:
if
(
IsValidPlainScalar
(
str
,
flowType
,
escapeNonAscii
))
if
(
IsValidPlainScalar
(
str
,
flowType
,
escapeNonAscii
))
return
StringFormat
::
Plain
;
return
StringFormat
::
DoubleQuoted
;
case
SingleQuoted
:
if
(
IsValidSingleQuotedScalar
(
str
,
escapeNonAscii
))
if
(
IsValidSingleQuotedScalar
(
str
,
escapeNonAscii
))
return
StringFormat
::
SingleQuoted
;
return
StringFormat
::
DoubleQuoted
;
case
DoubleQuoted
:
return
StringFormat
::
DoubleQuoted
;
case
Literal
:
if
(
IsValidLiteralScalar
(
str
,
flowType
,
escapeNonAscii
))
if
(
IsValidLiteralScalar
(
str
,
flowType
,
escapeNonAscii
))
return
StringFormat
::
Literal
;
return
StringFormat
::
DoubleQuoted
;
default:
...
...
@@ -243,18 +258,16 @@ namespace YAML
}
return
StringFormat
::
DoubleQuoted
;
}
}
bool
WriteSingleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
bool
WriteSingleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
out
<<
"'"
;
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());
)
{
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
if
(
codePoint
==
'\n'
)
return
false
;
// We can't handle a new line and the attendant indentation yet
return
false
;
// We can't handle a new line and the attendant indentation
// yet
if
(
codePoint
==
'\''
)
out
<<
"''"
;
...
...
@@ -263,27 +276,40 @@ namespace YAML
}
out
<<
"'"
;
return
true
;
}
}
bool
WriteDoubleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
escapeNonAscii
)
{
bool
WriteDoubleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
escapeNonAscii
)
{
out
<<
"
\"
"
;
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());
)
{
switch
(
codePoint
)
{
case
'\"'
:
out
<<
"
\\\"
"
;
break
;
case
'\\'
:
out
<<
"
\\\\
"
;
break
;
case
'\n'
:
out
<<
"
\\
n"
;
break
;
case
'\t'
:
out
<<
"
\\
t"
;
break
;
case
'\r'
:
out
<<
"
\\
r"
;
break
;
case
'\b'
:
out
<<
"
\\
b"
;
break
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
switch
(
codePoint
)
{
case
'\"'
:
out
<<
"
\\\"
"
;
break
;
case
'\\'
:
out
<<
"
\\\\
"
;
break
;
case
'\n'
:
out
<<
"
\\
n"
;
break
;
case
'\t'
:
out
<<
"
\\
t"
;
break
;
case
'\r'
:
out
<<
"
\\
r"
;
break
;
case
'\b'
:
out
<<
"
\\
b"
;
break
;
default:
if
(
codePoint
<
0x20
||
(
codePoint
>=
0x80
&&
codePoint
<=
0xA0
))
// Control characters and non-breaking space
if
(
codePoint
<
0x20
||
(
codePoint
>=
0x80
&&
codePoint
<=
0xA0
))
// Control characters and non-breaking space
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
else
if
(
codePoint
==
0xFEFF
)
// Byte order marks (ZWNS) should be escaped (YAML 1.2, sec. 5.2)
else
if
(
codePoint
==
0xFEFF
)
// Byte order marks (ZWNS) should be
// escaped (YAML 1.2, sec. 5.2)
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
else
if
(
escapeNonAscii
&&
codePoint
>
0x7E
)
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
...
...
@@ -293,36 +319,33 @@ namespace YAML
}
out
<<
"
\"
"
;
return
true
;
}
}
bool
WriteLiteralString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
indent
)
{
bool
WriteLiteralString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
indent
)
{
out
<<
"|
\n
"
;
out
<<
IndentTo
(
indent
);
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());
)
{
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
if
(
codePoint
==
'\n'
)
out
<<
"
\n
"
<<
IndentTo
(
indent
);
else
WriteCodePoint
(
out
,
codePoint
);
}
return
true
;
}
}
bool
WriteChar
(
ostream_wrapper
&
out
,
char
ch
)
{
if
((
'a'
<=
ch
&&
ch
<=
'z'
)
||
(
'A'
<=
ch
&&
ch
<=
'Z'
))
bool
WriteChar
(
ostream_wrapper
&
out
,
char
ch
)
{
if
((
'a'
<=
ch
&&
ch
<=
'z'
)
||
(
'A'
<=
ch
&&
ch
<=
'Z'
))
out
<<
ch
;
else
if
((
0x20
<=
ch
&&
ch
<=
0x7e
)
||
ch
==
' '
)
else
if
((
0x20
<=
ch
&&
ch
<=
0x7e
)
||
ch
==
' '
)
out
<<
"
\"
"
<<
ch
<<
"
\"
"
;
else
if
(
ch
==
'\t'
)
else
if
(
ch
==
'\t'
)
out
<<
"
\"\\
t
\"
"
;
else
if
(
ch
==
'\n'
)
else
if
(
ch
==
'\n'
)
out
<<
"
\"\\
n
\"
"
;
else
if
(
ch
==
'\b'
)
else
if
(
ch
==
'\b'
)
out
<<
"
\"\\
b
\"
"
;
else
{
out
<<
"
\"
"
;
...
...
@@ -330,51 +353,47 @@ namespace YAML
out
<<
"
\"
"
;
}
return
true
;
}
}
bool
WriteComment
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
postCommentIndent
)
{
bool
WriteComment
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
postCommentIndent
)
{
const
unsigned
curIndent
=
out
.
col
();
out
<<
"#"
<<
Indentation
(
postCommentIndent
);
out
.
set_comment
();
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());
)
{
if
(
codePoint
==
'\n'
)
{
out
<<
"
\n
"
<<
IndentTo
(
curIndent
)
<<
"#"
<<
Indentation
(
postCommentIndent
);
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
if
(
codePoint
==
'\n'
)
{
out
<<
"
\n
"
<<
IndentTo
(
curIndent
)
<<
"#"
<<
Indentation
(
postCommentIndent
);
out
.
set_comment
();
}
else
{
WriteCodePoint
(
out
,
codePoint
);
}
}
return
true
;
}
}
bool
WriteAlias
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
bool
WriteAlias
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
out
<<
"*"
;
return
WriteAliasName
(
out
,
str
);
}
}
bool
WriteAnchor
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
bool
WriteAnchor
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
)
{
out
<<
"&"
;
return
WriteAliasName
(
out
,
str
);
}
}
bool
WriteTag
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
verbatim
)
{
bool
WriteTag
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
verbatim
)
{
out
<<
(
verbatim
?
"!<"
:
"!"
);
StringCharSource
buffer
(
str
.
c_str
(),
str
.
size
());
const
RegEx
&
reValid
=
verbatim
?
Exp
::
URI
()
:
Exp
::
Tag
();
while
(
buffer
)
{
while
(
buffer
)
{
int
n
=
reValid
.
Match
(
buffer
);
if
(
n
<=
0
)
if
(
n
<=
0
)
return
false
;
while
(
--
n
>=
0
)
{
while
(
--
n
>=
0
)
{
out
<<
buffer
[
0
];
++
buffer
;
}
...
...
@@ -382,18 +401,18 @@ namespace YAML
if
(
verbatim
)
out
<<
">"
;
return
true
;
}
}
bool
WriteTagWithPrefix
(
ostream_wrapper
&
out
,
const
std
::
string
&
prefix
,
const
std
::
string
&
tag
)
{
bool
WriteTagWithPrefix
(
ostream_wrapper
&
out
,
const
std
::
string
&
prefix
,
const
std
::
string
&
tag
)
{
out
<<
"!"
;
StringCharSource
prefixBuffer
(
prefix
.
c_str
(),
prefix
.
size
());
while
(
prefixBuffer
)
{
while
(
prefixBuffer
)
{
int
n
=
Exp
::
URI
().
Match
(
prefixBuffer
);
if
(
n
<=
0
)
if
(
n
<=
0
)
return
false
;
while
(
--
n
>=
0
)
{
while
(
--
n
>=
0
)
{
out
<<
prefixBuffer
[
0
];
++
prefixBuffer
;
}
...
...
@@ -401,24 +420,23 @@ namespace YAML
out
<<
"!"
;
StringCharSource
tagBuffer
(
tag
.
c_str
(),
tag
.
size
());
while
(
tagBuffer
)
{
while
(
tagBuffer
)
{
int
n
=
Exp
::
Tag
().
Match
(
tagBuffer
);
if
(
n
<=
0
)
if
(
n
<=
0
)
return
false
;
while
(
--
n
>=
0
)
{
while
(
--
n
>=
0
)
{
out
<<
tagBuffer
[
0
];
++
tagBuffer
;
}
}
return
true
;
}
}
bool
WriteBinary
(
ostream_wrapper
&
out
,
const
Binary
&
binary
)
{
WriteDoubleQuotedString
(
out
,
EncodeBase64
(
binary
.
data
(),
binary
.
size
()),
false
);
bool
WriteBinary
(
ostream_wrapper
&
out
,
const
Binary
&
binary
)
{
WriteDoubleQuotedString
(
out
,
EncodeBase64
(
binary
.
data
(),
binary
.
size
()),
false
);
return
true
;
}
}
}
}
}
src/emitterutils.h
View file @
3355bbb3
#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "emitterstate.h"
#include "yaml-cpp/ostream_wrapper.h"
#include <string>
namespace
YAML
{
class
Binary
;
struct
StringFormat
{
enum
value
{
Plain
,
SingleQuoted
,
DoubleQuoted
,
Literal
};
};
namespace
Utils
{
StringFormat
::
value
ComputeStringFormat
(
const
std
::
string
&
str
,
EMITTER_MANIP
strFormat
,
FlowType
::
value
flowType
,
bool
escapeNonAscii
);
bool
WriteSingleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
);
bool
WriteDoubleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
escapeNonAscii
);
bool
WriteLiteralString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
indent
);
bool
WriteChar
(
ostream_wrapper
&
out
,
char
ch
);
bool
WriteComment
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
postCommentIndent
);
bool
WriteAlias
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
);
bool
WriteAnchor
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
);
bool
WriteTag
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
verbatim
);
bool
WriteTagWithPrefix
(
ostream_wrapper
&
out
,
const
std
::
string
&
prefix
,
const
std
::
string
&
tag
);
bool
WriteBinary
(
ostream_wrapper
&
out
,
const
Binary
&
binary
);
}
namespace
YAML
{
class
Binary
;
struct
StringFormat
{
enum
value
{
Plain
,
SingleQuoted
,
DoubleQuoted
,
Literal
};
};
namespace
Utils
{
StringFormat
::
value
ComputeStringFormat
(
const
std
::
string
&
str
,
EMITTER_MANIP
strFormat
,
FlowType
::
value
flowType
,
bool
escapeNonAscii
);
bool
WriteSingleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
);
bool
WriteDoubleQuotedString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
escapeNonAscii
);
bool
WriteLiteralString
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
indent
);
bool
WriteChar
(
ostream_wrapper
&
out
,
char
ch
);
bool
WriteComment
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
int
postCommentIndent
);
bool
WriteAlias
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
);
bool
WriteAnchor
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
);
bool
WriteTag
(
ostream_wrapper
&
out
,
const
std
::
string
&
str
,
bool
verbatim
);
bool
WriteTagWithPrefix
(
ostream_wrapper
&
out
,
const
std
::
string
&
prefix
,
const
std
::
string
&
tag
);
bool
WriteBinary
(
ostream_wrapper
&
out
,
const
Binary
&
binary
);
}
}
#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/exp.cpp
View file @
3355bbb3
...
...
@@ -2,21 +2,18 @@
#include "yaml-cpp/exceptions.h"
#include <sstream>
namespace
YAML
{
namespace
Exp
{
unsigned
ParseHex
(
const
std
::
string
&
str
,
const
Mark
&
mark
)
{
namespace
YAML
{
namespace
Exp
{
unsigned
ParseHex
(
const
std
::
string
&
str
,
const
Mark
&
mark
)
{
unsigned
value
=
0
;
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
char
ch
=
str
[
i
];
int
digit
=
0
;
if
(
'a'
<=
ch
&&
ch
<=
'f'
)
if
(
'a'
<=
ch
&&
ch
<=
'f'
)
digit
=
ch
-
'a'
+
10
;
else
if
(
'A'
<=
ch
&&
ch
<=
'F'
)
else
if
(
'A'
<=
ch
&&
ch
<=
'F'
)
digit
=
ch
-
'A'
+
10
;
else
if
(
'0'
<=
ch
&&
ch
<=
'9'
)
else
if
(
'0'
<=
ch
&&
ch
<=
'9'
)
digit
=
ch
-
'0'
;
else
throw
ParserException
(
mark
,
ErrorMsg
::
INVALID_HEX
);
...
...
@@ -25,51 +22,49 @@ namespace YAML
}
return
value
;
}
}
std
::
string
Str
(
unsigned
ch
)
{
return
std
::
string
(
1
,
static_cast
<
char
>
(
ch
));
}
std
::
string
Str
(
unsigned
ch
)
{
return
std
::
string
(
1
,
static_cast
<
char
>
(
ch
));
}
// Escape
// . Translates the next 'codeLength' characters into a hex number and returns
the result.
//
. Throws if it's not actually hex
.
std
::
string
Escape
(
Stream
&
in
,
int
codeLength
)
{
// Escape
// . Translates the next 'codeLength' characters into a hex number and returns
//
the result
.
// . Throws if it's not actually hex.
std
::
string
Escape
(
Stream
&
in
,
int
codeLength
)
{
// grab string
std
::
string
str
;
for
(
int
i
=
0
;
i
<
codeLength
;
i
++
)
for
(
int
i
=
0
;
i
<
codeLength
;
i
++
)
str
+=
in
.
get
();
// get the value
unsigned
value
=
ParseHex
(
str
,
in
.
mark
());
// legal unicode?
if
((
value
>=
0xD800
&&
value
<=
0xDFFF
)
||
value
>
0x10FFFF
)
{
if
((
value
>=
0xD800
&&
value
<=
0xDFFF
)
||
value
>
0x10FFFF
)
{
std
::
stringstream
msg
;
msg
<<
ErrorMsg
::
INVALID_UNICODE
<<
value
;
throw
ParserException
(
in
.
mark
(),
msg
.
str
());
}
// now break it up into chars
if
(
value
<=
0x7F
)
if
(
value
<=
0x7F
)
return
Str
(
value
);
else
if
(
value
<=
0x7FF
)
else
if
(
value
<=
0x7FF
)
return
Str
(
0xC0
+
(
value
>>
6
))
+
Str
(
0x80
+
(
value
&
0x3F
));
else
if
(
value
<=
0xFFFF
)
return
Str
(
0xE0
+
(
value
>>
12
))
+
Str
(
0x80
+
((
value
>>
6
)
&
0x3F
))
+
Str
(
0x80
+
(
value
&
0x3F
));
else
if
(
value
<=
0xFFFF
)
return
Str
(
0xE0
+
(
value
>>
12
))
+
Str
(
0x80
+
((
value
>>
6
)
&
0x3F
))
+
Str
(
0x80
+
(
value
&
0x3F
));
else
return
Str
(
0xF0
+
(
value
>>
18
))
+
Str
(
0x80
+
((
value
>>
12
)
&
0x3F
))
+
Str
(
0x80
+
((
value
>>
6
)
&
0x3F
))
+
Str
(
0x80
+
(
value
&
0x3F
));
}
}
// Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single
quote)
//
and returns the result.
//
. Throws if it's an unknown escape character
.
std
::
string
Escape
(
Stream
&
in
)
{
// Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single
//
quote)
//
and returns the result
.
// . Throws if it's an unknown escape character.
std
::
string
Escape
(
Stream
&
in
)
{
// eat slash
char
escape
=
in
.
get
();
...
...
@@ -77,37 +72,59 @@ namespace YAML
char
ch
=
in
.
get
();
// first do single quote, since it's easier
if
(
escape
==
'\''
&&
ch
==
'\''
)
if
(
escape
==
'\''
&&
ch
==
'\''
)
return
"
\'
"
;
// now do the slash (we're not gonna check if it's a slash - you better pass one!)
switch
(
ch
)
{
case
'0'
:
return
std
::
string
(
1
,
'\x00'
);
case
'a'
:
return
"
\x07
"
;
case
'b'
:
return
"
\x08
"
;
// now do the slash (we're not gonna check if it's a slash - you better pass
// one!)
switch
(
ch
)
{
case
'0'
:
return
std
::
string
(
1
,
'\x00'
);
case
'a'
:
return
"
\x07
"
;
case
'b'
:
return
"
\x08
"
;
case
't'
:
case
'\t'
:
return
"
\x09
"
;
case
'n'
:
return
"
\x0A
"
;
case
'v'
:
return
"
\x0B
"
;
case
'f'
:
return
"
\x0C
"
;
case
'r'
:
return
"
\x0D
"
;
case
'e'
:
return
"
\x1B
"
;
case
' '
:
return
"
\x20
"
;
case
'\"'
:
return
"
\"
"
;
case
'\''
:
return
"
\'
"
;
case
'\\'
:
return
"
\\
"
;
case
'/'
:
return
"/"
;
case
'N'
:
return
"
\x85
"
;
case
'_'
:
return
"
\xA0
"
;
case
'L'
:
return
"
\xE2\x80\xA8
"
;
// LS (#x2028)
case
'P'
:
return
"
\xE2\x80\xA9
"
;
// PS (#x2029)
case
'x'
:
return
Escape
(
in
,
2
);
case
'u'
:
return
Escape
(
in
,
4
);
case
'U'
:
return
Escape
(
in
,
8
);
case
'\t'
:
return
"
\x09
"
;
case
'n'
:
return
"
\x0A
"
;
case
'v'
:
return
"
\x0B
"
;
case
'f'
:
return
"
\x0C
"
;
case
'r'
:
return
"
\x0D
"
;
case
'e'
:
return
"
\x1B
"
;
case
' '
:
return
"
\x20
"
;
case
'\"'
:
return
"
\"
"
;
case
'\''
:
return
"
\'
"
;
case
'\\'
:
return
"
\\
"
;
case
'/'
:
return
"/"
;
case
'N'
:
return
"
\x85
"
;
case
'_'
:
return
"
\xA0
"
;
case
'L'
:
return
"
\xE2\x80\xA8
"
;
// LS (#x2028)
case
'P'
:
return
"
\xE2\x80\xA9
"
;
// PS (#x2029)
case
'x'
:
return
Escape
(
in
,
2
);
case
'u'
:
return
Escape
(
in
,
4
);
case
'U'
:
return
Escape
(
in
,
8
);
}
std
::
stringstream
msg
;
throw
ParserException
(
in
.
mark
(),
std
::
string
(
ErrorMsg
::
INVALID_ESCAPE
)
+
ch
);
}
}
}
}
}
src/exp.h
View file @
3355bbb3
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "regex.h"
#include <string>
#include <ios>
#include "stream.h"
namespace
YAML
{
////////////////////////////////////////////////////////////////////////////////
//
Here we store a bunch of expressions for matching different parts of the
file.
namespace
YAML
{
////////////////////////////////////////////////////////////////////////////////
// Here we store a bunch of expressions for matching different parts of the
// file.
namespace
Exp
{
// misc
inline
const
RegEx
&
Space
()
{
namespace
Exp
{
// misc
inline
const
RegEx
&
Space
()
{
static
const
RegEx
e
=
RegEx
(
' '
);
return
e
;
}
inline
const
RegEx
&
Tab
()
{
}
inline
const
RegEx
&
Tab
()
{
static
const
RegEx
e
=
RegEx
(
'\t'
);
return
e
;
}
inline
const
RegEx
&
Blank
()
{
}
inline
const
RegEx
&
Blank
()
{
static
const
RegEx
e
=
Space
()
||
Tab
();
return
e
;
}
inline
const
RegEx
&
Break
()
{
}
inline
const
RegEx
&
Break
()
{
static
const
RegEx
e
=
RegEx
(
'\n'
)
||
RegEx
(
"
\r\n
"
);
return
e
;
}
inline
const
RegEx
&
BlankOrBreak
()
{
}
inline
const
RegEx
&
BlankOrBreak
()
{
static
const
RegEx
e
=
Blank
()
||
Break
();
return
e
;
}
inline
const
RegEx
&
Digit
()
{
}
inline
const
RegEx
&
Digit
()
{
static
const
RegEx
e
=
RegEx
(
'0'
,
'9'
);
return
e
;
}
inline
const
RegEx
&
Alpha
()
{
}
inline
const
RegEx
&
Alpha
()
{
static
const
RegEx
e
=
RegEx
(
'a'
,
'z'
)
||
RegEx
(
'A'
,
'Z'
);
return
e
;
}
inline
const
RegEx
&
AlphaNumeric
()
{
}
inline
const
RegEx
&
AlphaNumeric
()
{
static
const
RegEx
e
=
Alpha
()
||
Digit
();
return
e
;
}
inline
const
RegEx
&
Word
()
{
}
inline
const
RegEx
&
Word
()
{
static
const
RegEx
e
=
AlphaNumeric
()
||
RegEx
(
'-'
);
return
e
;
}
inline
const
RegEx
&
Hex
()
{
}
inline
const
RegEx
&
Hex
()
{
static
const
RegEx
e
=
Digit
()
||
RegEx
(
'A'
,
'F'
)
||
RegEx
(
'a'
,
'f'
);
return
e
;
}
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1)
inline
const
RegEx
&
NotPrintable
()
{
static
const
RegEx
e
=
RegEx
(
0
)
||
}
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
// 5.1)
inline
const
RegEx
&
NotPrintable
()
{
static
const
RegEx
e
=
RegEx
(
0
)
||
RegEx
(
"
\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F
"
,
REGEX_OR
)
||
RegEx
(
0x0E
,
0x1F
)
||
(
RegEx
(
'\xC2'
)
+
(
RegEx
(
'\x80'
,
'\x84'
)
||
RegEx
(
'\x86'
,
'\x9F'
)));
return
e
;
}
inline
const
RegEx
&
Utf8_ByteOrderMark
()
{
}
inline
const
RegEx
&
Utf8_ByteOrderMark
()
{
static
const
RegEx
e
=
RegEx
(
"
\xEF\xBB\xBF
"
);
return
e
;
}
}
// actual tags
// actual tags
inline
const
RegEx
&
DocStart
()
{
inline
const
RegEx
&
DocStart
()
{
static
const
RegEx
e
=
RegEx
(
"---"
)
+
(
BlankOrBreak
()
||
RegEx
());
return
e
;
}
inline
const
RegEx
&
DocEnd
()
{
}
inline
const
RegEx
&
DocEnd
()
{
static
const
RegEx
e
=
RegEx
(
"..."
)
+
(
BlankOrBreak
()
||
RegEx
());
return
e
;
}
inline
const
RegEx
&
DocIndicator
()
{
}
inline
const
RegEx
&
DocIndicator
()
{
static
const
RegEx
e
=
DocStart
()
||
DocEnd
();
return
e
;
}
inline
const
RegEx
&
BlockEntry
()
{
}
inline
const
RegEx
&
BlockEntry
()
{
static
const
RegEx
e
=
RegEx
(
'-'
)
+
(
BlankOrBreak
()
||
RegEx
());
return
e
;
}
inline
const
RegEx
&
Key
()
{
}
inline
const
RegEx
&
Key
()
{
static
const
RegEx
e
=
RegEx
(
'?'
)
+
BlankOrBreak
();
return
e
;
}
inline
const
RegEx
&
KeyInFlow
()
{
}
inline
const
RegEx
&
KeyInFlow
()
{
static
const
RegEx
e
=
RegEx
(
'?'
)
+
BlankOrBreak
();
return
e
;
}
inline
const
RegEx
&
Value
()
{
}
inline
const
RegEx
&
Value
()
{
static
const
RegEx
e
=
RegEx
(
':'
)
+
(
BlankOrBreak
()
||
RegEx
());
return
e
;
}
inline
const
RegEx
&
ValueInFlow
()
{
}
inline
const
RegEx
&
ValueInFlow
()
{
static
const
RegEx
e
=
RegEx
(
':'
)
+
(
BlankOrBreak
()
||
RegEx
(
",}"
,
REGEX_OR
));
return
e
;
}
inline
const
RegEx
&
ValueInJSONFlow
()
{
}
inline
const
RegEx
&
ValueInJSONFlow
()
{
static
const
RegEx
e
=
RegEx
(
':'
);
return
e
;
}
inline
const
RegEx
Comment
()
{
}
inline
const
RegEx
Comment
()
{
static
const
RegEx
e
=
RegEx
(
'#'
);
return
e
;
}
inline
const
RegEx
&
Anchor
()
{
}
inline
const
RegEx
&
Anchor
()
{
static
const
RegEx
e
=
!
(
RegEx
(
"[]{},"
,
REGEX_OR
)
||
BlankOrBreak
());
return
e
;
}
inline
const
RegEx
&
AnchorEnd
()
{
}
inline
const
RegEx
&
AnchorEnd
()
{
static
const
RegEx
e
=
RegEx
(
"?:,]}%@`"
,
REGEX_OR
)
||
BlankOrBreak
();
return
e
;
}
inline
const
RegEx
&
URI
()
{
static
const
RegEx
e
=
Word
()
||
RegEx
(
"#;/?:@&=+$,_.!~*'()[]"
,
REGEX_OR
)
||
(
RegEx
(
'%'
)
+
Hex
()
+
Hex
());
}
inline
const
RegEx
&
URI
()
{
static
const
RegEx
e
=
Word
()
||
RegEx
(
"#;/?:@&=+$,_.!~*'()[]"
,
REGEX_OR
)
||
(
RegEx
(
'%'
)
+
Hex
()
+
Hex
());
return
e
;
}
inline
const
RegEx
&
Tag
()
{
static
const
RegEx
e
=
Word
()
||
RegEx
(
"#;/?:@&=+$_.~*'"
,
REGEX_OR
)
||
(
RegEx
(
'%'
)
+
Hex
()
+
Hex
());
}
inline
const
RegEx
&
Tag
()
{
static
const
RegEx
e
=
Word
()
||
RegEx
(
"#;/?:@&=+$_.~*'"
,
REGEX_OR
)
||
(
RegEx
(
'%'
)
+
Hex
()
+
Hex
());
return
e
;
}
}
// Plain scalar rules:
// . Cannot start with a blank.
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . 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.
inline
const
RegEx
&
PlainScalar
()
{
static
const
RegEx
e
=
!
(
BlankOrBreak
()
||
RegEx
(
",[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-?:"
,
REGEX_OR
)
+
(
BlankOrBreak
()
||
RegEx
())));
return
e
;
}
inline
const
RegEx
&
PlainScalarInFlow
()
{
static
const
RegEx
e
=
!
(
BlankOrBreak
()
||
RegEx
(
"?,[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-:"
,
REGEX_OR
)
+
Blank
()));
return
e
;
}
inline
const
RegEx
&
EndScalar
()
{
// Plain scalar rules:
// . Cannot start with a blank.
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . 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.
inline
const
RegEx
&
PlainScalar
()
{
static
const
RegEx
e
=
!
(
BlankOrBreak
()
||
RegEx
(
",[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-?:"
,
REGEX_OR
)
+
(
BlankOrBreak
()
||
RegEx
())));
return
e
;
}
inline
const
RegEx
&
PlainScalarInFlow
()
{
static
const
RegEx
e
=
!
(
BlankOrBreak
()
||
RegEx
(
"?,[]{}#&*!|>
\'\"
%@`"
,
REGEX_OR
)
||
(
RegEx
(
"-:"
,
REGEX_OR
)
+
Blank
()));
return
e
;
}
inline
const
RegEx
&
EndScalar
()
{
static
const
RegEx
e
=
RegEx
(
':'
)
+
(
BlankOrBreak
()
||
RegEx
());
return
e
;
}
inline
const
RegEx
&
EndScalarInFlow
()
{
static
const
RegEx
e
=
(
RegEx
(
':'
)
+
(
BlankOrBreak
()
||
RegEx
()
||
RegEx
(
",]}"
,
REGEX_OR
)))
||
RegEx
(
",?[]{}"
,
REGEX_OR
);
}
inline
const
RegEx
&
EndScalarInFlow
()
{
static
const
RegEx
e
=
(
RegEx
(
':'
)
+
(
BlankOrBreak
()
||
RegEx
()
||
RegEx
(
",]}"
,
REGEX_OR
)))
||
RegEx
(
",?[]{}"
,
REGEX_OR
);
return
e
;
}
}
inline
const
RegEx
&
EscSingleQuote
()
{
inline
const
RegEx
&
EscSingleQuote
()
{
static
const
RegEx
e
=
RegEx
(
"
\'\'
"
);
return
e
;
}
inline
const
RegEx
&
EscBreak
()
{
}
inline
const
RegEx
&
EscBreak
()
{
static
const
RegEx
e
=
RegEx
(
'\\'
)
+
Break
();
return
e
;
}
}
inline
const
RegEx
&
ChompIndicator
()
{
inline
const
RegEx
&
ChompIndicator
()
{
static
const
RegEx
e
=
RegEx
(
"+-"
,
REGEX_OR
);
return
e
;
}
inline
const
RegEx
&
Chomp
()
{
static
const
RegEx
e
=
(
ChompIndicator
()
+
Digit
())
||
(
Digit
()
+
ChompIndicator
())
||
ChompIndicator
()
||
Digit
();
}
inline
const
RegEx
&
Chomp
()
{
static
const
RegEx
e
=
(
ChompIndicator
()
+
Digit
())
||
(
Digit
()
+
ChompIndicator
())
||
ChompIndicator
()
||
Digit
();
return
e
;
}
}
// and some functions
std
::
string
Escape
(
Stream
&
in
);
}
// and some functions
std
::
string
Escape
(
Stream
&
in
);
}
namespace
Keys
{
const
char
Directive
=
'%'
;
const
char
FlowSeqStart
=
'['
;
const
char
FlowSeqEnd
=
']'
;
const
char
FlowMapStart
=
'{'
;
const
char
FlowMapEnd
=
'}'
;
const
char
FlowEntry
=
','
;
const
char
Alias
=
'*'
;
const
char
Anchor
=
'&'
;
const
char
Tag
=
'!'
;
const
char
LiteralScalar
=
'|'
;
const
char
FoldedScalar
=
'>'
;
const
char
VerbatimTagStart
=
'<'
;
const
char
VerbatimTagEnd
=
'>'
;
}
namespace
Keys
{
const
char
Directive
=
'%'
;
const
char
FlowSeqStart
=
'['
;
const
char
FlowSeqEnd
=
']'
;
const
char
FlowMapStart
=
'{'
;
const
char
FlowMapEnd
=
'}'
;
const
char
FlowEntry
=
','
;
const
char
Alias
=
'*'
;
const
char
Anchor
=
'&'
;
const
char
Tag
=
'!'
;
const
char
LiteralScalar
=
'|'
;
const
char
FoldedScalar
=
'>'
;
const
char
VerbatimTagStart
=
'<'
;
const
char
VerbatimTagEnd
=
'>'
;
}
}
#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/indentation.h
View file @
3355bbb3
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "yaml-cpp/ostream_wrapper.h"
#include <iostream>
namespace
YAML
{
struct
Indentation
{
Indentation
(
unsigned
n_
)
:
n
(
n_
)
{}
namespace
YAML
{
struct
Indentation
{
Indentation
(
unsigned
n_
)
:
n
(
n_
)
{}
unsigned
n
;
};
};
inline
ostream_wrapper
&
operator
<<
(
ostream_wrapper
&
out
,
const
Indentation
&
indent
)
{
for
(
unsigned
i
=
0
;
i
<
indent
.
n
;
i
++
)
inline
ostream_wrapper
&
operator
<<
(
ostream_wrapper
&
out
,
const
Indentation
&
indent
)
{
for
(
unsigned
i
=
0
;
i
<
indent
.
n
;
i
++
)
out
<<
' '
;
return
out
;
}
}
struct
IndentTo
{
IndentTo
(
unsigned
n_
)
:
n
(
n_
)
{}
struct
IndentTo
{
IndentTo
(
unsigned
n_
)
:
n
(
n_
)
{}
unsigned
n
;
};
};
inline
ostream_wrapper
&
operator
<<
(
ostream_wrapper
&
out
,
const
IndentTo
&
indent
)
{
while
(
out
.
col
()
<
indent
.
n
)
inline
ostream_wrapper
&
operator
<<
(
ostream_wrapper
&
out
,
const
IndentTo
&
indent
)
{
while
(
out
.
col
()
<
indent
.
n
)
out
<<
' '
;
return
out
;
}
}
}
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/null.cpp
View file @
3355bbb3
#include "yaml-cpp/null.h"
namespace
YAML
{
_Null
Null
;
namespace
YAML
{
_Null
Null
;
}
src/parser.cpp
View file @
3355bbb3
...
...
@@ -9,133 +9,119 @@
#include <sstream>
#include <cstdio>
namespace
YAML
{
Parser
::
Parser
()
{
}
namespace
YAML
{
Parser
::
Parser
()
{}
Parser
::
Parser
(
std
::
istream
&
in
)
{
Load
(
in
);
}
Parser
::
Parser
(
std
::
istream
&
in
)
{
Load
(
in
);
}
Parser
::~
Parser
()
{
}
Parser
::~
Parser
()
{}
Parser
::
operator
bool
()
const
{
Parser
::
operator
bool
()
const
{
return
m_pScanner
.
get
()
&&
!
m_pScanner
->
empty
();
}
}
void
Parser
::
Load
(
std
::
istream
&
in
)
{
void
Parser
::
Load
(
std
::
istream
&
in
)
{
m_pScanner
.
reset
(
new
Scanner
(
in
));
m_pDirectives
.
reset
(
new
Directives
);
}
}
// HandleNextDocument
// . Handles the next document
// . Throws a ParserException on error.
// . Returns false if there are no more documents
bool
Parser
::
HandleNextDocument
(
EventHandler
&
eventHandler
)
{
if
(
!
m_pScanner
.
get
())
// HandleNextDocument
// . Handles the next document
// . Throws a ParserException on error.
// . Returns false if there are no more documents
bool
Parser
::
HandleNextDocument
(
EventHandler
&
eventHandler
)
{
if
(
!
m_pScanner
.
get
())
return
false
;
ParseDirectives
();
if
(
m_pScanner
->
empty
())
if
(
m_pScanner
->
empty
())
return
false
;
SingleDocParser
sdp
(
*
m_pScanner
,
*
m_pDirectives
);
sdp
.
HandleDocument
(
eventHandler
);
return
true
;
}
}
// ParseDirectives
// . Reads any directives that are next in the queue.
void
Parser
::
ParseDirectives
()
{
// ParseDirectives
// . Reads any directives that are next in the queue.
void
Parser
::
ParseDirectives
()
{
bool
readDirective
=
false
;
while
(
1
)
{
if
(
m_pScanner
->
empty
())
while
(
1
)
{
if
(
m_pScanner
->
empty
())
break
;
Token
&
token
=
m_pScanner
->
peek
();
if
(
token
.
type
!=
Token
::
DIRECTIVE
)
if
(
token
.
type
!=
Token
::
DIRECTIVE
)
break
;
// we keep the directives from the last document if none are specified;
// but if any directives are specific, then we reset them
if
(
!
readDirective
)
if
(
!
readDirective
)
m_pDirectives
.
reset
(
new
Directives
);
readDirective
=
true
;
HandleDirective
(
token
);
m_pScanner
->
pop
();
}
}
}
void
Parser
::
HandleDirective
(
const
Token
&
token
)
{
if
(
token
.
value
==
"YAML"
)
void
Parser
::
HandleDirective
(
const
Token
&
token
)
{
if
(
token
.
value
==
"YAML"
)
HandleYamlDirective
(
token
);
else
if
(
token
.
value
==
"TAG"
)
else
if
(
token
.
value
==
"TAG"
)
HandleTagDirective
(
token
);
}
}
// HandleYamlDirective
// . Should be of the form 'major.minor' (like a version number)
void
Parser
::
HandleYamlDirective
(
const
Token
&
token
)
{
if
(
token
.
params
.
size
()
!=
1
)
// HandleYamlDirective
// . Should be of the form 'major.minor' (like a version number)
void
Parser
::
HandleYamlDirective
(
const
Token
&
token
)
{
if
(
token
.
params
.
size
()
!=
1
)
throw
ParserException
(
token
.
mark
,
ErrorMsg
::
YAML_DIRECTIVE_ARGS
);
if
(
!
m_pDirectives
->
version
.
isDefault
)
if
(
!
m_pDirectives
->
version
.
isDefault
)
throw
ParserException
(
token
.
mark
,
ErrorMsg
::
REPEATED_YAML_DIRECTIVE
);
std
::
stringstream
str
(
token
.
params
[
0
]);
str
>>
m_pDirectives
->
version
.
major
;
str
.
get
();
str
>>
m_pDirectives
->
version
.
minor
;
if
(
!
str
||
str
.
peek
()
!=
EOF
)
throw
ParserException
(
token
.
mark
,
std
::
string
(
ErrorMsg
::
YAML_VERSION
)
+
token
.
params
[
0
]);
if
(
!
str
||
str
.
peek
()
!=
EOF
)
throw
ParserException
(
token
.
mark
,
std
::
string
(
ErrorMsg
::
YAML_VERSION
)
+
token
.
params
[
0
]);
if
(
m_pDirectives
->
version
.
major
>
1
)
if
(
m_pDirectives
->
version
.
major
>
1
)
throw
ParserException
(
token
.
mark
,
ErrorMsg
::
YAML_MAJOR_VERSION
);
m_pDirectives
->
version
.
isDefault
=
false
;
// TODO: warning on major == 1, minor > 2?
}
}
// HandleTagDirective
// . Should be of the form 'handle prefix', where 'handle' is converted to
'prefix' in the file.
void
Parser
::
HandleTagDirective
(
const
Token
&
token
)
{
if
(
token
.
params
.
size
()
!=
2
)
// HandleTagDirective
// . Should be of the form 'handle prefix', where 'handle' is converted to
// 'prefix' in the file.
void
Parser
::
HandleTagDirective
(
const
Token
&
token
)
{
if
(
token
.
params
.
size
()
!=
2
)
throw
ParserException
(
token
.
mark
,
ErrorMsg
::
TAG_DIRECTIVE_ARGS
);
const
std
::
string
&
handle
=
token
.
params
[
0
];
const
std
::
string
&
prefix
=
token
.
params
[
1
];
if
(
m_pDirectives
->
tags
.
find
(
handle
)
!=
m_pDirectives
->
tags
.
end
())
if
(
m_pDirectives
->
tags
.
find
(
handle
)
!=
m_pDirectives
->
tags
.
end
())
throw
ParserException
(
token
.
mark
,
ErrorMsg
::
REPEATED_TAG_DIRECTIVE
);
m_pDirectives
->
tags
[
handle
]
=
prefix
;
}
}
void
Parser
::
PrintTokens
(
std
::
ostream
&
out
)
{
if
(
!
m_pScanner
.
get
())
void
Parser
::
PrintTokens
(
std
::
ostream
&
out
)
{
if
(
!
m_pScanner
.
get
())
return
;
while
(
1
)
{
if
(
m_pScanner
->
empty
())
while
(
1
)
{
if
(
m_pScanner
->
empty
())
break
;
out
<<
m_pScanner
->
peek
()
<<
"
\n
"
;
m_pScanner
->
pop
();
}
}
}
}
src/ptr_stack.h
View file @
3355bbb3
#ifndef PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
...
...
@@ -12,14 +14,13 @@
#include <vector>
template
<
typename
T
>
class
ptr_stack
:
private
YAML
::
noncopyable
{
public:
class
ptr_stack
:
private
YAML
::
noncopyable
{
public:
ptr_stack
()
{}
~
ptr_stack
()
{
clear
();
}
void
clear
()
{
for
(
unsigned
i
=
0
;
i
<
m_data
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
m_data
.
size
();
i
++
)
delete
m_data
[
i
];
m_data
.
clear
();
}
...
...
@@ -40,9 +41,11 @@ public:
const
T
&
top
()
const
{
return
*
m_data
.
back
();
}
T
&
top
(
std
::
ptrdiff_t
diff
)
{
return
**
(
m_data
.
end
()
-
1
+
diff
);
}
const
T
&
top
(
std
::
ptrdiff_t
diff
)
const
{
return
**
(
m_data
.
end
()
-
1
+
diff
);
}
const
T
&
top
(
std
::
ptrdiff_t
diff
)
const
{
return
**
(
m_data
.
end
()
-
1
+
diff
);
}
private:
private:
std
::
vector
<
T
*>
m_data
;
};
...
...
src/ptr_vector.h
View file @
3355bbb3
#ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
...
...
@@ -13,15 +15,14 @@
namespace
YAML
{
template
<
typename
T
>
class
ptr_vector
:
private
YAML
::
noncopyable
{
template
<
typename
T
>
class
ptr_vector
:
private
YAML
::
noncopyable
{
public:
ptr_vector
()
{}
~
ptr_vector
()
{
clear
();
}
void
clear
()
{
for
(
unsigned
i
=
0
;
i
<
m_data
.
size
();
i
++
)
for
(
unsigned
i
=
0
;
i
<
m_data
.
size
();
i
++
)
delete
m_data
[
i
];
m_data
.
clear
();
}
...
...
@@ -41,7 +42,7 @@ namespace YAML {
private:
std
::
vector
<
T
*>
m_data
;
};
};
}
#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/regex.cpp
View file @
3355bbb3
#include "regex.h"
namespace
YAML
{
// constructors
RegEx
::
RegEx
()
:
m_op
(
REGEX_EMPTY
)
{
}
RegEx
::
RegEx
(
REGEX_OP
op
)
:
m_op
(
op
)
{
}
RegEx
::
RegEx
(
char
ch
)
:
m_op
(
REGEX_MATCH
),
m_a
(
ch
)
{
}
RegEx
::
RegEx
(
char
a
,
char
z
)
:
m_op
(
REGEX_RANGE
),
m_a
(
a
),
m_z
(
z
)
{
}
RegEx
::
RegEx
(
const
std
::
string
&
str
,
REGEX_OP
op
)
:
m_op
(
op
)
{
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
namespace
YAML
{
// constructors
RegEx
::
RegEx
()
:
m_op
(
REGEX_EMPTY
)
{}
RegEx
::
RegEx
(
REGEX_OP
op
)
:
m_op
(
op
)
{}
RegEx
::
RegEx
(
char
ch
)
:
m_op
(
REGEX_MATCH
),
m_a
(
ch
)
{}
RegEx
::
RegEx
(
char
a
,
char
z
)
:
m_op
(
REGEX_RANGE
),
m_a
(
a
),
m_z
(
z
)
{}
RegEx
::
RegEx
(
const
std
::
string
&
str
,
REGEX_OP
op
)
:
m_op
(
op
)
{
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
m_params
.
push_back
(
RegEx
(
str
[
i
]));
}
}
// combination constructors
RegEx
operator
!
(
const
RegEx
&
ex
)
{
// combination constructors
RegEx
operator
!
(
const
RegEx
&
ex
)
{
RegEx
ret
(
REGEX_NOT
);
ret
.
m_params
.
push_back
(
ex
);
return
ret
;
}
}
RegEx
operator
||
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
RegEx
operator
||
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
RegEx
ret
(
REGEX_OR
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex2
);
return
ret
;
}
}
RegEx
operator
&&
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
RegEx
operator
&&
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
RegEx
ret
(
REGEX_AND
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex2
);
return
ret
;
}
}
RegEx
operator
+
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
RegEx
operator
+
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
)
{
RegEx
ret
(
REGEX_SEQ
);
ret
.
m_params
.
push_back
(
ex1
);
ret
.
m_params
.
push_back
(
ex2
);
return
ret
;
}
}
}
src/regex.h
View file @
3355bbb3
#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include <vector>
#include <string>
namespace
YAML
{
class
Stream
;
namespace
YAML
{
class
Stream
;
enum
REGEX_OP
{
REGEX_EMPTY
,
REGEX_MATCH
,
REGEX_RANGE
,
REGEX_OR
,
REGEX_AND
,
REGEX_NOT
,
REGEX_SEQ
};
enum
REGEX_OP
{
REGEX_EMPTY
,
REGEX_MATCH
,
REGEX_RANGE
,
REGEX_OR
,
REGEX_AND
,
REGEX_NOT
,
REGEX_SEQ
};
// simplified regular expressions
// . Only straightforward matches (no repeated characters)
// . Only matches from start of string
class
RegEx
{
// simplified regular expressions
// . Only straightforward matches (no repeated characters)
// . Only matches from start of string
class
RegEx
{
public:
RegEx
();
RegEx
(
char
ch
);
...
...
@@ -27,39 +34,50 @@ namespace YAML
RegEx
(
const
std
::
string
&
str
,
REGEX_OP
op
=
REGEX_SEQ
);
~
RegEx
()
{}
friend
RegEx
operator
!
(
const
RegEx
&
ex
);
friend
RegEx
operator
||
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
);
friend
RegEx
operator
&&
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
);
friend
RegEx
operator
+
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
);
friend
RegEx
operator
!
(
const
RegEx
&
ex
);
friend
RegEx
operator
||
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
);
friend
RegEx
operator
&&
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
);
friend
RegEx
operator
+
(
const
RegEx
&
ex1
,
const
RegEx
&
ex2
);
bool
Matches
(
char
ch
)
const
;
bool
Matches
(
const
std
::
string
&
str
)
const
;
bool
Matches
(
const
Stream
&
in
)
const
;
template
<
typename
Source
>
bool
Matches
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
bool
Matches
(
const
Source
&
source
)
const
;
int
Match
(
const
std
::
string
&
str
)
const
;
int
Match
(
const
Stream
&
in
)
const
;
template
<
typename
Source
>
int
Match
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
Match
(
const
Source
&
source
)
const
;
private:
RegEx
(
REGEX_OP
op
);
template
<
typename
Source
>
bool
IsValidSource
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchUnchecked
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
bool
IsValidSource
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchUnchecked
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpEmpty
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpMatch
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpRange
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpOr
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpAnd
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpNot
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpSeq
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpEmpty
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpMatch
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpRange
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpOr
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpAnd
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpNot
(
const
Source
&
source
)
const
;
template
<
typename
Source
>
int
MatchOpSeq
(
const
Source
&
source
)
const
;
private:
REGEX_OP
m_op
;
char
m_a
,
m_z
;
std
::
vector
<
RegEx
>
m_params
;
};
std
::
vector
<
RegEx
>
m_params
;
};
}
#include "regeximpl.h"
...
...
src/regeximpl.h
View file @
3355bbb3
#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
#include "stream.h"
#include "stringsource.h"
#include "streamcharsource.h"
namespace
YAML
{
// query matches
inline
bool
RegEx
::
Matches
(
char
ch
)
const
{
namespace
YAML
{
// query matches
inline
bool
RegEx
::
Matches
(
char
ch
)
const
{
std
::
string
str
;
str
+=
ch
;
return
Matches
(
str
);
}
}
inline
bool
RegEx
::
Matches
(
const
std
::
string
&
str
)
const
{
inline
bool
RegEx
::
Matches
(
const
std
::
string
&
str
)
const
{
return
Match
(
str
)
>=
0
;
}
}
inline
bool
RegEx
::
Matches
(
const
Stream
&
in
)
const
{
return
Match
(
in
)
>=
0
;
}
inline
bool
RegEx
::
Matches
(
const
Stream
&
in
)
const
{
return
Match
(
in
)
>=
0
;
}
template
<
typename
Source
>
inline
bool
RegEx
::
Matches
(
const
Source
&
source
)
const
{
template
<
typename
Source
>
inline
bool
RegEx
::
Matches
(
const
Source
&
source
)
const
{
return
Match
(
source
)
>=
0
;
}
}
// Match
// . Matches the given string against this regular expression.
// . Returns the number of characters matched.
// . Returns -1 if no characters were matched (the reason for
// not returning zero is that we may have an empty regex
// which is ALWAYS successful at matching zero characters).
// . REMEMBER that we only match from the start of the buffer!
inline
int
RegEx
::
Match
(
const
std
::
string
&
str
)
const
{
// Match
// . Matches the given string against this regular expression.
// . Returns the number of characters matched.
// . Returns -1 if no characters were matched (the reason for
// not returning zero is that we may have an empty regex
// which is ALWAYS successful at matching zero characters).
// . REMEMBER that we only match from the start of the buffer!
inline
int
RegEx
::
Match
(
const
std
::
string
&
str
)
const
{
StringCharSource
source
(
str
.
c_str
(),
str
.
size
());
return
Match
(
source
);
}
}
inline
int
RegEx
::
Match
(
const
Stream
&
in
)
const
{
inline
int
RegEx
::
Match
(
const
Stream
&
in
)
const
{
StreamCharSource
source
(
in
);
return
Match
(
source
);
}
}
template
<
typename
Source
>
inline
bool
RegEx
::
IsValidSource
(
const
Source
&
source
)
const
{
template
<
typename
Source
>
inline
bool
RegEx
::
IsValidSource
(
const
Source
&
source
)
const
{
return
source
;
}
}
template
<
>
inline
bool
RegEx
::
IsValidSource
<
StringCharSource
>
(
const
StringCharSource
&
source
)
const
{
switch
(
m_op
)
{
template
<
>
inline
bool
RegEx
::
IsValidSource
<
StringCharSource
>
(
const
StringCharSource
&
source
)
const
{
switch
(
m_op
)
{
case
REGEX_MATCH
:
case
REGEX_RANGE
:
return
source
;
default:
return
true
;
}
}
}
template
<
typename
Source
>
inline
int
RegEx
::
Match
(
const
Source
&
source
)
const
{
template
<
typename
Source
>
inline
int
RegEx
::
Match
(
const
Source
&
source
)
const
{
return
IsValidSource
(
source
)
?
MatchUnchecked
(
source
)
:
-
1
;
}
}
template
<
typename
Source
>
inline
int
RegEx
::
MatchUnchecked
(
const
Source
&
source
)
const
{
switch
(
m_op
)
{
template
<
typename
Source
>
inline
int
RegEx
::
MatchUnchecked
(
const
Source
&
source
)
const
{
switch
(
m_op
)
{
case
REGEX_EMPTY
:
return
MatchOpEmpty
(
source
);
case
REGEX_MATCH
:
...
...
@@ -96,91 +89,98 @@ namespace YAML
}
return
-
1
;
}
}
//////////////////////////////////////////////////////////////////////////////
// Operators
// Note: the convention MatchOp*<Source> is that we can assume IsSourceValid(source).
// So we do all our checks *before* we call these functions
//////////////////////////////////////////////////////////////////////////////
// Operators
// Note: the convention MatchOp*<Source> is that we can assume
// IsSourceValid(source).
// So we do all our checks *before* we call these functions
// EmptyOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpEmpty
(
const
Source
&
source
)
const
{
// EmptyOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpEmpty
(
const
Source
&
source
)
const
{
return
source
[
0
]
==
Stream
::
eof
()
?
0
:
-
1
;
}
}
template
<
>
inline
int
RegEx
::
MatchOpEmpty
<
StringCharSource
>
(
const
StringCharSource
&
source
)
const
{
return
!
source
?
0
:
-
1
;
// the empty regex only is successful on the empty string
}
template
<
>
inline
int
RegEx
::
MatchOpEmpty
<
StringCharSource
>
(
const
StringCharSource
&
source
)
const
{
return
!
source
?
0
:
-
1
;
// the empty regex only is successful on the empty string
}
// MatchOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpMatch
(
const
Source
&
source
)
const
{
if
(
source
[
0
]
!=
m_a
)
// MatchOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpMatch
(
const
Source
&
source
)
const
{
if
(
source
[
0
]
!=
m_a
)
return
-
1
;
return
1
;
}
}
// RangeOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpRange
(
const
Source
&
source
)
const
{
if
(
m_a
>
source
[
0
]
||
m_z
<
source
[
0
])
// RangeOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpRange
(
const
Source
&
source
)
const
{
if
(
m_a
>
source
[
0
]
||
m_z
<
source
[
0
])
return
-
1
;
return
1
;
}
}
// OrOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpOr
(
const
Source
&
source
)
const
{
for
(
std
::
size_t
i
=
0
;
i
<
m_params
.
size
();
i
++
)
{
// OrOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpOr
(
const
Source
&
source
)
const
{
for
(
std
::
size_t
i
=
0
;
i
<
m_params
.
size
();
i
++
)
{
int
n
=
m_params
[
i
].
MatchUnchecked
(
source
);
if
(
n
>=
0
)
if
(
n
>=
0
)
return
n
;
}
return
-
1
;
}
}
// AndOperator
// 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
// the FIRST entry on the list.
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpAnd
(
const
Source
&
source
)
const
{
// AndOperator
// 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
// the FIRST entry on the list.
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpAnd
(
const
Source
&
source
)
const
{
int
first
=
-
1
;
for
(
std
::
size_t
i
=
0
;
i
<
m_params
.
size
();
i
++
)
{
for
(
std
::
size_t
i
=
0
;
i
<
m_params
.
size
();
i
++
)
{
int
n
=
m_params
[
i
].
MatchUnchecked
(
source
);
if
(
n
==
-
1
)
if
(
n
==
-
1
)
return
-
1
;
if
(
i
==
0
)
if
(
i
==
0
)
first
=
n
;
}
return
first
;
}
}
// NotOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpNot
(
const
Source
&
source
)
const
{
if
(
m_params
.
empty
())
// NotOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpNot
(
const
Source
&
source
)
const
{
if
(
m_params
.
empty
())
return
-
1
;
if
(
m_params
[
0
].
MatchUnchecked
(
source
)
>=
0
)
if
(
m_params
[
0
].
MatchUnchecked
(
source
)
>=
0
)
return
-
1
;
return
1
;
}
}
// SeqOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpSeq
(
const
Source
&
source
)
const
{
// SeqOperator
template
<
typename
Source
>
inline
int
RegEx
::
MatchOpSeq
(
const
Source
&
source
)
const
{
int
offset
=
0
;
for
(
std
::
size_t
i
=
0
;
i
<
m_params
.
size
();
i
++
)
{
int
n
=
m_params
[
i
].
Match
(
source
+
offset
);
// note Match, not MatchUnchecked because we need to check validity after the offset
if
(
n
==
-
1
)
for
(
std
::
size_t
i
=
0
;
i
<
m_params
.
size
();
i
++
)
{
int
n
=
m_params
[
i
].
Match
(
source
+
offset
);
// note Match, not
// MatchUnchecked because we
// need to check validity after
// the offset
if
(
n
==
-
1
)
return
-
1
;
offset
+=
n
;
}
return
offset
;
}
}
}
#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
src/scanner.cpp
View file @
3355bbb3
...
...
@@ -5,40 +5,37 @@
#include <cassert>
#include <memory>
namespace
YAML
{
Scanner
::
Scanner
(
std
::
istream
&
in
)
:
INPUT
(
in
),
m_startedStream
(
false
),
m_endedStream
(
false
),
m_simpleKeyAllowed
(
false
),
m_canBeJSONFlow
(
false
)
{
}
Scanner
::~
Scanner
()
{
}
// empty
// . Returns true if there are no more tokens to be read
bool
Scanner
::
empty
()
{
namespace
YAML
{
Scanner
::
Scanner
(
std
::
istream
&
in
)
:
INPUT
(
in
),
m_startedStream
(
false
),
m_endedStream
(
false
),
m_simpleKeyAllowed
(
false
),
m_canBeJSONFlow
(
false
)
{}
Scanner
::~
Scanner
()
{}
// empty
// . Returns true if there are no more tokens to be read
bool
Scanner
::
empty
()
{
EnsureTokensInQueue
();
return
m_tokens
.
empty
();
}
}
// pop
// . Simply removes the next token on the queue.
void
Scanner
::
pop
()
{
// pop
// . Simply removes the next token on the queue.
void
Scanner
::
pop
()
{
EnsureTokensInQueue
();
if
(
!
m_tokens
.
empty
())
if
(
!
m_tokens
.
empty
())
m_tokens
.
pop
();
}
}
// peek
// . Returns (but does not remove) the next token on the queue.
Token
&
Scanner
::
peek
()
{
// peek
// . Returns (but does not remove) the next token on the queue.
Token
&
Scanner
::
peek
()
{
EnsureTokensInQueue
();
assert
(
!
m_tokens
.
empty
());
// should we be asserting here? I mean, we really just be checking
assert
(
!
m_tokens
.
empty
());
// should we be asserting here? I mean, we really
// just be checking
// if it's empty before peeking.
#if 0
...
...
@@ -49,30 +46,26 @@ namespace YAML
#endif
return
m_tokens
.
front
();
}
}
// mark
// . Returns the current mark in the stream
Mark
Scanner
::
mark
()
const
{
return
INPUT
.
mark
();
}
// mark
// . Returns the current mark in the stream
Mark
Scanner
::
mark
()
const
{
return
INPUT
.
mark
();
}
// EnsureTokensInQueue
// . Scan until there's a valid token at the front of the queue,
// or we're sure the queue is empty.
void
Scanner
::
EnsureTokensInQueue
()
{
while
(
1
)
{
if
(
!
m_tokens
.
empty
())
{
// EnsureTokensInQueue
// . Scan until there's a valid token at the front of the queue,
// or we're sure the queue is empty.
void
Scanner
::
EnsureTokensInQueue
()
{
while
(
1
)
{
if
(
!
m_tokens
.
empty
())
{
Token
&
token
=
m_tokens
.
front
();
// if this guy's valid, then we're done
if
(
token
.
status
==
Token
::
VALID
)
if
(
token
.
status
==
Token
::
VALID
)
return
;
// here's where we clean up the impossible tokens
if
(
token
.
status
==
Token
::
INVALID
)
{
if
(
token
.
status
==
Token
::
INVALID
)
{
m_tokens
.
pop
();
continue
;
}
...
...
@@ -81,23 +74,22 @@ namespace YAML
}
// no token? maybe we've actually finished
if
(
m_endedStream
)
if
(
m_endedStream
)
return
;
// no? then scan...
ScanNextToken
();
}
}
}
// ScanNextToken
// . The main scanning function; here we branch out and
// scan whatever the next token should be.
void
Scanner
::
ScanNextToken
()
{
if
(
m_endedStream
)
// ScanNextToken
// . The main scanning function; here we branch out and
// scan whatever the next token should be.
void
Scanner
::
ScanNextToken
()
{
if
(
m_endedStream
)
return
;
if
(
!
m_startedStream
)
if
(
!
m_startedStream
)
return
StartStream
();
// get rid of whitespace, etc. (in between tokens it should be irrelevent)
...
...
@@ -111,83 +103,84 @@ namespace YAML
// *****
// end of stream
if
(
!
INPUT
)
if
(
!
INPUT
)
return
EndStream
();
if
(
INPUT
.
column
()
==
0
&&
INPUT
.
peek
()
==
Keys
::
Directive
)
if
(
INPUT
.
column
()
==
0
&&
INPUT
.
peek
()
==
Keys
::
Directive
)
return
ScanDirective
();
// document token
if
(
INPUT
.
column
()
==
0
&&
Exp
::
DocStart
().
Matches
(
INPUT
))
if
(
INPUT
.
column
()
==
0
&&
Exp
::
DocStart
().
Matches
(
INPUT
))
return
ScanDocStart
();
if
(
INPUT
.
column
()
==
0
&&
Exp
::
DocEnd
().
Matches
(
INPUT
))
if
(
INPUT
.
column
()
==
0
&&
Exp
::
DocEnd
().
Matches
(
INPUT
))
return
ScanDocEnd
();
// flow start/end/entry
if
(
INPUT
.
peek
()
==
Keys
::
FlowSeqStart
||
INPUT
.
peek
()
==
Keys
::
FlowMapStart
)
if
(
INPUT
.
peek
()
==
Keys
::
FlowSeqStart
||
INPUT
.
peek
()
==
Keys
::
FlowMapStart
)
return
ScanFlowStart
();
if
(
INPUT
.
peek
()
==
Keys
::
FlowSeqEnd
||
INPUT
.
peek
()
==
Keys
::
FlowMapEnd
)
if
(
INPUT
.
peek
()
==
Keys
::
FlowSeqEnd
||
INPUT
.
peek
()
==
Keys
::
FlowMapEnd
)
return
ScanFlowEnd
();
if
(
INPUT
.
peek
()
==
Keys
::
FlowEntry
)
if
(
INPUT
.
peek
()
==
Keys
::
FlowEntry
)
return
ScanFlowEntry
();
// block/map stuff
if
(
Exp
::
BlockEntry
().
Matches
(
INPUT
))
if
(
Exp
::
BlockEntry
().
Matches
(
INPUT
))
return
ScanBlockEntry
();
if
((
InBlockContext
()
?
Exp
::
Key
()
:
Exp
::
KeyInFlow
()).
Matches
(
INPUT
))
if
((
InBlockContext
()
?
Exp
::
Key
()
:
Exp
::
KeyInFlow
()).
Matches
(
INPUT
))
return
ScanKey
();
if
(
GetValueRegex
().
Matches
(
INPUT
))
if
(
GetValueRegex
().
Matches
(
INPUT
))
return
ScanValue
();
// alias/anchor
if
(
INPUT
.
peek
()
==
Keys
::
Alias
||
INPUT
.
peek
()
==
Keys
::
Anchor
)
if
(
INPUT
.
peek
()
==
Keys
::
Alias
||
INPUT
.
peek
()
==
Keys
::
Anchor
)
return
ScanAnchorOrAlias
();
// tag
if
(
INPUT
.
peek
()
==
Keys
::
Tag
)
if
(
INPUT
.
peek
()
==
Keys
::
Tag
)
return
ScanTag
();
// special scalars
if
(
InBlockContext
()
&&
(
INPUT
.
peek
()
==
Keys
::
LiteralScalar
||
INPUT
.
peek
()
==
Keys
::
FoldedScalar
))
if
(
InBlockContext
()
&&
(
INPUT
.
peek
()
==
Keys
::
LiteralScalar
||
INPUT
.
peek
()
==
Keys
::
FoldedScalar
))
return
ScanBlockScalar
();
if
(
INPUT
.
peek
()
==
'\''
||
INPUT
.
peek
()
==
'\"'
)
if
(
INPUT
.
peek
()
==
'\''
||
INPUT
.
peek
()
==
'\"'
)
return
ScanQuotedScalar
();
// plain scalars
if
((
InBlockContext
()
?
Exp
::
PlainScalar
()
:
Exp
::
PlainScalarInFlow
()).
Matches
(
INPUT
))
if
((
InBlockContext
()
?
Exp
::
PlainScalar
()
:
Exp
::
PlainScalarInFlow
())
.
Matches
(
INPUT
))
return
ScanPlainScalar
();
// don't know what it is!
throw
ParserException
(
INPUT
.
mark
(),
ErrorMsg
::
UNKNOWN_TOKEN
);
}
}
// ScanToNextToken
// . Eats input until we reach the next token-like thing.
void
Scanner
::
ScanToNextToken
()
{
while
(
1
)
{
// ScanToNextToken
// . Eats input until we reach the next token-like thing.
void
Scanner
::
ScanToNextToken
()
{
while
(
1
)
{
// first eat whitespace
while
(
INPUT
&&
IsWhitespaceToBeEaten
(
INPUT
.
peek
()))
{
if
(
InBlockContext
()
&&
Exp
::
Tab
().
Matches
(
INPUT
))
while
(
INPUT
&&
IsWhitespaceToBeEaten
(
INPUT
.
peek
()))
{
if
(
InBlockContext
()
&&
Exp
::
Tab
().
Matches
(
INPUT
))
m_simpleKeyAllowed
=
false
;
INPUT
.
eat
(
1
);
}
// then eat a comment
if
(
Exp
::
Comment
().
Matches
(
INPUT
))
{
if
(
Exp
::
Comment
().
Matches
(
INPUT
))
{
// eat until line break
while
(
INPUT
&&
!
Exp
::
Break
().
Matches
(
INPUT
))
while
(
INPUT
&&
!
Exp
::
Break
().
Matches
(
INPUT
))
INPUT
.
eat
(
1
);
}
// if it's NOT a line break, then we're done!
if
(
!
Exp
::
Break
().
Matches
(
INPUT
))
if
(
!
Exp
::
Break
().
Matches
(
INPUT
))
break
;
// otherwise, let's eat the line break and keep going
...
...
@@ -198,60 +191,57 @@ namespace YAML
InvalidateSimpleKey
();
// new line - we may be able to accept a simple key now
if
(
InBlockContext
())
if
(
InBlockContext
())
m_simpleKeyAllowed
=
true
;
}
}
}
///////////////////////////////////////////////////////////////////////
// Misc. helpers
// IsWhitespaceToBeEaten
// . We can eat whitespace if it's a space or tab
// . Note: originally tabs in block context couldn't be eaten
// "where a simple key could be allowed
// (i.e., not at the beginning of a line, or following '-', '?', or
':')"
//
I think this is wrong, since tabs can be non-content whitespace; it's just
//
that they can't contribute to indentation, so once you've seen a tab in a
//
line, you can't start a simple key
bool
Scanner
::
IsWhitespaceToBeEaten
(
char
ch
)
{
if
(
ch
==
' '
)
///////////////////////////////////////////////////////////////////////
// Misc. helpers
// IsWhitespaceToBeEaten
// . We can eat whitespace if it's a space or tab
// . Note: originally tabs in block context couldn't be eaten
// "where a simple key could be allowed
// (i.e., not at the beginning of a line, or following '-', '?', or
//
':')"
//
I think this is wrong, since tabs can be non-content whitespace; it's just
//
that they can't contribute to indentation, so once you've seen a tab in a
// line, you can't start a simple key
bool
Scanner
::
IsWhitespaceToBeEaten
(
char
ch
)
{
if
(
ch
==
' '
)
return
true
;
if
(
ch
==
'\t'
)
if
(
ch
==
'\t'
)
return
true
;
return
false
;
}
}
// GetValueRegex
// . Get the appropriate regex to check if it's a value token
const
RegEx
&
Scanner
::
GetValueRegex
()
const
{
if
(
InBlockContext
())
// GetValueRegex
// . Get the appropriate regex to check if it's a value token
const
RegEx
&
Scanner
::
GetValueRegex
()
const
{
if
(
InBlockContext
())
return
Exp
::
Value
();
return
m_canBeJSONFlow
?
Exp
::
ValueInJSONFlow
()
:
Exp
::
ValueInFlow
();
}
}
// StartStream
// . Set the initial conditions for starting a stream.
void
Scanner
::
StartStream
()
{
// StartStream
// . Set the initial conditions for starting a stream.
void
Scanner
::
StartStream
()
{
m_startedStream
=
true
;
m_simpleKeyAllowed
=
true
;
std
::
auto_ptr
<
IndentMarker
>
pIndent
(
new
IndentMarker
(
-
1
,
IndentMarker
::
NONE
));
m_indentRefs
.
push_back
(
pIndent
);
m_indents
.
push
(
&
m_indentRefs
.
back
());
}
}
// EndStream
// . Close out the stream, finish up, etc.
void
Scanner
::
EndStream
()
{
// EndStream
// . Close out the stream, finish up, etc.
void
Scanner
::
EndStream
()
{
// force newline
if
(
INPUT
.
column
()
>
0
)
if
(
INPUT
.
column
()
>
0
)
INPUT
.
ResetColumn
();
PopAllIndents
();
...
...
@@ -259,33 +249,35 @@ namespace YAML
m_simpleKeyAllowed
=
false
;
m_endedStream
=
true
;
}
}
Token
*
Scanner
::
PushToken
(
Token
::
TYPE
type
)
{
Token
*
Scanner
::
PushToken
(
Token
::
TYPE
type
)
{
m_tokens
.
push
(
Token
(
type
,
INPUT
.
mark
()));
return
&
m_tokens
.
back
();
}
}
Token
::
TYPE
Scanner
::
GetStartTokenFor
(
IndentMarker
::
INDENT_TYPE
type
)
const
{
switch
(
type
)
{
case
IndentMarker
::
SEQ
:
return
Token
::
BLOCK_SEQ_START
;
case
IndentMarker
::
MAP
:
return
Token
::
BLOCK_MAP_START
;
case
IndentMarker
::
NONE
:
assert
(
false
);
break
;
Token
::
TYPE
Scanner
::
GetStartTokenFor
(
IndentMarker
::
INDENT_TYPE
type
)
const
{
switch
(
type
)
{
case
IndentMarker
::
SEQ
:
return
Token
::
BLOCK_SEQ_START
;
case
IndentMarker
::
MAP
:
return
Token
::
BLOCK_MAP_START
;
case
IndentMarker
::
NONE
:
assert
(
false
);
break
;
}
assert
(
false
);
throw
std
::
runtime_error
(
"yaml-cpp: internal error, invalid indent type"
);
}
}
// PushIndentTo
// . Pushes an indentation onto the stack, and enqueues the
// proper token (sequence start or mapping start).
// . Returns the indent marker it generates (if any).
Scanner
::
IndentMarker
*
Scanner
::
PushIndentTo
(
int
column
,
IndentMarker
::
INDENT_TYPE
type
)
{
// PushIndentTo
// . Pushes an indentation onto the stack, and enqueues the
// proper token (sequence start or mapping start).
// . Returns the indent marker it generates (if any).
Scanner
::
IndentMarker
*
Scanner
::
PushIndentTo
(
int
column
,
IndentMarker
::
INDENT_TYPE
type
)
{
// are we in flow?
if
(
InFlowContext
())
if
(
InFlowContext
())
return
0
;
std
::
auto_ptr
<
IndentMarker
>
pIndent
(
new
IndentMarker
(
column
,
type
));
...
...
@@ -293,9 +285,11 @@ namespace YAML
const
IndentMarker
&
lastIndent
=
*
m_indents
.
top
();
// is this actually an indentation?
if
(
indent
.
column
<
lastIndent
.
column
)
if
(
indent
.
column
<
lastIndent
.
column
)
return
0
;
if
(
indent
.
column
==
lastIndent
.
column
&&
!
(
indent
.
type
==
IndentMarker
::
SEQ
&&
lastIndent
.
type
==
IndentMarker
::
MAP
))
if
(
indent
.
column
==
lastIndent
.
column
&&
!
(
indent
.
type
==
IndentMarker
::
SEQ
&&
lastIndent
.
type
==
IndentMarker
::
MAP
))
return
0
;
// push a start token
...
...
@@ -305,90 +299,86 @@ namespace YAML
m_indents
.
push
(
&
indent
);
m_indentRefs
.
push_back
(
pIndent
);
return
&
m_indentRefs
.
back
();
}
}
// PopIndentToHere
// . Pops indentations off the stack until we reach the current indentation
level,
//
and enqueues the proper token each time.
//
. T
he
n
pop
s all invalid indentations off
.
void
Scanner
::
PopIndentToHere
()
{
// PopIndentToHere
// . Pops indentations off the stack until we reach the current indentation
//
level,
//
and enqueues t
he p
r
op
er token each time
.
// . Then pops all invalid indentations off.
void
Scanner
::
PopIndentToHere
()
{
// are we in flow?
if
(
InFlowContext
())
if
(
InFlowContext
())
return
;
// now pop away
while
(
!
m_indents
.
empty
())
{
while
(
!
m_indents
.
empty
())
{
const
IndentMarker
&
indent
=
*
m_indents
.
top
();
if
(
indent
.
column
<
INPUT
.
column
())
if
(
indent
.
column
<
INPUT
.
column
())
break
;
if
(
indent
.
column
==
INPUT
.
column
()
&&
!
(
indent
.
type
==
IndentMarker
::
SEQ
&&
!
Exp
::
BlockEntry
().
Matches
(
INPUT
)))
if
(
indent
.
column
==
INPUT
.
column
()
&&
!
(
indent
.
type
==
IndentMarker
::
SEQ
&&
!
Exp
::
BlockEntry
().
Matches
(
INPUT
)))
break
;
PopIndent
();
}
while
(
!
m_indents
.
empty
()
&&
m_indents
.
top
()
->
status
==
IndentMarker
::
INVALID
)
while
(
!
m_indents
.
empty
()
&&
m_indents
.
top
()
->
status
==
IndentMarker
::
INVALID
)
PopIndent
();
}
}
// PopAllIndents
// . Pops all indentations (except for the base empty one) off the stack,
// and enqueues the proper token each time.
void
Scanner
::
PopAllIndents
()
{
// PopAllIndents
// . Pops all indentations (except for the base empty one) off the stack,
// and enqueues the proper token each time.
void
Scanner
::
PopAllIndents
()
{
// are we in flow?
if
(
InFlowContext
())
if
(
InFlowContext
())
return
;
// now pop away
while
(
!
m_indents
.
empty
())
{
while
(
!
m_indents
.
empty
())
{
const
IndentMarker
&
indent
=
*
m_indents
.
top
();
if
(
indent
.
type
==
IndentMarker
::
NONE
)
if
(
indent
.
type
==
IndentMarker
::
NONE
)
break
;
PopIndent
();
}
}
}
// PopIndent
// . Pops a single indent, pushing the proper token
void
Scanner
::
PopIndent
()
{
// PopIndent
// . Pops a single indent, pushing the proper token
void
Scanner
::
PopIndent
()
{
const
IndentMarker
&
indent
=
*
m_indents
.
top
();
m_indents
.
pop
();
if
(
indent
.
status
!=
IndentMarker
::
VALID
)
{
if
(
indent
.
status
!=
IndentMarker
::
VALID
)
{
InvalidateSimpleKey
();
return
;
}
if
(
indent
.
type
==
IndentMarker
::
SEQ
)
if
(
indent
.
type
==
IndentMarker
::
SEQ
)
m_tokens
.
push
(
Token
(
Token
::
BLOCK_SEQ_END
,
INPUT
.
mark
()));
else
if
(
indent
.
type
==
IndentMarker
::
MAP
)
else
if
(
indent
.
type
==
IndentMarker
::
MAP
)
m_tokens
.
push
(
Token
(
Token
::
BLOCK_MAP_END
,
INPUT
.
mark
()));
}
}
// GetTopIndent
int
Scanner
::
GetTopIndent
()
const
{
if
(
m_indents
.
empty
())
// GetTopIndent
int
Scanner
::
GetTopIndent
()
const
{
if
(
m_indents
.
empty
())
return
0
;
return
m_indents
.
top
()
->
column
;
}
}
// 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
{
// 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
{
Mark
mark
=
Mark
::
null_mark
();
if
(
!
m_tokens
.
empty
())
{
if
(
!
m_tokens
.
empty
())
{
const
Token
&
token
=
m_tokens
.
front
();
mark
=
token
.
mark
;
}
throw
ParserException
(
mark
,
msg
);
}
}
}
Prev
1
2
3
4
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