Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yaml-cpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
yaml-cpp
Commits
899b6614
Commit
899b6614
authored
Jan 24, 2015
by
Jesse Beder
Browse files
Options
Browse Files
Download
Plain Diff
Merge from core
parents
7d932f0a
bc86fd4a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
41 deletions
+80
-41
src/emitterutils.cpp
+74
-41
test/integration/emitter_test.cpp
+6
-0
No files found.
src/emitterutils.cpp
View file @
899b6614
...
@@ -32,22 +32,29 @@ bool IsAnchorChar(int ch) { // test for ns-anchor-char
...
@@ -32,22 +32,29 @@ bool IsAnchorChar(int ch) { // test for ns-anchor-char
return
true
;
return
true
;
}
}
if
(
ch
<
0x20
)
if
(
ch
<
0x20
)
{
return
false
;
return
false
;
}
if
(
ch
<
0x7E
)
if
(
ch
<
0x7E
)
{
return
true
;
return
true
;
}
if
(
ch
<
0xA0
)
if
(
ch
<
0xA0
)
{
return
false
;
return
false
;
if
(
ch
>=
0xD800
&&
ch
<=
0xDFFF
)
}
if
(
ch
>=
0xD800
&&
ch
<=
0xDFFF
)
{
return
false
;
return
false
;
if
((
ch
&
0xFFFE
)
==
0xFFFE
)
}
if
((
ch
&
0xFFFE
)
==
0xFFFE
)
{
return
false
;
return
false
;
if
((
ch
>=
0xFDD0
)
&&
(
ch
<=
0xFDEF
))
}
if
((
ch
>=
0xFDD0
)
&&
(
ch
<=
0xFDEF
))
{
return
false
;
return
false
;
if
(
ch
>
0x10FFFF
)
}
if
(
ch
>
0x10FFFF
)
{
return
false
;
return
false
;
}
return
true
;
return
true
;
}
}
...
@@ -145,19 +152,27 @@ void WriteCodePoint(ostream_wrapper& out, int codePoint) {
...
@@ -145,19 +152,27 @@ void WriteCodePoint(ostream_wrapper& out, int codePoint) {
bool
IsValidPlainScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
IsValidPlainScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
allowOnlyAscii
)
{
bool
allowOnlyAscii
)
{
if
(
str
.
empty
())
if
(
str
.
empty
())
{
return
false
;
}
// check against null
if
(
str
==
"null"
)
{
return
false
;
return
false
;
}
//
first
check the start
// check the start
const
RegEx
&
start
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
PlainScalarInFlow
()
const
RegEx
&
start
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
PlainScalarInFlow
()
:
Exp
::
PlainScalar
());
:
Exp
::
PlainScalar
());
if
(
!
start
.
Matches
(
str
))
if
(
!
start
.
Matches
(
str
))
{
return
false
;
return
false
;
}
// and check the end for plain whitespace (which can't be faithfully kept in a
// and check the end for plain whitespace (which can't be faithfully kept in a
// plain scalar)
// plain scalar)
if
(
!
str
.
empty
()
&&
*
str
.
rbegin
()
==
' '
)
if
(
!
str
.
empty
()
&&
*
str
.
rbegin
()
==
' '
)
{
return
false
;
return
false
;
}
// then check until something is disallowed
// then check until something is disallowed
const
RegEx
&
disallowed
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
EndScalarInFlow
()
const
RegEx
&
disallowed
=
(
flowType
==
FlowType
::
Flow
?
Exp
::
EndScalarInFlow
()
...
@@ -167,10 +182,12 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
...
@@ -167,10 +182,12 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
Exp
::
Break
()
||
Exp
::
Tab
();
Exp
::
Break
()
||
Exp
::
Tab
();
StringCharSource
buffer
(
str
.
c_str
(),
str
.
size
());
StringCharSource
buffer
(
str
.
c_str
(),
str
.
size
());
while
(
buffer
)
{
while
(
buffer
)
{
if
(
disallowed
.
Matches
(
buffer
))
if
(
disallowed
.
Matches
(
buffer
))
{
return
false
;
return
false
;
if
(
allowOnlyAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
buffer
[
0
])))
}
if
(
allowOnlyAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
buffer
[
0
])))
{
return
false
;
return
false
;
}
++
buffer
;
++
buffer
;
}
}
...
@@ -180,23 +197,27 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
...
@@ -180,23 +197,27 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
bool
IsValidSingleQuotedScalar
(
const
std
::
string
&
str
,
bool
escapeNonAscii
)
{
bool
IsValidSingleQuotedScalar
(
const
std
::
string
&
str
,
bool
escapeNonAscii
)
{
// TODO: check for non-printable characters?
// TODO: check for non-printable characters?
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
{
return
false
;
return
false
;
if
(
str
[
i
]
==
'\n'
)
}
if
(
str
[
i
]
==
'\n'
)
{
return
false
;
return
false
;
}
}
}
return
true
;
return
true
;
}
}
bool
IsValidLiteralScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
IsValidLiteralScalar
(
const
std
::
string
&
str
,
FlowType
::
value
flowType
,
bool
escapeNonAscii
)
{
bool
escapeNonAscii
)
{
if
(
flowType
==
FlowType
::
Flow
)
if
(
flowType
==
FlowType
::
Flow
)
{
return
false
;
return
false
;
}
// TODO: check for non-printable characters?
// TODO: check for non-printable characters?
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
for
(
std
::
size_t
i
=
0
;
i
<
str
.
size
();
i
++
)
{
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
if
(
escapeNonAscii
&&
(
0x80
<=
static_cast
<
unsigned
char
>
(
str
[
i
])))
{
return
false
;
return
false
;
}
}
}
return
true
;
return
true
;
}
}
...
@@ -226,8 +247,9 @@ bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
...
@@ -226,8 +247,9 @@ bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
int
codePoint
;
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
if
(
!
IsAnchorChar
(
codePoint
))
if
(
!
IsAnchorChar
(
codePoint
))
{
return
false
;
return
false
;
}
WriteCodePoint
(
out
,
codePoint
);
WriteCodePoint
(
out
,
codePoint
);
}
}
...
@@ -241,18 +263,21 @@ StringFormat::value ComputeStringFormat(const std::string& str,
...
@@ -241,18 +263,21 @@ StringFormat::value ComputeStringFormat(const std::string& str,
bool
escapeNonAscii
)
{
bool
escapeNonAscii
)
{
switch
(
strFormat
)
{
switch
(
strFormat
)
{
case
Auto
:
case
Auto
:
if
(
IsValidPlainScalar
(
str
,
flowType
,
escapeNonAscii
))
if
(
IsValidPlainScalar
(
str
,
flowType
,
escapeNonAscii
))
{
return
StringFormat
::
Plain
;
return
StringFormat
::
Plain
;
}
return
StringFormat
::
DoubleQuoted
;
return
StringFormat
::
DoubleQuoted
;
case
SingleQuoted
:
case
SingleQuoted
:
if
(
IsValidSingleQuotedScalar
(
str
,
escapeNonAscii
))
if
(
IsValidSingleQuotedScalar
(
str
,
escapeNonAscii
))
{
return
StringFormat
::
SingleQuoted
;
return
StringFormat
::
SingleQuoted
;
}
return
StringFormat
::
DoubleQuoted
;
return
StringFormat
::
DoubleQuoted
;
case
DoubleQuoted
:
case
DoubleQuoted
:
return
StringFormat
::
DoubleQuoted
;
return
StringFormat
::
DoubleQuoted
;
case
Literal
:
case
Literal
:
if
(
IsValidLiteralScalar
(
str
,
flowType
,
escapeNonAscii
))
if
(
IsValidLiteralScalar
(
str
,
flowType
,
escapeNonAscii
))
{
return
StringFormat
::
Literal
;
return
StringFormat
::
Literal
;
}
return
StringFormat
::
DoubleQuoted
;
return
StringFormat
::
DoubleQuoted
;
default
:
default
:
break
;
break
;
...
@@ -266,14 +291,16 @@ bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
...
@@ -266,14 +291,16 @@ bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
int
codePoint
;
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
if
(
codePoint
==
'\n'
)
if
(
codePoint
==
'\n'
)
{
return
false
;
// We can't handle a new line and the attendant indentation
return
false
;
// We can't handle a new line and the attendant indentation
// yet
// yet
}
if
(
codePoint
==
'\''
)
if
(
codePoint
==
'\''
)
{
out
<<
"''"
;
out
<<
"''"
;
else
}
else
{
WriteCodePoint
(
out
,
codePoint
);
WriteCodePoint
(
out
,
codePoint
);
}
}
}
out
<<
"'"
;
out
<<
"'"
;
return
true
;
return
true
;
...
@@ -307,15 +334,16 @@ bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
...
@@ -307,15 +334,16 @@ bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
default
:
default
:
if
(
codePoint
<
0x20
||
if
(
codePoint
<
0x20
||
(
codePoint
>=
0x80
&&
(
codePoint
>=
0x80
&&
codePoint
<=
0xA0
))
// Control characters and non-breaking space
codePoint
<=
0xA0
))
{
// Control characters and non-breaking space
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
else
if
(
codePoint
==
0xFEFF
)
// Byte order marks (ZWNS) should be
}
else
if
(
codePoint
==
0xFEFF
)
{
// Byte order marks (ZWNS) should be
// escaped (YAML 1.2, sec. 5.2)
// escaped (YAML 1.2, sec. 5.2)
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
else
if
(
escapeNonAscii
&&
codePoint
>
0x7E
)
}
else
if
(
escapeNonAscii
&&
codePoint
>
0x7E
)
{
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
WriteDoubleQuoteEscapeSequence
(
out
,
codePoint
);
else
}
else
{
WriteCodePoint
(
out
,
codePoint
);
WriteCodePoint
(
out
,
codePoint
);
}
}
}
}
}
out
<<
"
\"
"
;
out
<<
"
\"
"
;
...
@@ -329,26 +357,27 @@ bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
...
@@ -329,26 +357,27 @@ bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
int
codePoint
;
int
codePoint
;
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
for
(
std
::
string
::
const_iterator
i
=
str
.
begin
();
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
GetNextCodePointAndAdvance
(
codePoint
,
i
,
str
.
end
());)
{
if
(
codePoint
==
'\n'
)
if
(
codePoint
==
'\n'
)
{
out
<<
"
\n
"
<<
IndentTo
(
indent
);
out
<<
"
\n
"
<<
IndentTo
(
indent
);
else
}
else
{
WriteCodePoint
(
out
,
codePoint
);
WriteCodePoint
(
out
,
codePoint
);
}
}
}
return
true
;
return
true
;
}
}
bool
WriteChar
(
ostream_wrapper
&
out
,
char
ch
)
{
bool
WriteChar
(
ostream_wrapper
&
out
,
char
ch
)
{
if
((
'a'
<=
ch
&&
ch
<=
'z'
)
||
(
'A'
<=
ch
&&
ch
<=
'Z'
))
if
((
'a'
<=
ch
&&
ch
<=
'z'
)
||
(
'A'
<=
ch
&&
ch
<=
'Z'
))
{
out
<<
ch
;
out
<<
ch
;
else
if
((
0x20
<=
ch
&&
ch
<=
0x7e
)
||
ch
==
' '
)
}
else
if
((
0x20
<=
ch
&&
ch
<=
0x7e
)
||
ch
==
' '
)
{
out
<<
"
\"
"
<<
ch
<<
"
\"
"
;
out
<<
"
\"
"
<<
ch
<<
"
\"
"
;
else
if
(
ch
==
'\t'
)
}
else
if
(
ch
==
'\t'
)
{
out
<<
"
\"\\
t
\"
"
;
out
<<
"
\"\\
t
\"
"
;
else
if
(
ch
==
'\n'
)
}
else
if
(
ch
==
'\n'
)
{
out
<<
"
\"\\
n
\"
"
;
out
<<
"
\"\\
n
\"
"
;
else
if
(
ch
==
'\b'
)
}
else
if
(
ch
==
'\b'
)
{
out
<<
"
\"\\
b
\"
"
;
out
<<
"
\"\\
b
\"
"
;
else
{
}
else
{
out
<<
"
\"
"
;
out
<<
"
\"
"
;
WriteDoubleQuoteEscapeSequence
(
out
,
ch
);
WriteDoubleQuoteEscapeSequence
(
out
,
ch
);
out
<<
"
\"
"
;
out
<<
"
\"
"
;
...
@@ -391,16 +420,18 @@ bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
...
@@ -391,16 +420,18 @@ bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
const
RegEx
&
reValid
=
verbatim
?
Exp
::
URI
()
:
Exp
::
Tag
();
const
RegEx
&
reValid
=
verbatim
?
Exp
::
URI
()
:
Exp
::
Tag
();
while
(
buffer
)
{
while
(
buffer
)
{
int
n
=
reValid
.
Match
(
buffer
);
int
n
=
reValid
.
Match
(
buffer
);
if
(
n
<=
0
)
if
(
n
<=
0
)
{
return
false
;
return
false
;
}
while
(
--
n
>=
0
)
{
while
(
--
n
>=
0
)
{
out
<<
buffer
[
0
];
out
<<
buffer
[
0
];
++
buffer
;
++
buffer
;
}
}
}
}
if
(
verbatim
)
if
(
verbatim
)
{
out
<<
">"
;
out
<<
">"
;
}
return
true
;
return
true
;
}
}
...
@@ -410,8 +441,9 @@ bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
...
@@ -410,8 +441,9 @@ bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
StringCharSource
prefixBuffer
(
prefix
.
c_str
(),
prefix
.
size
());
StringCharSource
prefixBuffer
(
prefix
.
c_str
(),
prefix
.
size
());
while
(
prefixBuffer
)
{
while
(
prefixBuffer
)
{
int
n
=
Exp
::
URI
().
Match
(
prefixBuffer
);
int
n
=
Exp
::
URI
().
Match
(
prefixBuffer
);
if
(
n
<=
0
)
if
(
n
<=
0
)
{
return
false
;
return
false
;
}
while
(
--
n
>=
0
)
{
while
(
--
n
>=
0
)
{
out
<<
prefixBuffer
[
0
];
out
<<
prefixBuffer
[
0
];
...
@@ -423,8 +455,9 @@ bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
...
@@ -423,8 +455,9 @@ bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
StringCharSource
tagBuffer
(
tag
.
c_str
(),
tag
.
size
());
StringCharSource
tagBuffer
(
tag
.
c_str
(),
tag
.
size
());
while
(
tagBuffer
)
{
while
(
tagBuffer
)
{
int
n
=
Exp
::
Tag
().
Match
(
tagBuffer
);
int
n
=
Exp
::
Tag
().
Match
(
tagBuffer
);
if
(
n
<=
0
)
if
(
n
<=
0
)
{
return
false
;
return
false
;
}
while
(
--
n
>=
0
)
{
while
(
--
n
>=
0
)
{
out
<<
tagBuffer
[
0
];
out
<<
tagBuffer
[
0
];
...
...
test/integration/emitter_test.cpp
View file @
899b6614
...
@@ -956,6 +956,12 @@ TEST_F(EmitterTest, ForceSingleQuotedToDouble) {
...
@@ -956,6 +956,12 @@ TEST_F(EmitterTest, ForceSingleQuotedToDouble) {
ExpectEmit
(
"
\"
Hello
\\
nWorld
\"
"
);
ExpectEmit
(
"
\"
Hello
\\
nWorld
\"
"
);
}
}
TEST_F
(
EmitterTest
,
QuoteNull
)
{
out
<<
"null"
;
ExpectEmit
(
"
\"
null
\"
"
);
}
class
EmitterErrorTest
:
public
::
testing
::
Test
{
class
EmitterErrorTest
:
public
::
testing
::
Test
{
protected
:
protected
:
void
ExpectEmitError
(
const
std
::
string
&
expectedError
)
{
void
ExpectEmitError
(
const
std
::
string
&
expectedError
)
{
...
...
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