in yaml/scannerc.go [2585:2735]
func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
var s, leading_break, trailing_breaks, whitespaces []byte
var leading_blanks bool
var indent = parser.indent + 1
start_mark := parser.mark
end_mark := parser.mark
// Consume the content of the plain scalar.
for {
// Check for a document indicator.
if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
return false
}
if parser.mark.column == 0 &&
((parser.buffer[parser.buffer_pos+0] == '-' &&
parser.buffer[parser.buffer_pos+1] == '-' &&
parser.buffer[parser.buffer_pos+2] == '-') ||
(parser.buffer[parser.buffer_pos+0] == '.' &&
parser.buffer[parser.buffer_pos+1] == '.' &&
parser.buffer[parser.buffer_pos+2] == '.')) &&
is_blankz(parser.buffer, parser.buffer_pos+3) {
break
}
// Check for a comment.
if parser.buffer[parser.buffer_pos] == '#' {
break
}
// Consume non-blank characters.
for !is_blankz(parser.buffer, parser.buffer_pos) {
// Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
if parser.flow_level > 0 &&
parser.buffer[parser.buffer_pos] == ':' &&
!is_blankz(parser.buffer, parser.buffer_pos+1) {
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
start_mark, "found unexpected ':'")
return false
}
// Check for indicators that may end a plain scalar.
if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
(parser.flow_level > 0 &&
(parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
parser.buffer[parser.buffer_pos] == '}')) {
break
}
// Check if we need to join whitespaces and breaks.
if leading_blanks || len(whitespaces) > 0 {
if leading_blanks {
// Do we need to fold line breaks?
if leading_break[0] == '\n' {
if len(trailing_breaks) == 0 {
s = append(s, ' ')
} else {
s = append(s, trailing_breaks...)
}
} else {
s = append(s, leading_break...)
s = append(s, trailing_breaks...)
}
trailing_breaks = trailing_breaks[:0]
leading_break = leading_break[:0]
leading_blanks = false
} else {
s = append(s, whitespaces...)
whitespaces = whitespaces[:0]
}
}
// Copy the character.
s = read(parser, s)
end_mark = parser.mark
if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
return false
}
}
// Is it the end?
if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
break
}
// Consume blank characters.
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
return false
}
for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
if is_blank(parser.buffer, parser.buffer_pos) {
// Check for tab character that abuse indentation.
if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
start_mark, "found a tab character that violate indentation")
return false
}
// Consume a space or a tab character.
if !leading_blanks {
whitespaces = read(parser, whitespaces)
} else {
skip(parser)
}
} else {
if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
return false
}
// Check if it is a first line break.
if !leading_blanks {
whitespaces = whitespaces[:0]
leading_break = read_line(parser, leading_break)
leading_blanks = true
} else {
trailing_breaks = read_line(parser, trailing_breaks)
}
}
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
return false
}
}
// Check indentation level.
if parser.flow_level == 0 && parser.mark.column < indent {
break
}
}
// Create a token.
*token = yaml_token_t{
typ: yaml_SCALAR_TOKEN,
start_mark: start_mark,
end_mark: end_mark,
value: s,
style: yaml_PLAIN_SCALAR_STYLE,
}
// Note that we change the 'simple_key_allowed' flag.
if leading_blanks {
parser.simple_key_allowed = true
}
return true
}