1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package yaml
24
25 import (
26 "bytes"
27 "fmt"
28 )
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507 func cache(parser *yaml_parser_t, length int) bool {
508
509 return parser.unread >= length || yaml_parser_update_buffer(parser, length)
510 }
511
512
513 func skip(parser *yaml_parser_t) {
514 if !is_blank(parser.buffer, parser.buffer_pos) {
515 parser.newlines = 0
516 }
517 parser.mark.index++
518 parser.mark.column++
519 parser.unread--
520 parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
521 }
522
523 func skip_line(parser *yaml_parser_t) {
524 if is_crlf(parser.buffer, parser.buffer_pos) {
525 parser.mark.index += 2
526 parser.mark.column = 0
527 parser.mark.line++
528 parser.unread -= 2
529 parser.buffer_pos += 2
530 parser.newlines++
531 } else if is_break(parser.buffer, parser.buffer_pos) {
532 parser.mark.index++
533 parser.mark.column = 0
534 parser.mark.line++
535 parser.unread--
536 parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
537 parser.newlines++
538 }
539 }
540
541
542 func read(parser *yaml_parser_t, s []byte) []byte {
543 if !is_blank(parser.buffer, parser.buffer_pos) {
544 parser.newlines = 0
545 }
546 w := width(parser.buffer[parser.buffer_pos])
547 if w == 0 {
548 panic("invalid character sequence")
549 }
550 if len(s) == 0 {
551 s = make([]byte, 0, 32)
552 }
553 if w == 1 && len(s)+w <= cap(s) {
554 s = s[:len(s)+1]
555 s[len(s)-1] = parser.buffer[parser.buffer_pos]
556 parser.buffer_pos++
557 } else {
558 s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
559 parser.buffer_pos += w
560 }
561 parser.mark.index++
562 parser.mark.column++
563 parser.unread--
564 return s
565 }
566
567
568 func read_line(parser *yaml_parser_t, s []byte) []byte {
569 buf := parser.buffer
570 pos := parser.buffer_pos
571 switch {
572 case buf[pos] == '\r' && buf[pos+1] == '\n':
573
574 s = append(s, '\n')
575 parser.buffer_pos += 2
576 parser.mark.index++
577 parser.unread--
578 case buf[pos] == '\r' || buf[pos] == '\n':
579
580 s = append(s, '\n')
581 parser.buffer_pos += 1
582 case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
583
584 s = append(s, '\n')
585 parser.buffer_pos += 2
586 case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
587
588 s = append(s, buf[parser.buffer_pos:pos+3]...)
589 parser.buffer_pos += 3
590 default:
591 return s
592 }
593 parser.mark.index++
594 parser.mark.column = 0
595 parser.mark.line++
596 parser.unread--
597 parser.newlines++
598 return s
599 }
600
601
602 func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
603
604 *token = yaml_token_t{}
605
606
607 if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
608 return true
609 }
610
611
612 if !parser.token_available {
613 if !yaml_parser_fetch_more_tokens(parser) {
614 return false
615 }
616 }
617
618
619 *token = parser.tokens[parser.tokens_head]
620 parser.tokens_head++
621 parser.tokens_parsed++
622 parser.token_available = false
623
624 if token.typ == yaml_STREAM_END_TOKEN {
625 parser.stream_end_produced = true
626 }
627 return true
628 }
629
630
631 func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
632 parser.error = yaml_SCANNER_ERROR
633 parser.context = context
634 parser.context_mark = context_mark
635 parser.problem = problem
636 parser.problem_mark = parser.mark
637 return false
638 }
639
640 func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
641 context := "while parsing a tag"
642 if directive {
643 context = "while parsing a %TAG directive"
644 }
645 return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
646 }
647
648 func trace(args ...interface{}) func() {
649 pargs := append([]interface{}{"+++"}, args...)
650 fmt.Println(pargs...)
651 pargs = append([]interface{}{"---"}, args...)
652 return func() { fmt.Println(pargs...) }
653 }
654
655
656
657 func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
658
659 for {
660
661
662
663
664 if parser.tokens_head < len(parser.tokens)-2 {
665
666
667 head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed]
668 if !ok {
669 break
670 } else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok {
671 return false
672 } else if !valid {
673 break
674 }
675 }
676
677 if !yaml_parser_fetch_next_token(parser) {
678 return false
679 }
680 }
681
682 parser.token_available = true
683 return true
684 }
685
686
687 func yaml_parser_fetch_next_token(parser *yaml_parser_t) (ok bool) {
688
689 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
690 return false
691 }
692
693
694 if !parser.stream_start_produced {
695 return yaml_parser_fetch_stream_start(parser)
696 }
697
698 scan_mark := parser.mark
699
700
701 if !yaml_parser_scan_to_next_token(parser) {
702 return false
703 }
704
705
706
707
708
709
710 if !yaml_parser_unroll_indent(parser, parser.mark.column, scan_mark) {
711 return false
712 }
713
714
715
716 if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
717 return false
718 }
719
720
721 if is_z(parser.buffer, parser.buffer_pos) {
722 return yaml_parser_fetch_stream_end(parser)
723 }
724
725
726 if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
727 return yaml_parser_fetch_directive(parser)
728 }
729
730 buf := parser.buffer
731 pos := parser.buffer_pos
732
733
734 if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
735 return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
736 }
737
738
739 if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
740 return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
741 }
742
743 comment_mark := parser.mark
744 if len(parser.tokens) > 0 && (parser.flow_level == 0 && buf[pos] == ':' || parser.flow_level > 0 && buf[pos] == ',') {
745
746 comment_mark = parser.tokens[len(parser.tokens)-1].start_mark
747 }
748 defer func() {
749 if !ok {
750 return
751 }
752 if len(parser.tokens) > 0 && parser.tokens[len(parser.tokens)-1].typ == yaml_BLOCK_ENTRY_TOKEN {
753
754
755 return
756 }
757 if !yaml_parser_scan_line_comment(parser, comment_mark) {
758 ok = false
759 return
760 }
761 }()
762
763
764 if buf[pos] == '[' {
765 return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
766 }
767
768
769 if parser.buffer[parser.buffer_pos] == '{' {
770 return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
771 }
772
773
774 if parser.buffer[parser.buffer_pos] == ']' {
775 return yaml_parser_fetch_flow_collection_end(parser,
776 yaml_FLOW_SEQUENCE_END_TOKEN)
777 }
778
779
780 if parser.buffer[parser.buffer_pos] == '}' {
781 return yaml_parser_fetch_flow_collection_end(parser,
782 yaml_FLOW_MAPPING_END_TOKEN)
783 }
784
785
786 if parser.buffer[parser.buffer_pos] == ',' {
787 return yaml_parser_fetch_flow_entry(parser)
788 }
789
790
791 if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
792 return yaml_parser_fetch_block_entry(parser)
793 }
794
795
796 if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
797 return yaml_parser_fetch_key(parser)
798 }
799
800
801 if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
802 return yaml_parser_fetch_value(parser)
803 }
804
805
806 if parser.buffer[parser.buffer_pos] == '*' {
807 return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
808 }
809
810
811 if parser.buffer[parser.buffer_pos] == '&' {
812 return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
813 }
814
815
816 if parser.buffer[parser.buffer_pos] == '!' {
817 return yaml_parser_fetch_tag(parser)
818 }
819
820
821 if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
822 return yaml_parser_fetch_block_scalar(parser, true)
823 }
824
825
826 if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
827 return yaml_parser_fetch_block_scalar(parser, false)
828 }
829
830
831 if parser.buffer[parser.buffer_pos] == '\'' {
832 return yaml_parser_fetch_flow_scalar(parser, true)
833 }
834
835
836 if parser.buffer[parser.buffer_pos] == '"' {
837 return yaml_parser_fetch_flow_scalar(parser, false)
838 }
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860 if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
861 parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
862 parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
863 parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
864 parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
865 parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
866 parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
867 parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
868 parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
869 parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
870 (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
871 (parser.flow_level == 0 &&
872 (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
873 !is_blankz(parser.buffer, parser.buffer_pos+1)) {
874 return yaml_parser_fetch_plain_scalar(parser)
875 }
876
877
878 return yaml_parser_set_scanner_error(parser,
879 "while scanning for the next token", parser.mark,
880 "found character that cannot start any token")
881 }
882
883 func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) {
884 if !simple_key.possible {
885 return false, true
886 }
887
888
889
890
891
892
893
894
895
896 if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index {
897
898 if simple_key.required {
899 return false, yaml_parser_set_scanner_error(parser,
900 "while scanning a simple key", simple_key.mark,
901 "could not find expected ':'")
902 }
903 simple_key.possible = false
904 return false, true
905 }
906 return true, true
907 }
908
909
910
911 func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
912
913
914
915
916 required := parser.flow_level == 0 && parser.indent == parser.mark.column
917
918
919
920
921 if parser.simple_key_allowed {
922 simple_key := yaml_simple_key_t{
923 possible: true,
924 required: required,
925 token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
926 mark: parser.mark,
927 }
928
929 if !yaml_parser_remove_simple_key(parser) {
930 return false
931 }
932 parser.simple_keys[len(parser.simple_keys)-1] = simple_key
933 parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1
934 }
935 return true
936 }
937
938
939 func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
940 i := len(parser.simple_keys) - 1
941 if parser.simple_keys[i].possible {
942
943 if parser.simple_keys[i].required {
944 return yaml_parser_set_scanner_error(parser,
945 "while scanning a simple key", parser.simple_keys[i].mark,
946 "could not find expected ':'")
947 }
948
949 parser.simple_keys[i].possible = false
950 delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number)
951 }
952 return true
953 }
954
955
956 const max_flow_level = 10000
957
958
959 func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
960
961 parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{
962 possible: false,
963 required: false,
964 token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
965 mark: parser.mark,
966 })
967
968
969 parser.flow_level++
970 if parser.flow_level > max_flow_level {
971 return yaml_parser_set_scanner_error(parser,
972 "while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark,
973 fmt.Sprintf("exceeded max depth of %d", max_flow_level))
974 }
975 return true
976 }
977
978
979 func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
980 if parser.flow_level > 0 {
981 parser.flow_level--
982 last := len(parser.simple_keys) - 1
983 delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number)
984 parser.simple_keys = parser.simple_keys[:last]
985 }
986 return true
987 }
988
989
990 const max_indents = 10000
991
992
993
994
995 func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
996
997 if parser.flow_level > 0 {
998 return true
999 }
1000
1001 if parser.indent < column {
1002
1003
1004 parser.indents = append(parser.indents, parser.indent)
1005 parser.indent = column
1006 if len(parser.indents) > max_indents {
1007 return yaml_parser_set_scanner_error(parser,
1008 "while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark,
1009 fmt.Sprintf("exceeded max depth of %d", max_indents))
1010 }
1011
1012
1013 token := yaml_token_t{
1014 typ: typ,
1015 start_mark: mark,
1016 end_mark: mark,
1017 }
1018 if number > -1 {
1019 number -= parser.tokens_parsed
1020 }
1021 yaml_insert_token(parser, number, &token)
1022 }
1023 return true
1024 }
1025
1026
1027
1028
1029 func yaml_parser_unroll_indent(parser *yaml_parser_t, column int, scan_mark yaml_mark_t) bool {
1030
1031 if parser.flow_level > 0 {
1032 return true
1033 }
1034
1035 block_mark := scan_mark
1036 block_mark.index--
1037
1038
1039 for parser.indent > column {
1040
1041
1042
1043
1044
1045 stop_index := block_mark.index
1046 for i := len(parser.comments) - 1; i >= 0; i-- {
1047 comment := &parser.comments[i]
1048
1049 if comment.end_mark.index < stop_index {
1050
1051
1052
1053 break
1054 }
1055 if comment.start_mark.column == parser.indent+1 {
1056
1057
1058 block_mark = comment.start_mark
1059 }
1060
1061
1062
1063
1064 stop_index = comment.scan_mark.index
1065 }
1066
1067
1068 token := yaml_token_t{
1069 typ: yaml_BLOCK_END_TOKEN,
1070 start_mark: block_mark,
1071 end_mark: block_mark,
1072 }
1073 yaml_insert_token(parser, -1, &token)
1074
1075
1076 parser.indent = parser.indents[len(parser.indents)-1]
1077 parser.indents = parser.indents[:len(parser.indents)-1]
1078 }
1079 return true
1080 }
1081
1082
1083 func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
1084
1085
1086 parser.indent = -1
1087
1088
1089 parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
1090
1091 parser.simple_keys_by_tok = make(map[int]int)
1092
1093
1094 parser.simple_key_allowed = true
1095
1096
1097 parser.stream_start_produced = true
1098
1099
1100 token := yaml_token_t{
1101 typ: yaml_STREAM_START_TOKEN,
1102 start_mark: parser.mark,
1103 end_mark: parser.mark,
1104 encoding: parser.encoding,
1105 }
1106 yaml_insert_token(parser, -1, &token)
1107 return true
1108 }
1109
1110
1111 func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
1112
1113
1114 if parser.mark.column != 0 {
1115 parser.mark.column = 0
1116 parser.mark.line++
1117 }
1118
1119
1120 if !yaml_parser_unroll_indent(parser, -1, parser.mark) {
1121 return false
1122 }
1123
1124
1125 if !yaml_parser_remove_simple_key(parser) {
1126 return false
1127 }
1128
1129 parser.simple_key_allowed = false
1130
1131
1132 token := yaml_token_t{
1133 typ: yaml_STREAM_END_TOKEN,
1134 start_mark: parser.mark,
1135 end_mark: parser.mark,
1136 }
1137 yaml_insert_token(parser, -1, &token)
1138 return true
1139 }
1140
1141
1142 func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
1143
1144 if !yaml_parser_unroll_indent(parser, -1, parser.mark) {
1145 return false
1146 }
1147
1148
1149 if !yaml_parser_remove_simple_key(parser) {
1150 return false
1151 }
1152
1153 parser.simple_key_allowed = false
1154
1155
1156 token := yaml_token_t{}
1157 if !yaml_parser_scan_directive(parser, &token) {
1158 return false
1159 }
1160
1161 yaml_insert_token(parser, -1, &token)
1162 return true
1163 }
1164
1165
1166 func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1167
1168 if !yaml_parser_unroll_indent(parser, -1, parser.mark) {
1169 return false
1170 }
1171
1172
1173 if !yaml_parser_remove_simple_key(parser) {
1174 return false
1175 }
1176
1177 parser.simple_key_allowed = false
1178
1179
1180 start_mark := parser.mark
1181
1182 skip(parser)
1183 skip(parser)
1184 skip(parser)
1185
1186 end_mark := parser.mark
1187
1188
1189 token := yaml_token_t{
1190 typ: typ,
1191 start_mark: start_mark,
1192 end_mark: end_mark,
1193 }
1194
1195 yaml_insert_token(parser, -1, &token)
1196 return true
1197 }
1198
1199
1200 func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1201
1202
1203 if !yaml_parser_save_simple_key(parser) {
1204 return false
1205 }
1206
1207
1208 if !yaml_parser_increase_flow_level(parser) {
1209 return false
1210 }
1211
1212
1213 parser.simple_key_allowed = true
1214
1215
1216 start_mark := parser.mark
1217 skip(parser)
1218 end_mark := parser.mark
1219
1220
1221 token := yaml_token_t{
1222 typ: typ,
1223 start_mark: start_mark,
1224 end_mark: end_mark,
1225 }
1226
1227 yaml_insert_token(parser, -1, &token)
1228 return true
1229 }
1230
1231
1232 func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1233
1234 if !yaml_parser_remove_simple_key(parser) {
1235 return false
1236 }
1237
1238
1239 if !yaml_parser_decrease_flow_level(parser) {
1240 return false
1241 }
1242
1243
1244 parser.simple_key_allowed = false
1245
1246
1247
1248 start_mark := parser.mark
1249 skip(parser)
1250 end_mark := parser.mark
1251
1252
1253 token := yaml_token_t{
1254 typ: typ,
1255 start_mark: start_mark,
1256 end_mark: end_mark,
1257 }
1258
1259 yaml_insert_token(parser, -1, &token)
1260 return true
1261 }
1262
1263
1264 func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
1265
1266 if !yaml_parser_remove_simple_key(parser) {
1267 return false
1268 }
1269
1270
1271 parser.simple_key_allowed = true
1272
1273
1274 start_mark := parser.mark
1275 skip(parser)
1276 end_mark := parser.mark
1277
1278
1279 token := yaml_token_t{
1280 typ: yaml_FLOW_ENTRY_TOKEN,
1281 start_mark: start_mark,
1282 end_mark: end_mark,
1283 }
1284 yaml_insert_token(parser, -1, &token)
1285 return true
1286 }
1287
1288
1289 func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
1290
1291 if parser.flow_level == 0 {
1292
1293 if !parser.simple_key_allowed {
1294 return yaml_parser_set_scanner_error(parser, "", parser.mark,
1295 "block sequence entries are not allowed in this context")
1296 }
1297
1298 if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
1299 return false
1300 }
1301 } else {
1302
1303
1304
1305 }
1306
1307
1308 if !yaml_parser_remove_simple_key(parser) {
1309 return false
1310 }
1311
1312
1313 parser.simple_key_allowed = true
1314
1315
1316 start_mark := parser.mark
1317 skip(parser)
1318 end_mark := parser.mark
1319
1320
1321 token := yaml_token_t{
1322 typ: yaml_BLOCK_ENTRY_TOKEN,
1323 start_mark: start_mark,
1324 end_mark: end_mark,
1325 }
1326 yaml_insert_token(parser, -1, &token)
1327 return true
1328 }
1329
1330
1331 func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
1332
1333
1334 if parser.flow_level == 0 {
1335
1336 if !parser.simple_key_allowed {
1337 return yaml_parser_set_scanner_error(parser, "", parser.mark,
1338 "mapping keys are not allowed in this context")
1339 }
1340
1341 if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
1342 return false
1343 }
1344 }
1345
1346
1347 if !yaml_parser_remove_simple_key(parser) {
1348 return false
1349 }
1350
1351
1352 parser.simple_key_allowed = parser.flow_level == 0
1353
1354
1355 start_mark := parser.mark
1356 skip(parser)
1357 end_mark := parser.mark
1358
1359
1360 token := yaml_token_t{
1361 typ: yaml_KEY_TOKEN,
1362 start_mark: start_mark,
1363 end_mark: end_mark,
1364 }
1365 yaml_insert_token(parser, -1, &token)
1366 return true
1367 }
1368
1369
1370 func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
1371
1372 simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
1373
1374
1375 if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok {
1376 return false
1377
1378 } else if valid {
1379
1380
1381 token := yaml_token_t{
1382 typ: yaml_KEY_TOKEN,
1383 start_mark: simple_key.mark,
1384 end_mark: simple_key.mark,
1385 }
1386 yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
1387
1388
1389 if !yaml_parser_roll_indent(parser, simple_key.mark.column,
1390 simple_key.token_number,
1391 yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
1392 return false
1393 }
1394
1395
1396 simple_key.possible = false
1397 delete(parser.simple_keys_by_tok, simple_key.token_number)
1398
1399
1400 parser.simple_key_allowed = false
1401
1402 } else {
1403
1404
1405
1406 if parser.flow_level == 0 {
1407
1408
1409 if !parser.simple_key_allowed {
1410 return yaml_parser_set_scanner_error(parser, "", parser.mark,
1411 "mapping values are not allowed in this context")
1412 }
1413
1414
1415 if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
1416 return false
1417 }
1418 }
1419
1420
1421 parser.simple_key_allowed = parser.flow_level == 0
1422 }
1423
1424
1425 start_mark := parser.mark
1426 skip(parser)
1427 end_mark := parser.mark
1428
1429
1430 token := yaml_token_t{
1431 typ: yaml_VALUE_TOKEN,
1432 start_mark: start_mark,
1433 end_mark: end_mark,
1434 }
1435 yaml_insert_token(parser, -1, &token)
1436 return true
1437 }
1438
1439
1440 func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1441
1442 if !yaml_parser_save_simple_key(parser) {
1443 return false
1444 }
1445
1446
1447 parser.simple_key_allowed = false
1448
1449
1450 var token yaml_token_t
1451 if !yaml_parser_scan_anchor(parser, &token, typ) {
1452 return false
1453 }
1454 yaml_insert_token(parser, -1, &token)
1455 return true
1456 }
1457
1458
1459 func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
1460
1461 if !yaml_parser_save_simple_key(parser) {
1462 return false
1463 }
1464
1465
1466 parser.simple_key_allowed = false
1467
1468
1469 var token yaml_token_t
1470 if !yaml_parser_scan_tag(parser, &token) {
1471 return false
1472 }
1473 yaml_insert_token(parser, -1, &token)
1474 return true
1475 }
1476
1477
1478 func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
1479
1480 if !yaml_parser_remove_simple_key(parser) {
1481 return false
1482 }
1483
1484
1485 parser.simple_key_allowed = true
1486
1487
1488 var token yaml_token_t
1489 if !yaml_parser_scan_block_scalar(parser, &token, literal) {
1490 return false
1491 }
1492 yaml_insert_token(parser, -1, &token)
1493 return true
1494 }
1495
1496
1497 func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
1498
1499 if !yaml_parser_save_simple_key(parser) {
1500 return false
1501 }
1502
1503
1504 parser.simple_key_allowed = false
1505
1506
1507 var token yaml_token_t
1508 if !yaml_parser_scan_flow_scalar(parser, &token, single) {
1509 return false
1510 }
1511 yaml_insert_token(parser, -1, &token)
1512 return true
1513 }
1514
1515
1516 func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
1517
1518 if !yaml_parser_save_simple_key(parser) {
1519 return false
1520 }
1521
1522
1523 parser.simple_key_allowed = false
1524
1525
1526 var token yaml_token_t
1527 if !yaml_parser_scan_plain_scalar(parser, &token) {
1528 return false
1529 }
1530 yaml_insert_token(parser, -1, &token)
1531 return true
1532 }
1533
1534
1535 func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
1536
1537 scan_mark := parser.mark
1538
1539
1540 for {
1541
1542 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1543 return false
1544 }
1545 if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
1546 skip(parser)
1547 }
1548
1549
1550
1551
1552
1553
1554 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1555 return false
1556 }
1557
1558 for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
1559 skip(parser)
1560 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1561 return false
1562 }
1563 }
1564
1565
1566
1567
1568
1569
1570
1571
1572 if len(parser.comments) > 0 && len(parser.tokens) > 1 {
1573 tokenA := parser.tokens[len(parser.tokens)-2]
1574 tokenB := parser.tokens[len(parser.tokens)-1]
1575 comment := &parser.comments[len(parser.comments)-1]
1576 if tokenA.typ == yaml_BLOCK_SEQUENCE_START_TOKEN && tokenB.typ == yaml_BLOCK_ENTRY_TOKEN && len(comment.line) > 0 && !is_break(parser.buffer, parser.buffer_pos) {
1577
1578
1579
1580 comment.head = comment.line
1581 comment.line = nil
1582 if comment.start_mark.line == parser.mark.line-1 {
1583 comment.token_mark = parser.mark
1584 }
1585 }
1586 }
1587
1588
1589 if parser.buffer[parser.buffer_pos] == '#' {
1590 if !yaml_parser_scan_comments(parser, scan_mark) {
1591 return false
1592 }
1593 }
1594
1595
1596 if is_break(parser.buffer, parser.buffer_pos) {
1597 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
1598 return false
1599 }
1600 skip_line(parser)
1601
1602
1603 if parser.flow_level == 0 {
1604 parser.simple_key_allowed = true
1605 }
1606 } else {
1607 break
1608 }
1609 }
1610
1611 return true
1612 }
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622 func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
1623
1624 start_mark := parser.mark
1625 skip(parser)
1626
1627
1628 var name []byte
1629 if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
1630 return false
1631 }
1632
1633
1634 if bytes.Equal(name, []byte("YAML")) {
1635
1636 var major, minor int8
1637 if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
1638 return false
1639 }
1640 end_mark := parser.mark
1641
1642
1643 *token = yaml_token_t{
1644 typ: yaml_VERSION_DIRECTIVE_TOKEN,
1645 start_mark: start_mark,
1646 end_mark: end_mark,
1647 major: major,
1648 minor: minor,
1649 }
1650
1651
1652 } else if bytes.Equal(name, []byte("TAG")) {
1653
1654 var handle, prefix []byte
1655 if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
1656 return false
1657 }
1658 end_mark := parser.mark
1659
1660
1661 *token = yaml_token_t{
1662 typ: yaml_TAG_DIRECTIVE_TOKEN,
1663 start_mark: start_mark,
1664 end_mark: end_mark,
1665 value: handle,
1666 prefix: prefix,
1667 }
1668
1669
1670 } else {
1671 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1672 start_mark, "found unknown directive name")
1673 return false
1674 }
1675
1676
1677 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1678 return false
1679 }
1680
1681 for is_blank(parser.buffer, parser.buffer_pos) {
1682 skip(parser)
1683 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1684 return false
1685 }
1686 }
1687
1688 if parser.buffer[parser.buffer_pos] == '#' {
1689
1690
1691
1692
1693 for !is_breakz(parser.buffer, parser.buffer_pos) {
1694 skip(parser)
1695 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1696 return false
1697 }
1698 }
1699 }
1700
1701
1702 if !is_breakz(parser.buffer, parser.buffer_pos) {
1703 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1704 start_mark, "did not find expected comment or line break")
1705 return false
1706 }
1707
1708
1709 if is_break(parser.buffer, parser.buffer_pos) {
1710 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
1711 return false
1712 }
1713 skip_line(parser)
1714 }
1715
1716 return true
1717 }
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727 func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
1728
1729 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1730 return false
1731 }
1732
1733 var s []byte
1734 for is_alpha(parser.buffer, parser.buffer_pos) {
1735 s = read(parser, s)
1736 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1737 return false
1738 }
1739 }
1740
1741
1742 if len(s) == 0 {
1743 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1744 start_mark, "could not find expected directive name")
1745 return false
1746 }
1747
1748
1749 if !is_blankz(parser.buffer, parser.buffer_pos) {
1750 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1751 start_mark, "found unexpected non-alphabetical character")
1752 return false
1753 }
1754 *name = s
1755 return true
1756 }
1757
1758
1759
1760
1761
1762
1763 func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
1764
1765 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1766 return false
1767 }
1768 for is_blank(parser.buffer, parser.buffer_pos) {
1769 skip(parser)
1770 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1771 return false
1772 }
1773 }
1774
1775
1776 if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
1777 return false
1778 }
1779
1780
1781 if parser.buffer[parser.buffer_pos] != '.' {
1782 return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
1783 start_mark, "did not find expected digit or '.' character")
1784 }
1785
1786 skip(parser)
1787
1788
1789 if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
1790 return false
1791 }
1792 return true
1793 }
1794
1795 const max_number_length = 2
1796
1797
1798
1799
1800
1801
1802
1803
1804 func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
1805
1806
1807 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1808 return false
1809 }
1810 var value, length int8
1811 for is_digit(parser.buffer, parser.buffer_pos) {
1812
1813 length++
1814 if length > max_number_length {
1815 return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
1816 start_mark, "found extremely long version number")
1817 }
1818 value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
1819 skip(parser)
1820 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1821 return false
1822 }
1823 }
1824
1825
1826 if length == 0 {
1827 return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
1828 start_mark, "did not find expected version number")
1829 }
1830 *number = value
1831 return true
1832 }
1833
1834
1835
1836
1837
1838
1839
1840 func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
1841 var handle_value, prefix_value []byte
1842
1843
1844 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1845 return false
1846 }
1847
1848 for is_blank(parser.buffer, parser.buffer_pos) {
1849 skip(parser)
1850 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1851 return false
1852 }
1853 }
1854
1855
1856 if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
1857 return false
1858 }
1859
1860
1861 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1862 return false
1863 }
1864 if !is_blank(parser.buffer, parser.buffer_pos) {
1865 yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
1866 start_mark, "did not find expected whitespace")
1867 return false
1868 }
1869
1870
1871 for is_blank(parser.buffer, parser.buffer_pos) {
1872 skip(parser)
1873 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1874 return false
1875 }
1876 }
1877
1878
1879 if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
1880 return false
1881 }
1882
1883
1884 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1885 return false
1886 }
1887 if !is_blankz(parser.buffer, parser.buffer_pos) {
1888 yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
1889 start_mark, "did not find expected whitespace or line break")
1890 return false
1891 }
1892
1893 *handle = handle_value
1894 *prefix = prefix_value
1895 return true
1896 }
1897
1898 func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
1899 var s []byte
1900
1901
1902 start_mark := parser.mark
1903 skip(parser)
1904
1905
1906 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1907 return false
1908 }
1909
1910 for is_alpha(parser.buffer, parser.buffer_pos) {
1911 s = read(parser, s)
1912 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1913 return false
1914 }
1915 }
1916
1917 end_mark := parser.mark
1918
1919
1925
1926 if len(s) == 0 ||
1927 !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
1928 parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
1929 parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
1930 parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
1931 parser.buffer[parser.buffer_pos] == '`') {
1932 context := "while scanning an alias"
1933 if typ == yaml_ANCHOR_TOKEN {
1934 context = "while scanning an anchor"
1935 }
1936 yaml_parser_set_scanner_error(parser, context, start_mark,
1937 "did not find expected alphabetic or numeric character")
1938 return false
1939 }
1940
1941
1942 *token = yaml_token_t{
1943 typ: typ,
1944 start_mark: start_mark,
1945 end_mark: end_mark,
1946 value: s,
1947 }
1948
1949 return true
1950 }
1951
1952
1955
1956 func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
1957 var handle, suffix []byte
1958
1959 start_mark := parser.mark
1960
1961
1962 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
1963 return false
1964 }
1965
1966 if parser.buffer[parser.buffer_pos+1] == '<' {
1967
1968
1969
1970 skip(parser)
1971 skip(parser)
1972
1973
1974 if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
1975 return false
1976 }
1977
1978
1979 if parser.buffer[parser.buffer_pos] != '>' {
1980 yaml_parser_set_scanner_error(parser, "while scanning a tag",
1981 start_mark, "did not find the expected '>'")
1982 return false
1983 }
1984
1985 skip(parser)
1986 } else {
1987
1988
1989
1990 if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
1991 return false
1992 }
1993
1994
1995 if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
1996
1997 if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
1998 return false
1999 }
2000 } else {
2001
2002 if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
2003 return false
2004 }
2005
2006
2007 handle = []byte{'!'}
2008
2009
2010
2011 if len(suffix) == 0 {
2012 handle, suffix = suffix, handle
2013 }
2014 }
2015 }
2016
2017
2018 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2019 return false
2020 }
2021 if !is_blankz(parser.buffer, parser.buffer_pos) {
2022 yaml_parser_set_scanner_error(parser, "while scanning a tag",
2023 start_mark, "did not find expected whitespace or line break")
2024 return false
2025 }
2026
2027 end_mark := parser.mark
2028
2029
2030 *token = yaml_token_t{
2031 typ: yaml_TAG_TOKEN,
2032 start_mark: start_mark,
2033 end_mark: end_mark,
2034 value: handle,
2035 suffix: suffix,
2036 }
2037 return true
2038 }
2039
2040
2041 func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
2042
2043 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2044 return false
2045 }
2046 if parser.buffer[parser.buffer_pos] != '!' {
2047 yaml_parser_set_scanner_tag_error(parser, directive,
2048 start_mark, "did not find expected '!'")
2049 return false
2050 }
2051
2052 var s []byte
2053
2054
2055 s = read(parser, s)
2056
2057
2058 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2059 return false
2060 }
2061 for is_alpha(parser.buffer, parser.buffer_pos) {
2062 s = read(parser, s)
2063 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2064 return false
2065 }
2066 }
2067
2068
2069 if parser.buffer[parser.buffer_pos] == '!' {
2070 s = read(parser, s)
2071 } else {
2072
2073
2074 if directive && string(s) != "!" {
2075 yaml_parser_set_scanner_tag_error(parser, directive,
2076 start_mark, "did not find expected '!'")
2077 return false
2078 }
2079 }
2080
2081 *handle = s
2082 return true
2083 }
2084
2085
2086 func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
2087
2088 var s []byte
2089 hasTag := len(head) > 0
2090
2091
2092
2093
2094 if len(head) > 1 {
2095 s = append(s, head[1:]...)
2096 }
2097
2098
2099 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2100 return false
2101 }
2102
2103
2104
2105
2106
2107
2108
2109 for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
2110 parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
2111 parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
2112 parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
2113 parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
2114 parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
2115 parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
2116 parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
2117 parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
2118 parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
2119 parser.buffer[parser.buffer_pos] == '%' {
2120
2121 if parser.buffer[parser.buffer_pos] == '%' {
2122 if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
2123 return false
2124 }
2125 } else {
2126 s = read(parser, s)
2127 }
2128 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2129 return false
2130 }
2131 hasTag = true
2132 }
2133
2134 if !hasTag {
2135 yaml_parser_set_scanner_tag_error(parser, directive,
2136 start_mark, "did not find expected tag URI")
2137 return false
2138 }
2139 *uri = s
2140 return true
2141 }
2142
2143
2144 func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
2145
2146
2147 w := 1024
2148 for w > 0 {
2149
2150 if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
2151 return false
2152 }
2153
2154 if !(parser.buffer[parser.buffer_pos] == '%' &&
2155 is_hex(parser.buffer, parser.buffer_pos+1) &&
2156 is_hex(parser.buffer, parser.buffer_pos+2)) {
2157 return yaml_parser_set_scanner_tag_error(parser, directive,
2158 start_mark, "did not find URI escaped octet")
2159 }
2160
2161
2162 octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
2163
2164
2165 if w == 1024 {
2166 w = width(octet)
2167 if w == 0 {
2168 return yaml_parser_set_scanner_tag_error(parser, directive,
2169 start_mark, "found an incorrect leading UTF-8 octet")
2170 }
2171 } else {
2172
2173 if octet&0xC0 != 0x80 {
2174 return yaml_parser_set_scanner_tag_error(parser, directive,
2175 start_mark, "found an incorrect trailing UTF-8 octet")
2176 }
2177 }
2178
2179
2180 *s = append(*s, octet)
2181 skip(parser)
2182 skip(parser)
2183 skip(parser)
2184 w--
2185 }
2186 return true
2187 }
2188
2189
2190 func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
2191
2192 start_mark := parser.mark
2193 skip(parser)
2194
2195
2196 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2197 return false
2198 }
2199
2200
2201 var chomping, increment int
2202 if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
2203
2204 if parser.buffer[parser.buffer_pos] == '+' {
2205 chomping = +1
2206 } else {
2207 chomping = -1
2208 }
2209 skip(parser)
2210
2211
2212 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2213 return false
2214 }
2215 if is_digit(parser.buffer, parser.buffer_pos) {
2216
2217 if parser.buffer[parser.buffer_pos] == '0' {
2218 yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2219 start_mark, "found an indentation indicator equal to 0")
2220 return false
2221 }
2222
2223
2224 increment = as_digit(parser.buffer, parser.buffer_pos)
2225 skip(parser)
2226 }
2227
2228 } else if is_digit(parser.buffer, parser.buffer_pos) {
2229
2230
2231 if parser.buffer[parser.buffer_pos] == '0' {
2232 yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2233 start_mark, "found an indentation indicator equal to 0")
2234 return false
2235 }
2236 increment = as_digit(parser.buffer, parser.buffer_pos)
2237 skip(parser)
2238
2239 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2240 return false
2241 }
2242 if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
2243 if parser.buffer[parser.buffer_pos] == '+' {
2244 chomping = +1
2245 } else {
2246 chomping = -1
2247 }
2248 skip(parser)
2249 }
2250 }
2251
2252
2253 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2254 return false
2255 }
2256 for is_blank(parser.buffer, parser.buffer_pos) {
2257 skip(parser)
2258 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2259 return false
2260 }
2261 }
2262 if parser.buffer[parser.buffer_pos] == '#' {
2263 if !yaml_parser_scan_line_comment(parser, start_mark) {
2264 return false
2265 }
2266 for !is_breakz(parser.buffer, parser.buffer_pos) {
2267 skip(parser)
2268 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2269 return false
2270 }
2271 }
2272 }
2273
2274
2275 if !is_breakz(parser.buffer, parser.buffer_pos) {
2276 yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2277 start_mark, "did not find expected comment or line break")
2278 return false
2279 }
2280
2281
2282 if is_break(parser.buffer, parser.buffer_pos) {
2283 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2284 return false
2285 }
2286 skip_line(parser)
2287 }
2288
2289 end_mark := parser.mark
2290
2291
2292 var indent int
2293 if increment > 0 {
2294 if parser.indent >= 0 {
2295 indent = parser.indent + increment
2296 } else {
2297 indent = increment
2298 }
2299 }
2300
2301
2302 var s, leading_break, trailing_breaks []byte
2303 if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
2304 return false
2305 }
2306
2307
2308 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2309 return false
2310 }
2311 var leading_blank, trailing_blank bool
2312 for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
2313
2314
2315
2316 trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
2317
2318
2319 if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
2320
2321 if len(trailing_breaks) == 0 {
2322 s = append(s, ' ')
2323 }
2324 } else {
2325 s = append(s, leading_break...)
2326 }
2327 leading_break = leading_break[:0]
2328
2329
2330 s = append(s, trailing_breaks...)
2331 trailing_breaks = trailing_breaks[:0]
2332
2333
2334 leading_blank = is_blank(parser.buffer, parser.buffer_pos)
2335
2336
2337 for !is_breakz(parser.buffer, parser.buffer_pos) {
2338 s = read(parser, s)
2339 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2340 return false
2341 }
2342 }
2343
2344
2345 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2346 return false
2347 }
2348
2349 leading_break = read_line(parser, leading_break)
2350
2351
2352 if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
2353 return false
2354 }
2355 }
2356
2357
2358 if chomping != -1 {
2359 s = append(s, leading_break...)
2360 }
2361 if chomping == 1 {
2362 s = append(s, trailing_breaks...)
2363 }
2364
2365
2366 *token = yaml_token_t{
2367 typ: yaml_SCALAR_TOKEN,
2368 start_mark: start_mark,
2369 end_mark: end_mark,
2370 value: s,
2371 style: yaml_LITERAL_SCALAR_STYLE,
2372 }
2373 if !literal {
2374 token.style = yaml_FOLDED_SCALAR_STYLE
2375 }
2376 return true
2377 }
2378
2379
2380
2381 func yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {
2382 *end_mark = parser.mark
2383
2384
2385 max_indent := 0
2386 for {
2387
2388 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2389 return false
2390 }
2391 for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
2392 skip(parser)
2393 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2394 return false
2395 }
2396 }
2397 if parser.mark.column > max_indent {
2398 max_indent = parser.mark.column
2399 }
2400
2401
2402 if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
2403 return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2404 start_mark, "found a tab character where an indentation space is expected")
2405 }
2406
2407
2408 if !is_break(parser.buffer, parser.buffer_pos) {
2409 break
2410 }
2411
2412
2413 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2414 return false
2415 }
2416
2417 *breaks = read_line(parser, *breaks)
2418 *end_mark = parser.mark
2419 }
2420
2421
2422 if *indent == 0 {
2423 *indent = max_indent
2424 if *indent < parser.indent+1 {
2425 *indent = parser.indent + 1
2426 }
2427 if *indent < 1 {
2428 *indent = 1
2429 }
2430 }
2431 return true
2432 }
2433
2434
2435 func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
2436
2437 start_mark := parser.mark
2438 skip(parser)
2439
2440
2441 var s, leading_break, trailing_breaks, whitespaces []byte
2442 for {
2443
2444 if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
2445 return false
2446 }
2447
2448 if parser.mark.column == 0 &&
2449 ((parser.buffer[parser.buffer_pos+0] == '-' &&
2450 parser.buffer[parser.buffer_pos+1] == '-' &&
2451 parser.buffer[parser.buffer_pos+2] == '-') ||
2452 (parser.buffer[parser.buffer_pos+0] == '.' &&
2453 parser.buffer[parser.buffer_pos+1] == '.' &&
2454 parser.buffer[parser.buffer_pos+2] == '.')) &&
2455 is_blankz(parser.buffer, parser.buffer_pos+3) {
2456 yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
2457 start_mark, "found unexpected document indicator")
2458 return false
2459 }
2460
2461
2462 if is_z(parser.buffer, parser.buffer_pos) {
2463 yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
2464 start_mark, "found unexpected end of stream")
2465 return false
2466 }
2467
2468
2469 leading_blanks := false
2470 for !is_blankz(parser.buffer, parser.buffer_pos) {
2471 if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
2472
2473 s = append(s, '\'')
2474 skip(parser)
2475 skip(parser)
2476
2477 } else if single && parser.buffer[parser.buffer_pos] == '\'' {
2478
2479 break
2480 } else if !single && parser.buffer[parser.buffer_pos] == '"' {
2481
2482 break
2483
2484 } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
2485
2486 if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
2487 return false
2488 }
2489 skip(parser)
2490 skip_line(parser)
2491 leading_blanks = true
2492 break
2493
2494 } else if !single && parser.buffer[parser.buffer_pos] == '\\' {
2495
2496 code_length := 0
2497
2498
2499 switch parser.buffer[parser.buffer_pos+1] {
2500 case '0':
2501 s = append(s, 0)
2502 case 'a':
2503 s = append(s, '\x07')
2504 case 'b':
2505 s = append(s, '\x08')
2506 case 't', '\t':
2507 s = append(s, '\x09')
2508 case 'n':
2509 s = append(s, '\x0A')
2510 case 'v':
2511 s = append(s, '\x0B')
2512 case 'f':
2513 s = append(s, '\x0C')
2514 case 'r':
2515 s = append(s, '\x0D')
2516 case 'e':
2517 s = append(s, '\x1B')
2518 case ' ':
2519 s = append(s, '\x20')
2520 case '"':
2521 s = append(s, '"')
2522 case '\'':
2523 s = append(s, '\'')
2524 case '\\':
2525 s = append(s, '\\')
2526 case 'N':
2527 s = append(s, '\xC2')
2528 s = append(s, '\x85')
2529 case '_':
2530 s = append(s, '\xC2')
2531 s = append(s, '\xA0')
2532 case 'L':
2533 s = append(s, '\xE2')
2534 s = append(s, '\x80')
2535 s = append(s, '\xA8')
2536 case 'P':
2537 s = append(s, '\xE2')
2538 s = append(s, '\x80')
2539 s = append(s, '\xA9')
2540 case 'x':
2541 code_length = 2
2542 case 'u':
2543 code_length = 4
2544 case 'U':
2545 code_length = 8
2546 default:
2547 yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
2548 start_mark, "found unknown escape character")
2549 return false
2550 }
2551
2552 skip(parser)
2553 skip(parser)
2554
2555
2556 if code_length > 0 {
2557 var value int
2558
2559
2560 if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
2561 return false
2562 }
2563 for k := 0; k < code_length; k++ {
2564 if !is_hex(parser.buffer, parser.buffer_pos+k) {
2565 yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
2566 start_mark, "did not find expected hexdecimal number")
2567 return false
2568 }
2569 value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
2570 }
2571
2572
2573 if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
2574 yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
2575 start_mark, "found invalid Unicode character escape code")
2576 return false
2577 }
2578 if value <= 0x7F {
2579 s = append(s, byte(value))
2580 } else if value <= 0x7FF {
2581 s = append(s, byte(0xC0+(value>>6)))
2582 s = append(s, byte(0x80+(value&0x3F)))
2583 } else if value <= 0xFFFF {
2584 s = append(s, byte(0xE0+(value>>12)))
2585 s = append(s, byte(0x80+((value>>6)&0x3F)))
2586 s = append(s, byte(0x80+(value&0x3F)))
2587 } else {
2588 s = append(s, byte(0xF0+(value>>18)))
2589 s = append(s, byte(0x80+((value>>12)&0x3F)))
2590 s = append(s, byte(0x80+((value>>6)&0x3F)))
2591 s = append(s, byte(0x80+(value&0x3F)))
2592 }
2593
2594
2595 for k := 0; k < code_length; k++ {
2596 skip(parser)
2597 }
2598 }
2599 } else {
2600
2601 s = read(parser, s)
2602 }
2603 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2604 return false
2605 }
2606 }
2607
2608 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2609 return false
2610 }
2611
2612
2613 if single {
2614 if parser.buffer[parser.buffer_pos] == '\'' {
2615 break
2616 }
2617 } else {
2618 if parser.buffer[parser.buffer_pos] == '"' {
2619 break
2620 }
2621 }
2622
2623
2624 for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
2625 if is_blank(parser.buffer, parser.buffer_pos) {
2626
2627 if !leading_blanks {
2628 whitespaces = read(parser, whitespaces)
2629 } else {
2630 skip(parser)
2631 }
2632 } else {
2633 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2634 return false
2635 }
2636
2637
2638 if !leading_blanks {
2639 whitespaces = whitespaces[:0]
2640 leading_break = read_line(parser, leading_break)
2641 leading_blanks = true
2642 } else {
2643 trailing_breaks = read_line(parser, trailing_breaks)
2644 }
2645 }
2646 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2647 return false
2648 }
2649 }
2650
2651
2652 if leading_blanks {
2653
2654 if len(leading_break) > 0 && leading_break[0] == '\n' {
2655 if len(trailing_breaks) == 0 {
2656 s = append(s, ' ')
2657 } else {
2658 s = append(s, trailing_breaks...)
2659 }
2660 } else {
2661 s = append(s, leading_break...)
2662 s = append(s, trailing_breaks...)
2663 }
2664 trailing_breaks = trailing_breaks[:0]
2665 leading_break = leading_break[:0]
2666 } else {
2667 s = append(s, whitespaces...)
2668 whitespaces = whitespaces[:0]
2669 }
2670 }
2671
2672
2673 skip(parser)
2674 end_mark := parser.mark
2675
2676
2677 *token = yaml_token_t{
2678 typ: yaml_SCALAR_TOKEN,
2679 start_mark: start_mark,
2680 end_mark: end_mark,
2681 value: s,
2682 style: yaml_SINGLE_QUOTED_SCALAR_STYLE,
2683 }
2684 if !single {
2685 token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
2686 }
2687 return true
2688 }
2689
2690
2691 func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
2692
2693 var s, leading_break, trailing_breaks, whitespaces []byte
2694 var leading_blanks bool
2695 var indent = parser.indent + 1
2696
2697 start_mark := parser.mark
2698 end_mark := parser.mark
2699
2700
2701 for {
2702
2703 if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
2704 return false
2705 }
2706 if parser.mark.column == 0 &&
2707 ((parser.buffer[parser.buffer_pos+0] == '-' &&
2708 parser.buffer[parser.buffer_pos+1] == '-' &&
2709 parser.buffer[parser.buffer_pos+2] == '-') ||
2710 (parser.buffer[parser.buffer_pos+0] == '.' &&
2711 parser.buffer[parser.buffer_pos+1] == '.' &&
2712 parser.buffer[parser.buffer_pos+2] == '.')) &&
2713 is_blankz(parser.buffer, parser.buffer_pos+3) {
2714 break
2715 }
2716
2717
2718 if parser.buffer[parser.buffer_pos] == '#' {
2719 break
2720 }
2721
2722
2723 for !is_blankz(parser.buffer, parser.buffer_pos) {
2724
2725
2726 if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
2727 (parser.flow_level > 0 &&
2728 (parser.buffer[parser.buffer_pos] == ',' ||
2729 parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
2730 parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
2731 parser.buffer[parser.buffer_pos] == '}')) {
2732 break
2733 }
2734
2735
2736 if leading_blanks || len(whitespaces) > 0 {
2737 if leading_blanks {
2738
2739 if leading_break[0] == '\n' {
2740 if len(trailing_breaks) == 0 {
2741 s = append(s, ' ')
2742 } else {
2743 s = append(s, trailing_breaks...)
2744 }
2745 } else {
2746 s = append(s, leading_break...)
2747 s = append(s, trailing_breaks...)
2748 }
2749 trailing_breaks = trailing_breaks[:0]
2750 leading_break = leading_break[:0]
2751 leading_blanks = false
2752 } else {
2753 s = append(s, whitespaces...)
2754 whitespaces = whitespaces[:0]
2755 }
2756 }
2757
2758
2759 s = read(parser, s)
2760
2761 end_mark = parser.mark
2762 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2763 return false
2764 }
2765 }
2766
2767
2768 if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
2769 break
2770 }
2771
2772
2773 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2774 return false
2775 }
2776
2777 for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
2778 if is_blank(parser.buffer, parser.buffer_pos) {
2779
2780
2781 if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
2782 yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
2783 start_mark, "found a tab character that violates indentation")
2784 return false
2785 }
2786
2787
2788 if !leading_blanks {
2789 whitespaces = read(parser, whitespaces)
2790 } else {
2791 skip(parser)
2792 }
2793 } else {
2794 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2795 return false
2796 }
2797
2798
2799 if !leading_blanks {
2800 whitespaces = whitespaces[:0]
2801 leading_break = read_line(parser, leading_break)
2802 leading_blanks = true
2803 } else {
2804 trailing_breaks = read_line(parser, trailing_breaks)
2805 }
2806 }
2807 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2808 return false
2809 }
2810 }
2811
2812
2813 if parser.flow_level == 0 && parser.mark.column < indent {
2814 break
2815 }
2816 }
2817
2818
2819 *token = yaml_token_t{
2820 typ: yaml_SCALAR_TOKEN,
2821 start_mark: start_mark,
2822 end_mark: end_mark,
2823 value: s,
2824 style: yaml_PLAIN_SCALAR_STYLE,
2825 }
2826
2827
2828 if leading_blanks {
2829 parser.simple_key_allowed = true
2830 }
2831 return true
2832 }
2833
2834 func yaml_parser_scan_line_comment(parser *yaml_parser_t, token_mark yaml_mark_t) bool {
2835 if parser.newlines > 0 {
2836 return true
2837 }
2838
2839 var start_mark yaml_mark_t
2840 var text []byte
2841
2842 for peek := 0; peek < 512; peek++ {
2843 if parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) {
2844 break
2845 }
2846 if is_blank(parser.buffer, parser.buffer_pos+peek) {
2847 continue
2848 }
2849 if parser.buffer[parser.buffer_pos+peek] == '#' {
2850 seen := parser.mark.index+peek
2851 for {
2852 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2853 return false
2854 }
2855 if is_breakz(parser.buffer, parser.buffer_pos) {
2856 if parser.mark.index >= seen {
2857 break
2858 }
2859 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2860 return false
2861 }
2862 skip_line(parser)
2863 } else if parser.mark.index >= seen {
2864 if len(text) == 0 {
2865 start_mark = parser.mark
2866 }
2867 text = read(parser, text)
2868 } else {
2869 skip(parser)
2870 }
2871 }
2872 }
2873 break
2874 }
2875 if len(text) > 0 {
2876 parser.comments = append(parser.comments, yaml_comment_t{
2877 token_mark: token_mark,
2878 start_mark: start_mark,
2879 line: text,
2880 })
2881 }
2882 return true
2883 }
2884
2885 func yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) bool {
2886 token := parser.tokens[len(parser.tokens)-1]
2887
2888 if token.typ == yaml_FLOW_ENTRY_TOKEN && len(parser.tokens) > 1 {
2889 token = parser.tokens[len(parser.tokens)-2]
2890 }
2891
2892 var token_mark = token.start_mark
2893 var start_mark yaml_mark_t
2894 var next_indent = parser.indent
2895 if next_indent < 0 {
2896 next_indent = 0
2897 }
2898
2899 var recent_empty = false
2900 var first_empty = parser.newlines <= 1
2901
2902 var line = parser.mark.line
2903 var column = parser.mark.column
2904
2905 var text []byte
2906
2907
2908
2909
2910
2911 var foot_line = -1
2912 if scan_mark.line > 0 {
2913 foot_line = parser.mark.line-parser.newlines+1
2914 if parser.newlines == 0 && parser.mark.column > 1 {
2915 foot_line++
2916 }
2917 }
2918
2919 var peek = 0
2920 for ; peek < 512; peek++ {
2921 if parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) {
2922 break
2923 }
2924 column++
2925 if is_blank(parser.buffer, parser.buffer_pos+peek) {
2926 continue
2927 }
2928 c := parser.buffer[parser.buffer_pos+peek]
2929 var close_flow = parser.flow_level > 0 && (c == ']' || c == '}')
2930 if close_flow || is_breakz(parser.buffer, parser.buffer_pos+peek) {
2931
2932 if close_flow || !recent_empty {
2933 if close_flow || first_empty && (start_mark.line == foot_line && token.typ != yaml_VALUE_TOKEN || start_mark.column-1 < next_indent) {
2934
2935
2936
2937
2938
2939 if len(text) > 0 {
2940 if start_mark.column-1 < next_indent {
2941
2942 token_mark = start_mark
2943 }
2944 parser.comments = append(parser.comments, yaml_comment_t{
2945 scan_mark: scan_mark,
2946 token_mark: token_mark,
2947 start_mark: start_mark,
2948 end_mark: yaml_mark_t{parser.mark.index + peek, line, column},
2949 foot: text,
2950 })
2951 scan_mark = yaml_mark_t{parser.mark.index + peek, line, column}
2952 token_mark = scan_mark
2953 text = nil
2954 }
2955 } else {
2956 if len(text) > 0 && parser.buffer[parser.buffer_pos+peek] != 0 {
2957 text = append(text, '\n')
2958 }
2959 }
2960 }
2961 if !is_break(parser.buffer, parser.buffer_pos+peek) {
2962 break
2963 }
2964 first_empty = false
2965 recent_empty = true
2966 column = 0
2967 line++
2968 continue
2969 }
2970
2971 if len(text) > 0 && (close_flow || column-1 < next_indent && column != start_mark.column) {
2972
2973
2974 parser.comments = append(parser.comments, yaml_comment_t{
2975 scan_mark: scan_mark,
2976 token_mark: token_mark,
2977 start_mark: start_mark,
2978 end_mark: yaml_mark_t{parser.mark.index + peek, line, column},
2979 foot: text,
2980 })
2981 scan_mark = yaml_mark_t{parser.mark.index + peek, line, column}
2982 token_mark = scan_mark
2983 text = nil
2984 }
2985
2986 if parser.buffer[parser.buffer_pos+peek] != '#' {
2987 break
2988 }
2989
2990 if len(text) == 0 {
2991 start_mark = yaml_mark_t{parser.mark.index + peek, line, column}
2992 } else {
2993 text = append(text, '\n')
2994 }
2995
2996 recent_empty = false
2997
2998
2999 seen := parser.mark.index+peek
3000 for {
3001 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
3002 return false
3003 }
3004 if is_breakz(parser.buffer, parser.buffer_pos) {
3005 if parser.mark.index >= seen {
3006 break
3007 }
3008 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
3009 return false
3010 }
3011 skip_line(parser)
3012 } else if parser.mark.index >= seen {
3013 text = read(parser, text)
3014 } else {
3015 skip(parser)
3016 }
3017 }
3018
3019 peek = 0
3020 column = 0
3021 line = parser.mark.line
3022 next_indent = parser.indent
3023 if next_indent < 0 {
3024 next_indent = 0
3025 }
3026 }
3027
3028 if len(text) > 0 {
3029 parser.comments = append(parser.comments, yaml_comment_t{
3030 scan_mark: scan_mark,
3031 token_mark: start_mark,
3032 start_mark: start_mark,
3033 end_mark: yaml_mark_t{parser.mark.index + peek - 1, line, column},
3034 head: text,
3035 })
3036 }
3037 return true
3038 }
3039
View as plain text