in yaml/scannerc.go [1854:1936]
func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
var handle, suffix []byte
start_mark := parser.mark
// Check if the tag is in the canonical form.
if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
return false
}
if parser.buffer[parser.buffer_pos+1] == '<' {
// Keep the handle as ''
// Eat '!<'
skip(parser)
skip(parser)
// Consume the tag value.
if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
return false
}
// Check for '>' and eat it.
if parser.buffer[parser.buffer_pos] != '>' {
yaml_parser_set_scanner_error(parser, "while scanning a tag",
start_mark, "did not find the expected '>'")
return false
}
skip(parser)
} else {
// The tag has either the '!suffix' or the '!handle!suffix' form.
// First, try to scan a handle.
if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
return false
}
// Check if it is, indeed, handle.
if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
// Scan the suffix now.
if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
return false
}
} else {
// It wasn't a handle after all. Scan the rest of the tag.
if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
return false
}
// Set the handle to '!'.
handle = []byte{'!'}
// A special case: the '!' tag. Set the handle to '' and the
// suffix to '!'.
if len(suffix) == 0 {
handle, suffix = suffix, handle
}
}
}
// Check the character which ends the tag.
if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
return false
}
if !is_blankz(parser.buffer, parser.buffer_pos) {
yaml_parser_set_scanner_error(parser, "while scanning a tag",
start_mark, "did not find expected whitespace or line break")
return false
}
end_mark := parser.mark
// Create a token.
*token = yaml_token_t{
typ: yaml_TAG_TOKEN,
start_mark: start_mark,
end_mark: end_mark,
value: handle,
suffix: suffix,
}
return true
}