1247738Sbapt 2247738Sbapt#include "yaml_private.h" 3247738Sbapt 4247738Sbapt/* 5247738Sbapt * Flush the buffer if needed. 6247738Sbapt */ 7247738Sbapt 8247738Sbapt#define FLUSH(emitter) \ 9247738Sbapt ((emitter->buffer.pointer+5 < emitter->buffer.end) \ 10247738Sbapt || yaml_emitter_flush(emitter)) 11247738Sbapt 12247738Sbapt/* 13247738Sbapt * Put a character to the output buffer. 14247738Sbapt */ 15247738Sbapt 16247738Sbapt#define PUT(emitter,value) \ 17247738Sbapt (FLUSH(emitter) \ 18247738Sbapt && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \ 19247738Sbapt emitter->column ++, \ 20247738Sbapt 1)) 21247738Sbapt 22247738Sbapt/* 23247738Sbapt * Put a line break to the output buffer. 24247738Sbapt */ 25247738Sbapt 26247738Sbapt#define PUT_BREAK(emitter) \ 27247738Sbapt (FLUSH(emitter) \ 28247738Sbapt && ((emitter->line_break == YAML_CR_BREAK ? \ 29247738Sbapt (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \ 30247738Sbapt emitter->line_break == YAML_LN_BREAK ? \ 31247738Sbapt (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \ 32247738Sbapt emitter->line_break == YAML_CRLN_BREAK ? \ 33247738Sbapt (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \ 34247738Sbapt *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \ 35247738Sbapt emitter->column = 0, \ 36247738Sbapt emitter->line ++, \ 37247738Sbapt 1)) 38247738Sbapt 39247738Sbapt/* 40247738Sbapt * Copy a character from a string into buffer. 41247738Sbapt */ 42247738Sbapt 43247738Sbapt#define WRITE(emitter,string) \ 44247738Sbapt (FLUSH(emitter) \ 45247738Sbapt && (COPY(emitter->buffer,string), \ 46247738Sbapt emitter->column ++, \ 47247738Sbapt 1)) 48247738Sbapt 49247738Sbapt/* 50247738Sbapt * Copy a line break character from a string into buffer. 51247738Sbapt */ 52247738Sbapt 53247738Sbapt#define WRITE_BREAK(emitter,string) \ 54247738Sbapt (FLUSH(emitter) \ 55247738Sbapt && (CHECK(string,'\n') ? \ 56247738Sbapt (PUT_BREAK(emitter), \ 57247738Sbapt string.pointer ++, \ 58247738Sbapt 1) : \ 59247738Sbapt (COPY(emitter->buffer,string), \ 60247738Sbapt emitter->column = 0, \ 61247738Sbapt emitter->line ++, \ 62247738Sbapt 1))) 63247738Sbapt 64247738Sbapt/* 65247738Sbapt * API functions. 66247738Sbapt */ 67247738Sbapt 68247738SbaptYAML_DECLARE(int) 69247738Sbaptyaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); 70247738Sbapt 71247738Sbapt/* 72247738Sbapt * Utility functions. 73247738Sbapt */ 74247738Sbapt 75247738Sbaptstatic int 76247738Sbaptyaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem); 77247738Sbapt 78247738Sbaptstatic int 79247738Sbaptyaml_emitter_need_more_events(yaml_emitter_t *emitter); 80247738Sbapt 81247738Sbaptstatic int 82247738Sbaptyaml_emitter_append_tag_directive(yaml_emitter_t *emitter, 83247738Sbapt yaml_tag_directive_t value, int allow_duplicates); 84247738Sbapt 85247738Sbaptstatic int 86247738Sbaptyaml_emitter_increase_indent(yaml_emitter_t *emitter, 87247738Sbapt int flow, int indentless); 88247738Sbapt 89247738Sbapt/* 90247738Sbapt * State functions. 91247738Sbapt */ 92247738Sbapt 93247738Sbaptstatic int 94247738Sbaptyaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event); 95247738Sbapt 96247738Sbaptstatic int 97247738Sbaptyaml_emitter_emit_stream_start(yaml_emitter_t *emitter, 98247738Sbapt yaml_event_t *event); 99247738Sbapt 100247738Sbaptstatic int 101247738Sbaptyaml_emitter_emit_document_start(yaml_emitter_t *emitter, 102247738Sbapt yaml_event_t *event, int first); 103247738Sbapt 104247738Sbaptstatic int 105247738Sbaptyaml_emitter_emit_document_content(yaml_emitter_t *emitter, 106247738Sbapt yaml_event_t *event); 107247738Sbapt 108247738Sbaptstatic int 109247738Sbaptyaml_emitter_emit_document_end(yaml_emitter_t *emitter, 110247738Sbapt yaml_event_t *event); 111247738Sbapt 112247738Sbaptstatic int 113247738Sbaptyaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, 114247738Sbapt yaml_event_t *event, int first); 115247738Sbapt 116247738Sbaptstatic int 117247738Sbaptyaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, 118247738Sbapt yaml_event_t *event, int first); 119247738Sbapt 120247738Sbaptstatic int 121247738Sbaptyaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, 122247738Sbapt yaml_event_t *event, int simple); 123247738Sbapt 124247738Sbaptstatic int 125247738Sbaptyaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, 126247738Sbapt yaml_event_t *event, int first); 127247738Sbapt 128247738Sbaptstatic int 129247738Sbaptyaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, 130247738Sbapt yaml_event_t *event, int first); 131247738Sbapt 132247738Sbaptstatic int 133247738Sbaptyaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, 134247738Sbapt yaml_event_t *event, int simple); 135247738Sbapt 136247738Sbaptstatic int 137247738Sbaptyaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, 138247738Sbapt int root, int sequence, int mapping, int simple_key); 139247738Sbapt 140247738Sbaptstatic int 141247738Sbaptyaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event); 142247738Sbapt 143247738Sbaptstatic int 144247738Sbaptyaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event); 145247738Sbapt 146247738Sbaptstatic int 147247738Sbaptyaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event); 148247738Sbapt 149247738Sbaptstatic int 150247738Sbaptyaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event); 151247738Sbapt 152247738Sbapt/* 153247738Sbapt * Checkers. 154247738Sbapt */ 155247738Sbapt 156247738Sbaptstatic int 157247738Sbaptyaml_emitter_check_empty_document(yaml_emitter_t *emitter); 158247738Sbapt 159247738Sbaptstatic int 160247738Sbaptyaml_emitter_check_empty_sequence(yaml_emitter_t *emitter); 161247738Sbapt 162247738Sbaptstatic int 163247738Sbaptyaml_emitter_check_empty_mapping(yaml_emitter_t *emitter); 164247738Sbapt 165247738Sbaptstatic int 166247738Sbaptyaml_emitter_check_simple_key(yaml_emitter_t *emitter); 167247738Sbapt 168247738Sbaptstatic int 169247738Sbaptyaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event); 170247738Sbapt 171247738Sbapt/* 172247738Sbapt * Processors. 173247738Sbapt */ 174247738Sbapt 175247738Sbaptstatic int 176247738Sbaptyaml_emitter_process_anchor(yaml_emitter_t *emitter); 177247738Sbapt 178247738Sbaptstatic int 179247738Sbaptyaml_emitter_process_tag(yaml_emitter_t *emitter); 180247738Sbapt 181247738Sbaptstatic int 182247738Sbaptyaml_emitter_process_scalar(yaml_emitter_t *emitter); 183247738Sbapt 184247738Sbapt/* 185247738Sbapt * Analyzers. 186247738Sbapt */ 187247738Sbapt 188247738Sbaptstatic int 189247738Sbaptyaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, 190247738Sbapt yaml_version_directive_t version_directive); 191247738Sbapt 192247738Sbaptstatic int 193247738Sbaptyaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, 194247738Sbapt yaml_tag_directive_t tag_directive); 195247738Sbapt 196247738Sbaptstatic int 197247738Sbaptyaml_emitter_analyze_anchor(yaml_emitter_t *emitter, 198247738Sbapt yaml_char_t *anchor, int alias); 199247738Sbapt 200247738Sbaptstatic int 201247738Sbaptyaml_emitter_analyze_tag(yaml_emitter_t *emitter, 202247738Sbapt yaml_char_t *tag); 203247738Sbapt 204247738Sbaptstatic int 205247738Sbaptyaml_emitter_analyze_scalar(yaml_emitter_t *emitter, 206247738Sbapt yaml_char_t *value, size_t length); 207247738Sbapt 208247738Sbaptstatic int 209247738Sbaptyaml_emitter_analyze_event(yaml_emitter_t *emitter, 210247738Sbapt yaml_event_t *event); 211247738Sbapt 212247738Sbapt/* 213247738Sbapt * Writers. 214247738Sbapt */ 215247738Sbapt 216247738Sbaptstatic int 217247738Sbaptyaml_emitter_write_bom(yaml_emitter_t *emitter); 218247738Sbapt 219247738Sbaptstatic int 220247738Sbaptyaml_emitter_write_indent(yaml_emitter_t *emitter); 221247738Sbapt 222247738Sbaptstatic int 223247738Sbaptyaml_emitter_write_indicator(yaml_emitter_t *emitter, 224247738Sbapt char *indicator, int need_whitespace, 225247738Sbapt int is_whitespace, int is_indention); 226247738Sbapt 227247738Sbaptstatic int 228247738Sbaptyaml_emitter_write_anchor(yaml_emitter_t *emitter, 229247738Sbapt yaml_char_t *value, size_t length); 230247738Sbapt 231247738Sbaptstatic int 232247738Sbaptyaml_emitter_write_tag_handle(yaml_emitter_t *emitter, 233247738Sbapt yaml_char_t *value, size_t length); 234247738Sbapt 235247738Sbaptstatic int 236247738Sbaptyaml_emitter_write_tag_content(yaml_emitter_t *emitter, 237247738Sbapt yaml_char_t *value, size_t length, int need_whitespace); 238247738Sbapt 239247738Sbaptstatic int 240247738Sbaptyaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, 241247738Sbapt yaml_char_t *value, size_t length, int allow_breaks); 242247738Sbapt 243247738Sbaptstatic int 244247738Sbaptyaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, 245247738Sbapt yaml_char_t *value, size_t length, int allow_breaks); 246247738Sbapt 247247738Sbaptstatic int 248247738Sbaptyaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, 249247738Sbapt yaml_char_t *value, size_t length, int allow_breaks); 250247738Sbapt 251247738Sbaptstatic int 252247738Sbaptyaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, 253247738Sbapt yaml_string_t string); 254247738Sbapt 255247738Sbaptstatic int 256247738Sbaptyaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, 257247738Sbapt yaml_char_t *value, size_t length); 258247738Sbapt 259247738Sbaptstatic int 260247738Sbaptyaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, 261247738Sbapt yaml_char_t *value, size_t length); 262247738Sbapt 263247738Sbapt/* 264247738Sbapt * Set an emitter error and return 0. 265247738Sbapt */ 266247738Sbapt 267247738Sbaptstatic int 268247738Sbaptyaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem) 269247738Sbapt{ 270247738Sbapt emitter->error = YAML_EMITTER_ERROR; 271247738Sbapt emitter->problem = problem; 272247738Sbapt 273247738Sbapt return 0; 274247738Sbapt} 275247738Sbapt 276247738Sbapt/* 277247738Sbapt * Emit an event. 278247738Sbapt */ 279247738Sbapt 280247738SbaptYAML_DECLARE(int) 281247738Sbaptyaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event) 282247738Sbapt{ 283247738Sbapt if (!ENQUEUE(emitter, emitter->events, *event)) { 284247738Sbapt yaml_event_delete(event); 285247738Sbapt return 0; 286247738Sbapt } 287247738Sbapt 288247738Sbapt while (!yaml_emitter_need_more_events(emitter)) { 289247738Sbapt if (!yaml_emitter_analyze_event(emitter, emitter->events.head)) 290247738Sbapt return 0; 291247738Sbapt if (!yaml_emitter_state_machine(emitter, emitter->events.head)) 292247738Sbapt return 0; 293247738Sbapt yaml_event_delete(&DEQUEUE(emitter, emitter->events)); 294247738Sbapt } 295247738Sbapt 296247738Sbapt return 1; 297247738Sbapt} 298247738Sbapt 299247738Sbapt/* 300247738Sbapt * Check if we need to accumulate more events before emitting. 301247738Sbapt * 302247738Sbapt * We accumulate extra 303247738Sbapt * - 1 event for DOCUMENT-START 304247738Sbapt * - 2 events for SEQUENCE-START 305247738Sbapt * - 3 events for MAPPING-START 306247738Sbapt */ 307247738Sbapt 308247738Sbaptstatic int 309247738Sbaptyaml_emitter_need_more_events(yaml_emitter_t *emitter) 310247738Sbapt{ 311247738Sbapt int level = 0; 312247738Sbapt int accumulate = 0; 313247738Sbapt yaml_event_t *event; 314247738Sbapt 315247738Sbapt if (QUEUE_EMPTY(emitter, emitter->events)) 316247738Sbapt return 1; 317247738Sbapt 318247738Sbapt switch (emitter->events.head->type) { 319247738Sbapt case YAML_DOCUMENT_START_EVENT: 320247738Sbapt accumulate = 1; 321247738Sbapt break; 322247738Sbapt case YAML_SEQUENCE_START_EVENT: 323247738Sbapt accumulate = 2; 324247738Sbapt break; 325247738Sbapt case YAML_MAPPING_START_EVENT: 326247738Sbapt accumulate = 3; 327247738Sbapt break; 328247738Sbapt default: 329247738Sbapt return 0; 330247738Sbapt } 331247738Sbapt 332247738Sbapt if (emitter->events.tail - emitter->events.head > accumulate) 333247738Sbapt return 0; 334247738Sbapt 335247738Sbapt for (event = emitter->events.head; event != emitter->events.tail; event ++) { 336247738Sbapt switch (event->type) { 337247738Sbapt case YAML_STREAM_START_EVENT: 338247738Sbapt case YAML_DOCUMENT_START_EVENT: 339247738Sbapt case YAML_SEQUENCE_START_EVENT: 340247738Sbapt case YAML_MAPPING_START_EVENT: 341247738Sbapt level += 1; 342247738Sbapt break; 343247738Sbapt case YAML_STREAM_END_EVENT: 344247738Sbapt case YAML_DOCUMENT_END_EVENT: 345247738Sbapt case YAML_SEQUENCE_END_EVENT: 346247738Sbapt case YAML_MAPPING_END_EVENT: 347247738Sbapt level -= 1; 348247738Sbapt break; 349247738Sbapt default: 350247738Sbapt break; 351247738Sbapt } 352247738Sbapt if (!level) 353247738Sbapt return 0; 354247738Sbapt } 355247738Sbapt 356247738Sbapt return 1; 357247738Sbapt} 358247738Sbapt 359247738Sbapt/* 360247738Sbapt * Append a directive to the directives stack. 361247738Sbapt */ 362247738Sbapt 363247738Sbaptstatic int 364247738Sbaptyaml_emitter_append_tag_directive(yaml_emitter_t *emitter, 365247738Sbapt yaml_tag_directive_t value, int allow_duplicates) 366247738Sbapt{ 367247738Sbapt yaml_tag_directive_t *tag_directive; 368247738Sbapt yaml_tag_directive_t copy = { NULL, NULL }; 369247738Sbapt 370247738Sbapt for (tag_directive = emitter->tag_directives.start; 371247738Sbapt tag_directive != emitter->tag_directives.top; tag_directive ++) { 372247738Sbapt if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { 373247738Sbapt if (allow_duplicates) 374247738Sbapt return 1; 375247738Sbapt return yaml_emitter_set_emitter_error(emitter, 376247738Sbapt "duplicate %TAG directive"); 377247738Sbapt } 378247738Sbapt } 379247738Sbapt 380247738Sbapt copy.handle = yaml_strdup(value.handle); 381247738Sbapt copy.prefix = yaml_strdup(value.prefix); 382247738Sbapt if (!copy.handle || !copy.prefix) { 383247738Sbapt emitter->error = YAML_MEMORY_ERROR; 384247738Sbapt goto error; 385247738Sbapt } 386247738Sbapt 387247738Sbapt if (!PUSH(emitter, emitter->tag_directives, copy)) 388247738Sbapt goto error; 389247738Sbapt 390247738Sbapt return 1; 391247738Sbapt 392247738Sbapterror: 393247738Sbapt yaml_free(copy.handle); 394247738Sbapt yaml_free(copy.prefix); 395247738Sbapt return 0; 396247738Sbapt} 397247738Sbapt 398247738Sbapt/* 399247738Sbapt * Increase the indentation level. 400247738Sbapt */ 401247738Sbapt 402247738Sbaptstatic int 403247738Sbaptyaml_emitter_increase_indent(yaml_emitter_t *emitter, 404247738Sbapt int flow, int indentless) 405247738Sbapt{ 406247738Sbapt if (!PUSH(emitter, emitter->indents, emitter->indent)) 407247738Sbapt return 0; 408247738Sbapt 409247738Sbapt if (emitter->indent < 0) { 410247738Sbapt emitter->indent = flow ? emitter->best_indent : 0; 411247738Sbapt } 412247738Sbapt else if (!indentless) { 413247738Sbapt emitter->indent += emitter->best_indent; 414247738Sbapt } 415247738Sbapt 416247738Sbapt return 1; 417247738Sbapt} 418247738Sbapt 419247738Sbapt/* 420247738Sbapt * State dispatcher. 421247738Sbapt */ 422247738Sbapt 423247738Sbaptstatic int 424247738Sbaptyaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event) 425247738Sbapt{ 426247738Sbapt switch (emitter->state) 427247738Sbapt { 428247738Sbapt case YAML_EMIT_STREAM_START_STATE: 429247738Sbapt return yaml_emitter_emit_stream_start(emitter, event); 430247738Sbapt 431247738Sbapt case YAML_EMIT_FIRST_DOCUMENT_START_STATE: 432247738Sbapt return yaml_emitter_emit_document_start(emitter, event, 1); 433247738Sbapt 434247738Sbapt case YAML_EMIT_DOCUMENT_START_STATE: 435247738Sbapt return yaml_emitter_emit_document_start(emitter, event, 0); 436247738Sbapt 437247738Sbapt case YAML_EMIT_DOCUMENT_CONTENT_STATE: 438247738Sbapt return yaml_emitter_emit_document_content(emitter, event); 439247738Sbapt 440247738Sbapt case YAML_EMIT_DOCUMENT_END_STATE: 441247738Sbapt return yaml_emitter_emit_document_end(emitter, event); 442247738Sbapt 443247738Sbapt case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: 444247738Sbapt return yaml_emitter_emit_flow_sequence_item(emitter, event, 1); 445247738Sbapt 446247738Sbapt case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE: 447247738Sbapt return yaml_emitter_emit_flow_sequence_item(emitter, event, 0); 448247738Sbapt 449247738Sbapt case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: 450247738Sbapt return yaml_emitter_emit_flow_mapping_key(emitter, event, 1); 451247738Sbapt 452247738Sbapt case YAML_EMIT_FLOW_MAPPING_KEY_STATE: 453247738Sbapt return yaml_emitter_emit_flow_mapping_key(emitter, event, 0); 454247738Sbapt 455247738Sbapt case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: 456247738Sbapt return yaml_emitter_emit_flow_mapping_value(emitter, event, 1); 457247738Sbapt 458247738Sbapt case YAML_EMIT_FLOW_MAPPING_VALUE_STATE: 459247738Sbapt return yaml_emitter_emit_flow_mapping_value(emitter, event, 0); 460247738Sbapt 461247738Sbapt case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: 462247738Sbapt return yaml_emitter_emit_block_sequence_item(emitter, event, 1); 463247738Sbapt 464247738Sbapt case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE: 465247738Sbapt return yaml_emitter_emit_block_sequence_item(emitter, event, 0); 466247738Sbapt 467247738Sbapt case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: 468247738Sbapt return yaml_emitter_emit_block_mapping_key(emitter, event, 1); 469247738Sbapt 470247738Sbapt case YAML_EMIT_BLOCK_MAPPING_KEY_STATE: 471247738Sbapt return yaml_emitter_emit_block_mapping_key(emitter, event, 0); 472247738Sbapt 473247738Sbapt case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: 474247738Sbapt return yaml_emitter_emit_block_mapping_value(emitter, event, 1); 475247738Sbapt 476247738Sbapt case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE: 477247738Sbapt return yaml_emitter_emit_block_mapping_value(emitter, event, 0); 478247738Sbapt 479247738Sbapt case YAML_EMIT_END_STATE: 480247738Sbapt return yaml_emitter_set_emitter_error(emitter, 481247738Sbapt "expected nothing after STREAM-END"); 482247738Sbapt 483247738Sbapt default: 484247738Sbapt assert(1); /* Invalid state. */ 485247738Sbapt } 486247738Sbapt 487247738Sbapt return 0; 488247738Sbapt} 489247738Sbapt 490247738Sbapt/* 491247738Sbapt * Expect STREAM-START. 492247738Sbapt */ 493247738Sbapt 494247738Sbaptstatic int 495247738Sbaptyaml_emitter_emit_stream_start(yaml_emitter_t *emitter, 496247738Sbapt yaml_event_t *event) 497247738Sbapt{ 498247738Sbapt if (event->type == YAML_STREAM_START_EVENT) 499247738Sbapt { 500247738Sbapt if (!emitter->encoding) { 501247738Sbapt emitter->encoding = event->data.stream_start.encoding; 502247738Sbapt } 503247738Sbapt 504247738Sbapt if (!emitter->encoding) { 505247738Sbapt emitter->encoding = YAML_UTF8_ENCODING; 506247738Sbapt } 507247738Sbapt 508247738Sbapt if (emitter->best_indent < 2 || emitter->best_indent > 9) { 509247738Sbapt emitter->best_indent = 2; 510247738Sbapt } 511247738Sbapt 512247738Sbapt if (emitter->best_width >= 0 513247738Sbapt && emitter->best_width <= emitter->best_indent*2) { 514247738Sbapt emitter->best_width = 80; 515247738Sbapt } 516247738Sbapt 517247738Sbapt if (emitter->best_width < 0) { 518247738Sbapt emitter->best_width = INT_MAX; 519247738Sbapt } 520247738Sbapt 521247738Sbapt if (!emitter->line_break) { 522247738Sbapt emitter->line_break = YAML_LN_BREAK; 523247738Sbapt } 524247738Sbapt 525247738Sbapt emitter->indent = -1; 526247738Sbapt 527247738Sbapt emitter->line = 0; 528247738Sbapt emitter->column = 0; 529247738Sbapt emitter->whitespace = 1; 530247738Sbapt emitter->indention = 1; 531247738Sbapt 532247738Sbapt if (emitter->encoding != YAML_UTF8_ENCODING) { 533247738Sbapt if (!yaml_emitter_write_bom(emitter)) 534247738Sbapt return 0; 535247738Sbapt } 536247738Sbapt 537247738Sbapt emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE; 538247738Sbapt 539247738Sbapt return 1; 540247738Sbapt } 541247738Sbapt 542247738Sbapt return yaml_emitter_set_emitter_error(emitter, 543247738Sbapt "expected STREAM-START"); 544247738Sbapt} 545247738Sbapt 546247738Sbapt/* 547247738Sbapt * Expect DOCUMENT-START or STREAM-END. 548247738Sbapt */ 549247738Sbapt 550247738Sbaptstatic int 551247738Sbaptyaml_emitter_emit_document_start(yaml_emitter_t *emitter, 552247738Sbapt yaml_event_t *event, int first) 553247738Sbapt{ 554247738Sbapt if (event->type == YAML_DOCUMENT_START_EVENT) 555247738Sbapt { 556247738Sbapt yaml_tag_directive_t default_tag_directives[] = { 557247738Sbapt {(yaml_char_t *)"!", (yaml_char_t *)"!"}, 558247738Sbapt {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, 559247738Sbapt {NULL, NULL} 560247738Sbapt }; 561247738Sbapt yaml_tag_directive_t *tag_directive; 562247738Sbapt int implicit; 563247738Sbapt 564247738Sbapt if (event->data.document_start.version_directive) { 565247738Sbapt if (!yaml_emitter_analyze_version_directive(emitter, 566247738Sbapt *event->data.document_start.version_directive)) 567247738Sbapt return 0; 568247738Sbapt } 569247738Sbapt 570247738Sbapt for (tag_directive = event->data.document_start.tag_directives.start; 571247738Sbapt tag_directive != event->data.document_start.tag_directives.end; 572247738Sbapt tag_directive ++) { 573247738Sbapt if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive)) 574247738Sbapt return 0; 575247738Sbapt if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0)) 576247738Sbapt return 0; 577247738Sbapt } 578247738Sbapt 579247738Sbapt for (tag_directive = default_tag_directives; 580247738Sbapt tag_directive->handle; tag_directive ++) { 581247738Sbapt if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1)) 582247738Sbapt return 0; 583247738Sbapt } 584247738Sbapt 585247738Sbapt implicit = event->data.document_start.implicit; 586247738Sbapt if (!first || emitter->canonical) { 587247738Sbapt implicit = 0; 588247738Sbapt } 589247738Sbapt 590247738Sbapt if ((event->data.document_start.version_directive || 591247738Sbapt (event->data.document_start.tag_directives.start 592247738Sbapt != event->data.document_start.tag_directives.end)) && 593247738Sbapt emitter->open_ended) 594247738Sbapt { 595247738Sbapt if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) 596247738Sbapt return 0; 597247738Sbapt if (!yaml_emitter_write_indent(emitter)) 598247738Sbapt return 0; 599247738Sbapt } 600247738Sbapt 601247738Sbapt if (event->data.document_start.version_directive) { 602247738Sbapt implicit = 0; 603247738Sbapt if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0)) 604247738Sbapt return 0; 605247738Sbapt if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0)) 606247738Sbapt return 0; 607247738Sbapt if (!yaml_emitter_write_indent(emitter)) 608247738Sbapt return 0; 609247738Sbapt } 610247738Sbapt 611247738Sbapt if (event->data.document_start.tag_directives.start 612247738Sbapt != event->data.document_start.tag_directives.end) { 613247738Sbapt implicit = 0; 614247738Sbapt for (tag_directive = event->data.document_start.tag_directives.start; 615247738Sbapt tag_directive != event->data.document_start.tag_directives.end; 616247738Sbapt tag_directive ++) { 617247738Sbapt if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0)) 618247738Sbapt return 0; 619247738Sbapt if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle, 620247738Sbapt strlen((char *)tag_directive->handle))) 621247738Sbapt return 0; 622247738Sbapt if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix, 623247738Sbapt strlen((char *)tag_directive->prefix), 1)) 624247738Sbapt return 0; 625247738Sbapt if (!yaml_emitter_write_indent(emitter)) 626247738Sbapt return 0; 627247738Sbapt } 628247738Sbapt } 629247738Sbapt 630247738Sbapt if (yaml_emitter_check_empty_document(emitter)) { 631247738Sbapt implicit = 0; 632247738Sbapt } 633247738Sbapt 634247738Sbapt if (!implicit) { 635247738Sbapt if (!yaml_emitter_write_indent(emitter)) 636247738Sbapt return 0; 637247738Sbapt if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0)) 638247738Sbapt return 0; 639247738Sbapt if (emitter->canonical) { 640247738Sbapt if (!yaml_emitter_write_indent(emitter)) 641247738Sbapt return 0; 642247738Sbapt } 643247738Sbapt } 644247738Sbapt 645247738Sbapt emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE; 646247738Sbapt 647247738Sbapt return 1; 648247738Sbapt } 649247738Sbapt 650247738Sbapt else if (event->type == YAML_STREAM_END_EVENT) 651247738Sbapt { 652247738Sbapt if (emitter->open_ended) 653247738Sbapt { 654247738Sbapt if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) 655247738Sbapt return 0; 656247738Sbapt if (!yaml_emitter_write_indent(emitter)) 657247738Sbapt return 0; 658247738Sbapt } 659247738Sbapt 660247738Sbapt if (!yaml_emitter_flush(emitter)) 661247738Sbapt return 0; 662247738Sbapt 663247738Sbapt emitter->state = YAML_EMIT_END_STATE; 664247738Sbapt 665247738Sbapt return 1; 666247738Sbapt } 667247738Sbapt 668247738Sbapt return yaml_emitter_set_emitter_error(emitter, 669247738Sbapt "expected DOCUMENT-START or STREAM-END"); 670247738Sbapt} 671247738Sbapt 672247738Sbapt/* 673247738Sbapt * Expect the root node. 674247738Sbapt */ 675247738Sbapt 676247738Sbaptstatic int 677247738Sbaptyaml_emitter_emit_document_content(yaml_emitter_t *emitter, 678247738Sbapt yaml_event_t *event) 679247738Sbapt{ 680247738Sbapt if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE)) 681247738Sbapt return 0; 682247738Sbapt 683247738Sbapt return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0); 684247738Sbapt} 685247738Sbapt 686247738Sbapt/* 687247738Sbapt * Expect DOCUMENT-END. 688247738Sbapt */ 689247738Sbapt 690247738Sbaptstatic int 691247738Sbaptyaml_emitter_emit_document_end(yaml_emitter_t *emitter, 692247738Sbapt yaml_event_t *event) 693247738Sbapt{ 694247738Sbapt if (event->type == YAML_DOCUMENT_END_EVENT) 695247738Sbapt { 696247738Sbapt if (!yaml_emitter_write_indent(emitter)) 697247738Sbapt return 0; 698247738Sbapt if (!event->data.document_end.implicit) { 699247738Sbapt if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) 700247738Sbapt return 0; 701247738Sbapt if (!yaml_emitter_write_indent(emitter)) 702247738Sbapt return 0; 703247738Sbapt } 704247738Sbapt if (!yaml_emitter_flush(emitter)) 705247738Sbapt return 0; 706247738Sbapt 707247738Sbapt emitter->state = YAML_EMIT_DOCUMENT_START_STATE; 708247738Sbapt 709247738Sbapt while (!STACK_EMPTY(emitter, emitter->tag_directives)) { 710247738Sbapt yaml_tag_directive_t tag_directive = POP(emitter, 711247738Sbapt emitter->tag_directives); 712247738Sbapt yaml_free(tag_directive.handle); 713247738Sbapt yaml_free(tag_directive.prefix); 714247738Sbapt } 715247738Sbapt 716247738Sbapt return 1; 717247738Sbapt } 718247738Sbapt 719247738Sbapt return yaml_emitter_set_emitter_error(emitter, 720247738Sbapt "expected DOCUMENT-END"); 721247738Sbapt} 722247738Sbapt 723247738Sbapt/* 724247738Sbapt * 725247738Sbapt * Expect a flow item node. 726247738Sbapt */ 727247738Sbapt 728247738Sbaptstatic int 729247738Sbaptyaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, 730247738Sbapt yaml_event_t *event, int first) 731247738Sbapt{ 732247738Sbapt if (first) 733247738Sbapt { 734247738Sbapt if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0)) 735247738Sbapt return 0; 736247738Sbapt if (!yaml_emitter_increase_indent(emitter, 1, 0)) 737247738Sbapt return 0; 738247738Sbapt emitter->flow_level ++; 739247738Sbapt } 740247738Sbapt 741247738Sbapt if (event->type == YAML_SEQUENCE_END_EVENT) 742247738Sbapt { 743247738Sbapt emitter->flow_level --; 744247738Sbapt emitter->indent = POP(emitter, emitter->indents); 745247738Sbapt if (emitter->canonical && !first) { 746247738Sbapt if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) 747247738Sbapt return 0; 748247738Sbapt if (!yaml_emitter_write_indent(emitter)) 749247738Sbapt return 0; 750247738Sbapt } 751247738Sbapt if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0)) 752247738Sbapt return 0; 753247738Sbapt emitter->state = POP(emitter, emitter->states); 754247738Sbapt 755247738Sbapt return 1; 756247738Sbapt } 757247738Sbapt 758247738Sbapt if (!first) { 759247738Sbapt if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) 760247738Sbapt return 0; 761247738Sbapt } 762247738Sbapt 763247738Sbapt if (emitter->canonical || emitter->column > emitter->best_width) { 764247738Sbapt if (!yaml_emitter_write_indent(emitter)) 765247738Sbapt return 0; 766247738Sbapt } 767247738Sbapt if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE)) 768247738Sbapt return 0; 769247738Sbapt 770247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); 771247738Sbapt} 772247738Sbapt 773247738Sbapt/* 774247738Sbapt * Expect a flow key node. 775247738Sbapt */ 776247738Sbapt 777247738Sbaptstatic int 778247738Sbaptyaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, 779247738Sbapt yaml_event_t *event, int first) 780247738Sbapt{ 781247738Sbapt if (first) 782247738Sbapt { 783247738Sbapt if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0)) 784247738Sbapt return 0; 785247738Sbapt if (!yaml_emitter_increase_indent(emitter, 1, 0)) 786247738Sbapt return 0; 787247738Sbapt emitter->flow_level ++; 788247738Sbapt } 789247738Sbapt 790247738Sbapt if (event->type == YAML_MAPPING_END_EVENT) 791247738Sbapt { 792247738Sbapt emitter->flow_level --; 793247738Sbapt emitter->indent = POP(emitter, emitter->indents); 794247738Sbapt if (emitter->canonical && !first) { 795247738Sbapt if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) 796247738Sbapt return 0; 797247738Sbapt if (!yaml_emitter_write_indent(emitter)) 798247738Sbapt return 0; 799247738Sbapt } 800247738Sbapt if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0)) 801247738Sbapt return 0; 802247738Sbapt emitter->state = POP(emitter, emitter->states); 803247738Sbapt 804247738Sbapt return 1; 805247738Sbapt } 806247738Sbapt 807247738Sbapt if (!first) { 808247738Sbapt if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) 809247738Sbapt return 0; 810247738Sbapt } 811247738Sbapt if (emitter->canonical || emitter->column > emitter->best_width) { 812247738Sbapt if (!yaml_emitter_write_indent(emitter)) 813247738Sbapt return 0; 814247738Sbapt } 815247738Sbapt 816247738Sbapt if (!emitter->canonical && yaml_emitter_check_simple_key(emitter)) 817247738Sbapt { 818247738Sbapt if (!PUSH(emitter, emitter->states, 819247738Sbapt YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)) 820247738Sbapt return 0; 821247738Sbapt 822247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); 823247738Sbapt } 824247738Sbapt else 825247738Sbapt { 826247738Sbapt if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0)) 827247738Sbapt return 0; 828247738Sbapt if (!PUSH(emitter, emitter->states, 829247738Sbapt YAML_EMIT_FLOW_MAPPING_VALUE_STATE)) 830247738Sbapt return 0; 831247738Sbapt 832247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 833247738Sbapt } 834247738Sbapt} 835247738Sbapt 836247738Sbapt/* 837247738Sbapt * Expect a flow value node. 838247738Sbapt */ 839247738Sbapt 840247738Sbaptstatic int 841247738Sbaptyaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, 842247738Sbapt yaml_event_t *event, int simple) 843247738Sbapt{ 844247738Sbapt if (simple) { 845247738Sbapt if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) 846247738Sbapt return 0; 847247738Sbapt } 848247738Sbapt else { 849247738Sbapt if (emitter->canonical || emitter->column > emitter->best_width) { 850247738Sbapt if (!yaml_emitter_write_indent(emitter)) 851247738Sbapt return 0; 852247738Sbapt } 853247738Sbapt if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0)) 854247738Sbapt return 0; 855247738Sbapt } 856247738Sbapt if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE)) 857247738Sbapt return 0; 858247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 859247738Sbapt} 860247738Sbapt 861247738Sbapt/* 862247738Sbapt * Expect a block item node. 863247738Sbapt */ 864247738Sbapt 865247738Sbaptstatic int 866247738Sbaptyaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, 867247738Sbapt yaml_event_t *event, int first) 868247738Sbapt{ 869247738Sbapt if (first) 870247738Sbapt { 871247738Sbapt if (!yaml_emitter_increase_indent(emitter, 0, 872247738Sbapt (emitter->mapping_context && !emitter->indention))) 873247738Sbapt return 0; 874247738Sbapt } 875247738Sbapt 876247738Sbapt if (event->type == YAML_SEQUENCE_END_EVENT) 877247738Sbapt { 878247738Sbapt emitter->indent = POP(emitter, emitter->indents); 879247738Sbapt emitter->state = POP(emitter, emitter->states); 880247738Sbapt 881247738Sbapt return 1; 882247738Sbapt } 883247738Sbapt 884247738Sbapt if (!yaml_emitter_write_indent(emitter)) 885247738Sbapt return 0; 886247738Sbapt if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1)) 887247738Sbapt return 0; 888247738Sbapt if (!PUSH(emitter, emitter->states, 889247738Sbapt YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE)) 890247738Sbapt return 0; 891247738Sbapt 892247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); 893247738Sbapt} 894247738Sbapt 895247738Sbapt/* 896247738Sbapt * Expect a block key node. 897247738Sbapt */ 898247738Sbapt 899247738Sbaptstatic int 900247738Sbaptyaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, 901247738Sbapt yaml_event_t *event, int first) 902247738Sbapt{ 903247738Sbapt if (first) 904247738Sbapt { 905247738Sbapt if (!yaml_emitter_increase_indent(emitter, 0, 0)) 906247738Sbapt return 0; 907247738Sbapt } 908247738Sbapt 909247738Sbapt if (event->type == YAML_MAPPING_END_EVENT) 910247738Sbapt { 911247738Sbapt emitter->indent = POP(emitter, emitter->indents); 912247738Sbapt emitter->state = POP(emitter, emitter->states); 913247738Sbapt 914247738Sbapt return 1; 915247738Sbapt } 916247738Sbapt 917247738Sbapt if (!yaml_emitter_write_indent(emitter)) 918247738Sbapt return 0; 919247738Sbapt 920247738Sbapt if (yaml_emitter_check_simple_key(emitter)) 921247738Sbapt { 922247738Sbapt if (!PUSH(emitter, emitter->states, 923247738Sbapt YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)) 924247738Sbapt return 0; 925247738Sbapt 926247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); 927247738Sbapt } 928247738Sbapt else 929247738Sbapt { 930247738Sbapt if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1)) 931247738Sbapt return 0; 932247738Sbapt if (!PUSH(emitter, emitter->states, 933247738Sbapt YAML_EMIT_BLOCK_MAPPING_VALUE_STATE)) 934247738Sbapt return 0; 935247738Sbapt 936247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 937247738Sbapt } 938247738Sbapt} 939247738Sbapt 940247738Sbapt/* 941247738Sbapt * Expect a block value node. 942247738Sbapt */ 943247738Sbapt 944247738Sbaptstatic int 945247738Sbaptyaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, 946247738Sbapt yaml_event_t *event, int simple) 947247738Sbapt{ 948247738Sbapt if (simple) { 949247738Sbapt if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) 950247738Sbapt return 0; 951247738Sbapt } 952247738Sbapt else { 953247738Sbapt if (!yaml_emitter_write_indent(emitter)) 954247738Sbapt return 0; 955247738Sbapt if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1)) 956247738Sbapt return 0; 957247738Sbapt } 958247738Sbapt if (!PUSH(emitter, emitter->states, 959247738Sbapt YAML_EMIT_BLOCK_MAPPING_KEY_STATE)) 960247738Sbapt return 0; 961247738Sbapt 962247738Sbapt return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); 963247738Sbapt} 964247738Sbapt 965247738Sbapt/* 966247738Sbapt * Expect a node. 967247738Sbapt */ 968247738Sbapt 969247738Sbaptstatic int 970247738Sbaptyaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, 971247738Sbapt int root, int sequence, int mapping, int simple_key) 972247738Sbapt{ 973247738Sbapt emitter->root_context = root; 974247738Sbapt emitter->sequence_context = sequence; 975247738Sbapt emitter->mapping_context = mapping; 976247738Sbapt emitter->simple_key_context = simple_key; 977247738Sbapt 978247738Sbapt switch (event->type) 979247738Sbapt { 980247738Sbapt case YAML_ALIAS_EVENT: 981247738Sbapt return yaml_emitter_emit_alias(emitter, event); 982247738Sbapt 983247738Sbapt case YAML_SCALAR_EVENT: 984247738Sbapt return yaml_emitter_emit_scalar(emitter, event); 985247738Sbapt 986247738Sbapt case YAML_SEQUENCE_START_EVENT: 987247738Sbapt return yaml_emitter_emit_sequence_start(emitter, event); 988247738Sbapt 989247738Sbapt case YAML_MAPPING_START_EVENT: 990247738Sbapt return yaml_emitter_emit_mapping_start(emitter, event); 991247738Sbapt 992247738Sbapt default: 993247738Sbapt return yaml_emitter_set_emitter_error(emitter, 994247738Sbapt "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS"); 995247738Sbapt } 996247738Sbapt 997247738Sbapt return 0; 998247738Sbapt} 999247738Sbapt 1000247738Sbapt/* 1001247738Sbapt * Expect ALIAS. 1002247738Sbapt */ 1003247738Sbapt 1004247738Sbaptstatic int 1005247738Sbaptyaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event) 1006247738Sbapt{ 1007247738Sbapt if (!yaml_emitter_process_anchor(emitter)) 1008247738Sbapt return 0; 1009247738Sbapt emitter->state = POP(emitter, emitter->states); 1010247738Sbapt 1011247738Sbapt return 1; 1012247738Sbapt} 1013247738Sbapt 1014247738Sbapt/* 1015247738Sbapt * Expect SCALAR. 1016247738Sbapt */ 1017247738Sbapt 1018247738Sbaptstatic int 1019247738Sbaptyaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event) 1020247738Sbapt{ 1021247738Sbapt if (!yaml_emitter_select_scalar_style(emitter, event)) 1022247738Sbapt return 0; 1023247738Sbapt if (!yaml_emitter_process_anchor(emitter)) 1024247738Sbapt return 0; 1025247738Sbapt if (!yaml_emitter_process_tag(emitter)) 1026247738Sbapt return 0; 1027247738Sbapt if (!yaml_emitter_increase_indent(emitter, 1, 0)) 1028247738Sbapt return 0; 1029247738Sbapt if (!yaml_emitter_process_scalar(emitter)) 1030247738Sbapt return 0; 1031247738Sbapt emitter->indent = POP(emitter, emitter->indents); 1032247738Sbapt emitter->state = POP(emitter, emitter->states); 1033247738Sbapt 1034247738Sbapt return 1; 1035247738Sbapt} 1036247738Sbapt 1037247738Sbapt/* 1038247738Sbapt * Expect SEQUENCE-START. 1039247738Sbapt */ 1040247738Sbapt 1041247738Sbaptstatic int 1042247738Sbaptyaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event) 1043247738Sbapt{ 1044247738Sbapt if (!yaml_emitter_process_anchor(emitter)) 1045247738Sbapt return 0; 1046247738Sbapt if (!yaml_emitter_process_tag(emitter)) 1047247738Sbapt return 0; 1048247738Sbapt 1049247738Sbapt if (emitter->flow_level || emitter->canonical 1050247738Sbapt || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE 1051247738Sbapt || yaml_emitter_check_empty_sequence(emitter)) { 1052247738Sbapt emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE; 1053247738Sbapt } 1054247738Sbapt else { 1055247738Sbapt emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE; 1056247738Sbapt } 1057247738Sbapt 1058247738Sbapt return 1; 1059247738Sbapt} 1060247738Sbapt 1061247738Sbapt/* 1062247738Sbapt * Expect MAPPING-START. 1063247738Sbapt */ 1064247738Sbapt 1065247738Sbaptstatic int 1066247738Sbaptyaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event) 1067247738Sbapt{ 1068247738Sbapt if (!yaml_emitter_process_anchor(emitter)) 1069247738Sbapt return 0; 1070247738Sbapt if (!yaml_emitter_process_tag(emitter)) 1071247738Sbapt return 0; 1072247738Sbapt 1073247738Sbapt if (emitter->flow_level || emitter->canonical 1074247738Sbapt || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE 1075247738Sbapt || yaml_emitter_check_empty_mapping(emitter)) { 1076247738Sbapt emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE; 1077247738Sbapt } 1078247738Sbapt else { 1079247738Sbapt emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE; 1080247738Sbapt } 1081247738Sbapt 1082247738Sbapt return 1; 1083247738Sbapt} 1084247738Sbapt 1085247738Sbapt/* 1086247738Sbapt * Check if the document content is an empty scalar. 1087247738Sbapt */ 1088247738Sbapt 1089247738Sbaptstatic int 1090247738Sbaptyaml_emitter_check_empty_document(yaml_emitter_t *emitter) 1091247738Sbapt{ 1092247738Sbapt return 0; 1093247738Sbapt} 1094247738Sbapt 1095247738Sbapt/* 1096247738Sbapt * Check if the next events represent an empty sequence. 1097247738Sbapt */ 1098247738Sbapt 1099247738Sbaptstatic int 1100247738Sbaptyaml_emitter_check_empty_sequence(yaml_emitter_t *emitter) 1101247738Sbapt{ 1102247738Sbapt if (emitter->events.tail - emitter->events.head < 2) 1103247738Sbapt return 0; 1104247738Sbapt 1105247738Sbapt return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT 1106247738Sbapt && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT); 1107247738Sbapt} 1108247738Sbapt 1109247738Sbapt/* 1110247738Sbapt * Check if the next events represent an empty mapping. 1111247738Sbapt */ 1112247738Sbapt 1113247738Sbaptstatic int 1114247738Sbaptyaml_emitter_check_empty_mapping(yaml_emitter_t *emitter) 1115247738Sbapt{ 1116247738Sbapt if (emitter->events.tail - emitter->events.head < 2) 1117247738Sbapt return 0; 1118247738Sbapt 1119247738Sbapt return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT 1120247738Sbapt && emitter->events.head[1].type == YAML_MAPPING_END_EVENT); 1121247738Sbapt} 1122247738Sbapt 1123247738Sbapt/* 1124247738Sbapt * Check if the next node can be expressed as a simple key. 1125247738Sbapt */ 1126247738Sbapt 1127247738Sbaptstatic int 1128247738Sbaptyaml_emitter_check_simple_key(yaml_emitter_t *emitter) 1129247738Sbapt{ 1130247738Sbapt yaml_event_t *event = emitter->events.head; 1131247738Sbapt size_t length = 0; 1132247738Sbapt 1133247738Sbapt switch (event->type) 1134247738Sbapt { 1135247738Sbapt case YAML_ALIAS_EVENT: 1136247738Sbapt length += emitter->anchor_data.anchor_length; 1137247738Sbapt break; 1138247738Sbapt 1139247738Sbapt case YAML_SCALAR_EVENT: 1140247738Sbapt if (emitter->scalar_data.multiline) 1141247738Sbapt return 0; 1142247738Sbapt length += emitter->anchor_data.anchor_length 1143247738Sbapt + emitter->tag_data.handle_length 1144247738Sbapt + emitter->tag_data.suffix_length 1145247738Sbapt + emitter->scalar_data.length; 1146247738Sbapt break; 1147247738Sbapt 1148247738Sbapt case YAML_SEQUENCE_START_EVENT: 1149247738Sbapt if (!yaml_emitter_check_empty_sequence(emitter)) 1150247738Sbapt return 0; 1151247738Sbapt length += emitter->anchor_data.anchor_length 1152247738Sbapt + emitter->tag_data.handle_length 1153247738Sbapt + emitter->tag_data.suffix_length; 1154247738Sbapt break; 1155247738Sbapt 1156247738Sbapt case YAML_MAPPING_START_EVENT: 1157247738Sbapt if (!yaml_emitter_check_empty_mapping(emitter)) 1158247738Sbapt return 0; 1159247738Sbapt length += emitter->anchor_data.anchor_length 1160247738Sbapt + emitter->tag_data.handle_length 1161247738Sbapt + emitter->tag_data.suffix_length; 1162247738Sbapt break; 1163247738Sbapt 1164247738Sbapt default: 1165247738Sbapt return 0; 1166247738Sbapt } 1167247738Sbapt 1168247738Sbapt if (length > 128) 1169247738Sbapt return 0; 1170247738Sbapt 1171247738Sbapt return 1; 1172247738Sbapt} 1173247738Sbapt 1174247738Sbapt/* 1175247738Sbapt * Determine an acceptable scalar style. 1176247738Sbapt */ 1177247738Sbapt 1178247738Sbaptstatic int 1179247738Sbaptyaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event) 1180247738Sbapt{ 1181247738Sbapt yaml_scalar_style_t style = event->data.scalar.style; 1182247738Sbapt int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix); 1183247738Sbapt 1184247738Sbapt if (no_tag && !event->data.scalar.plain_implicit 1185247738Sbapt && !event->data.scalar.quoted_implicit) { 1186247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1187247738Sbapt "neither tag nor implicit flags are specified"); 1188247738Sbapt } 1189247738Sbapt 1190247738Sbapt if (style == YAML_ANY_SCALAR_STYLE) 1191247738Sbapt style = YAML_PLAIN_SCALAR_STYLE; 1192247738Sbapt 1193247738Sbapt if (emitter->canonical) 1194247738Sbapt style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; 1195247738Sbapt 1196247738Sbapt if (emitter->simple_key_context && emitter->scalar_data.multiline) 1197247738Sbapt style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; 1198247738Sbapt 1199247738Sbapt if (style == YAML_PLAIN_SCALAR_STYLE) 1200247738Sbapt { 1201247738Sbapt if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed) 1202247738Sbapt || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed)) 1203247738Sbapt style = YAML_SINGLE_QUOTED_SCALAR_STYLE; 1204247738Sbapt if (!emitter->scalar_data.length 1205247738Sbapt && (emitter->flow_level || emitter->simple_key_context)) 1206247738Sbapt style = YAML_SINGLE_QUOTED_SCALAR_STYLE; 1207247738Sbapt if (no_tag && !event->data.scalar.plain_implicit) 1208247738Sbapt style = YAML_SINGLE_QUOTED_SCALAR_STYLE; 1209247738Sbapt } 1210247738Sbapt 1211247738Sbapt if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE) 1212247738Sbapt { 1213247738Sbapt if (!emitter->scalar_data.single_quoted_allowed) 1214247738Sbapt style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; 1215247738Sbapt } 1216247738Sbapt 1217247738Sbapt if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE) 1218247738Sbapt { 1219247738Sbapt if (!emitter->scalar_data.block_allowed 1220247738Sbapt || emitter->flow_level || emitter->simple_key_context) 1221247738Sbapt style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; 1222247738Sbapt } 1223247738Sbapt 1224247738Sbapt if (no_tag && !event->data.scalar.quoted_implicit 1225247738Sbapt && style != YAML_PLAIN_SCALAR_STYLE) 1226247738Sbapt { 1227247738Sbapt emitter->tag_data.handle = (yaml_char_t *)"!"; 1228247738Sbapt emitter->tag_data.handle_length = 1; 1229247738Sbapt } 1230247738Sbapt 1231247738Sbapt emitter->scalar_data.style = style; 1232247738Sbapt 1233247738Sbapt return 1; 1234247738Sbapt} 1235247738Sbapt 1236247738Sbapt/* 1237247738Sbapt * Write an achor. 1238247738Sbapt */ 1239247738Sbapt 1240247738Sbaptstatic int 1241247738Sbaptyaml_emitter_process_anchor(yaml_emitter_t *emitter) 1242247738Sbapt{ 1243247738Sbapt if (!emitter->anchor_data.anchor) 1244247738Sbapt return 1; 1245247738Sbapt 1246247738Sbapt if (!yaml_emitter_write_indicator(emitter, 1247247738Sbapt (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0)) 1248247738Sbapt return 0; 1249247738Sbapt 1250247738Sbapt return yaml_emitter_write_anchor(emitter, 1251247738Sbapt emitter->anchor_data.anchor, emitter->anchor_data.anchor_length); 1252247738Sbapt} 1253247738Sbapt 1254247738Sbapt/* 1255247738Sbapt * Write a tag. 1256247738Sbapt */ 1257247738Sbapt 1258247738Sbaptstatic int 1259247738Sbaptyaml_emitter_process_tag(yaml_emitter_t *emitter) 1260247738Sbapt{ 1261247738Sbapt if (!emitter->tag_data.handle && !emitter->tag_data.suffix) 1262247738Sbapt return 1; 1263247738Sbapt 1264247738Sbapt if (emitter->tag_data.handle) 1265247738Sbapt { 1266247738Sbapt if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle, 1267247738Sbapt emitter->tag_data.handle_length)) 1268247738Sbapt return 0; 1269247738Sbapt if (emitter->tag_data.suffix) { 1270247738Sbapt if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, 1271247738Sbapt emitter->tag_data.suffix_length, 0)) 1272247738Sbapt return 0; 1273247738Sbapt } 1274247738Sbapt } 1275247738Sbapt else 1276247738Sbapt { 1277247738Sbapt if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0)) 1278247738Sbapt return 0; 1279247738Sbapt if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, 1280247738Sbapt emitter->tag_data.suffix_length, 0)) 1281247738Sbapt return 0; 1282247738Sbapt if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0)) 1283247738Sbapt return 0; 1284247738Sbapt } 1285247738Sbapt 1286247738Sbapt return 1; 1287247738Sbapt} 1288247738Sbapt 1289247738Sbapt/* 1290247738Sbapt * Write a scalar. 1291247738Sbapt */ 1292247738Sbapt 1293247738Sbaptstatic int 1294247738Sbaptyaml_emitter_process_scalar(yaml_emitter_t *emitter) 1295247738Sbapt{ 1296247738Sbapt switch (emitter->scalar_data.style) 1297247738Sbapt { 1298247738Sbapt case YAML_PLAIN_SCALAR_STYLE: 1299247738Sbapt return yaml_emitter_write_plain_scalar(emitter, 1300247738Sbapt emitter->scalar_data.value, emitter->scalar_data.length, 1301247738Sbapt !emitter->simple_key_context); 1302247738Sbapt 1303247738Sbapt case YAML_SINGLE_QUOTED_SCALAR_STYLE: 1304247738Sbapt return yaml_emitter_write_single_quoted_scalar(emitter, 1305247738Sbapt emitter->scalar_data.value, emitter->scalar_data.length, 1306247738Sbapt !emitter->simple_key_context); 1307247738Sbapt 1308247738Sbapt case YAML_DOUBLE_QUOTED_SCALAR_STYLE: 1309247738Sbapt return yaml_emitter_write_double_quoted_scalar(emitter, 1310247738Sbapt emitter->scalar_data.value, emitter->scalar_data.length, 1311247738Sbapt !emitter->simple_key_context); 1312247738Sbapt 1313247738Sbapt case YAML_LITERAL_SCALAR_STYLE: 1314247738Sbapt return yaml_emitter_write_literal_scalar(emitter, 1315247738Sbapt emitter->scalar_data.value, emitter->scalar_data.length); 1316247738Sbapt 1317247738Sbapt case YAML_FOLDED_SCALAR_STYLE: 1318247738Sbapt return yaml_emitter_write_folded_scalar(emitter, 1319247738Sbapt emitter->scalar_data.value, emitter->scalar_data.length); 1320247738Sbapt 1321247738Sbapt default: 1322247738Sbapt assert(1); /* Impossible. */ 1323247738Sbapt } 1324247738Sbapt 1325247738Sbapt return 0; 1326247738Sbapt} 1327247738Sbapt 1328247738Sbapt/* 1329247738Sbapt * Check if a %YAML directive is valid. 1330247738Sbapt */ 1331247738Sbapt 1332247738Sbaptstatic int 1333247738Sbaptyaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, 1334247738Sbapt yaml_version_directive_t version_directive) 1335247738Sbapt{ 1336247738Sbapt if (version_directive.major != 1 || version_directive.minor != 1) { 1337247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1338247738Sbapt "incompatible %YAML directive"); 1339247738Sbapt } 1340247738Sbapt 1341247738Sbapt return 1; 1342247738Sbapt} 1343247738Sbapt 1344247738Sbapt/* 1345247738Sbapt * Check if a %TAG directive is valid. 1346247738Sbapt */ 1347247738Sbapt 1348247738Sbaptstatic int 1349247738Sbaptyaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, 1350247738Sbapt yaml_tag_directive_t tag_directive) 1351247738Sbapt{ 1352247738Sbapt yaml_string_t handle; 1353247738Sbapt yaml_string_t prefix; 1354247738Sbapt size_t handle_length; 1355247738Sbapt size_t prefix_length; 1356247738Sbapt 1357247738Sbapt handle_length = strlen((char *)tag_directive.handle); 1358247738Sbapt prefix_length = strlen((char *)tag_directive.prefix); 1359247738Sbapt STRING_ASSIGN(handle, tag_directive.handle, handle_length); 1360247738Sbapt STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length); 1361247738Sbapt 1362247738Sbapt if (handle.start == handle.end) { 1363247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1364247738Sbapt "tag handle must not be empty"); 1365247738Sbapt } 1366247738Sbapt 1367247738Sbapt if (handle.start[0] != '!') { 1368247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1369247738Sbapt "tag handle must start with '!'"); 1370247738Sbapt } 1371247738Sbapt 1372247738Sbapt if (handle.end[-1] != '!') { 1373247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1374247738Sbapt "tag handle must end with '!'"); 1375247738Sbapt } 1376247738Sbapt 1377247738Sbapt handle.pointer ++; 1378247738Sbapt 1379247738Sbapt while (handle.pointer < handle.end-1) { 1380247738Sbapt if (!IS_ALPHA(handle)) { 1381247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1382247738Sbapt "tag handle must contain alphanumerical characters only"); 1383247738Sbapt } 1384247738Sbapt MOVE(handle); 1385247738Sbapt } 1386247738Sbapt 1387247738Sbapt if (prefix.start == prefix.end) { 1388247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1389247738Sbapt "tag prefix must not be empty"); 1390247738Sbapt } 1391247738Sbapt 1392247738Sbapt return 1; 1393247738Sbapt} 1394247738Sbapt 1395247738Sbapt/* 1396247738Sbapt * Check if an anchor is valid. 1397247738Sbapt */ 1398247738Sbapt 1399247738Sbaptstatic int 1400247738Sbaptyaml_emitter_analyze_anchor(yaml_emitter_t *emitter, 1401247738Sbapt yaml_char_t *anchor, int alias) 1402247738Sbapt{ 1403247738Sbapt size_t anchor_length; 1404247738Sbapt yaml_string_t string; 1405247738Sbapt 1406247738Sbapt anchor_length = strlen((char *)anchor); 1407247738Sbapt STRING_ASSIGN(string, anchor, anchor_length); 1408247738Sbapt 1409247738Sbapt if (string.start == string.end) { 1410247738Sbapt return yaml_emitter_set_emitter_error(emitter, alias ? 1411247738Sbapt "alias value must not be empty" : 1412247738Sbapt "anchor value must not be empty"); 1413247738Sbapt } 1414247738Sbapt 1415247738Sbapt while (string.pointer != string.end) { 1416247738Sbapt if (!IS_ALPHA(string)) { 1417247738Sbapt return yaml_emitter_set_emitter_error(emitter, alias ? 1418247738Sbapt "alias value must contain alphanumerical characters only" : 1419247738Sbapt "anchor value must contain alphanumerical characters only"); 1420247738Sbapt } 1421247738Sbapt MOVE(string); 1422247738Sbapt } 1423247738Sbapt 1424247738Sbapt emitter->anchor_data.anchor = string.start; 1425247738Sbapt emitter->anchor_data.anchor_length = string.end - string.start; 1426247738Sbapt emitter->anchor_data.alias = alias; 1427247738Sbapt 1428247738Sbapt return 1; 1429247738Sbapt} 1430247738Sbapt 1431247738Sbapt/* 1432247738Sbapt * Check if a tag is valid. 1433247738Sbapt */ 1434247738Sbapt 1435247738Sbaptstatic int 1436247738Sbaptyaml_emitter_analyze_tag(yaml_emitter_t *emitter, 1437247738Sbapt yaml_char_t *tag) 1438247738Sbapt{ 1439247738Sbapt size_t tag_length; 1440247738Sbapt yaml_string_t string; 1441247738Sbapt yaml_tag_directive_t *tag_directive; 1442247738Sbapt 1443247738Sbapt tag_length = strlen((char *)tag); 1444247738Sbapt STRING_ASSIGN(string, tag, tag_length); 1445247738Sbapt 1446247738Sbapt if (string.start == string.end) { 1447247738Sbapt return yaml_emitter_set_emitter_error(emitter, 1448247738Sbapt "tag value must not be empty"); 1449247738Sbapt } 1450247738Sbapt 1451247738Sbapt for (tag_directive = emitter->tag_directives.start; 1452247738Sbapt tag_directive != emitter->tag_directives.top; tag_directive ++) { 1453247738Sbapt size_t prefix_length = strlen((char *)tag_directive->prefix); 1454247738Sbapt if (prefix_length < (size_t)(string.end - string.start) 1455247738Sbapt && strncmp((char *)tag_directive->prefix, (char *)string.start, 1456247738Sbapt prefix_length) == 0) 1457247738Sbapt { 1458247738Sbapt emitter->tag_data.handle = tag_directive->handle; 1459247738Sbapt emitter->tag_data.handle_length = 1460247738Sbapt strlen((char *)tag_directive->handle); 1461247738Sbapt emitter->tag_data.suffix = string.start + prefix_length; 1462247738Sbapt emitter->tag_data.suffix_length = 1463247738Sbapt (string.end - string.start) - prefix_length; 1464247738Sbapt return 1; 1465247738Sbapt } 1466247738Sbapt } 1467247738Sbapt 1468247738Sbapt emitter->tag_data.suffix = string.start; 1469247738Sbapt emitter->tag_data.suffix_length = string.end - string.start; 1470247738Sbapt 1471247738Sbapt return 1; 1472247738Sbapt} 1473247738Sbapt 1474247738Sbapt/* 1475247738Sbapt * Check if a scalar is valid. 1476247738Sbapt */ 1477247738Sbapt 1478247738Sbaptstatic int 1479247738Sbaptyaml_emitter_analyze_scalar(yaml_emitter_t *emitter, 1480247738Sbapt yaml_char_t *value, size_t length) 1481247738Sbapt{ 1482247738Sbapt yaml_string_t string; 1483247738Sbapt 1484247738Sbapt int block_indicators = 0; 1485247738Sbapt int flow_indicators = 0; 1486247738Sbapt int line_breaks = 0; 1487247738Sbapt int special_characters = 0; 1488247738Sbapt 1489247738Sbapt int leading_space = 0; 1490247738Sbapt int leading_break = 0; 1491247738Sbapt int trailing_space = 0; 1492247738Sbapt int trailing_break = 0; 1493247738Sbapt int break_space = 0; 1494247738Sbapt int space_break = 0; 1495247738Sbapt 1496247738Sbapt int preceeded_by_whitespace = 0; 1497247738Sbapt int followed_by_whitespace = 0; 1498247738Sbapt int previous_space = 0; 1499247738Sbapt int previous_break = 0; 1500247738Sbapt 1501247738Sbapt STRING_ASSIGN(string, value, length); 1502247738Sbapt 1503247738Sbapt emitter->scalar_data.value = value; 1504247738Sbapt emitter->scalar_data.length = length; 1505247738Sbapt 1506247738Sbapt if (string.start == string.end) 1507247738Sbapt { 1508247738Sbapt emitter->scalar_data.multiline = 0; 1509247738Sbapt emitter->scalar_data.flow_plain_allowed = 0; 1510247738Sbapt emitter->scalar_data.block_plain_allowed = 1; 1511247738Sbapt emitter->scalar_data.single_quoted_allowed = 1; 1512247738Sbapt emitter->scalar_data.block_allowed = 0; 1513247738Sbapt 1514247738Sbapt return 1; 1515247738Sbapt } 1516247738Sbapt 1517247738Sbapt if ((CHECK_AT(string, '-', 0) 1518247738Sbapt && CHECK_AT(string, '-', 1) 1519247738Sbapt && CHECK_AT(string, '-', 2)) 1520247738Sbapt || (CHECK_AT(string, '.', 0) 1521247738Sbapt && CHECK_AT(string, '.', 1) 1522247738Sbapt && CHECK_AT(string, '.', 2))) { 1523247738Sbapt block_indicators = 1; 1524247738Sbapt flow_indicators = 1; 1525247738Sbapt } 1526247738Sbapt 1527247738Sbapt preceeded_by_whitespace = 1; 1528247738Sbapt followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); 1529247738Sbapt 1530247738Sbapt while (string.pointer != string.end) 1531247738Sbapt { 1532247738Sbapt if (string.start == string.pointer) 1533247738Sbapt { 1534247738Sbapt if (CHECK(string, '#') || CHECK(string, ',') 1535247738Sbapt || CHECK(string, '[') || CHECK(string, ']') 1536247738Sbapt || CHECK(string, '{') || CHECK(string, '}') 1537247738Sbapt || CHECK(string, '&') || CHECK(string, '*') 1538247738Sbapt || CHECK(string, '!') || CHECK(string, '|') 1539247738Sbapt || CHECK(string, '>') || CHECK(string, '\'') 1540247738Sbapt || CHECK(string, '"') || CHECK(string, '%') 1541247738Sbapt || CHECK(string, '@') || CHECK(string, '`')) { 1542247738Sbapt flow_indicators = 1; 1543247738Sbapt block_indicators = 1; 1544247738Sbapt } 1545247738Sbapt 1546247738Sbapt if (CHECK(string, '?') || CHECK(string, ':')) { 1547247738Sbapt flow_indicators = 1; 1548247738Sbapt if (followed_by_whitespace) { 1549247738Sbapt block_indicators = 1; 1550247738Sbapt } 1551247738Sbapt } 1552247738Sbapt 1553247738Sbapt if (CHECK(string, '-') && followed_by_whitespace) { 1554247738Sbapt flow_indicators = 1; 1555247738Sbapt block_indicators = 1; 1556247738Sbapt } 1557247738Sbapt } 1558247738Sbapt else 1559247738Sbapt { 1560247738Sbapt if (CHECK(string, ',') || CHECK(string, '?') 1561247738Sbapt || CHECK(string, '[') || CHECK(string, ']') 1562247738Sbapt || CHECK(string, '{') || CHECK(string, '}')) { 1563247738Sbapt flow_indicators = 1; 1564247738Sbapt } 1565247738Sbapt 1566247738Sbapt if (CHECK(string, ':')) { 1567247738Sbapt flow_indicators = 1; 1568247738Sbapt if (followed_by_whitespace) { 1569247738Sbapt block_indicators = 1; 1570247738Sbapt } 1571247738Sbapt } 1572247738Sbapt 1573247738Sbapt if (CHECK(string, '#') && preceeded_by_whitespace) { 1574247738Sbapt flow_indicators = 1; 1575247738Sbapt block_indicators = 1; 1576247738Sbapt } 1577247738Sbapt } 1578247738Sbapt 1579247738Sbapt if (!IS_PRINTABLE(string) 1580247738Sbapt || (!IS_ASCII(string) && !emitter->unicode)) { 1581247738Sbapt special_characters = 1; 1582247738Sbapt } 1583247738Sbapt 1584247738Sbapt if (IS_BREAK(string)) { 1585247738Sbapt line_breaks = 1; 1586247738Sbapt } 1587247738Sbapt 1588247738Sbapt if (IS_SPACE(string)) 1589247738Sbapt { 1590247738Sbapt if (string.start == string.pointer) { 1591247738Sbapt leading_space = 1; 1592247738Sbapt } 1593247738Sbapt if (string.pointer+WIDTH(string) == string.end) { 1594247738Sbapt trailing_space = 1; 1595247738Sbapt } 1596247738Sbapt if (previous_break) { 1597247738Sbapt break_space = 1; 1598247738Sbapt } 1599247738Sbapt previous_space = 1; 1600247738Sbapt previous_break = 0; 1601247738Sbapt } 1602247738Sbapt else if (IS_BREAK(string)) 1603247738Sbapt { 1604247738Sbapt if (string.start == string.pointer) { 1605247738Sbapt leading_break = 1; 1606247738Sbapt } 1607247738Sbapt if (string.pointer+WIDTH(string) == string.end) { 1608247738Sbapt trailing_break = 1; 1609247738Sbapt } 1610247738Sbapt if (previous_space) { 1611247738Sbapt space_break = 1; 1612247738Sbapt } 1613247738Sbapt previous_space = 0; 1614247738Sbapt previous_break = 1; 1615247738Sbapt } 1616247738Sbapt else 1617247738Sbapt { 1618247738Sbapt previous_space = 0; 1619247738Sbapt previous_break = 0; 1620247738Sbapt } 1621247738Sbapt 1622247738Sbapt preceeded_by_whitespace = IS_BLANKZ(string); 1623247738Sbapt MOVE(string); 1624247738Sbapt if (string.pointer != string.end) { 1625247738Sbapt followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); 1626247738Sbapt } 1627247738Sbapt } 1628247738Sbapt 1629247738Sbapt emitter->scalar_data.multiline = line_breaks; 1630247738Sbapt 1631247738Sbapt emitter->scalar_data.flow_plain_allowed = 1; 1632247738Sbapt emitter->scalar_data.block_plain_allowed = 1; 1633247738Sbapt emitter->scalar_data.single_quoted_allowed = 1; 1634247738Sbapt emitter->scalar_data.block_allowed = 1; 1635247738Sbapt 1636247738Sbapt if (leading_space || leading_break || trailing_space || trailing_break) { 1637247738Sbapt emitter->scalar_data.flow_plain_allowed = 0; 1638247738Sbapt emitter->scalar_data.block_plain_allowed = 0; 1639247738Sbapt } 1640247738Sbapt 1641247738Sbapt if (trailing_space) { 1642247738Sbapt emitter->scalar_data.block_allowed = 0; 1643247738Sbapt } 1644247738Sbapt 1645247738Sbapt if (break_space) { 1646247738Sbapt emitter->scalar_data.flow_plain_allowed = 0; 1647247738Sbapt emitter->scalar_data.block_plain_allowed = 0; 1648247738Sbapt emitter->scalar_data.single_quoted_allowed = 0; 1649247738Sbapt } 1650247738Sbapt 1651247738Sbapt if (space_break || special_characters) { 1652247738Sbapt emitter->scalar_data.flow_plain_allowed = 0; 1653247738Sbapt emitter->scalar_data.block_plain_allowed = 0; 1654247738Sbapt emitter->scalar_data.single_quoted_allowed = 0; 1655247738Sbapt emitter->scalar_data.block_allowed = 0; 1656247738Sbapt } 1657247738Sbapt 1658247738Sbapt if (line_breaks) { 1659247738Sbapt emitter->scalar_data.flow_plain_allowed = 0; 1660247738Sbapt emitter->scalar_data.block_plain_allowed = 0; 1661247738Sbapt } 1662247738Sbapt 1663247738Sbapt if (flow_indicators) { 1664247738Sbapt emitter->scalar_data.flow_plain_allowed = 0; 1665247738Sbapt } 1666247738Sbapt 1667247738Sbapt if (block_indicators) { 1668247738Sbapt emitter->scalar_data.block_plain_allowed = 0; 1669247738Sbapt } 1670247738Sbapt 1671247738Sbapt return 1; 1672247738Sbapt} 1673247738Sbapt 1674247738Sbapt/* 1675247738Sbapt * Check if the event data is valid. 1676247738Sbapt */ 1677247738Sbapt 1678247738Sbaptstatic int 1679247738Sbaptyaml_emitter_analyze_event(yaml_emitter_t *emitter, 1680247738Sbapt yaml_event_t *event) 1681247738Sbapt{ 1682247738Sbapt emitter->anchor_data.anchor = NULL; 1683247738Sbapt emitter->anchor_data.anchor_length = 0; 1684247738Sbapt emitter->tag_data.handle = NULL; 1685247738Sbapt emitter->tag_data.handle_length = 0; 1686247738Sbapt emitter->tag_data.suffix = NULL; 1687247738Sbapt emitter->tag_data.suffix_length = 0; 1688247738Sbapt emitter->scalar_data.value = NULL; 1689247738Sbapt emitter->scalar_data.length = 0; 1690247738Sbapt 1691247738Sbapt switch (event->type) 1692247738Sbapt { 1693247738Sbapt case YAML_ALIAS_EVENT: 1694247738Sbapt if (!yaml_emitter_analyze_anchor(emitter, 1695247738Sbapt event->data.alias.anchor, 1)) 1696247738Sbapt return 0; 1697247738Sbapt return 1; 1698247738Sbapt 1699247738Sbapt case YAML_SCALAR_EVENT: 1700247738Sbapt if (event->data.scalar.anchor) { 1701247738Sbapt if (!yaml_emitter_analyze_anchor(emitter, 1702247738Sbapt event->data.scalar.anchor, 0)) 1703247738Sbapt return 0; 1704247738Sbapt } 1705247738Sbapt if (event->data.scalar.tag && (emitter->canonical || 1706247738Sbapt (!event->data.scalar.plain_implicit 1707247738Sbapt && !event->data.scalar.quoted_implicit))) { 1708247738Sbapt if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag)) 1709247738Sbapt return 0; 1710247738Sbapt } 1711247738Sbapt if (!yaml_emitter_analyze_scalar(emitter, 1712247738Sbapt event->data.scalar.value, event->data.scalar.length)) 1713247738Sbapt return 0; 1714247738Sbapt return 1; 1715247738Sbapt 1716247738Sbapt case YAML_SEQUENCE_START_EVENT: 1717247738Sbapt if (event->data.sequence_start.anchor) { 1718247738Sbapt if (!yaml_emitter_analyze_anchor(emitter, 1719247738Sbapt event->data.sequence_start.anchor, 0)) 1720247738Sbapt return 0; 1721247738Sbapt } 1722247738Sbapt if (event->data.sequence_start.tag && (emitter->canonical || 1723247738Sbapt !event->data.sequence_start.implicit)) { 1724247738Sbapt if (!yaml_emitter_analyze_tag(emitter, 1725247738Sbapt event->data.sequence_start.tag)) 1726247738Sbapt return 0; 1727247738Sbapt } 1728247738Sbapt return 1; 1729247738Sbapt 1730247738Sbapt case YAML_MAPPING_START_EVENT: 1731247738Sbapt if (event->data.mapping_start.anchor) { 1732247738Sbapt if (!yaml_emitter_analyze_anchor(emitter, 1733247738Sbapt event->data.mapping_start.anchor, 0)) 1734247738Sbapt return 0; 1735247738Sbapt } 1736247738Sbapt if (event->data.mapping_start.tag && (emitter->canonical || 1737247738Sbapt !event->data.mapping_start.implicit)) { 1738247738Sbapt if (!yaml_emitter_analyze_tag(emitter, 1739247738Sbapt event->data.mapping_start.tag)) 1740247738Sbapt return 0; 1741247738Sbapt } 1742247738Sbapt return 1; 1743247738Sbapt 1744247738Sbapt default: 1745247738Sbapt return 1; 1746247738Sbapt } 1747247738Sbapt} 1748247738Sbapt 1749247738Sbapt/* 1750247738Sbapt * Write the BOM character. 1751247738Sbapt */ 1752247738Sbapt 1753247738Sbaptstatic int 1754247738Sbaptyaml_emitter_write_bom(yaml_emitter_t *emitter) 1755247738Sbapt{ 1756247738Sbapt if (!FLUSH(emitter)) return 0; 1757247738Sbapt 1758247738Sbapt *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF'; 1759247738Sbapt *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB'; 1760247738Sbapt *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF'; 1761247738Sbapt 1762247738Sbapt return 1; 1763247738Sbapt} 1764247738Sbapt 1765247738Sbaptstatic int 1766247738Sbaptyaml_emitter_write_indent(yaml_emitter_t *emitter) 1767247738Sbapt{ 1768247738Sbapt int indent = (emitter->indent >= 0) ? emitter->indent : 0; 1769247738Sbapt 1770247738Sbapt if (!emitter->indention || emitter->column > indent 1771247738Sbapt || (emitter->column == indent && !emitter->whitespace)) { 1772247738Sbapt if (!PUT_BREAK(emitter)) return 0; 1773247738Sbapt } 1774247738Sbapt 1775247738Sbapt while (emitter->column < indent) { 1776247738Sbapt if (!PUT(emitter, ' ')) return 0; 1777247738Sbapt } 1778247738Sbapt 1779247738Sbapt emitter->whitespace = 1; 1780247738Sbapt emitter->indention = 1; 1781247738Sbapt 1782247738Sbapt return 1; 1783247738Sbapt} 1784247738Sbapt 1785247738Sbaptstatic int 1786247738Sbaptyaml_emitter_write_indicator(yaml_emitter_t *emitter, 1787247738Sbapt char *indicator, int need_whitespace, 1788247738Sbapt int is_whitespace, int is_indention) 1789247738Sbapt{ 1790247738Sbapt size_t indicator_length; 1791247738Sbapt yaml_string_t string; 1792247738Sbapt 1793247738Sbapt indicator_length = strlen(indicator); 1794247738Sbapt STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length); 1795247738Sbapt 1796247738Sbapt if (need_whitespace && !emitter->whitespace) { 1797247738Sbapt if (!PUT(emitter, ' ')) return 0; 1798247738Sbapt } 1799247738Sbapt 1800247738Sbapt while (string.pointer != string.end) { 1801247738Sbapt if (!WRITE(emitter, string)) return 0; 1802247738Sbapt } 1803247738Sbapt 1804247738Sbapt emitter->whitespace = is_whitespace; 1805247738Sbapt emitter->indention = (emitter->indention && is_indention); 1806247738Sbapt emitter->open_ended = 0; 1807247738Sbapt 1808247738Sbapt return 1; 1809247738Sbapt} 1810247738Sbapt 1811247738Sbaptstatic int 1812247738Sbaptyaml_emitter_write_anchor(yaml_emitter_t *emitter, 1813247738Sbapt yaml_char_t *value, size_t length) 1814247738Sbapt{ 1815247738Sbapt yaml_string_t string; 1816247738Sbapt STRING_ASSIGN(string, value, length); 1817247738Sbapt 1818247738Sbapt while (string.pointer != string.end) { 1819247738Sbapt if (!WRITE(emitter, string)) return 0; 1820247738Sbapt } 1821247738Sbapt 1822247738Sbapt emitter->whitespace = 0; 1823247738Sbapt emitter->indention = 0; 1824247738Sbapt 1825247738Sbapt return 1; 1826247738Sbapt} 1827247738Sbapt 1828247738Sbaptstatic int 1829247738Sbaptyaml_emitter_write_tag_handle(yaml_emitter_t *emitter, 1830247738Sbapt yaml_char_t *value, size_t length) 1831247738Sbapt{ 1832247738Sbapt yaml_string_t string; 1833247738Sbapt STRING_ASSIGN(string, value, length); 1834247738Sbapt 1835247738Sbapt if (!emitter->whitespace) { 1836247738Sbapt if (!PUT(emitter, ' ')) return 0; 1837247738Sbapt } 1838247738Sbapt 1839247738Sbapt while (string.pointer != string.end) { 1840247738Sbapt if (!WRITE(emitter, string)) return 0; 1841247738Sbapt } 1842247738Sbapt 1843247738Sbapt emitter->whitespace = 0; 1844247738Sbapt emitter->indention = 0; 1845247738Sbapt 1846247738Sbapt return 1; 1847247738Sbapt} 1848247738Sbapt 1849247738Sbaptstatic int 1850247738Sbaptyaml_emitter_write_tag_content(yaml_emitter_t *emitter, 1851247738Sbapt yaml_char_t *value, size_t length, 1852247738Sbapt int need_whitespace) 1853247738Sbapt{ 1854247738Sbapt yaml_string_t string; 1855247738Sbapt STRING_ASSIGN(string, value, length); 1856247738Sbapt 1857247738Sbapt if (need_whitespace && !emitter->whitespace) { 1858247738Sbapt if (!PUT(emitter, ' ')) return 0; 1859247738Sbapt } 1860247738Sbapt 1861247738Sbapt while (string.pointer != string.end) { 1862247738Sbapt if (IS_ALPHA(string) 1863247738Sbapt || CHECK(string, ';') || CHECK(string, '/') 1864247738Sbapt || CHECK(string, '?') || CHECK(string, ':') 1865247738Sbapt || CHECK(string, '@') || CHECK(string, '&') 1866247738Sbapt || CHECK(string, '=') || CHECK(string, '+') 1867247738Sbapt || CHECK(string, '$') || CHECK(string, ',') 1868247738Sbapt || CHECK(string, '_') || CHECK(string, '.') 1869247738Sbapt || CHECK(string, '~') || CHECK(string, '*') 1870247738Sbapt || CHECK(string, '\'') || CHECK(string, '(') 1871247738Sbapt || CHECK(string, ')') || CHECK(string, '[') 1872247738Sbapt || CHECK(string, ']')) { 1873247738Sbapt if (!WRITE(emitter, string)) return 0; 1874247738Sbapt } 1875247738Sbapt else { 1876247738Sbapt int width = WIDTH(string); 1877247738Sbapt unsigned int value; 1878247738Sbapt while (width --) { 1879247738Sbapt value = *(string.pointer++); 1880247738Sbapt if (!PUT(emitter, '%')) return 0; 1881247738Sbapt if (!PUT(emitter, (value >> 4) 1882247738Sbapt + ((value >> 4) < 10 ? '0' : 'A' - 10))) 1883247738Sbapt return 0; 1884247738Sbapt if (!PUT(emitter, (value & 0x0F) 1885247738Sbapt + ((value & 0x0F) < 10 ? '0' : 'A' - 10))) 1886247738Sbapt return 0; 1887247738Sbapt } 1888247738Sbapt } 1889247738Sbapt } 1890247738Sbapt 1891247738Sbapt emitter->whitespace = 0; 1892247738Sbapt emitter->indention = 0; 1893247738Sbapt 1894247738Sbapt return 1; 1895247738Sbapt} 1896247738Sbapt 1897247738Sbaptstatic int 1898247738Sbaptyaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, 1899247738Sbapt yaml_char_t *value, size_t length, int allow_breaks) 1900247738Sbapt{ 1901247738Sbapt yaml_string_t string; 1902247738Sbapt int spaces = 0; 1903247738Sbapt int breaks = 0; 1904247738Sbapt 1905247738Sbapt STRING_ASSIGN(string, value, length); 1906247738Sbapt 1907247738Sbapt if (!emitter->whitespace) { 1908247738Sbapt if (!PUT(emitter, ' ')) return 0; 1909247738Sbapt } 1910247738Sbapt 1911247738Sbapt while (string.pointer != string.end) 1912247738Sbapt { 1913247738Sbapt if (IS_SPACE(string)) 1914247738Sbapt { 1915247738Sbapt if (allow_breaks && !spaces 1916247738Sbapt && emitter->column > emitter->best_width 1917247738Sbapt && !IS_SPACE_AT(string, 1)) { 1918247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 1919247738Sbapt MOVE(string); 1920247738Sbapt } 1921247738Sbapt else { 1922247738Sbapt if (!WRITE(emitter, string)) return 0; 1923247738Sbapt } 1924247738Sbapt spaces = 1; 1925247738Sbapt } 1926247738Sbapt else if (IS_BREAK(string)) 1927247738Sbapt { 1928247738Sbapt if (!breaks && CHECK(string, '\n')) { 1929247738Sbapt if (!PUT_BREAK(emitter)) return 0; 1930247738Sbapt } 1931247738Sbapt if (!WRITE_BREAK(emitter, string)) return 0; 1932247738Sbapt emitter->indention = 1; 1933247738Sbapt breaks = 1; 1934247738Sbapt } 1935247738Sbapt else 1936247738Sbapt { 1937247738Sbapt if (breaks) { 1938247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 1939247738Sbapt } 1940247738Sbapt if (!WRITE(emitter, string)) return 0; 1941247738Sbapt emitter->indention = 0; 1942247738Sbapt spaces = 0; 1943247738Sbapt breaks = 0; 1944247738Sbapt } 1945247738Sbapt } 1946247738Sbapt 1947247738Sbapt emitter->whitespace = 0; 1948247738Sbapt emitter->indention = 0; 1949247738Sbapt if (emitter->root_context) 1950247738Sbapt { 1951247738Sbapt emitter->open_ended = 1; 1952247738Sbapt } 1953247738Sbapt 1954247738Sbapt return 1; 1955247738Sbapt} 1956247738Sbapt 1957247738Sbaptstatic int 1958247738Sbaptyaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, 1959247738Sbapt yaml_char_t *value, size_t length, int allow_breaks) 1960247738Sbapt{ 1961247738Sbapt yaml_string_t string; 1962247738Sbapt int spaces = 0; 1963247738Sbapt int breaks = 0; 1964247738Sbapt 1965247738Sbapt STRING_ASSIGN(string, value, length); 1966247738Sbapt 1967247738Sbapt if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0)) 1968247738Sbapt return 0; 1969247738Sbapt 1970247738Sbapt while (string.pointer != string.end) 1971247738Sbapt { 1972247738Sbapt if (IS_SPACE(string)) 1973247738Sbapt { 1974247738Sbapt if (allow_breaks && !spaces 1975247738Sbapt && emitter->column > emitter->best_width 1976247738Sbapt && string.pointer != string.start 1977247738Sbapt && string.pointer != string.end - 1 1978247738Sbapt && !IS_SPACE_AT(string, 1)) { 1979247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 1980247738Sbapt MOVE(string); 1981247738Sbapt } 1982247738Sbapt else { 1983247738Sbapt if (!WRITE(emitter, string)) return 0; 1984247738Sbapt } 1985247738Sbapt spaces = 1; 1986247738Sbapt } 1987247738Sbapt else if (IS_BREAK(string)) 1988247738Sbapt { 1989247738Sbapt if (!breaks && CHECK(string, '\n')) { 1990247738Sbapt if (!PUT_BREAK(emitter)) return 0; 1991247738Sbapt } 1992247738Sbapt if (!WRITE_BREAK(emitter, string)) return 0; 1993247738Sbapt emitter->indention = 1; 1994247738Sbapt breaks = 1; 1995247738Sbapt } 1996247738Sbapt else 1997247738Sbapt { 1998247738Sbapt if (breaks) { 1999247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 2000247738Sbapt } 2001247738Sbapt if (CHECK(string, '\'')) { 2002247738Sbapt if (!PUT(emitter, '\'')) return 0; 2003247738Sbapt } 2004247738Sbapt if (!WRITE(emitter, string)) return 0; 2005247738Sbapt emitter->indention = 0; 2006247738Sbapt spaces = 0; 2007247738Sbapt breaks = 0; 2008247738Sbapt } 2009247738Sbapt } 2010247738Sbapt 2011247738Sbapt if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0)) 2012247738Sbapt return 0; 2013247738Sbapt 2014247738Sbapt emitter->whitespace = 0; 2015247738Sbapt emitter->indention = 0; 2016247738Sbapt 2017247738Sbapt return 1; 2018247738Sbapt} 2019247738Sbapt 2020247738Sbaptstatic int 2021247738Sbaptyaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, 2022247738Sbapt yaml_char_t *value, size_t length, int allow_breaks) 2023247738Sbapt{ 2024247738Sbapt yaml_string_t string; 2025247738Sbapt int spaces = 0; 2026247738Sbapt 2027247738Sbapt STRING_ASSIGN(string, value, length); 2028247738Sbapt 2029247738Sbapt if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0)) 2030247738Sbapt return 0; 2031247738Sbapt 2032247738Sbapt while (string.pointer != string.end) 2033247738Sbapt { 2034247738Sbapt if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string)) 2035247738Sbapt || IS_BOM(string) || IS_BREAK(string) 2036247738Sbapt || CHECK(string, '"') || CHECK(string, '\\')) 2037247738Sbapt { 2038247738Sbapt unsigned char octet; 2039247738Sbapt unsigned int width; 2040247738Sbapt unsigned int value; 2041247738Sbapt int k; 2042247738Sbapt 2043247738Sbapt octet = string.pointer[0]; 2044247738Sbapt width = (octet & 0x80) == 0x00 ? 1 : 2045247738Sbapt (octet & 0xE0) == 0xC0 ? 2 : 2046247738Sbapt (octet & 0xF0) == 0xE0 ? 3 : 2047247738Sbapt (octet & 0xF8) == 0xF0 ? 4 : 0; 2048247738Sbapt value = (octet & 0x80) == 0x00 ? octet & 0x7F : 2049247738Sbapt (octet & 0xE0) == 0xC0 ? octet & 0x1F : 2050247738Sbapt (octet & 0xF0) == 0xE0 ? octet & 0x0F : 2051247738Sbapt (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 2052247738Sbapt for (k = 1; k < (int)width; k ++) { 2053247738Sbapt octet = string.pointer[k]; 2054247738Sbapt value = (value << 6) + (octet & 0x3F); 2055247738Sbapt } 2056247738Sbapt string.pointer += width; 2057247738Sbapt 2058247738Sbapt if (!PUT(emitter, '\\')) return 0; 2059247738Sbapt 2060247738Sbapt switch (value) 2061247738Sbapt { 2062247738Sbapt case 0x00: 2063247738Sbapt if (!PUT(emitter, '0')) return 0; 2064247738Sbapt break; 2065247738Sbapt 2066247738Sbapt case 0x07: 2067247738Sbapt if (!PUT(emitter, 'a')) return 0; 2068247738Sbapt break; 2069247738Sbapt 2070247738Sbapt case 0x08: 2071247738Sbapt if (!PUT(emitter, 'b')) return 0; 2072247738Sbapt break; 2073247738Sbapt 2074247738Sbapt case 0x09: 2075247738Sbapt if (!PUT(emitter, 't')) return 0; 2076247738Sbapt break; 2077247738Sbapt 2078247738Sbapt case 0x0A: 2079247738Sbapt if (!PUT(emitter, 'n')) return 0; 2080247738Sbapt break; 2081247738Sbapt 2082247738Sbapt case 0x0B: 2083247738Sbapt if (!PUT(emitter, 'v')) return 0; 2084247738Sbapt break; 2085247738Sbapt 2086247738Sbapt case 0x0C: 2087247738Sbapt if (!PUT(emitter, 'f')) return 0; 2088247738Sbapt break; 2089247738Sbapt 2090247738Sbapt case 0x0D: 2091247738Sbapt if (!PUT(emitter, 'r')) return 0; 2092247738Sbapt break; 2093247738Sbapt 2094247738Sbapt case 0x1B: 2095247738Sbapt if (!PUT(emitter, 'e')) return 0; 2096247738Sbapt break; 2097247738Sbapt 2098247738Sbapt case 0x22: 2099247738Sbapt if (!PUT(emitter, '\"')) return 0; 2100247738Sbapt break; 2101247738Sbapt 2102247738Sbapt case 0x5C: 2103247738Sbapt if (!PUT(emitter, '\\')) return 0; 2104247738Sbapt break; 2105247738Sbapt 2106247738Sbapt case 0x85: 2107247738Sbapt if (!PUT(emitter, 'N')) return 0; 2108247738Sbapt break; 2109247738Sbapt 2110247738Sbapt case 0xA0: 2111247738Sbapt if (!PUT(emitter, '_')) return 0; 2112247738Sbapt break; 2113247738Sbapt 2114247738Sbapt case 0x2028: 2115247738Sbapt if (!PUT(emitter, 'L')) return 0; 2116247738Sbapt break; 2117247738Sbapt 2118247738Sbapt case 0x2029: 2119247738Sbapt if (!PUT(emitter, 'P')) return 0; 2120247738Sbapt break; 2121247738Sbapt 2122247738Sbapt default: 2123247738Sbapt if (value <= 0xFF) { 2124247738Sbapt if (!PUT(emitter, 'x')) return 0; 2125247738Sbapt width = 2; 2126247738Sbapt } 2127247738Sbapt else if (value <= 0xFFFF) { 2128247738Sbapt if (!PUT(emitter, 'u')) return 0; 2129247738Sbapt width = 4; 2130247738Sbapt } 2131247738Sbapt else { 2132247738Sbapt if (!PUT(emitter, 'U')) return 0; 2133247738Sbapt width = 8; 2134247738Sbapt } 2135247738Sbapt for (k = (width-1)*4; k >= 0; k -= 4) { 2136247738Sbapt int digit = (value >> k) & 0x0F; 2137247738Sbapt if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10))) 2138247738Sbapt return 0; 2139247738Sbapt } 2140247738Sbapt } 2141247738Sbapt spaces = 0; 2142247738Sbapt } 2143247738Sbapt else if (IS_SPACE(string)) 2144247738Sbapt { 2145247738Sbapt if (allow_breaks && !spaces 2146247738Sbapt && emitter->column > emitter->best_width 2147247738Sbapt && string.pointer != string.start 2148247738Sbapt && string.pointer != string.end - 1) { 2149247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 2150247738Sbapt if (IS_SPACE_AT(string, 1)) { 2151247738Sbapt if (!PUT(emitter, '\\')) return 0; 2152247738Sbapt } 2153247738Sbapt MOVE(string); 2154247738Sbapt } 2155247738Sbapt else { 2156247738Sbapt if (!WRITE(emitter, string)) return 0; 2157247738Sbapt } 2158247738Sbapt spaces = 1; 2159247738Sbapt } 2160247738Sbapt else 2161247738Sbapt { 2162247738Sbapt if (!WRITE(emitter, string)) return 0; 2163247738Sbapt spaces = 0; 2164247738Sbapt } 2165247738Sbapt } 2166247738Sbapt 2167247738Sbapt if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0)) 2168247738Sbapt return 0; 2169247738Sbapt 2170247738Sbapt emitter->whitespace = 0; 2171247738Sbapt emitter->indention = 0; 2172247738Sbapt 2173247738Sbapt return 1; 2174247738Sbapt} 2175247738Sbapt 2176247738Sbaptstatic int 2177247738Sbaptyaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, 2178247738Sbapt yaml_string_t string) 2179247738Sbapt{ 2180247738Sbapt char indent_hint[2]; 2181247738Sbapt char *chomp_hint = NULL; 2182247738Sbapt 2183247738Sbapt if (IS_SPACE(string) || IS_BREAK(string)) 2184247738Sbapt { 2185247738Sbapt indent_hint[0] = '0' + (char)emitter->best_indent; 2186247738Sbapt indent_hint[1] = '\0'; 2187247738Sbapt if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0)) 2188247738Sbapt return 0; 2189247738Sbapt } 2190247738Sbapt 2191247738Sbapt emitter->open_ended = 0; 2192247738Sbapt 2193247738Sbapt string.pointer = string.end; 2194247738Sbapt if (string.start == string.pointer) 2195247738Sbapt { 2196247738Sbapt chomp_hint = "-"; 2197247738Sbapt } 2198247738Sbapt else 2199247738Sbapt { 2200247738Sbapt do { 2201247738Sbapt string.pointer --; 2202247738Sbapt } while ((*string.pointer & 0xC0) == 0x80); 2203247738Sbapt if (!IS_BREAK(string)) 2204247738Sbapt { 2205247738Sbapt chomp_hint = "-"; 2206247738Sbapt } 2207247738Sbapt else if (string.start == string.pointer) 2208247738Sbapt { 2209247738Sbapt chomp_hint = "+"; 2210247738Sbapt emitter->open_ended = 1; 2211247738Sbapt } 2212247738Sbapt else 2213247738Sbapt { 2214247738Sbapt do { 2215247738Sbapt string.pointer --; 2216247738Sbapt } while ((*string.pointer & 0xC0) == 0x80); 2217247738Sbapt if (IS_BREAK(string)) 2218247738Sbapt { 2219247738Sbapt chomp_hint = "+"; 2220247738Sbapt emitter->open_ended = 1; 2221247738Sbapt } 2222247738Sbapt } 2223247738Sbapt } 2224247738Sbapt 2225247738Sbapt if (chomp_hint) 2226247738Sbapt { 2227247738Sbapt if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0)) 2228247738Sbapt return 0; 2229247738Sbapt } 2230247738Sbapt 2231247738Sbapt return 1; 2232247738Sbapt} 2233247738Sbapt 2234247738Sbaptstatic int 2235247738Sbaptyaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, 2236247738Sbapt yaml_char_t *value, size_t length) 2237247738Sbapt{ 2238247738Sbapt yaml_string_t string; 2239247738Sbapt int breaks = 1; 2240247738Sbapt 2241247738Sbapt STRING_ASSIGN(string, value, length); 2242247738Sbapt 2243247738Sbapt if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0)) 2244247738Sbapt return 0; 2245247738Sbapt if (!yaml_emitter_write_block_scalar_hints(emitter, string)) 2246247738Sbapt return 0; 2247247738Sbapt if (!PUT_BREAK(emitter)) return 0; 2248247738Sbapt emitter->indention = 1; 2249247738Sbapt emitter->whitespace = 1; 2250247738Sbapt 2251247738Sbapt while (string.pointer != string.end) 2252247738Sbapt { 2253247738Sbapt if (IS_BREAK(string)) 2254247738Sbapt { 2255247738Sbapt if (!WRITE_BREAK(emitter, string)) return 0; 2256247738Sbapt emitter->indention = 1; 2257247738Sbapt breaks = 1; 2258247738Sbapt } 2259247738Sbapt else 2260247738Sbapt { 2261247738Sbapt if (breaks) { 2262247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 2263247738Sbapt } 2264247738Sbapt if (!WRITE(emitter, string)) return 0; 2265247738Sbapt emitter->indention = 0; 2266247738Sbapt breaks = 0; 2267247738Sbapt } 2268247738Sbapt } 2269247738Sbapt 2270247738Sbapt return 1; 2271247738Sbapt} 2272247738Sbapt 2273247738Sbaptstatic int 2274247738Sbaptyaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, 2275247738Sbapt yaml_char_t *value, size_t length) 2276247738Sbapt{ 2277247738Sbapt yaml_string_t string; 2278247738Sbapt int breaks = 1; 2279247738Sbapt int leading_spaces = 1; 2280247738Sbapt 2281247738Sbapt STRING_ASSIGN(string, value, length); 2282247738Sbapt 2283247738Sbapt if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0)) 2284247738Sbapt return 0; 2285247738Sbapt if (!yaml_emitter_write_block_scalar_hints(emitter, string)) 2286247738Sbapt return 0; 2287247738Sbapt if (!PUT_BREAK(emitter)) return 0; 2288247738Sbapt emitter->indention = 1; 2289247738Sbapt emitter->whitespace = 1; 2290247738Sbapt 2291247738Sbapt while (string.pointer != string.end) 2292247738Sbapt { 2293247738Sbapt if (IS_BREAK(string)) 2294247738Sbapt { 2295247738Sbapt if (!breaks && !leading_spaces && CHECK(string, '\n')) { 2296247738Sbapt int k = 0; 2297247738Sbapt while (IS_BREAK_AT(string, k)) { 2298247738Sbapt k += WIDTH_AT(string, k); 2299247738Sbapt } 2300247738Sbapt if (!IS_BLANKZ_AT(string, k)) { 2301247738Sbapt if (!PUT_BREAK(emitter)) return 0; 2302247738Sbapt } 2303247738Sbapt } 2304247738Sbapt if (!WRITE_BREAK(emitter, string)) return 0; 2305247738Sbapt emitter->indention = 1; 2306247738Sbapt breaks = 1; 2307247738Sbapt } 2308247738Sbapt else 2309247738Sbapt { 2310247738Sbapt if (breaks) { 2311247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 2312247738Sbapt leading_spaces = IS_BLANK(string); 2313247738Sbapt } 2314247738Sbapt if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1) 2315247738Sbapt && emitter->column > emitter->best_width) { 2316247738Sbapt if (!yaml_emitter_write_indent(emitter)) return 0; 2317247738Sbapt MOVE(string); 2318247738Sbapt } 2319247738Sbapt else { 2320247738Sbapt if (!WRITE(emitter, string)) return 0; 2321247738Sbapt } 2322247738Sbapt emitter->indention = 0; 2323247738Sbapt breaks = 0; 2324247738Sbapt } 2325247738Sbapt } 2326247738Sbapt 2327247738Sbapt return 1; 2328247738Sbapt} 2329247738Sbapt 2330