//1// Copyright (c) 2011-2019 Canonical Ltd2// Copyright (c) 2006-2010 Kirill Simonov3//4// Permission is hereby granted, free of charge, to any person obtaining a copy of5// this software and associated documentation files (the "Software"), to deal in6// the Software without restriction, including without limitation the rights to7// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies8// of the Software, and to permit persons to whom the Software is furnished to do9// so, subject to the following conditions:10//11// The above copyright notice and this permission notice shall be included in all12// copies or substantial portions of the Software.13//14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE17// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20// SOFTWARE.2122package yaml2324import (25"io"26)2728func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {29//fmt.Println("yaml_insert_token", "pos:", pos, "typ:", token.typ, "head:", parser.tokens_head, "len:", len(parser.tokens))3031// Check if we can move the queue at the beginning of the buffer.32if parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {33if parser.tokens_head != len(parser.tokens) {34copy(parser.tokens, parser.tokens[parser.tokens_head:])35}36parser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]37parser.tokens_head = 038}39parser.tokens = append(parser.tokens, *token)40if pos < 0 {41return42}43copy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])44parser.tokens[parser.tokens_head+pos] = *token45}4647// Create a new parser object.48func yaml_parser_initialize(parser *yaml_parser_t) bool {49*parser = yaml_parser_t{50raw_buffer: make([]byte, 0, input_raw_buffer_size),51buffer: make([]byte, 0, input_buffer_size),52}53return true54}5556// Destroy a parser object.57func yaml_parser_delete(parser *yaml_parser_t) {58*parser = yaml_parser_t{}59}6061// String read handler.62func yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {63if parser.input_pos == len(parser.input) {64return 0, io.EOF65}66n = copy(buffer, parser.input[parser.input_pos:])67parser.input_pos += n68return n, nil69}7071// Reader read handler.72func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {73return parser.input_reader.Read(buffer)74}7576// Set a string input.77func yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {78if parser.read_handler != nil {79panic("must set the input source only once")80}81parser.read_handler = yaml_string_read_handler82parser.input = input83parser.input_pos = 084}8586// Set a file input.87func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {88if parser.read_handler != nil {89panic("must set the input source only once")90}91parser.read_handler = yaml_reader_read_handler92parser.input_reader = r93}9495// Set the source encoding.96func yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {97if parser.encoding != yaml_ANY_ENCODING {98panic("must set the encoding only once")99}100parser.encoding = encoding101}102103// Create a new emitter object.104func yaml_emitter_initialize(emitter *yaml_emitter_t) {105*emitter = yaml_emitter_t{106buffer: make([]byte, output_buffer_size),107raw_buffer: make([]byte, 0, output_raw_buffer_size),108states: make([]yaml_emitter_state_t, 0, initial_stack_size),109events: make([]yaml_event_t, 0, initial_queue_size),110best_width: -1,111}112}113114// Destroy an emitter object.115func yaml_emitter_delete(emitter *yaml_emitter_t) {116*emitter = yaml_emitter_t{}117}118119// String write handler.120func yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {121*emitter.output_buffer = append(*emitter.output_buffer, buffer...)122return nil123}124125// yaml_writer_write_handler uses emitter.output_writer to write the126// emitted text.127func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {128_, err := emitter.output_writer.Write(buffer)129return err130}131132// Set a string output.133func yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {134if emitter.write_handler != nil {135panic("must set the output target only once")136}137emitter.write_handler = yaml_string_write_handler138emitter.output_buffer = output_buffer139}140141// Set a file output.142func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {143if emitter.write_handler != nil {144panic("must set the output target only once")145}146emitter.write_handler = yaml_writer_write_handler147emitter.output_writer = w148}149150// Set the output encoding.151func yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {152if emitter.encoding != yaml_ANY_ENCODING {153panic("must set the output encoding only once")154}155emitter.encoding = encoding156}157158// Set the canonical output style.159func yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {160emitter.canonical = canonical161}162163// Set the indentation increment.164func yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {165if indent < 2 || indent > 9 {166indent = 2167}168emitter.best_indent = indent169}170171// Set the preferred line width.172func yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {173if width < 0 {174width = -1175}176emitter.best_width = width177}178179// Set if unescaped non-ASCII characters are allowed.180func yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {181emitter.unicode = unicode182}183184// Set the preferred line break character.185func yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {186emitter.line_break = line_break187}188189///*190// * Destroy a token object.191// */192//193//YAML_DECLARE(void)194//yaml_token_delete(yaml_token_t *token)195//{196// assert(token); // Non-NULL token object expected.197//198// switch (token.type)199// {200// case YAML_TAG_DIRECTIVE_TOKEN:201// yaml_free(token.data.tag_directive.handle);202// yaml_free(token.data.tag_directive.prefix);203// break;204//205// case YAML_ALIAS_TOKEN:206// yaml_free(token.data.alias.value);207// break;208//209// case YAML_ANCHOR_TOKEN:210// yaml_free(token.data.anchor.value);211// break;212//213// case YAML_TAG_TOKEN:214// yaml_free(token.data.tag.handle);215// yaml_free(token.data.tag.suffix);216// break;217//218// case YAML_SCALAR_TOKEN:219// yaml_free(token.data.scalar.value);220// break;221//222// default:223// break;224// }225//226// memset(token, 0, sizeof(yaml_token_t));227//}228//229///*230// * Check if a string is a valid UTF-8 sequence.231// *232// * Check 'reader.c' for more details on UTF-8 encoding.233// */234//235//static int236//yaml_check_utf8(yaml_char_t *start, size_t length)237//{238// yaml_char_t *end = start+length;239// yaml_char_t *pointer = start;240//241// while (pointer < end) {242// unsigned char octet;243// unsigned int width;244// unsigned int value;245// size_t k;246//247// octet = pointer[0];248// width = (octet & 0x80) == 0x00 ? 1 :249// (octet & 0xE0) == 0xC0 ? 2 :250// (octet & 0xF0) == 0xE0 ? 3 :251// (octet & 0xF8) == 0xF0 ? 4 : 0;252// value = (octet & 0x80) == 0x00 ? octet & 0x7F :253// (octet & 0xE0) == 0xC0 ? octet & 0x1F :254// (octet & 0xF0) == 0xE0 ? octet & 0x0F :255// (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;256// if (!width) return 0;257// if (pointer+width > end) return 0;258// for (k = 1; k < width; k ++) {259// octet = pointer[k];260// if ((octet & 0xC0) != 0x80) return 0;261// value = (value << 6) + (octet & 0x3F);262// }263// if (!((width == 1) ||264// (width == 2 && value >= 0x80) ||265// (width == 3 && value >= 0x800) ||266// (width == 4 && value >= 0x10000))) return 0;267//268// pointer += width;269// }270//271// return 1;272//}273//274275// Create STREAM-START.276func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {277*event = yaml_event_t{278typ: yaml_STREAM_START_EVENT,279encoding: encoding,280}281}282283// Create STREAM-END.284func yaml_stream_end_event_initialize(event *yaml_event_t) {285*event = yaml_event_t{286typ: yaml_STREAM_END_EVENT,287}288}289290// Create DOCUMENT-START.291func yaml_document_start_event_initialize(292event *yaml_event_t,293version_directive *yaml_version_directive_t,294tag_directives []yaml_tag_directive_t,295implicit bool,296) {297*event = yaml_event_t{298typ: yaml_DOCUMENT_START_EVENT,299version_directive: version_directive,300tag_directives: tag_directives,301implicit: implicit,302}303}304305// Create DOCUMENT-END.306func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {307*event = yaml_event_t{308typ: yaml_DOCUMENT_END_EVENT,309implicit: implicit,310}311}312313// Create ALIAS.314func yaml_alias_event_initialize(event *yaml_event_t, anchor []byte) bool {315*event = yaml_event_t{316typ: yaml_ALIAS_EVENT,317anchor: anchor,318}319return true320}321322// Create SCALAR.323func yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {324*event = yaml_event_t{325typ: yaml_SCALAR_EVENT,326anchor: anchor,327tag: tag,328value: value,329implicit: plain_implicit,330quoted_implicit: quoted_implicit,331style: yaml_style_t(style),332}333return true334}335336// Create SEQUENCE-START.337func yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {338*event = yaml_event_t{339typ: yaml_SEQUENCE_START_EVENT,340anchor: anchor,341tag: tag,342implicit: implicit,343style: yaml_style_t(style),344}345return true346}347348// Create SEQUENCE-END.349func yaml_sequence_end_event_initialize(event *yaml_event_t) bool {350*event = yaml_event_t{351typ: yaml_SEQUENCE_END_EVENT,352}353return true354}355356// Create MAPPING-START.357func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {358*event = yaml_event_t{359typ: yaml_MAPPING_START_EVENT,360anchor: anchor,361tag: tag,362implicit: implicit,363style: yaml_style_t(style),364}365}366367// Create MAPPING-END.368func yaml_mapping_end_event_initialize(event *yaml_event_t) {369*event = yaml_event_t{370typ: yaml_MAPPING_END_EVENT,371}372}373374// Destroy an event object.375func yaml_event_delete(event *yaml_event_t) {376*event = yaml_event_t{}377}378379///*380// * Create a document object.381// */382//383//YAML_DECLARE(int)384//yaml_document_initialize(document *yaml_document_t,385// version_directive *yaml_version_directive_t,386// tag_directives_start *yaml_tag_directive_t,387// tag_directives_end *yaml_tag_directive_t,388// start_implicit int, end_implicit int)389//{390// struct {391// error yaml_error_type_t392// } context393// struct {394// start *yaml_node_t395// end *yaml_node_t396// top *yaml_node_t397// } nodes = { NULL, NULL, NULL }398// version_directive_copy *yaml_version_directive_t = NULL399// struct {400// start *yaml_tag_directive_t401// end *yaml_tag_directive_t402// top *yaml_tag_directive_t403// } tag_directives_copy = { NULL, NULL, NULL }404// value yaml_tag_directive_t = { NULL, NULL }405// mark yaml_mark_t = { 0, 0, 0 }406//407// assert(document) // Non-NULL document object is expected.408// assert((tag_directives_start && tag_directives_end) ||409// (tag_directives_start == tag_directives_end))410// // Valid tag directives are expected.411//412// if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error413//414// if (version_directive) {415// version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))416// if (!version_directive_copy) goto error417// version_directive_copy.major = version_directive.major418// version_directive_copy.minor = version_directive.minor419// }420//421// if (tag_directives_start != tag_directives_end) {422// tag_directive *yaml_tag_directive_t423// if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))424// goto error425// for (tag_directive = tag_directives_start426// tag_directive != tag_directives_end; tag_directive ++) {427// assert(tag_directive.handle)428// assert(tag_directive.prefix)429// if (!yaml_check_utf8(tag_directive.handle,430// strlen((char *)tag_directive.handle)))431// goto error432// if (!yaml_check_utf8(tag_directive.prefix,433// strlen((char *)tag_directive.prefix)))434// goto error435// value.handle = yaml_strdup(tag_directive.handle)436// value.prefix = yaml_strdup(tag_directive.prefix)437// if (!value.handle || !value.prefix) goto error438// if (!PUSH(&context, tag_directives_copy, value))439// goto error440// value.handle = NULL441// value.prefix = NULL442// }443// }444//445// DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,446// tag_directives_copy.start, tag_directives_copy.top,447// start_implicit, end_implicit, mark, mark)448//449// return 1450//451//error:452// STACK_DEL(&context, nodes)453// yaml_free(version_directive_copy)454// while (!STACK_EMPTY(&context, tag_directives_copy)) {455// value yaml_tag_directive_t = POP(&context, tag_directives_copy)456// yaml_free(value.handle)457// yaml_free(value.prefix)458// }459// STACK_DEL(&context, tag_directives_copy)460// yaml_free(value.handle)461// yaml_free(value.prefix)462//463// return 0464//}465//466///*467// * Destroy a document object.468// */469//470//YAML_DECLARE(void)471//yaml_document_delete(document *yaml_document_t)472//{473// struct {474// error yaml_error_type_t475// } context476// tag_directive *yaml_tag_directive_t477//478// context.error = YAML_NO_ERROR // Eliminate a compiler warning.479//480// assert(document) // Non-NULL document object is expected.481//482// while (!STACK_EMPTY(&context, document.nodes)) {483// node yaml_node_t = POP(&context, document.nodes)484// yaml_free(node.tag)485// switch (node.type) {486// case YAML_SCALAR_NODE:487// yaml_free(node.data.scalar.value)488// break489// case YAML_SEQUENCE_NODE:490// STACK_DEL(&context, node.data.sequence.items)491// break492// case YAML_MAPPING_NODE:493// STACK_DEL(&context, node.data.mapping.pairs)494// break495// default:496// assert(0) // Should not happen.497// }498// }499// STACK_DEL(&context, document.nodes)500//501// yaml_free(document.version_directive)502// for (tag_directive = document.tag_directives.start503// tag_directive != document.tag_directives.end504// tag_directive++) {505// yaml_free(tag_directive.handle)506// yaml_free(tag_directive.prefix)507// }508// yaml_free(document.tag_directives.start)509//510// memset(document, 0, sizeof(yaml_document_t))511//}512//513///**514// * Get a document node.515// */516//517//YAML_DECLARE(yaml_node_t *)518//yaml_document_get_node(document *yaml_document_t, index int)519//{520// assert(document) // Non-NULL document object is expected.521//522// if (index > 0 && document.nodes.start + index <= document.nodes.top) {523// return document.nodes.start + index - 1524// }525// return NULL526//}527//528///**529// * Get the root object.530// */531//532//YAML_DECLARE(yaml_node_t *)533//yaml_document_get_root_node(document *yaml_document_t)534//{535// assert(document) // Non-NULL document object is expected.536//537// if (document.nodes.top != document.nodes.start) {538// return document.nodes.start539// }540// return NULL541//}542//543///*544// * Add a scalar node to a document.545// */546//547//YAML_DECLARE(int)548//yaml_document_add_scalar(document *yaml_document_t,549// tag *yaml_char_t, value *yaml_char_t, length int,550// style yaml_scalar_style_t)551//{552// struct {553// error yaml_error_type_t554// } context555// mark yaml_mark_t = { 0, 0, 0 }556// tag_copy *yaml_char_t = NULL557// value_copy *yaml_char_t = NULL558// node yaml_node_t559//560// assert(document) // Non-NULL document object is expected.561// assert(value) // Non-NULL value is expected.562//563// if (!tag) {564// tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG565// }566//567// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error568// tag_copy = yaml_strdup(tag)569// if (!tag_copy) goto error570//571// if (length < 0) {572// length = strlen((char *)value)573// }574//575// if (!yaml_check_utf8(value, length)) goto error576// value_copy = yaml_malloc(length+1)577// if (!value_copy) goto error578// memcpy(value_copy, value, length)579// value_copy[length] = '\0'580//581// SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)582// if (!PUSH(&context, document.nodes, node)) goto error583//584// return document.nodes.top - document.nodes.start585//586//error:587// yaml_free(tag_copy)588// yaml_free(value_copy)589//590// return 0591//}592//593///*594// * Add a sequence node to a document.595// */596//597//YAML_DECLARE(int)598//yaml_document_add_sequence(document *yaml_document_t,599// tag *yaml_char_t, style yaml_sequence_style_t)600//{601// struct {602// error yaml_error_type_t603// } context604// mark yaml_mark_t = { 0, 0, 0 }605// tag_copy *yaml_char_t = NULL606// struct {607// start *yaml_node_item_t608// end *yaml_node_item_t609// top *yaml_node_item_t610// } items = { NULL, NULL, NULL }611// node yaml_node_t612//613// assert(document) // Non-NULL document object is expected.614//615// if (!tag) {616// tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG617// }618//619// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error620// tag_copy = yaml_strdup(tag)621// if (!tag_copy) goto error622//623// if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error624//625// SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,626// style, mark, mark)627// if (!PUSH(&context, document.nodes, node)) goto error628//629// return document.nodes.top - document.nodes.start630//631//error:632// STACK_DEL(&context, items)633// yaml_free(tag_copy)634//635// return 0636//}637//638///*639// * Add a mapping node to a document.640// */641//642//YAML_DECLARE(int)643//yaml_document_add_mapping(document *yaml_document_t,644// tag *yaml_char_t, style yaml_mapping_style_t)645//{646// struct {647// error yaml_error_type_t648// } context649// mark yaml_mark_t = { 0, 0, 0 }650// tag_copy *yaml_char_t = NULL651// struct {652// start *yaml_node_pair_t653// end *yaml_node_pair_t654// top *yaml_node_pair_t655// } pairs = { NULL, NULL, NULL }656// node yaml_node_t657//658// assert(document) // Non-NULL document object is expected.659//660// if (!tag) {661// tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG662// }663//664// if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error665// tag_copy = yaml_strdup(tag)666// if (!tag_copy) goto error667//668// if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error669//670// MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,671// style, mark, mark)672// if (!PUSH(&context, document.nodes, node)) goto error673//674// return document.nodes.top - document.nodes.start675//676//error:677// STACK_DEL(&context, pairs)678// yaml_free(tag_copy)679//680// return 0681//}682//683///*684// * Append an item to a sequence node.685// */686//687//YAML_DECLARE(int)688//yaml_document_append_sequence_item(document *yaml_document_t,689// sequence int, item int)690//{691// struct {692// error yaml_error_type_t693// } context694//695// assert(document) // Non-NULL document is required.696// assert(sequence > 0697// && document.nodes.start + sequence <= document.nodes.top)698// // Valid sequence id is required.699// assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)700// // A sequence node is required.701// assert(item > 0 && document.nodes.start + item <= document.nodes.top)702// // Valid item id is required.703//704// if (!PUSH(&context,705// document.nodes.start[sequence-1].data.sequence.items, item))706// return 0707//708// return 1709//}710//711///*712// * Append a pair of a key and a value to a mapping node.713// */714//715//YAML_DECLARE(int)716//yaml_document_append_mapping_pair(document *yaml_document_t,717// mapping int, key int, value int)718//{719// struct {720// error yaml_error_type_t721// } context722//723// pair yaml_node_pair_t724//725// assert(document) // Non-NULL document is required.726// assert(mapping > 0727// && document.nodes.start + mapping <= document.nodes.top)728// // Valid mapping id is required.729// assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)730// // A mapping node is required.731// assert(key > 0 && document.nodes.start + key <= document.nodes.top)732// // Valid key id is required.733// assert(value > 0 && document.nodes.start + value <= document.nodes.top)734// // Valid value id is required.735//736// pair.key = key737// pair.value = value738//739// if (!PUSH(&context,740// document.nodes.start[mapping-1].data.mapping.pairs, pair))741// return 0742//743// return 1744//}745//746//747748749