1 package yaml
2
3 import (
4 "bytes"
5 "fmt"
6 )
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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 func cache(parser *yaml_parser_t, length int) bool {
486
487 return parser.unread >= length || yaml_parser_update_buffer(parser, length)
488 }
489
490
491 func skip(parser *yaml_parser_t) {
492 parser.mark.index++
493 parser.mark.column++
494 parser.unread--
495 parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
496 }
497
498 func skip_line(parser *yaml_parser_t) {
499 if is_crlf(parser.buffer, parser.buffer_pos) {
500 parser.mark.index += 2
501 parser.mark.column = 0
502 parser.mark.line++
503 parser.unread -= 2
504 parser.buffer_pos += 2
505 } else if is_break(parser.buffer, parser.buffer_pos) {
506 parser.mark.index++
507 parser.mark.column = 0
508 parser.mark.line++
509 parser.unread--
510 parser.buffer_pos += width(parser.buffer[parser.buffer_pos])
511 }
512 }
513
514
515 func read(parser *yaml_parser_t, s []byte) []byte {
516 w := width(parser.buffer[parser.buffer_pos])
517 if w == 0 {
518 panic("invalid character sequence")
519 }
520 if len(s) == 0 {
521 s = make([]byte, 0, 32)
522 }
523 if w == 1 && len(s)+w <= cap(s) {
524 s = s[:len(s)+1]
525 s[len(s)-1] = parser.buffer[parser.buffer_pos]
526 parser.buffer_pos++
527 } else {
528 s = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)
529 parser.buffer_pos += w
530 }
531 parser.mark.index++
532 parser.mark.column++
533 parser.unread--
534 return s
535 }
536
537
538 func read_line(parser *yaml_parser_t, s []byte) []byte {
539 buf := parser.buffer
540 pos := parser.buffer_pos
541 switch {
542 case buf[pos] == '\r' && buf[pos+1] == '\n':
543
544 s = append(s, '\n')
545 parser.buffer_pos += 2
546 parser.mark.index++
547 parser.unread--
548 case buf[pos] == '\r' || buf[pos] == '\n':
549
550 s = append(s, '\n')
551 parser.buffer_pos += 1
552 case buf[pos] == '\xC2' && buf[pos+1] == '\x85':
553
554 s = append(s, '\n')
555 parser.buffer_pos += 2
556 case buf[pos] == '\xE2' && buf[pos+1] == '\x80' && (buf[pos+2] == '\xA8' || buf[pos+2] == '\xA9'):
557
558 s = append(s, buf[parser.buffer_pos:pos+3]...)
559 parser.buffer_pos += 3
560 default:
561 return s
562 }
563 parser.mark.index++
564 parser.mark.column = 0
565 parser.mark.line++
566 parser.unread--
567 return s
568 }
569
570
571 func yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {
572
573 *token = yaml_token_t{}
574
575
576 if parser.stream_end_produced || parser.error != yaml_NO_ERROR {
577 return true
578 }
579
580
581 if !parser.token_available {
582 if !yaml_parser_fetch_more_tokens(parser) {
583 return false
584 }
585 }
586
587
588 *token = parser.tokens[parser.tokens_head]
589 parser.tokens_head++
590 parser.tokens_parsed++
591 parser.token_available = false
592
593 if token.typ == yaml_STREAM_END_TOKEN {
594 parser.stream_end_produced = true
595 }
596 return true
597 }
598
599
600 func yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {
601 parser.error = yaml_SCANNER_ERROR
602 parser.context = context
603 parser.context_mark = context_mark
604 parser.problem = problem
605 parser.problem_mark = parser.mark
606 return false
607 }
608
609 func yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {
610 context := "while parsing a tag"
611 if directive {
612 context = "while parsing a %TAG directive"
613 }
614 return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
615 }
616
617 func trace(args ...interface{}) func() {
618 pargs := append([]interface{}{"+++"}, args...)
619 fmt.Println(pargs...)
620 pargs = append([]interface{}{"---"}, args...)
621 return func() { fmt.Println(pargs...) }
622 }
623
624
625
626 func yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {
627
628 for {
629 if parser.tokens_head != len(parser.tokens) {
630
631
632 head_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed]
633 if !ok {
634 break
635 } else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok {
636 return false
637 } else if !valid {
638 break
639 }
640 }
641
642 if !yaml_parser_fetch_next_token(parser) {
643 return false
644 }
645 }
646
647 parser.token_available = true
648 return true
649 }
650
651
652 func yaml_parser_fetch_next_token(parser *yaml_parser_t) bool {
653
654 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
655 return false
656 }
657
658
659 if !parser.stream_start_produced {
660 return yaml_parser_fetch_stream_start(parser)
661 }
662
663
664 if !yaml_parser_scan_to_next_token(parser) {
665 return false
666 }
667
668
669 if !yaml_parser_unroll_indent(parser, parser.mark.column) {
670 return false
671 }
672
673
674
675 if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
676 return false
677 }
678
679
680 if is_z(parser.buffer, parser.buffer_pos) {
681 return yaml_parser_fetch_stream_end(parser)
682 }
683
684
685 if parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {
686 return yaml_parser_fetch_directive(parser)
687 }
688
689 buf := parser.buffer
690 pos := parser.buffer_pos
691
692
693 if parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {
694 return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)
695 }
696
697
698 if parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {
699 return yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)
700 }
701
702
703 if buf[pos] == '[' {
704 return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)
705 }
706
707
708 if parser.buffer[parser.buffer_pos] == '{' {
709 return yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)
710 }
711
712
713 if parser.buffer[parser.buffer_pos] == ']' {
714 return yaml_parser_fetch_flow_collection_end(parser,
715 yaml_FLOW_SEQUENCE_END_TOKEN)
716 }
717
718
719 if parser.buffer[parser.buffer_pos] == '}' {
720 return yaml_parser_fetch_flow_collection_end(parser,
721 yaml_FLOW_MAPPING_END_TOKEN)
722 }
723
724
725 if parser.buffer[parser.buffer_pos] == ',' {
726 return yaml_parser_fetch_flow_entry(parser)
727 }
728
729
730 if parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {
731 return yaml_parser_fetch_block_entry(parser)
732 }
733
734
735 if parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
736 return yaml_parser_fetch_key(parser)
737 }
738
739
740 if parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {
741 return yaml_parser_fetch_value(parser)
742 }
743
744
745 if parser.buffer[parser.buffer_pos] == '*' {
746 return yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)
747 }
748
749
750 if parser.buffer[parser.buffer_pos] == '&' {
751 return yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)
752 }
753
754
755 if parser.buffer[parser.buffer_pos] == '!' {
756 return yaml_parser_fetch_tag(parser)
757 }
758
759
760 if parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {
761 return yaml_parser_fetch_block_scalar(parser, true)
762 }
763
764
765 if parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {
766 return yaml_parser_fetch_block_scalar(parser, false)
767 }
768
769
770 if parser.buffer[parser.buffer_pos] == '\'' {
771 return yaml_parser_fetch_flow_scalar(parser, true)
772 }
773
774
775 if parser.buffer[parser.buffer_pos] == '"' {
776 return yaml_parser_fetch_flow_scalar(parser, false)
777 }
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799 if !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||
800 parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||
801 parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||
802 parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
803 parser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||
804 parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||
805 parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||
806 parser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\'' ||
807 parser.buffer[parser.buffer_pos] == '"' || parser.buffer[parser.buffer_pos] == '%' ||
808 parser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||
809 (parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||
810 (parser.flow_level == 0 &&
811 (parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&
812 !is_blankz(parser.buffer, parser.buffer_pos+1)) {
813 return yaml_parser_fetch_plain_scalar(parser)
814 }
815
816
817 return yaml_parser_set_scanner_error(parser,
818 "while scanning for the next token", parser.mark,
819 "found character that cannot start any token")
820 }
821
822 func yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) {
823 if !simple_key.possible {
824 return false, true
825 }
826
827
828
829
830
831
832
833
834
835 if simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index {
836
837 if simple_key.required {
838 return false, yaml_parser_set_scanner_error(parser,
839 "while scanning a simple key", simple_key.mark,
840 "could not find expected ':'")
841 }
842 simple_key.possible = false
843 return false, true
844 }
845 return true, true
846 }
847
848
849
850 func yaml_parser_save_simple_key(parser *yaml_parser_t) bool {
851
852
853
854
855 required := parser.flow_level == 0 && parser.indent == parser.mark.column
856
857
858
859
860 if parser.simple_key_allowed {
861 simple_key := yaml_simple_key_t{
862 possible: true,
863 required: required,
864 token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
865 mark: parser.mark,
866 }
867
868 if !yaml_parser_remove_simple_key(parser) {
869 return false
870 }
871 parser.simple_keys[len(parser.simple_keys)-1] = simple_key
872 parser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1
873 }
874 return true
875 }
876
877
878 func yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {
879 i := len(parser.simple_keys) - 1
880 if parser.simple_keys[i].possible {
881
882 if parser.simple_keys[i].required {
883 return yaml_parser_set_scanner_error(parser,
884 "while scanning a simple key", parser.simple_keys[i].mark,
885 "could not find expected ':'")
886 }
887
888 parser.simple_keys[i].possible = false
889 delete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number)
890 }
891 return true
892 }
893
894
895 const max_flow_level = 10000
896
897
898 func yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {
899
900 parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{
901 possible: false,
902 required: false,
903 token_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),
904 mark: parser.mark,
905 })
906
907
908 parser.flow_level++
909 if parser.flow_level > max_flow_level {
910 return yaml_parser_set_scanner_error(parser,
911 "while increasing flow level", parser.simple_keys[len(parser.simple_keys)-1].mark,
912 fmt.Sprintf("exceeded max depth of %d", max_flow_level))
913 }
914 return true
915 }
916
917
918 func yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {
919 if parser.flow_level > 0 {
920 parser.flow_level--
921 last := len(parser.simple_keys) - 1
922 delete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number)
923 parser.simple_keys = parser.simple_keys[:last]
924 }
925 return true
926 }
927
928
929 const max_indents = 10000
930
931
932
933
934 func yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {
935
936 if parser.flow_level > 0 {
937 return true
938 }
939
940 if parser.indent < column {
941
942
943 parser.indents = append(parser.indents, parser.indent)
944 parser.indent = column
945 if len(parser.indents) > max_indents {
946 return yaml_parser_set_scanner_error(parser,
947 "while increasing indent level", parser.simple_keys[len(parser.simple_keys)-1].mark,
948 fmt.Sprintf("exceeded max depth of %d", max_indents))
949 }
950
951
952 token := yaml_token_t{
953 typ: typ,
954 start_mark: mark,
955 end_mark: mark,
956 }
957 if number > -1 {
958 number -= parser.tokens_parsed
959 }
960 yaml_insert_token(parser, number, &token)
961 }
962 return true
963 }
964
965
966
967
968 func yaml_parser_unroll_indent(parser *yaml_parser_t, column int) bool {
969
970 if parser.flow_level > 0 {
971 return true
972 }
973
974
975 for parser.indent > column {
976
977 token := yaml_token_t{
978 typ: yaml_BLOCK_END_TOKEN,
979 start_mark: parser.mark,
980 end_mark: parser.mark,
981 }
982 yaml_insert_token(parser, -1, &token)
983
984
985 parser.indent = parser.indents[len(parser.indents)-1]
986 parser.indents = parser.indents[:len(parser.indents)-1]
987 }
988 return true
989 }
990
991
992 func yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {
993
994
995 parser.indent = -1
996
997
998 parser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})
999
1000 parser.simple_keys_by_tok = make(map[int]int)
1001
1002
1003 parser.simple_key_allowed = true
1004
1005
1006 parser.stream_start_produced = true
1007
1008
1009 token := yaml_token_t{
1010 typ: yaml_STREAM_START_TOKEN,
1011 start_mark: parser.mark,
1012 end_mark: parser.mark,
1013 encoding: parser.encoding,
1014 }
1015 yaml_insert_token(parser, -1, &token)
1016 return true
1017 }
1018
1019
1020 func yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {
1021
1022
1023 if parser.mark.column != 0 {
1024 parser.mark.column = 0
1025 parser.mark.line++
1026 }
1027
1028
1029 if !yaml_parser_unroll_indent(parser, -1) {
1030 return false
1031 }
1032
1033
1034 if !yaml_parser_remove_simple_key(parser) {
1035 return false
1036 }
1037
1038 parser.simple_key_allowed = false
1039
1040
1041 token := yaml_token_t{
1042 typ: yaml_STREAM_END_TOKEN,
1043 start_mark: parser.mark,
1044 end_mark: parser.mark,
1045 }
1046 yaml_insert_token(parser, -1, &token)
1047 return true
1048 }
1049
1050
1051 func yaml_parser_fetch_directive(parser *yaml_parser_t) bool {
1052
1053 if !yaml_parser_unroll_indent(parser, -1) {
1054 return false
1055 }
1056
1057
1058 if !yaml_parser_remove_simple_key(parser) {
1059 return false
1060 }
1061
1062 parser.simple_key_allowed = false
1063
1064
1065 token := yaml_token_t{}
1066 if !yaml_parser_scan_directive(parser, &token) {
1067 return false
1068 }
1069
1070 yaml_insert_token(parser, -1, &token)
1071 return true
1072 }
1073
1074
1075 func yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1076
1077 if !yaml_parser_unroll_indent(parser, -1) {
1078 return false
1079 }
1080
1081
1082 if !yaml_parser_remove_simple_key(parser) {
1083 return false
1084 }
1085
1086 parser.simple_key_allowed = false
1087
1088
1089 start_mark := parser.mark
1090
1091 skip(parser)
1092 skip(parser)
1093 skip(parser)
1094
1095 end_mark := parser.mark
1096
1097
1098 token := yaml_token_t{
1099 typ: typ,
1100 start_mark: start_mark,
1101 end_mark: end_mark,
1102 }
1103
1104 yaml_insert_token(parser, -1, &token)
1105 return true
1106 }
1107
1108
1109 func yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1110
1111 if !yaml_parser_save_simple_key(parser) {
1112 return false
1113 }
1114
1115
1116 if !yaml_parser_increase_flow_level(parser) {
1117 return false
1118 }
1119
1120
1121 parser.simple_key_allowed = true
1122
1123
1124 start_mark := parser.mark
1125 skip(parser)
1126 end_mark := parser.mark
1127
1128
1129 token := yaml_token_t{
1130 typ: typ,
1131 start_mark: start_mark,
1132 end_mark: end_mark,
1133 }
1134
1135 yaml_insert_token(parser, -1, &token)
1136 return true
1137 }
1138
1139
1140 func yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1141
1142 if !yaml_parser_remove_simple_key(parser) {
1143 return false
1144 }
1145
1146
1147 if !yaml_parser_decrease_flow_level(parser) {
1148 return false
1149 }
1150
1151
1152 parser.simple_key_allowed = false
1153
1154
1155
1156 start_mark := parser.mark
1157 skip(parser)
1158 end_mark := parser.mark
1159
1160
1161 token := yaml_token_t{
1162 typ: typ,
1163 start_mark: start_mark,
1164 end_mark: end_mark,
1165 }
1166
1167 yaml_insert_token(parser, -1, &token)
1168 return true
1169 }
1170
1171
1172 func yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {
1173
1174 if !yaml_parser_remove_simple_key(parser) {
1175 return false
1176 }
1177
1178
1179 parser.simple_key_allowed = true
1180
1181
1182 start_mark := parser.mark
1183 skip(parser)
1184 end_mark := parser.mark
1185
1186
1187 token := yaml_token_t{
1188 typ: yaml_FLOW_ENTRY_TOKEN,
1189 start_mark: start_mark,
1190 end_mark: end_mark,
1191 }
1192 yaml_insert_token(parser, -1, &token)
1193 return true
1194 }
1195
1196
1197 func yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {
1198
1199 if parser.flow_level == 0 {
1200
1201 if !parser.simple_key_allowed {
1202 return yaml_parser_set_scanner_error(parser, "", parser.mark,
1203 "block sequence entries are not allowed in this context")
1204 }
1205
1206 if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {
1207 return false
1208 }
1209 } else {
1210
1211
1212
1213 }
1214
1215
1216 if !yaml_parser_remove_simple_key(parser) {
1217 return false
1218 }
1219
1220
1221 parser.simple_key_allowed = true
1222
1223
1224 start_mark := parser.mark
1225 skip(parser)
1226 end_mark := parser.mark
1227
1228
1229 token := yaml_token_t{
1230 typ: yaml_BLOCK_ENTRY_TOKEN,
1231 start_mark: start_mark,
1232 end_mark: end_mark,
1233 }
1234 yaml_insert_token(parser, -1, &token)
1235 return true
1236 }
1237
1238
1239 func yaml_parser_fetch_key(parser *yaml_parser_t) bool {
1240
1241
1242 if parser.flow_level == 0 {
1243
1244 if !parser.simple_key_allowed {
1245 return yaml_parser_set_scanner_error(parser, "", parser.mark,
1246 "mapping keys are not allowed in this context")
1247 }
1248
1249 if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
1250 return false
1251 }
1252 }
1253
1254
1255 if !yaml_parser_remove_simple_key(parser) {
1256 return false
1257 }
1258
1259
1260 parser.simple_key_allowed = parser.flow_level == 0
1261
1262
1263 start_mark := parser.mark
1264 skip(parser)
1265 end_mark := parser.mark
1266
1267
1268 token := yaml_token_t{
1269 typ: yaml_KEY_TOKEN,
1270 start_mark: start_mark,
1271 end_mark: end_mark,
1272 }
1273 yaml_insert_token(parser, -1, &token)
1274 return true
1275 }
1276
1277
1278 func yaml_parser_fetch_value(parser *yaml_parser_t) bool {
1279
1280 simple_key := &parser.simple_keys[len(parser.simple_keys)-1]
1281
1282
1283 if valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok {
1284 return false
1285
1286 } else if valid {
1287
1288
1289 token := yaml_token_t{
1290 typ: yaml_KEY_TOKEN,
1291 start_mark: simple_key.mark,
1292 end_mark: simple_key.mark,
1293 }
1294 yaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)
1295
1296
1297 if !yaml_parser_roll_indent(parser, simple_key.mark.column,
1298 simple_key.token_number,
1299 yaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {
1300 return false
1301 }
1302
1303
1304 simple_key.possible = false
1305 delete(parser.simple_keys_by_tok, simple_key.token_number)
1306
1307
1308 parser.simple_key_allowed = false
1309
1310 } else {
1311
1312
1313
1314 if parser.flow_level == 0 {
1315
1316
1317 if !parser.simple_key_allowed {
1318 return yaml_parser_set_scanner_error(parser, "", parser.mark,
1319 "mapping values are not allowed in this context")
1320 }
1321
1322
1323 if !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {
1324 return false
1325 }
1326 }
1327
1328
1329 parser.simple_key_allowed = parser.flow_level == 0
1330 }
1331
1332
1333 start_mark := parser.mark
1334 skip(parser)
1335 end_mark := parser.mark
1336
1337
1338 token := yaml_token_t{
1339 typ: yaml_VALUE_TOKEN,
1340 start_mark: start_mark,
1341 end_mark: end_mark,
1342 }
1343 yaml_insert_token(parser, -1, &token)
1344 return true
1345 }
1346
1347
1348 func yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {
1349
1350 if !yaml_parser_save_simple_key(parser) {
1351 return false
1352 }
1353
1354
1355 parser.simple_key_allowed = false
1356
1357
1358 var token yaml_token_t
1359 if !yaml_parser_scan_anchor(parser, &token, typ) {
1360 return false
1361 }
1362 yaml_insert_token(parser, -1, &token)
1363 return true
1364 }
1365
1366
1367 func yaml_parser_fetch_tag(parser *yaml_parser_t) bool {
1368
1369 if !yaml_parser_save_simple_key(parser) {
1370 return false
1371 }
1372
1373
1374 parser.simple_key_allowed = false
1375
1376
1377 var token yaml_token_t
1378 if !yaml_parser_scan_tag(parser, &token) {
1379 return false
1380 }
1381 yaml_insert_token(parser, -1, &token)
1382 return true
1383 }
1384
1385
1386 func yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {
1387
1388 if !yaml_parser_remove_simple_key(parser) {
1389 return false
1390 }
1391
1392
1393 parser.simple_key_allowed = true
1394
1395
1396 var token yaml_token_t
1397 if !yaml_parser_scan_block_scalar(parser, &token, literal) {
1398 return false
1399 }
1400 yaml_insert_token(parser, -1, &token)
1401 return true
1402 }
1403
1404
1405 func yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {
1406
1407 if !yaml_parser_save_simple_key(parser) {
1408 return false
1409 }
1410
1411
1412 parser.simple_key_allowed = false
1413
1414
1415 var token yaml_token_t
1416 if !yaml_parser_scan_flow_scalar(parser, &token, single) {
1417 return false
1418 }
1419 yaml_insert_token(parser, -1, &token)
1420 return true
1421 }
1422
1423
1424 func yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {
1425
1426 if !yaml_parser_save_simple_key(parser) {
1427 return false
1428 }
1429
1430
1431 parser.simple_key_allowed = false
1432
1433
1434 var token yaml_token_t
1435 if !yaml_parser_scan_plain_scalar(parser, &token) {
1436 return false
1437 }
1438 yaml_insert_token(parser, -1, &token)
1439 return true
1440 }
1441
1442
1443 func yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {
1444
1445
1446 for {
1447
1448 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1449 return false
1450 }
1451 if parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {
1452 skip(parser)
1453 }
1454
1455
1456
1457
1458
1459
1460 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1461 return false
1462 }
1463
1464 for parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\t') {
1465 skip(parser)
1466 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1467 return false
1468 }
1469 }
1470
1471
1472 if parser.buffer[parser.buffer_pos] == '#' {
1473 for !is_breakz(parser.buffer, parser.buffer_pos) {
1474 skip(parser)
1475 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1476 return false
1477 }
1478 }
1479 }
1480
1481
1482 if is_break(parser.buffer, parser.buffer_pos) {
1483 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
1484 return false
1485 }
1486 skip_line(parser)
1487
1488
1489 if parser.flow_level == 0 {
1490 parser.simple_key_allowed = true
1491 }
1492 } else {
1493 break
1494 }
1495 }
1496
1497 return true
1498 }
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508 func yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {
1509
1510 start_mark := parser.mark
1511 skip(parser)
1512
1513
1514 var name []byte
1515 if !yaml_parser_scan_directive_name(parser, start_mark, &name) {
1516 return false
1517 }
1518
1519
1520 if bytes.Equal(name, []byte("YAML")) {
1521
1522 var major, minor int8
1523 if !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {
1524 return false
1525 }
1526 end_mark := parser.mark
1527
1528
1529 *token = yaml_token_t{
1530 typ: yaml_VERSION_DIRECTIVE_TOKEN,
1531 start_mark: start_mark,
1532 end_mark: end_mark,
1533 major: major,
1534 minor: minor,
1535 }
1536
1537
1538 } else if bytes.Equal(name, []byte("TAG")) {
1539
1540 var handle, prefix []byte
1541 if !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {
1542 return false
1543 }
1544 end_mark := parser.mark
1545
1546
1547 *token = yaml_token_t{
1548 typ: yaml_TAG_DIRECTIVE_TOKEN,
1549 start_mark: start_mark,
1550 end_mark: end_mark,
1551 value: handle,
1552 prefix: prefix,
1553 }
1554
1555
1556 } else {
1557 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1558 start_mark, "found unknown directive name")
1559 return false
1560 }
1561
1562
1563 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1564 return false
1565 }
1566
1567 for is_blank(parser.buffer, parser.buffer_pos) {
1568 skip(parser)
1569 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1570 return false
1571 }
1572 }
1573
1574 if parser.buffer[parser.buffer_pos] == '#' {
1575 for !is_breakz(parser.buffer, parser.buffer_pos) {
1576 skip(parser)
1577 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1578 return false
1579 }
1580 }
1581 }
1582
1583
1584 if !is_breakz(parser.buffer, parser.buffer_pos) {
1585 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1586 start_mark, "did not find expected comment or line break")
1587 return false
1588 }
1589
1590
1591 if is_break(parser.buffer, parser.buffer_pos) {
1592 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
1593 return false
1594 }
1595 skip_line(parser)
1596 }
1597
1598 return true
1599 }
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609 func yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {
1610
1611 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1612 return false
1613 }
1614
1615 var s []byte
1616 for is_alpha(parser.buffer, parser.buffer_pos) {
1617 s = read(parser, s)
1618 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1619 return false
1620 }
1621 }
1622
1623
1624 if len(s) == 0 {
1625 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1626 start_mark, "could not find expected directive name")
1627 return false
1628 }
1629
1630
1631 if !is_blankz(parser.buffer, parser.buffer_pos) {
1632 yaml_parser_set_scanner_error(parser, "while scanning a directive",
1633 start_mark, "found unexpected non-alphabetical character")
1634 return false
1635 }
1636 *name = s
1637 return true
1638 }
1639
1640
1641
1642
1643
1644
1645 func yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {
1646
1647 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1648 return false
1649 }
1650 for is_blank(parser.buffer, parser.buffer_pos) {
1651 skip(parser)
1652 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1653 return false
1654 }
1655 }
1656
1657
1658 if !yaml_parser_scan_version_directive_number(parser, start_mark, major) {
1659 return false
1660 }
1661
1662
1663 if parser.buffer[parser.buffer_pos] != '.' {
1664 return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
1665 start_mark, "did not find expected digit or '.' character")
1666 }
1667
1668 skip(parser)
1669
1670
1671 if !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {
1672 return false
1673 }
1674 return true
1675 }
1676
1677 const max_number_length = 2
1678
1679
1680
1681
1682
1683
1684
1685
1686 func yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {
1687
1688
1689 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1690 return false
1691 }
1692 var value, length int8
1693 for is_digit(parser.buffer, parser.buffer_pos) {
1694
1695 length++
1696 if length > max_number_length {
1697 return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
1698 start_mark, "found extremely long version number")
1699 }
1700 value = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))
1701 skip(parser)
1702 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1703 return false
1704 }
1705 }
1706
1707
1708 if length == 0 {
1709 return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
1710 start_mark, "did not find expected version number")
1711 }
1712 *number = value
1713 return true
1714 }
1715
1716
1717
1718
1719
1720
1721
1722 func yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {
1723 var handle_value, prefix_value []byte
1724
1725
1726 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1727 return false
1728 }
1729
1730 for is_blank(parser.buffer, parser.buffer_pos) {
1731 skip(parser)
1732 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1733 return false
1734 }
1735 }
1736
1737
1738 if !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {
1739 return false
1740 }
1741
1742
1743 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1744 return false
1745 }
1746 if !is_blank(parser.buffer, parser.buffer_pos) {
1747 yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
1748 start_mark, "did not find expected whitespace")
1749 return false
1750 }
1751
1752
1753 for is_blank(parser.buffer, parser.buffer_pos) {
1754 skip(parser)
1755 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1756 return false
1757 }
1758 }
1759
1760
1761 if !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {
1762 return false
1763 }
1764
1765
1766 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1767 return false
1768 }
1769 if !is_blankz(parser.buffer, parser.buffer_pos) {
1770 yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
1771 start_mark, "did not find expected whitespace or line break")
1772 return false
1773 }
1774
1775 *handle = handle_value
1776 *prefix = prefix_value
1777 return true
1778 }
1779
1780 func yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {
1781 var s []byte
1782
1783
1784 start_mark := parser.mark
1785 skip(parser)
1786
1787
1788 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1789 return false
1790 }
1791
1792 for is_alpha(parser.buffer, parser.buffer_pos) {
1793 s = read(parser, s)
1794 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1795 return false
1796 }
1797 }
1798
1799 end_mark := parser.mark
1800
1801
1807
1808 if len(s) == 0 ||
1809 !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||
1810 parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||
1811 parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||
1812 parser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||
1813 parser.buffer[parser.buffer_pos] == '`') {
1814 context := "while scanning an alias"
1815 if typ == yaml_ANCHOR_TOKEN {
1816 context = "while scanning an anchor"
1817 }
1818 yaml_parser_set_scanner_error(parser, context, start_mark,
1819 "did not find expected alphabetic or numeric character")
1820 return false
1821 }
1822
1823
1824 *token = yaml_token_t{
1825 typ: typ,
1826 start_mark: start_mark,
1827 end_mark: end_mark,
1828 value: s,
1829 }
1830
1831 return true
1832 }
1833
1834
1837
1838 func yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {
1839 var handle, suffix []byte
1840
1841 start_mark := parser.mark
1842
1843
1844 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
1845 return false
1846 }
1847
1848 if parser.buffer[parser.buffer_pos+1] == '<' {
1849
1850
1851
1852 skip(parser)
1853 skip(parser)
1854
1855
1856 if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
1857 return false
1858 }
1859
1860
1861 if parser.buffer[parser.buffer_pos] != '>' {
1862 yaml_parser_set_scanner_error(parser, "while scanning a tag",
1863 start_mark, "did not find the expected '>'")
1864 return false
1865 }
1866
1867 skip(parser)
1868 } else {
1869
1870
1871
1872 if !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {
1873 return false
1874 }
1875
1876
1877 if handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {
1878
1879 if !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {
1880 return false
1881 }
1882 } else {
1883
1884 if !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {
1885 return false
1886 }
1887
1888
1889 handle = []byte{'!'}
1890
1891
1892
1893 if len(suffix) == 0 {
1894 handle, suffix = suffix, handle
1895 }
1896 }
1897 }
1898
1899
1900 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1901 return false
1902 }
1903 if !is_blankz(parser.buffer, parser.buffer_pos) {
1904 yaml_parser_set_scanner_error(parser, "while scanning a tag",
1905 start_mark, "did not find expected whitespace or line break")
1906 return false
1907 }
1908
1909 end_mark := parser.mark
1910
1911
1912 *token = yaml_token_t{
1913 typ: yaml_TAG_TOKEN,
1914 start_mark: start_mark,
1915 end_mark: end_mark,
1916 value: handle,
1917 suffix: suffix,
1918 }
1919 return true
1920 }
1921
1922
1923 func yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {
1924
1925 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1926 return false
1927 }
1928 if parser.buffer[parser.buffer_pos] != '!' {
1929 yaml_parser_set_scanner_tag_error(parser, directive,
1930 start_mark, "did not find expected '!'")
1931 return false
1932 }
1933
1934 var s []byte
1935
1936
1937 s = read(parser, s)
1938
1939
1940 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1941 return false
1942 }
1943 for is_alpha(parser.buffer, parser.buffer_pos) {
1944 s = read(parser, s)
1945 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1946 return false
1947 }
1948 }
1949
1950
1951 if parser.buffer[parser.buffer_pos] == '!' {
1952 s = read(parser, s)
1953 } else {
1954
1955
1956 if directive && string(s) != "!" {
1957 yaml_parser_set_scanner_tag_error(parser, directive,
1958 start_mark, "did not find expected '!'")
1959 return false
1960 }
1961 }
1962
1963 *handle = s
1964 return true
1965 }
1966
1967
1968 func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
1969
1970 var s []byte
1971 hasTag := len(head) > 0
1972
1973
1974
1975
1976 if len(head) > 1 {
1977 s = append(s, head[1:]...)
1978 }
1979
1980
1981 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
1982 return false
1983 }
1984
1985
1986
1987
1988
1989
1990
1991 for is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||
1992 parser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||
1993 parser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||
1994 parser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||
1995 parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||
1996 parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||
1997 parser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||
1998 parser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\'' ||
1999 parser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||
2000 parser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||
2001 parser.buffer[parser.buffer_pos] == '%' {
2002
2003 if parser.buffer[parser.buffer_pos] == '%' {
2004 if !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {
2005 return false
2006 }
2007 } else {
2008 s = read(parser, s)
2009 }
2010 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2011 return false
2012 }
2013 hasTag = true
2014 }
2015
2016 if !hasTag {
2017 yaml_parser_set_scanner_tag_error(parser, directive,
2018 start_mark, "did not find expected tag URI")
2019 return false
2020 }
2021 *uri = s
2022 return true
2023 }
2024
2025
2026 func yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {
2027
2028
2029 w := 1024
2030 for w > 0 {
2031
2032 if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
2033 return false
2034 }
2035
2036 if !(parser.buffer[parser.buffer_pos] == '%' &&
2037 is_hex(parser.buffer, parser.buffer_pos+1) &&
2038 is_hex(parser.buffer, parser.buffer_pos+2)) {
2039 return yaml_parser_set_scanner_tag_error(parser, directive,
2040 start_mark, "did not find URI escaped octet")
2041 }
2042
2043
2044 octet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))
2045
2046
2047 if w == 1024 {
2048 w = width(octet)
2049 if w == 0 {
2050 return yaml_parser_set_scanner_tag_error(parser, directive,
2051 start_mark, "found an incorrect leading UTF-8 octet")
2052 }
2053 } else {
2054
2055 if octet&0xC0 != 0x80 {
2056 return yaml_parser_set_scanner_tag_error(parser, directive,
2057 start_mark, "found an incorrect trailing UTF-8 octet")
2058 }
2059 }
2060
2061
2062 *s = append(*s, octet)
2063 skip(parser)
2064 skip(parser)
2065 skip(parser)
2066 w--
2067 }
2068 return true
2069 }
2070
2071
2072 func yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {
2073
2074 start_mark := parser.mark
2075 skip(parser)
2076
2077
2078 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2079 return false
2080 }
2081
2082
2083 var chomping, increment int
2084 if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
2085
2086 if parser.buffer[parser.buffer_pos] == '+' {
2087 chomping = +1
2088 } else {
2089 chomping = -1
2090 }
2091 skip(parser)
2092
2093
2094 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2095 return false
2096 }
2097 if is_digit(parser.buffer, parser.buffer_pos) {
2098
2099 if parser.buffer[parser.buffer_pos] == '0' {
2100 yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2101 start_mark, "found an indentation indicator equal to 0")
2102 return false
2103 }
2104
2105
2106 increment = as_digit(parser.buffer, parser.buffer_pos)
2107 skip(parser)
2108 }
2109
2110 } else if is_digit(parser.buffer, parser.buffer_pos) {
2111
2112
2113 if parser.buffer[parser.buffer_pos] == '0' {
2114 yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2115 start_mark, "found an indentation indicator equal to 0")
2116 return false
2117 }
2118 increment = as_digit(parser.buffer, parser.buffer_pos)
2119 skip(parser)
2120
2121 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2122 return false
2123 }
2124 if parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {
2125 if parser.buffer[parser.buffer_pos] == '+' {
2126 chomping = +1
2127 } else {
2128 chomping = -1
2129 }
2130 skip(parser)
2131 }
2132 }
2133
2134
2135 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2136 return false
2137 }
2138 for is_blank(parser.buffer, parser.buffer_pos) {
2139 skip(parser)
2140 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2141 return false
2142 }
2143 }
2144 if parser.buffer[parser.buffer_pos] == '#' {
2145 for !is_breakz(parser.buffer, parser.buffer_pos) {
2146 skip(parser)
2147 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2148 return false
2149 }
2150 }
2151 }
2152
2153
2154 if !is_breakz(parser.buffer, parser.buffer_pos) {
2155 yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2156 start_mark, "did not find expected comment or line break")
2157 return false
2158 }
2159
2160
2161 if is_break(parser.buffer, parser.buffer_pos) {
2162 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2163 return false
2164 }
2165 skip_line(parser)
2166 }
2167
2168 end_mark := parser.mark
2169
2170
2171 var indent int
2172 if increment > 0 {
2173 if parser.indent >= 0 {
2174 indent = parser.indent + increment
2175 } else {
2176 indent = increment
2177 }
2178 }
2179
2180
2181 var s, leading_break, trailing_breaks []byte
2182 if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
2183 return false
2184 }
2185
2186
2187 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2188 return false
2189 }
2190 var leading_blank, trailing_blank bool
2191 for parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {
2192
2193
2194
2195 trailing_blank = is_blank(parser.buffer, parser.buffer_pos)
2196
2197
2198 if !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\n' {
2199
2200 if len(trailing_breaks) == 0 {
2201 s = append(s, ' ')
2202 }
2203 } else {
2204 s = append(s, leading_break...)
2205 }
2206 leading_break = leading_break[:0]
2207
2208
2209 s = append(s, trailing_breaks...)
2210 trailing_breaks = trailing_breaks[:0]
2211
2212
2213 leading_blank = is_blank(parser.buffer, parser.buffer_pos)
2214
2215
2216 for !is_breakz(parser.buffer, parser.buffer_pos) {
2217 s = read(parser, s)
2218 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2219 return false
2220 }
2221 }
2222
2223
2224 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2225 return false
2226 }
2227
2228 leading_break = read_line(parser, leading_break)
2229
2230
2231 if !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {
2232 return false
2233 }
2234 }
2235
2236
2237 if chomping != -1 {
2238 s = append(s, leading_break...)
2239 }
2240 if chomping == 1 {
2241 s = append(s, trailing_breaks...)
2242 }
2243
2244
2245 *token = yaml_token_t{
2246 typ: yaml_SCALAR_TOKEN,
2247 start_mark: start_mark,
2248 end_mark: end_mark,
2249 value: s,
2250 style: yaml_LITERAL_SCALAR_STYLE,
2251 }
2252 if !literal {
2253 token.style = yaml_FOLDED_SCALAR_STYLE
2254 }
2255 return true
2256 }
2257
2258
2259
2260 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 {
2261 *end_mark = parser.mark
2262
2263
2264 max_indent := 0
2265 for {
2266
2267 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2268 return false
2269 }
2270 for (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {
2271 skip(parser)
2272 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2273 return false
2274 }
2275 }
2276 if parser.mark.column > max_indent {
2277 max_indent = parser.mark.column
2278 }
2279
2280
2281 if (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {
2282 return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2283 start_mark, "found a tab character where an indentation space is expected")
2284 }
2285
2286
2287 if !is_break(parser.buffer, parser.buffer_pos) {
2288 break
2289 }
2290
2291
2292 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2293 return false
2294 }
2295
2296 *breaks = read_line(parser, *breaks)
2297 *end_mark = parser.mark
2298 }
2299
2300
2301 if *indent == 0 {
2302 *indent = max_indent
2303 if *indent < parser.indent+1 {
2304 *indent = parser.indent + 1
2305 }
2306 if *indent < 1 {
2307 *indent = 1
2308 }
2309 }
2310 return true
2311 }
2312
2313
2314 func yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {
2315
2316 start_mark := parser.mark
2317 skip(parser)
2318
2319
2320 var s, leading_break, trailing_breaks, whitespaces []byte
2321 for {
2322
2323 if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
2324 return false
2325 }
2326
2327 if parser.mark.column == 0 &&
2328 ((parser.buffer[parser.buffer_pos+0] == '-' &&
2329 parser.buffer[parser.buffer_pos+1] == '-' &&
2330 parser.buffer[parser.buffer_pos+2] == '-') ||
2331 (parser.buffer[parser.buffer_pos+0] == '.' &&
2332 parser.buffer[parser.buffer_pos+1] == '.' &&
2333 parser.buffer[parser.buffer_pos+2] == '.')) &&
2334 is_blankz(parser.buffer, parser.buffer_pos+3) {
2335 yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
2336 start_mark, "found unexpected document indicator")
2337 return false
2338 }
2339
2340
2341 if is_z(parser.buffer, parser.buffer_pos) {
2342 yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
2343 start_mark, "found unexpected end of stream")
2344 return false
2345 }
2346
2347
2348 leading_blanks := false
2349 for !is_blankz(parser.buffer, parser.buffer_pos) {
2350 if single && parser.buffer[parser.buffer_pos] == '\'' && parser.buffer[parser.buffer_pos+1] == '\'' {
2351
2352 s = append(s, '\'')
2353 skip(parser)
2354 skip(parser)
2355
2356 } else if single && parser.buffer[parser.buffer_pos] == '\'' {
2357
2358 break
2359 } else if !single && parser.buffer[parser.buffer_pos] == '"' {
2360
2361 break
2362
2363 } else if !single && parser.buffer[parser.buffer_pos] == '\\' && is_break(parser.buffer, parser.buffer_pos+1) {
2364
2365 if parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {
2366 return false
2367 }
2368 skip(parser)
2369 skip_line(parser)
2370 leading_blanks = true
2371 break
2372
2373 } else if !single && parser.buffer[parser.buffer_pos] == '\\' {
2374
2375 code_length := 0
2376
2377
2378 switch parser.buffer[parser.buffer_pos+1] {
2379 case '0':
2380 s = append(s, 0)
2381 case 'a':
2382 s = append(s, '\x07')
2383 case 'b':
2384 s = append(s, '\x08')
2385 case 't', '\t':
2386 s = append(s, '\x09')
2387 case 'n':
2388 s = append(s, '\x0A')
2389 case 'v':
2390 s = append(s, '\x0B')
2391 case 'f':
2392 s = append(s, '\x0C')
2393 case 'r':
2394 s = append(s, '\x0D')
2395 case 'e':
2396 s = append(s, '\x1B')
2397 case ' ':
2398 s = append(s, '\x20')
2399 case '"':
2400 s = append(s, '"')
2401 case '\'':
2402 s = append(s, '\'')
2403 case '\\':
2404 s = append(s, '\\')
2405 case 'N':
2406 s = append(s, '\xC2')
2407 s = append(s, '\x85')
2408 case '_':
2409 s = append(s, '\xC2')
2410 s = append(s, '\xA0')
2411 case 'L':
2412 s = append(s, '\xE2')
2413 s = append(s, '\x80')
2414 s = append(s, '\xA8')
2415 case 'P':
2416 s = append(s, '\xE2')
2417 s = append(s, '\x80')
2418 s = append(s, '\xA9')
2419 case 'x':
2420 code_length = 2
2421 case 'u':
2422 code_length = 4
2423 case 'U':
2424 code_length = 8
2425 default:
2426 yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
2427 start_mark, "found unknown escape character")
2428 return false
2429 }
2430
2431 skip(parser)
2432 skip(parser)
2433
2434
2435 if code_length > 0 {
2436 var value int
2437
2438
2439 if parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {
2440 return false
2441 }
2442 for k := 0; k < code_length; k++ {
2443 if !is_hex(parser.buffer, parser.buffer_pos+k) {
2444 yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
2445 start_mark, "did not find expected hexdecimal number")
2446 return false
2447 }
2448 value = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)
2449 }
2450
2451
2452 if (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {
2453 yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
2454 start_mark, "found invalid Unicode character escape code")
2455 return false
2456 }
2457 if value <= 0x7F {
2458 s = append(s, byte(value))
2459 } else if value <= 0x7FF {
2460 s = append(s, byte(0xC0+(value>>6)))
2461 s = append(s, byte(0x80+(value&0x3F)))
2462 } else if value <= 0xFFFF {
2463 s = append(s, byte(0xE0+(value>>12)))
2464 s = append(s, byte(0x80+((value>>6)&0x3F)))
2465 s = append(s, byte(0x80+(value&0x3F)))
2466 } else {
2467 s = append(s, byte(0xF0+(value>>18)))
2468 s = append(s, byte(0x80+((value>>12)&0x3F)))
2469 s = append(s, byte(0x80+((value>>6)&0x3F)))
2470 s = append(s, byte(0x80+(value&0x3F)))
2471 }
2472
2473
2474 for k := 0; k < code_length; k++ {
2475 skip(parser)
2476 }
2477 }
2478 } else {
2479
2480 s = read(parser, s)
2481 }
2482 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2483 return false
2484 }
2485 }
2486
2487 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2488 return false
2489 }
2490
2491
2492 if single {
2493 if parser.buffer[parser.buffer_pos] == '\'' {
2494 break
2495 }
2496 } else {
2497 if parser.buffer[parser.buffer_pos] == '"' {
2498 break
2499 }
2500 }
2501
2502
2503 for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
2504 if is_blank(parser.buffer, parser.buffer_pos) {
2505
2506 if !leading_blanks {
2507 whitespaces = read(parser, whitespaces)
2508 } else {
2509 skip(parser)
2510 }
2511 } else {
2512 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2513 return false
2514 }
2515
2516
2517 if !leading_blanks {
2518 whitespaces = whitespaces[:0]
2519 leading_break = read_line(parser, leading_break)
2520 leading_blanks = true
2521 } else {
2522 trailing_breaks = read_line(parser, trailing_breaks)
2523 }
2524 }
2525 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2526 return false
2527 }
2528 }
2529
2530
2531 if leading_blanks {
2532
2533 if len(leading_break) > 0 && leading_break[0] == '\n' {
2534 if len(trailing_breaks) == 0 {
2535 s = append(s, ' ')
2536 } else {
2537 s = append(s, trailing_breaks...)
2538 }
2539 } else {
2540 s = append(s, leading_break...)
2541 s = append(s, trailing_breaks...)
2542 }
2543 trailing_breaks = trailing_breaks[:0]
2544 leading_break = leading_break[:0]
2545 } else {
2546 s = append(s, whitespaces...)
2547 whitespaces = whitespaces[:0]
2548 }
2549 }
2550
2551
2552 skip(parser)
2553 end_mark := parser.mark
2554
2555
2556 *token = yaml_token_t{
2557 typ: yaml_SCALAR_TOKEN,
2558 start_mark: start_mark,
2559 end_mark: end_mark,
2560 value: s,
2561 style: yaml_SINGLE_QUOTED_SCALAR_STYLE,
2562 }
2563 if !single {
2564 token.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
2565 }
2566 return true
2567 }
2568
2569
2570 func yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {
2571
2572 var s, leading_break, trailing_breaks, whitespaces []byte
2573 var leading_blanks bool
2574 var indent = parser.indent + 1
2575
2576 start_mark := parser.mark
2577 end_mark := parser.mark
2578
2579
2580 for {
2581
2582 if parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {
2583 return false
2584 }
2585 if parser.mark.column == 0 &&
2586 ((parser.buffer[parser.buffer_pos+0] == '-' &&
2587 parser.buffer[parser.buffer_pos+1] == '-' &&
2588 parser.buffer[parser.buffer_pos+2] == '-') ||
2589 (parser.buffer[parser.buffer_pos+0] == '.' &&
2590 parser.buffer[parser.buffer_pos+1] == '.' &&
2591 parser.buffer[parser.buffer_pos+2] == '.')) &&
2592 is_blankz(parser.buffer, parser.buffer_pos+3) {
2593 break
2594 }
2595
2596
2597 if parser.buffer[parser.buffer_pos] == '#' {
2598 break
2599 }
2600
2601
2602 for !is_blankz(parser.buffer, parser.buffer_pos) {
2603
2604
2605 if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
2606 (parser.flow_level > 0 &&
2607 (parser.buffer[parser.buffer_pos] == ',' ||
2608 parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
2609 parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
2610 parser.buffer[parser.buffer_pos] == '}')) {
2611 break
2612 }
2613
2614
2615 if leading_blanks || len(whitespaces) > 0 {
2616 if leading_blanks {
2617
2618 if leading_break[0] == '\n' {
2619 if len(trailing_breaks) == 0 {
2620 s = append(s, ' ')
2621 } else {
2622 s = append(s, trailing_breaks...)
2623 }
2624 } else {
2625 s = append(s, leading_break...)
2626 s = append(s, trailing_breaks...)
2627 }
2628 trailing_breaks = trailing_breaks[:0]
2629 leading_break = leading_break[:0]
2630 leading_blanks = false
2631 } else {
2632 s = append(s, whitespaces...)
2633 whitespaces = whitespaces[:0]
2634 }
2635 }
2636
2637
2638 s = read(parser, s)
2639
2640 end_mark = parser.mark
2641 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2642 return false
2643 }
2644 }
2645
2646
2647 if !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {
2648 break
2649 }
2650
2651
2652 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2653 return false
2654 }
2655
2656 for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
2657 if is_blank(parser.buffer, parser.buffer_pos) {
2658
2659
2660 if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
2661 yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
2662 start_mark, "found a tab character that violates indentation")
2663 return false
2664 }
2665
2666
2667 if !leading_blanks {
2668 whitespaces = read(parser, whitespaces)
2669 } else {
2670 skip(parser)
2671 }
2672 } else {
2673 if parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {
2674 return false
2675 }
2676
2677
2678 if !leading_blanks {
2679 whitespaces = whitespaces[:0]
2680 leading_break = read_line(parser, leading_break)
2681 leading_blanks = true
2682 } else {
2683 trailing_breaks = read_line(parser, trailing_breaks)
2684 }
2685 }
2686 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2687 return false
2688 }
2689 }
2690
2691
2692 if parser.flow_level == 0 && parser.mark.column < indent {
2693 break
2694 }
2695 }
2696
2697
2698 *token = yaml_token_t{
2699 typ: yaml_SCALAR_TOKEN,
2700 start_mark: start_mark,
2701 end_mark: end_mark,
2702 value: s,
2703 style: yaml_PLAIN_SCALAR_STYLE,
2704 }
2705
2706
2707 if leading_blanks {
2708 parser.simple_key_allowed = true
2709 }
2710 return true
2711 }
2712
View as plain text