rubysl-yaml 2.0.4 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -7
- data/MRI_LICENSE +56 -0
- data/lib/rubysl/yaml.rb +1 -1
- data/lib/rubysl/yaml/version.rb +1 -1
- data/lib/yaml.rb +59 -1
- data/rubysl-yaml.gemspec +0 -1
- metadata +73 -90
- data/ext/rubysl/syck/bytecode.c +0 -1165
- data/ext/rubysl/syck/emitter.c +0 -1247
- data/ext/rubysl/syck/extconf.rb +0 -5
- data/ext/rubysl/syck/gram.c +0 -1894
- data/ext/rubysl/syck/gram.h +0 -79
- data/ext/rubysl/syck/handler.c +0 -173
- data/ext/rubysl/syck/implicit.c +0 -2990
- data/ext/rubysl/syck/node.c +0 -407
- data/ext/rubysl/syck/rubyext.c +0 -2306
- data/ext/rubysl/syck/syck.c +0 -524
- data/ext/rubysl/syck/syck.h +0 -453
- data/ext/rubysl/syck/token.c +0 -2724
- data/ext/rubysl/syck/yaml2byte.c +0 -259
- data/ext/rubysl/syck/yamlbyte.h +0 -171
- data/lib/rubysl/yaml/yaml.rb +0 -122
- data/lib/syck.rb +0 -498
- data/lib/syck/baseemitter.rb +0 -242
- data/lib/syck/basenode.rb +0 -227
- data/lib/syck/constants.rb +0 -45
- data/lib/syck/encoding.rb +0 -35
- data/lib/syck/error.rb +0 -34
- data/lib/syck/loader.rb +0 -14
- data/lib/syck/rubytypes.rb +0 -467
- data/lib/syck/stream.rb +0 -41
- data/lib/syck/tag.rb +0 -95
- data/lib/syck/types.rb +0 -192
- data/lib/syck/yamlnode.rb +0 -54
- data/lib/syck/ypath.rb +0 -54
data/ext/rubysl/syck/emitter.c
DELETED
@@ -1,1247 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* emitter.c
|
3
|
-
*
|
4
|
-
* $Author: naruse $
|
5
|
-
*
|
6
|
-
* Copyright (C) 2003 why the lucky stiff
|
7
|
-
*
|
8
|
-
* All Base64 code from Ruby's pack.c.
|
9
|
-
* Ruby is Copyright (C) 1993-2007 Yukihiro Matsumoto
|
10
|
-
*/
|
11
|
-
#include "ruby/ruby.h"
|
12
|
-
|
13
|
-
#include <stdio.h>
|
14
|
-
#include <string.h>
|
15
|
-
|
16
|
-
#include "syck.h"
|
17
|
-
|
18
|
-
#define DEFAULT_ANCHOR_FORMAT "id%03d"
|
19
|
-
|
20
|
-
const char hex_table[] =
|
21
|
-
"0123456789ABCDEF";
|
22
|
-
static char b64_table[] =
|
23
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
24
|
-
|
25
|
-
/*
|
26
|
-
* Built-in base64 (from Ruby's pack.c)
|
27
|
-
*/
|
28
|
-
char *
|
29
|
-
syck_base64enc( char *s, long len )
|
30
|
-
{
|
31
|
-
long i = 0;
|
32
|
-
int padding = '=';
|
33
|
-
char *buff = S_ALLOC_N(char, len * 4 / 3 + 6);
|
34
|
-
|
35
|
-
while (len >= 3) {
|
36
|
-
buff[i++] = b64_table[077 & (*s >> 2)];
|
37
|
-
buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
|
38
|
-
buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
|
39
|
-
buff[i++] = b64_table[077 & s[2]];
|
40
|
-
s += 3;
|
41
|
-
len -= 3;
|
42
|
-
}
|
43
|
-
if (len == 2) {
|
44
|
-
buff[i++] = b64_table[077 & (*s >> 2)];
|
45
|
-
buff[i++] = b64_table[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
|
46
|
-
buff[i++] = b64_table[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))];
|
47
|
-
buff[i++] = padding;
|
48
|
-
}
|
49
|
-
else if (len == 1) {
|
50
|
-
buff[i++] = b64_table[077 & (*s >> 2)];
|
51
|
-
buff[i++] = b64_table[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))];
|
52
|
-
buff[i++] = padding;
|
53
|
-
buff[i++] = padding;
|
54
|
-
}
|
55
|
-
buff[i++] = '\n';
|
56
|
-
return buff;
|
57
|
-
}
|
58
|
-
|
59
|
-
char *
|
60
|
-
syck_base64dec( char *s, long len )
|
61
|
-
{
|
62
|
-
int a = -1,b = -1,c = 0,d;
|
63
|
-
static int first = 1;
|
64
|
-
static int b64_xtable[256];
|
65
|
-
char *ptr = syck_strndup( s, len );
|
66
|
-
char *end = ptr;
|
67
|
-
char *send = s + len;
|
68
|
-
|
69
|
-
if (first) {
|
70
|
-
int i;
|
71
|
-
first = 0;
|
72
|
-
|
73
|
-
for (i = 0; i < 256; i++) {
|
74
|
-
b64_xtable[i] = -1;
|
75
|
-
}
|
76
|
-
for (i = 0; i < 64; i++) {
|
77
|
-
b64_xtable[(int)b64_table[i]] = i;
|
78
|
-
}
|
79
|
-
}
|
80
|
-
while (s < send) {
|
81
|
-
while (s[0] == '\r' || s[0] == '\n') { s++; }
|
82
|
-
if ((a = b64_xtable[(int)s[0]]) == -1) break;
|
83
|
-
if ((b = b64_xtable[(int)s[1]]) == -1) break;
|
84
|
-
if ((c = b64_xtable[(int)s[2]]) == -1) break;
|
85
|
-
if ((d = b64_xtable[(int)s[3]]) == -1) break;
|
86
|
-
*end++ = a << 2 | b >> 4;
|
87
|
-
*end++ = b << 4 | c >> 2;
|
88
|
-
*end++ = c << 6 | d;
|
89
|
-
s += 4;
|
90
|
-
}
|
91
|
-
if (a != -1 && b != -1) {
|
92
|
-
if (s + 2 < send && s[2] == '=')
|
93
|
-
*end++ = a << 2 | b >> 4;
|
94
|
-
if (c != -1 && s + 3 < send && s[3] == '=') {
|
95
|
-
*end++ = a << 2 | b >> 4;
|
96
|
-
*end++ = b << 4 | c >> 2;
|
97
|
-
}
|
98
|
-
}
|
99
|
-
*end = '\0';
|
100
|
-
/*RSTRING_LEN(buf) = ptr - RSTRING_PTR(buf);*/
|
101
|
-
return ptr;
|
102
|
-
}
|
103
|
-
|
104
|
-
/*
|
105
|
-
* Allocate an emitter
|
106
|
-
*/
|
107
|
-
SyckEmitter *
|
108
|
-
syck_new_emitter(void)
|
109
|
-
{
|
110
|
-
SyckEmitter *e;
|
111
|
-
e = S_ALLOC( SyckEmitter );
|
112
|
-
e->headless = 0;
|
113
|
-
e->use_header = 0;
|
114
|
-
e->use_version = 0;
|
115
|
-
e->sort_keys = 0;
|
116
|
-
e->anchor_format = NULL;
|
117
|
-
e->explicit_typing = 0;
|
118
|
-
e->best_width = 80;
|
119
|
-
e->style = scalar_none;
|
120
|
-
e->stage = doc_open;
|
121
|
-
e->indent = 2;
|
122
|
-
e->level = -1;
|
123
|
-
e->anchors = NULL;
|
124
|
-
e->markers = NULL;
|
125
|
-
e->anchored = NULL;
|
126
|
-
e->bufsize = SYCK_BUFFERSIZE;
|
127
|
-
e->buffer = NULL;
|
128
|
-
e->marker = NULL;
|
129
|
-
e->bufpos = 0;
|
130
|
-
e->emitter_handler = NULL;
|
131
|
-
e->output_handler = NULL;
|
132
|
-
e->lvl_idx = 0;
|
133
|
-
e->lvl_capa = ALLOC_CT;
|
134
|
-
e->levels = S_ALLOC_N( SyckLevel, e->lvl_capa );
|
135
|
-
syck_emitter_reset_levels( e );
|
136
|
-
e->bonus = NULL;
|
137
|
-
return e;
|
138
|
-
}
|
139
|
-
|
140
|
-
int
|
141
|
-
syck_st_free_anchors( char *key, char *name, char *arg )
|
142
|
-
{
|
143
|
-
S_FREE( name );
|
144
|
-
return ST_CONTINUE;
|
145
|
-
}
|
146
|
-
|
147
|
-
void
|
148
|
-
syck_emitter_st_free( SyckEmitter *e )
|
149
|
-
{
|
150
|
-
/*
|
151
|
-
* Free the anchor tables
|
152
|
-
*/
|
153
|
-
if ( e->anchors != NULL )
|
154
|
-
{
|
155
|
-
st_foreach( e->anchors, syck_st_free_anchors, 0 );
|
156
|
-
st_free_table( e->anchors );
|
157
|
-
e->anchors = NULL;
|
158
|
-
}
|
159
|
-
|
160
|
-
if ( e->anchored != NULL )
|
161
|
-
{
|
162
|
-
st_free_table( e->anchored );
|
163
|
-
e->anchored = NULL;
|
164
|
-
}
|
165
|
-
|
166
|
-
/*
|
167
|
-
* Free the markers tables
|
168
|
-
*/
|
169
|
-
if ( e->markers != NULL )
|
170
|
-
{
|
171
|
-
st_free_table( e->markers );
|
172
|
-
e->markers = NULL;
|
173
|
-
}
|
174
|
-
}
|
175
|
-
|
176
|
-
SyckLevel *
|
177
|
-
syck_emitter_current_level( SyckEmitter *e )
|
178
|
-
{
|
179
|
-
return &e->levels[e->lvl_idx-1];
|
180
|
-
}
|
181
|
-
|
182
|
-
SyckLevel *
|
183
|
-
syck_emitter_parent_level( SyckEmitter *e )
|
184
|
-
{
|
185
|
-
return &e->levels[e->lvl_idx-2];
|
186
|
-
}
|
187
|
-
|
188
|
-
void
|
189
|
-
syck_emitter_pop_level( SyckEmitter *e )
|
190
|
-
{
|
191
|
-
ASSERT( e != NULL );
|
192
|
-
|
193
|
-
/* The root level should never be popped */
|
194
|
-
if ( e->lvl_idx <= 1 ) return;
|
195
|
-
|
196
|
-
e->lvl_idx -= 1;
|
197
|
-
free( e->levels[e->lvl_idx].domain );
|
198
|
-
}
|
199
|
-
|
200
|
-
void
|
201
|
-
syck_emitter_add_level( SyckEmitter *e, int len, enum syck_level_status status )
|
202
|
-
{
|
203
|
-
ASSERT( e != NULL );
|
204
|
-
if ( e->lvl_idx + 1 > e->lvl_capa )
|
205
|
-
{
|
206
|
-
e->lvl_capa += ALLOC_CT;
|
207
|
-
S_REALLOC_N( e->levels, SyckLevel, e->lvl_capa );
|
208
|
-
}
|
209
|
-
|
210
|
-
ASSERT( len > e->levels[e->lvl_idx-1].spaces );
|
211
|
-
e->levels[e->lvl_idx].spaces = len;
|
212
|
-
e->levels[e->lvl_idx].ncount = 0;
|
213
|
-
e->levels[e->lvl_idx].domain = syck_strndup( e->levels[e->lvl_idx-1].domain, strlen( e->levels[e->lvl_idx-1].domain ) );
|
214
|
-
e->levels[e->lvl_idx].status = status;
|
215
|
-
e->levels[e->lvl_idx].anctag = 0;
|
216
|
-
e->lvl_idx += 1;
|
217
|
-
}
|
218
|
-
|
219
|
-
void
|
220
|
-
syck_emitter_reset_levels( SyckEmitter *e )
|
221
|
-
{
|
222
|
-
while ( e->lvl_idx > 1 )
|
223
|
-
{
|
224
|
-
syck_emitter_pop_level( e );
|
225
|
-
}
|
226
|
-
|
227
|
-
if ( e->lvl_idx < 1 )
|
228
|
-
{
|
229
|
-
e->lvl_idx = 1;
|
230
|
-
e->levels[0].spaces = -1;
|
231
|
-
e->levels[0].ncount = 0;
|
232
|
-
e->levels[0].domain = syck_strndup( "", 0 );
|
233
|
-
e->levels[0].anctag = 0;
|
234
|
-
}
|
235
|
-
e->levels[0].status = syck_lvl_header;
|
236
|
-
}
|
237
|
-
|
238
|
-
void
|
239
|
-
syck_emitter_handler( SyckEmitter *e, SyckEmitterHandler hdlr )
|
240
|
-
{
|
241
|
-
e->emitter_handler = hdlr;
|
242
|
-
}
|
243
|
-
|
244
|
-
void
|
245
|
-
syck_output_handler( SyckEmitter *e, SyckOutputHandler hdlr )
|
246
|
-
{
|
247
|
-
e->output_handler = hdlr;
|
248
|
-
}
|
249
|
-
|
250
|
-
void
|
251
|
-
syck_free_emitter( SyckEmitter *e )
|
252
|
-
{
|
253
|
-
/*
|
254
|
-
* Free tables
|
255
|
-
*/
|
256
|
-
syck_emitter_st_free( e );
|
257
|
-
syck_emitter_reset_levels( e );
|
258
|
-
S_FREE( e->levels[0].domain );
|
259
|
-
S_FREE( e->levels );
|
260
|
-
if ( e->buffer != NULL )
|
261
|
-
{
|
262
|
-
S_FREE( e->buffer );
|
263
|
-
}
|
264
|
-
S_FREE( e );
|
265
|
-
}
|
266
|
-
|
267
|
-
void
|
268
|
-
syck_emitter_clear( SyckEmitter *e )
|
269
|
-
{
|
270
|
-
if ( e->buffer == NULL )
|
271
|
-
{
|
272
|
-
e->buffer = S_ALLOC_N( char, e->bufsize );
|
273
|
-
S_MEMZERO( e->buffer, char, e->bufsize );
|
274
|
-
}
|
275
|
-
e->buffer[0] = '\0';
|
276
|
-
e->marker = e->buffer;
|
277
|
-
e->bufpos = 0;
|
278
|
-
}
|
279
|
-
|
280
|
-
/*
|
281
|
-
* Raw write to the emitter buffer.
|
282
|
-
*/
|
283
|
-
void
|
284
|
-
syck_emitter_write( SyckEmitter *e, const char *str, long len )
|
285
|
-
{
|
286
|
-
long at;
|
287
|
-
ASSERT( str != NULL );
|
288
|
-
if ( e->buffer == NULL )
|
289
|
-
{
|
290
|
-
syck_emitter_clear( e );
|
291
|
-
}
|
292
|
-
|
293
|
-
/*
|
294
|
-
* Flush if at end of buffer
|
295
|
-
*/
|
296
|
-
at = e->marker - e->buffer;
|
297
|
-
if ( len + at >= (long)e->bufsize )
|
298
|
-
{
|
299
|
-
syck_emitter_flush( e, 0 );
|
300
|
-
for (;;) {
|
301
|
-
long rest = e->bufsize - (e->marker - e->buffer);
|
302
|
-
if (len <= rest) break;
|
303
|
-
S_MEMCPY( e->marker, str, char, rest );
|
304
|
-
e->marker += rest;
|
305
|
-
str += rest;
|
306
|
-
len -= rest;
|
307
|
-
syck_emitter_flush( e, 0 );
|
308
|
-
}
|
309
|
-
}
|
310
|
-
|
311
|
-
/*
|
312
|
-
* Write to buffer
|
313
|
-
*/
|
314
|
-
S_MEMCPY( e->marker, str, char, len );
|
315
|
-
e->marker += len;
|
316
|
-
}
|
317
|
-
|
318
|
-
/*
|
319
|
-
* Write a chunk of data out.
|
320
|
-
*/
|
321
|
-
void
|
322
|
-
syck_emitter_flush( SyckEmitter *e, long check_room )
|
323
|
-
{
|
324
|
-
/*
|
325
|
-
* Check for enough space in the buffer for check_room length.
|
326
|
-
*/
|
327
|
-
if ( check_room > 0 )
|
328
|
-
{
|
329
|
-
if ( (long)e->bufsize > ( e->marker - e->buffer ) + check_room )
|
330
|
-
{
|
331
|
-
return;
|
332
|
-
}
|
333
|
-
}
|
334
|
-
else
|
335
|
-
{
|
336
|
-
check_room = e->bufsize;
|
337
|
-
}
|
338
|
-
|
339
|
-
/*
|
340
|
-
* Commit buffer.
|
341
|
-
*/
|
342
|
-
if ( check_room > e->marker - e->buffer )
|
343
|
-
{
|
344
|
-
check_room = e->marker - e->buffer;
|
345
|
-
}
|
346
|
-
(e->output_handler)( e, e->buffer, check_room );
|
347
|
-
e->bufpos += check_room;
|
348
|
-
e->marker -= check_room;
|
349
|
-
}
|
350
|
-
|
351
|
-
/*
|
352
|
-
* Start emitting from the given node, check for anchoring and then
|
353
|
-
* issue the callback to the emitter handler.
|
354
|
-
*/
|
355
|
-
void
|
356
|
-
syck_emit( SyckEmitter *e, st_data_t n )
|
357
|
-
{
|
358
|
-
SYMID oid;
|
359
|
-
char *anchor_name = NULL;
|
360
|
-
int indent = 0;
|
361
|
-
long x = 0;
|
362
|
-
SyckLevel *lvl = syck_emitter_current_level( e );
|
363
|
-
|
364
|
-
/*
|
365
|
-
* Determine headers.
|
366
|
-
*/
|
367
|
-
if ( e->stage == doc_open && ( e->headless == 0 || e->use_header == 1 ) )
|
368
|
-
{
|
369
|
-
if ( e->use_version == 1 )
|
370
|
-
{
|
371
|
-
char *header = S_ALLOC_N( char, 64 );
|
372
|
-
S_MEMZERO( header, char, 64 );
|
373
|
-
sprintf( header, "--- %%YAML:%d.%d ", SYCK_YAML_MAJOR, SYCK_YAML_MINOR );
|
374
|
-
syck_emitter_write( e, header, strlen( header ) );
|
375
|
-
S_FREE( header );
|
376
|
-
}
|
377
|
-
else
|
378
|
-
{
|
379
|
-
syck_emitter_write( e, "--- ", 4 );
|
380
|
-
}
|
381
|
-
e->stage = doc_processing;
|
382
|
-
}
|
383
|
-
|
384
|
-
/* Add new level */
|
385
|
-
if ( lvl->spaces >= 0 ) {
|
386
|
-
indent = lvl->spaces + e->indent;
|
387
|
-
}
|
388
|
-
syck_emitter_add_level( e, indent, syck_lvl_open );
|
389
|
-
lvl = syck_emitter_current_level( e );
|
390
|
-
|
391
|
-
/* Look for anchor */
|
392
|
-
if ( e->anchors != NULL &&
|
393
|
-
st_lookup( e->markers, n, (st_data_t *)&oid ) &&
|
394
|
-
st_lookup( e->anchors, (st_data_t)oid, (void *)&anchor_name ) )
|
395
|
-
{
|
396
|
-
if ( e->anchored == NULL )
|
397
|
-
{
|
398
|
-
e->anchored = st_init_numtable();
|
399
|
-
}
|
400
|
-
|
401
|
-
if ( ! st_lookup( e->anchored, (st_data_t)anchor_name, (st_data_t *)&x ) )
|
402
|
-
{
|
403
|
-
char *an = S_ALLOC_N( char, strlen( anchor_name ) + 3 );
|
404
|
-
sprintf( an, "&%s ", anchor_name );
|
405
|
-
syck_emitter_write( e, an, strlen( anchor_name ) + 2 );
|
406
|
-
free( an );
|
407
|
-
|
408
|
-
x = 1;
|
409
|
-
st_insert( e->anchored, (st_data_t)anchor_name, (st_data_t)x );
|
410
|
-
lvl->anctag = 1;
|
411
|
-
}
|
412
|
-
else
|
413
|
-
{
|
414
|
-
char *an = S_ALLOC_N( char, strlen( anchor_name ) + 2 );
|
415
|
-
sprintf( an, "*%s", anchor_name );
|
416
|
-
syck_emitter_write( e, an, strlen( anchor_name ) + 1 );
|
417
|
-
free( an );
|
418
|
-
|
419
|
-
goto end_emit;
|
420
|
-
}
|
421
|
-
}
|
422
|
-
|
423
|
-
(e->emitter_handler)( e, n );
|
424
|
-
|
425
|
-
/* Pop the level */
|
426
|
-
end_emit:
|
427
|
-
syck_emitter_pop_level( e );
|
428
|
-
if ( e->lvl_idx == 1 ) {
|
429
|
-
syck_emitter_write( e, "\n", 1 );
|
430
|
-
e->headless = 0;
|
431
|
-
e->stage = doc_open;
|
432
|
-
}
|
433
|
-
}
|
434
|
-
|
435
|
-
/*
|
436
|
-
* Determine what tag needs to be written, based on the taguri of the node
|
437
|
-
* and the implicit tag which would be assigned to this node. If a tag is
|
438
|
-
* required, write the tag.
|
439
|
-
*/
|
440
|
-
void syck_emit_tag( SyckEmitter *e, const char *tag, const char *ignore )
|
441
|
-
{
|
442
|
-
SyckLevel *lvl;
|
443
|
-
if ( tag == NULL ) return;
|
444
|
-
if ( ignore != NULL && syck_tagcmp( tag, ignore ) == 0 && e->explicit_typing == 0 ) return;
|
445
|
-
lvl = syck_emitter_current_level( e );
|
446
|
-
|
447
|
-
/* implicit */
|
448
|
-
if ( strlen( tag ) == 0 ) {
|
449
|
-
syck_emitter_write( e, "! ", 2 );
|
450
|
-
|
451
|
-
/* global types */
|
452
|
-
} else if ( strncmp( tag, "tag:", 4 ) == 0 ) {
|
453
|
-
int taglen = (int)strlen( tag );
|
454
|
-
syck_emitter_write( e, "!", 1 );
|
455
|
-
if ( strncmp( tag + 4, YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) {
|
456
|
-
int skip = 4 + strlen( YAML_DOMAIN ) + 1;
|
457
|
-
syck_emitter_write( e, tag + skip, taglen - skip );
|
458
|
-
} else {
|
459
|
-
const char *subd = tag + 4;
|
460
|
-
while ( *subd != ':' && *subd != '\0' ) subd++;
|
461
|
-
if ( *subd == ':' ) {
|
462
|
-
if ( subd - tag > ( (long)( strlen( YAML_DOMAIN ) + 5 )) &&
|
463
|
-
strncmp( subd - strlen( YAML_DOMAIN ), YAML_DOMAIN, strlen( YAML_DOMAIN ) ) == 0 ) {
|
464
|
-
syck_emitter_write( e, tag + 4, subd - strlen( YAML_DOMAIN ) - ( tag + 4 ) - 1 );
|
465
|
-
syck_emitter_write( e, "/", 1 );
|
466
|
-
syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) );
|
467
|
-
} else {
|
468
|
-
syck_emitter_write( e, tag + 4, subd - ( tag + 4 ) );
|
469
|
-
syck_emitter_write( e, "/", 1 );
|
470
|
-
syck_emitter_write( e, subd + 1, ( tag + taglen ) - ( subd + 1 ) );
|
471
|
-
}
|
472
|
-
} else {
|
473
|
-
/* TODO: Invalid tag (no colon after domain) */
|
474
|
-
return;
|
475
|
-
}
|
476
|
-
}
|
477
|
-
syck_emitter_write( e, " ", 1 );
|
478
|
-
|
479
|
-
/* private types */
|
480
|
-
} else if ( strncmp( tag, "x-private:", 10 ) == 0 ) {
|
481
|
-
syck_emitter_write( e, "!!", 2 );
|
482
|
-
syck_emitter_write( e, tag + 10, strlen( tag ) - 10 );
|
483
|
-
syck_emitter_write( e, " ", 1 );
|
484
|
-
}
|
485
|
-
lvl->anctag = 1;
|
486
|
-
}
|
487
|
-
|
488
|
-
/*
|
489
|
-
* Emit a newline and an appropriately spaced indent.
|
490
|
-
*/
|
491
|
-
void syck_emit_indent( SyckEmitter *e )
|
492
|
-
{
|
493
|
-
int i;
|
494
|
-
SyckLevel *lvl = syck_emitter_current_level( e );
|
495
|
-
if ( e->bufpos == 0 && ( e->marker - e->buffer ) == 0 ) return;
|
496
|
-
if ( lvl->spaces >= 0 ) {
|
497
|
-
char *spcs = S_ALLOC_N( char, lvl->spaces + 2 );
|
498
|
-
|
499
|
-
spcs[0] = '\n'; spcs[lvl->spaces + 1] = '\0';
|
500
|
-
for ( i = 0; i < lvl->spaces; i++ ) spcs[i+1] = ' ';
|
501
|
-
syck_emitter_write( e, spcs, lvl->spaces + 1 );
|
502
|
-
free( spcs );
|
503
|
-
}
|
504
|
-
}
|
505
|
-
|
506
|
-
/* Clear the scan */
|
507
|
-
#define SCAN_NONE 0
|
508
|
-
/* All printable characters? */
|
509
|
-
#define SCAN_NONPRINT 1
|
510
|
-
/* Any indented lines? */
|
511
|
-
#define SCAN_INDENTED 2
|
512
|
-
/* Larger than the requested width? */
|
513
|
-
#define SCAN_WIDE 4
|
514
|
-
/* Opens or closes with whitespace? */
|
515
|
-
#define SCAN_WHITEEDGE 8
|
516
|
-
/* Contains a newline */
|
517
|
-
#define SCAN_NEWLINE 16
|
518
|
-
/* Contains a single quote */
|
519
|
-
#define SCAN_SINGLEQ 32
|
520
|
-
/* Contains a double quote */
|
521
|
-
#define SCAN_DOUBLEQ 64
|
522
|
-
/* Starts with a token */
|
523
|
-
#define SCAN_INDIC_S 128
|
524
|
-
/* Contains a flow indicator */
|
525
|
-
#define SCAN_INDIC_C 256
|
526
|
-
/* Ends without newlines */
|
527
|
-
#define SCAN_NONL_E 512
|
528
|
-
/* Ends with many newlines */
|
529
|
-
#define SCAN_MANYNL_E 1024
|
530
|
-
/* Contains flow map indicators */
|
531
|
-
#define SCAN_FLOWMAP 2048
|
532
|
-
/* Contains flow seq indicators */
|
533
|
-
#define SCAN_FLOWSEQ 4096
|
534
|
-
/* Contains a valid doc separator */
|
535
|
-
#define SCAN_DOCSEP 8192
|
536
|
-
|
537
|
-
/*
|
538
|
-
* Basic printable test for LATIN-1 characters.
|
539
|
-
*/
|
540
|
-
int
|
541
|
-
syck_scan_scalar( int req_width, const char *cursor, long len )
|
542
|
-
{
|
543
|
-
long i = 0, start = 0;
|
544
|
-
int flags = SCAN_NONE;
|
545
|
-
|
546
|
-
if ( len < 1 ) return flags;
|
547
|
-
|
548
|
-
/* c-indicators from the spec */
|
549
|
-
if ( cursor[0] == '[' || cursor[0] == ']' ||
|
550
|
-
cursor[0] == '{' || cursor[0] == '}' ||
|
551
|
-
cursor[0] == '!' || cursor[0] == '*' ||
|
552
|
-
cursor[0] == '&' || cursor[0] == '|' ||
|
553
|
-
cursor[0] == '>' || cursor[0] == '\'' ||
|
554
|
-
cursor[0] == '"' || cursor[0] == '#' ||
|
555
|
-
cursor[0] == '%' || cursor[0] == '@' ||
|
556
|
-
cursor[0] == '&' ) {
|
557
|
-
flags |= SCAN_INDIC_S;
|
558
|
-
}
|
559
|
-
if ( ( cursor[0] == '-' || cursor[0] == ':' ||
|
560
|
-
cursor[0] == '?' || cursor[0] == ',' ) &&
|
561
|
-
( len == 1 || cursor[1] == ' ' || cursor[1] == '\n' ) )
|
562
|
-
{
|
563
|
-
flags |= SCAN_INDIC_S;
|
564
|
-
}
|
565
|
-
|
566
|
-
/* whitespace edges */
|
567
|
-
if ( cursor[len-1] != '\n' ) {
|
568
|
-
flags |= SCAN_NONL_E;
|
569
|
-
} else if ( len > 1 && cursor[len-2] == '\n' ) {
|
570
|
-
flags |= SCAN_MANYNL_E;
|
571
|
-
}
|
572
|
-
if (
|
573
|
-
( len > 0 && ( cursor[0] == ' ' || cursor[0] == '\t' || cursor[0] == '\n' || cursor[0] == '\r' ) ) ||
|
574
|
-
( len > 1 && ( cursor[len-1] == ' ' || cursor[len-1] == '\t' ) )
|
575
|
-
) {
|
576
|
-
flags |= SCAN_WHITEEDGE;
|
577
|
-
}
|
578
|
-
|
579
|
-
/* opening doc sep */
|
580
|
-
if ( len >= 3 && strncmp( cursor, "---", 3 ) == 0 )
|
581
|
-
flags |= SCAN_DOCSEP;
|
582
|
-
|
583
|
-
/* scan string */
|
584
|
-
for ( i = 0; i < len; i++ ) {
|
585
|
-
|
586
|
-
if ( ! ( cursor[i] == 0x9 ||
|
587
|
-
cursor[i] == 0xA ||
|
588
|
-
cursor[i] == 0xD ||
|
589
|
-
( cursor[i] >= 0x20 && cursor[i] <= 0x7E ) )
|
590
|
-
) {
|
591
|
-
flags |= SCAN_NONPRINT;
|
592
|
-
}
|
593
|
-
else if ( cursor[i] == '\n' ) {
|
594
|
-
flags |= SCAN_NEWLINE;
|
595
|
-
if ( len - i >= 3 && strncmp( &cursor[i+1], "---", 3 ) == 0 )
|
596
|
-
flags |= SCAN_DOCSEP;
|
597
|
-
if ( cursor[i+1] == ' ' || cursor[i+1] == '\t' )
|
598
|
-
flags |= SCAN_INDENTED;
|
599
|
-
if ( req_width > 0 && i - start > req_width )
|
600
|
-
flags |= SCAN_WIDE;
|
601
|
-
start = i;
|
602
|
-
}
|
603
|
-
else if ( cursor[i] == '\'' )
|
604
|
-
{
|
605
|
-
flags |= SCAN_SINGLEQ;
|
606
|
-
}
|
607
|
-
else if ( cursor[i] == '"' )
|
608
|
-
{
|
609
|
-
flags |= SCAN_DOUBLEQ;
|
610
|
-
}
|
611
|
-
else if ( cursor[i] == ']' )
|
612
|
-
{
|
613
|
-
flags |= SCAN_FLOWSEQ;
|
614
|
-
}
|
615
|
-
else if ( cursor[i] == '}' )
|
616
|
-
{
|
617
|
-
flags |= SCAN_FLOWMAP;
|
618
|
-
}
|
619
|
-
/* remember, if plain collections get implemented, to add nb-plain-flow-char */
|
620
|
-
else if ( ( cursor[i] == ' ' && cursor[i+1] == '#' ) ||
|
621
|
-
( cursor[i] == ':' &&
|
622
|
-
( cursor[i+1] == ' ' || cursor[i+1] == '\n' || i == len - 1 ) ) )
|
623
|
-
{
|
624
|
-
flags |= SCAN_INDIC_C;
|
625
|
-
}
|
626
|
-
else if ( cursor[i] == ',' &&
|
627
|
-
( cursor[i+1] == ' ' || cursor[i+1] == '\n' || i == len - 1 ) )
|
628
|
-
{
|
629
|
-
flags |= SCAN_FLOWMAP;
|
630
|
-
flags |= SCAN_FLOWSEQ;
|
631
|
-
}
|
632
|
-
}
|
633
|
-
|
634
|
-
/* printf( "---STR---\n%s\nFLAGS: %d\n", cursor, flags ); */
|
635
|
-
return flags;
|
636
|
-
}
|
637
|
-
/*
|
638
|
-
* All scalars should be emitted through this function, which determines an appropriate style,
|
639
|
-
* tag and indent.
|
640
|
-
*/
|
641
|
-
void syck_emit_scalar( SyckEmitter *e, const char *tag, enum scalar_style force_style, int force_indent, int force_width,
|
642
|
-
char keep_nl, const char *str, long len )
|
643
|
-
{
|
644
|
-
enum scalar_style favor_style = scalar_literal;
|
645
|
-
SyckLevel *parent = syck_emitter_parent_level( e );
|
646
|
-
SyckLevel *lvl = syck_emitter_current_level( e );
|
647
|
-
int scan = 0;
|
648
|
-
const char *match_implicit;
|
649
|
-
char *implicit;
|
650
|
-
|
651
|
-
if ( str == NULL ) str = "";
|
652
|
-
|
653
|
-
/* No empty nulls as map keys */
|
654
|
-
if ( len == 0 && ( parent->status == syck_lvl_map || parent->status == syck_lvl_imap ) &&
|
655
|
-
parent->ncount % 2 == 1 && syck_tagcmp( tag, "tag:yaml.org,2002:null" ) == 0 )
|
656
|
-
{
|
657
|
-
str = "~";
|
658
|
-
len = 1;
|
659
|
-
}
|
660
|
-
|
661
|
-
scan = syck_scan_scalar( force_width, str, len );
|
662
|
-
match_implicit = syck_match_implicit( str, len );
|
663
|
-
|
664
|
-
/* quote strings which default to implicits */
|
665
|
-
implicit = syck_taguri( YAML_DOMAIN, match_implicit, (int)strlen( match_implicit ) );
|
666
|
-
if ( syck_tagcmp( tag, implicit ) != 0 && syck_tagcmp( tag, "tag:yaml.org,2002:str" ) == 0 ) {
|
667
|
-
force_style = scalar_2quote;
|
668
|
-
} else {
|
669
|
-
/* complex key */
|
670
|
-
if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 &&
|
671
|
-
( !( tag == NULL ||
|
672
|
-
( implicit != NULL && syck_tagcmp( tag, implicit ) == 0 && e->explicit_typing == 0 ) ) ) )
|
673
|
-
{
|
674
|
-
syck_emitter_write( e, "? ", 2 );
|
675
|
-
parent->status = syck_lvl_mapx;
|
676
|
-
}
|
677
|
-
syck_emit_tag( e, tag, implicit );
|
678
|
-
}
|
679
|
-
S_FREE( implicit );
|
680
|
-
|
681
|
-
/* if still arbitrary, sniff a good block style. */
|
682
|
-
if ( force_style == scalar_none ) {
|
683
|
-
if ( scan & SCAN_NEWLINE ) {
|
684
|
-
force_style = scalar_literal;
|
685
|
-
} else {
|
686
|
-
force_style = scalar_plain;
|
687
|
-
}
|
688
|
-
}
|
689
|
-
|
690
|
-
if ( e->style == scalar_fold ) {
|
691
|
-
favor_style = scalar_fold;
|
692
|
-
}
|
693
|
-
|
694
|
-
/* Determine block style */
|
695
|
-
if ( scan & SCAN_NONPRINT ) {
|
696
|
-
force_style = scalar_2quote;
|
697
|
-
} else if ( scan & SCAN_WHITEEDGE ) {
|
698
|
-
force_style = scalar_2quote;
|
699
|
-
} else if ( force_style != scalar_fold && ( scan & SCAN_INDENTED ) ) {
|
700
|
-
force_style = scalar_literal;
|
701
|
-
} else if ( force_style == scalar_plain && ( scan & SCAN_NEWLINE ) ) {
|
702
|
-
force_style = favor_style;
|
703
|
-
} else if ( force_style == scalar_plain && parent->status == syck_lvl_iseq && ( scan & SCAN_FLOWSEQ ) ) {
|
704
|
-
force_style = scalar_2quote;
|
705
|
-
} else if ( force_style == scalar_plain && parent->status == syck_lvl_imap && ( scan & SCAN_FLOWMAP ) ) {
|
706
|
-
force_style = scalar_2quote;
|
707
|
-
/* } else if ( force_style == scalar_fold && ( ! ( scan & SCAN_WIDE ) ) ) {
|
708
|
-
force_style = scalar_literal; */
|
709
|
-
} else if ( force_style == scalar_plain && ( scan & SCAN_INDIC_S || scan & SCAN_INDIC_C ) ) {
|
710
|
-
if ( scan & SCAN_NEWLINE ) {
|
711
|
-
force_style = favor_style;
|
712
|
-
} else {
|
713
|
-
force_style = scalar_2quote;
|
714
|
-
}
|
715
|
-
}
|
716
|
-
|
717
|
-
if ( force_indent > 0 ) {
|
718
|
-
lvl->spaces = parent->spaces + force_indent;
|
719
|
-
} else if ( scan & SCAN_DOCSEP ) {
|
720
|
-
lvl->spaces = parent->spaces + e->indent;
|
721
|
-
}
|
722
|
-
|
723
|
-
/* For now, all ambiguous keys are going to be double-quoted */
|
724
|
-
if ( ( parent->status == syck_lvl_map || parent->status == syck_lvl_mapx ) && parent->ncount % 2 == 1 ) {
|
725
|
-
if ( force_style != scalar_plain ) {
|
726
|
-
force_style = scalar_2quote;
|
727
|
-
}
|
728
|
-
}
|
729
|
-
|
730
|
-
/* If the parent is an inline, double quote anything complex */
|
731
|
-
if ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) {
|
732
|
-
if ( force_style != scalar_plain && force_style != scalar_1quote ) {
|
733
|
-
force_style = scalar_2quote;
|
734
|
-
}
|
735
|
-
}
|
736
|
-
|
737
|
-
/* Fix the ending newlines */
|
738
|
-
if ( scan & SCAN_NONL_E ) {
|
739
|
-
keep_nl = NL_CHOMP;
|
740
|
-
} else if ( scan & SCAN_MANYNL_E ) {
|
741
|
-
keep_nl = NL_KEEP;
|
742
|
-
}
|
743
|
-
|
744
|
-
/* Write the text node */
|
745
|
-
switch ( force_style )
|
746
|
-
{
|
747
|
-
case scalar_1quote:
|
748
|
-
syck_emit_1quoted( e, force_width, str, len );
|
749
|
-
break;
|
750
|
-
|
751
|
-
case scalar_none:
|
752
|
-
case scalar_2quote:
|
753
|
-
syck_emit_2quoted( e, force_width, str, len );
|
754
|
-
break;
|
755
|
-
|
756
|
-
case scalar_fold:
|
757
|
-
syck_emit_folded( e, force_width, keep_nl, str, len );
|
758
|
-
break;
|
759
|
-
|
760
|
-
case scalar_literal:
|
761
|
-
syck_emit_literal( e, keep_nl, str, len );
|
762
|
-
break;
|
763
|
-
|
764
|
-
case scalar_plain:
|
765
|
-
syck_emitter_write( e, str, len );
|
766
|
-
break;
|
767
|
-
}
|
768
|
-
|
769
|
-
if ( parent->status == syck_lvl_mapx )
|
770
|
-
{
|
771
|
-
syck_emitter_write( e, "\n", 1 );
|
772
|
-
}
|
773
|
-
}
|
774
|
-
|
775
|
-
void
|
776
|
-
syck_emitter_escape( SyckEmitter *e, const char *src, long len )
|
777
|
-
{
|
778
|
-
int i;
|
779
|
-
for( i = 0; i < len; i++ )
|
780
|
-
{
|
781
|
-
if( (src[i] < 0x20) || (0x7E < src[i]) )
|
782
|
-
{
|
783
|
-
syck_emitter_write( e, "\\", 1 );
|
784
|
-
if( '\0' == src[i] )
|
785
|
-
syck_emitter_write( e, "0", 1 );
|
786
|
-
else
|
787
|
-
{
|
788
|
-
syck_emitter_write( e, "x", 1 );
|
789
|
-
syck_emitter_write( e, (const char *)hex_table + ((src[i] & 0xF0) >> 4), 1 );
|
790
|
-
syck_emitter_write( e, (const char *)hex_table + (src[i] & 0x0F), 1 );
|
791
|
-
}
|
792
|
-
}
|
793
|
-
else
|
794
|
-
{
|
795
|
-
syck_emitter_write( e, src + i, 1 );
|
796
|
-
if( '\\' == src[i] )
|
797
|
-
syck_emitter_write( e, "\\", 1 );
|
798
|
-
}
|
799
|
-
}
|
800
|
-
}
|
801
|
-
|
802
|
-
/*
|
803
|
-
* Outputs a single-quoted block.
|
804
|
-
*/
|
805
|
-
void
|
806
|
-
syck_emit_1quoted( SyckEmitter *e, int width, const char *str, long len )
|
807
|
-
{
|
808
|
-
char do_indent = 0;
|
809
|
-
const char *mark = str;
|
810
|
-
const char *start = str;
|
811
|
-
const char *end = str;
|
812
|
-
syck_emitter_write( e, "'", 1 );
|
813
|
-
while ( mark < str + len ) {
|
814
|
-
if ( do_indent ) {
|
815
|
-
syck_emit_indent( e );
|
816
|
-
do_indent = 0;
|
817
|
-
}
|
818
|
-
switch ( *mark ) {
|
819
|
-
case '\'': syck_emitter_write( e, "'", 1 ); break;
|
820
|
-
|
821
|
-
case '\n':
|
822
|
-
end = mark + 1;
|
823
|
-
if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) {
|
824
|
-
syck_emitter_write( e, "\n\n", 2 );
|
825
|
-
} else {
|
826
|
-
syck_emitter_write( e, "\n", 1 );
|
827
|
-
}
|
828
|
-
do_indent = 1;
|
829
|
-
start = mark + 1;
|
830
|
-
break;
|
831
|
-
|
832
|
-
case ' ':
|
833
|
-
if ( width > 0 && *start != ' ' && mark - end > width ) {
|
834
|
-
do_indent = 1;
|
835
|
-
end = mark + 1;
|
836
|
-
} else {
|
837
|
-
syck_emitter_write( e, " ", 1 );
|
838
|
-
}
|
839
|
-
break;
|
840
|
-
|
841
|
-
default:
|
842
|
-
syck_emitter_write( e, mark, 1 );
|
843
|
-
break;
|
844
|
-
}
|
845
|
-
mark++;
|
846
|
-
}
|
847
|
-
syck_emitter_write( e, "'", 1 );
|
848
|
-
}
|
849
|
-
|
850
|
-
/*
|
851
|
-
* Outputs a double-quoted block.
|
852
|
-
*/
|
853
|
-
void
|
854
|
-
syck_emit_2quoted( SyckEmitter *e, int width, const char *str, long len )
|
855
|
-
{
|
856
|
-
char do_indent = 0;
|
857
|
-
const char *mark = str;
|
858
|
-
const char *start = str;
|
859
|
-
const char *end = str;
|
860
|
-
syck_emitter_write( e, "\"", 1 );
|
861
|
-
while ( mark < str + len ) {
|
862
|
-
if ( do_indent > 0 ) {
|
863
|
-
if ( do_indent == 2 ) {
|
864
|
-
syck_emitter_write( e, "\\", 1 );
|
865
|
-
}
|
866
|
-
syck_emit_indent( e );
|
867
|
-
do_indent = 0;
|
868
|
-
}
|
869
|
-
switch ( *mark ) {
|
870
|
-
|
871
|
-
/* Escape sequences allowed within double quotes. */
|
872
|
-
case '"': syck_emitter_write( e, "\\\"", 2 ); break;
|
873
|
-
case '\\': syck_emitter_write( e, "\\\\", 2 ); break;
|
874
|
-
case '\0': syck_emitter_write( e, "\\0", 2 ); break;
|
875
|
-
case '\a': syck_emitter_write( e, "\\a", 2 ); break;
|
876
|
-
case '\b': syck_emitter_write( e, "\\b", 2 ); break;
|
877
|
-
case '\f': syck_emitter_write( e, "\\f", 2 ); break;
|
878
|
-
case '\r': syck_emitter_write( e, "\\r", 2 ); break;
|
879
|
-
case '\t': syck_emitter_write( e, "\\t", 2 ); break;
|
880
|
-
case '\v': syck_emitter_write( e, "\\v", 2 ); break;
|
881
|
-
case 0x1b: syck_emitter_write( e, "\\e", 2 ); break;
|
882
|
-
|
883
|
-
case '\n':
|
884
|
-
end = mark + 1;
|
885
|
-
syck_emitter_write( e, "\\n", 2 );
|
886
|
-
do_indent = 2;
|
887
|
-
start = mark + 1;
|
888
|
-
if ( start < str + len && ( *start == ' ' || *start == '\n' ) ) {
|
889
|
-
do_indent = 0;
|
890
|
-
}
|
891
|
-
break;
|
892
|
-
|
893
|
-
case ' ':
|
894
|
-
if ( width > 0 && *start != ' ' && mark - end > width ) {
|
895
|
-
do_indent = 1;
|
896
|
-
end = mark + 1;
|
897
|
-
} else {
|
898
|
-
syck_emitter_write( e, " ", 1 );
|
899
|
-
}
|
900
|
-
break;
|
901
|
-
|
902
|
-
default:
|
903
|
-
syck_emitter_escape( e, mark, 1 );
|
904
|
-
break;
|
905
|
-
}
|
906
|
-
mark++;
|
907
|
-
}
|
908
|
-
syck_emitter_write( e, "\"", 1 );
|
909
|
-
}
|
910
|
-
|
911
|
-
/*
|
912
|
-
* Outputs a literal block.
|
913
|
-
*/
|
914
|
-
void
|
915
|
-
syck_emit_literal( SyckEmitter *e, char keep_nl, const char *str, long len )
|
916
|
-
{
|
917
|
-
const char *mark = str;
|
918
|
-
const char *start = str;
|
919
|
-
const char *end = str;
|
920
|
-
syck_emitter_write( e, "|", 1 );
|
921
|
-
if ( keep_nl == NL_CHOMP ) {
|
922
|
-
syck_emitter_write( e, "-", 1 );
|
923
|
-
} else if ( keep_nl == NL_KEEP ) {
|
924
|
-
syck_emitter_write( e, "+", 1 );
|
925
|
-
}
|
926
|
-
syck_emit_indent( e );
|
927
|
-
while ( mark < str + len ) {
|
928
|
-
if ( *mark == '\n' ) {
|
929
|
-
end = mark;
|
930
|
-
if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) end += 1;
|
931
|
-
syck_emitter_write( e, start, end - start );
|
932
|
-
if ( mark + 1 == str + len ) {
|
933
|
-
if ( keep_nl != NL_KEEP ) syck_emitter_write( e, "\n", 1 );
|
934
|
-
} else {
|
935
|
-
syck_emit_indent( e );
|
936
|
-
}
|
937
|
-
start = mark + 1;
|
938
|
-
}
|
939
|
-
mark++;
|
940
|
-
}
|
941
|
-
end = str + len;
|
942
|
-
if ( start < end ) {
|
943
|
-
syck_emitter_write( e, start, end - start );
|
944
|
-
}
|
945
|
-
}
|
946
|
-
|
947
|
-
/*
|
948
|
-
* Outputs a folded block.
|
949
|
-
*/
|
950
|
-
void
|
951
|
-
syck_emit_folded( SyckEmitter *e, int width, char keep_nl, const char *str, long len )
|
952
|
-
{
|
953
|
-
const char *mark = str;
|
954
|
-
const char *start = str;
|
955
|
-
const char *end = str;
|
956
|
-
syck_emitter_write( e, ">", 1 );
|
957
|
-
if ( keep_nl == NL_CHOMP ) {
|
958
|
-
syck_emitter_write( e, "-", 1 );
|
959
|
-
} else if ( keep_nl == NL_KEEP ) {
|
960
|
-
syck_emitter_write( e, "+", 1 );
|
961
|
-
}
|
962
|
-
syck_emit_indent( e );
|
963
|
-
if ( width <= 0 ) width = e->best_width;
|
964
|
-
while ( mark < str + len ) {
|
965
|
-
switch ( *mark ) {
|
966
|
-
case '\n':
|
967
|
-
syck_emitter_write( e, end, mark - end );
|
968
|
-
end = mark + 1;
|
969
|
-
if ( *start != ' ' && *start != '\n' && *end != '\n' && *end != ' ' ) {
|
970
|
-
syck_emitter_write( e, "\n", 1 );
|
971
|
-
}
|
972
|
-
if ( mark + 1 == str + len ) {
|
973
|
-
if ( keep_nl != NL_KEEP ) syck_emitter_write( e, "\n", 1 );
|
974
|
-
} else {
|
975
|
-
syck_emit_indent( e );
|
976
|
-
}
|
977
|
-
start = mark + 1;
|
978
|
-
break;
|
979
|
-
|
980
|
-
case ' ':
|
981
|
-
if ( *start != ' ' ) {
|
982
|
-
if ( mark - end > width ) {
|
983
|
-
syck_emitter_write( e, end, mark - end );
|
984
|
-
syck_emit_indent( e );
|
985
|
-
end = mark + 1;
|
986
|
-
}
|
987
|
-
}
|
988
|
-
break;
|
989
|
-
}
|
990
|
-
mark++;
|
991
|
-
}
|
992
|
-
if ( end < mark ) {
|
993
|
-
syck_emitter_write( e, end, mark - end );
|
994
|
-
}
|
995
|
-
}
|
996
|
-
|
997
|
-
/*
|
998
|
-
* Begins emission of a sequence.
|
999
|
-
*/
|
1000
|
-
void syck_emit_seq( SyckEmitter *e, const char *tag, enum seq_style style )
|
1001
|
-
{
|
1002
|
-
SyckLevel *parent = syck_emitter_parent_level( e );
|
1003
|
-
SyckLevel *lvl = syck_emitter_current_level( e );
|
1004
|
-
syck_emit_tag( e, tag, "tag:yaml.org,2002:seq" );
|
1005
|
-
if ( style == seq_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) {
|
1006
|
-
syck_emitter_write( e, "[", 1 );
|
1007
|
-
lvl->status = syck_lvl_iseq;
|
1008
|
-
} else {
|
1009
|
-
/* complex key */
|
1010
|
-
if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) {
|
1011
|
-
syck_emitter_write( e, "? ", 2 );
|
1012
|
-
parent->status = syck_lvl_mapx;
|
1013
|
-
}
|
1014
|
-
lvl->status = syck_lvl_seq;
|
1015
|
-
}
|
1016
|
-
}
|
1017
|
-
|
1018
|
-
/*
|
1019
|
-
* Begins emission of a mapping.
|
1020
|
-
*/
|
1021
|
-
void
|
1022
|
-
syck_emit_map( SyckEmitter *e, const char *tag, enum map_style style )
|
1023
|
-
{
|
1024
|
-
SyckLevel *parent = syck_emitter_parent_level( e );
|
1025
|
-
SyckLevel *lvl = syck_emitter_current_level( e );
|
1026
|
-
syck_emit_tag( e, tag, "tag:yaml.org,2002:map" );
|
1027
|
-
if ( style == map_inline || ( parent->status == syck_lvl_imap || parent->status == syck_lvl_iseq ) ) {
|
1028
|
-
syck_emitter_write( e, "{", 1 );
|
1029
|
-
lvl->status = syck_lvl_imap;
|
1030
|
-
} else {
|
1031
|
-
/* complex key */
|
1032
|
-
if ( parent->status == syck_lvl_map && parent->ncount % 2 == 1 ) {
|
1033
|
-
syck_emitter_write( e, "? ", 2 );
|
1034
|
-
parent->status = syck_lvl_mapx;
|
1035
|
-
}
|
1036
|
-
lvl->status = syck_lvl_map;
|
1037
|
-
}
|
1038
|
-
}
|
1039
|
-
|
1040
|
-
/*
|
1041
|
-
* Handles emitting of a collection item (for both
|
1042
|
-
* sequences and maps)
|
1043
|
-
*/
|
1044
|
-
void syck_emit_item( SyckEmitter *e, st_data_t n )
|
1045
|
-
{
|
1046
|
-
SyckLevel *lvl = syck_emitter_current_level( e );
|
1047
|
-
switch ( lvl->status )
|
1048
|
-
{
|
1049
|
-
case syck_lvl_seq:
|
1050
|
-
{
|
1051
|
-
SyckLevel *parent = syck_emitter_parent_level( e );
|
1052
|
-
|
1053
|
-
/* seq-in-map shortcut -- the lvl->anctag check should be unneccesary but
|
1054
|
-
* there is a nasty shift/reduce in the parser on this point and
|
1055
|
-
* i'm not ready to tickle it. */
|
1056
|
-
if ( lvl->anctag == 0 && parent->status == syck_lvl_map && lvl->ncount == 0 ) {
|
1057
|
-
lvl->spaces = parent->spaces;
|
1058
|
-
}
|
1059
|
-
|
1060
|
-
/* seq-in-seq shortcut */
|
1061
|
-
else if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) {
|
1062
|
-
int spcs = ( lvl->spaces - parent->spaces ) - 2;
|
1063
|
-
if ( spcs >= 0 ) {
|
1064
|
-
int i = 0;
|
1065
|
-
for ( i = 0; i < spcs; i++ ) {
|
1066
|
-
syck_emitter_write( e, " ", 1 );
|
1067
|
-
}
|
1068
|
-
syck_emitter_write( e, "- ", 2 );
|
1069
|
-
break;
|
1070
|
-
}
|
1071
|
-
}
|
1072
|
-
|
1073
|
-
syck_emit_indent( e );
|
1074
|
-
syck_emitter_write( e, "- ", 2 );
|
1075
|
-
}
|
1076
|
-
break;
|
1077
|
-
|
1078
|
-
case syck_lvl_iseq:
|
1079
|
-
{
|
1080
|
-
if ( lvl->ncount > 0 ) {
|
1081
|
-
syck_emitter_write( e, ", ", 2 );
|
1082
|
-
}
|
1083
|
-
}
|
1084
|
-
break;
|
1085
|
-
|
1086
|
-
case syck_lvl_map:
|
1087
|
-
{
|
1088
|
-
SyckLevel *parent = syck_emitter_parent_level( e );
|
1089
|
-
|
1090
|
-
/* map-in-seq shortcut */
|
1091
|
-
if ( lvl->anctag == 0 && parent->status == syck_lvl_seq && lvl->ncount == 0 ) {
|
1092
|
-
int spcs = ( lvl->spaces - parent->spaces ) - 2;
|
1093
|
-
if ( spcs >= 0 ) {
|
1094
|
-
int i = 0;
|
1095
|
-
for ( i = 0; i < spcs; i++ ) {
|
1096
|
-
syck_emitter_write( e, " ", 1 );
|
1097
|
-
}
|
1098
|
-
break;
|
1099
|
-
}
|
1100
|
-
}
|
1101
|
-
|
1102
|
-
if ( lvl->ncount % 2 == 0 ) {
|
1103
|
-
syck_emit_indent( e );
|
1104
|
-
} else {
|
1105
|
-
syck_emitter_write( e, ": ", 2 );
|
1106
|
-
}
|
1107
|
-
}
|
1108
|
-
break;
|
1109
|
-
|
1110
|
-
case syck_lvl_mapx:
|
1111
|
-
{
|
1112
|
-
if ( lvl->ncount % 2 == 0 ) {
|
1113
|
-
syck_emit_indent( e );
|
1114
|
-
lvl->status = syck_lvl_map;
|
1115
|
-
} else {
|
1116
|
-
int i;
|
1117
|
-
if ( lvl->spaces > 0 ) {
|
1118
|
-
char *spcs = S_ALLOC_N( char, lvl->spaces + 1 );
|
1119
|
-
|
1120
|
-
spcs[lvl->spaces] = '\0';
|
1121
|
-
for ( i = 0; i < lvl->spaces; i++ ) spcs[i] = ' ';
|
1122
|
-
syck_emitter_write( e, spcs, lvl->spaces );
|
1123
|
-
S_FREE( spcs );
|
1124
|
-
}
|
1125
|
-
syck_emitter_write( e, ": ", 2 );
|
1126
|
-
}
|
1127
|
-
}
|
1128
|
-
break;
|
1129
|
-
|
1130
|
-
case syck_lvl_imap:
|
1131
|
-
{
|
1132
|
-
if ( lvl->ncount > 0 ) {
|
1133
|
-
if ( lvl->ncount % 2 == 0 ) {
|
1134
|
-
syck_emitter_write( e, ", ", 2 );
|
1135
|
-
} else {
|
1136
|
-
syck_emitter_write( e, ": ", 2 );
|
1137
|
-
}
|
1138
|
-
}
|
1139
|
-
}
|
1140
|
-
break;
|
1141
|
-
|
1142
|
-
default: break;
|
1143
|
-
}
|
1144
|
-
lvl->ncount++;
|
1145
|
-
|
1146
|
-
syck_emit( e, n );
|
1147
|
-
}
|
1148
|
-
|
1149
|
-
/*
|
1150
|
-
* Closes emission of a collection.
|
1151
|
-
*/
|
1152
|
-
void syck_emit_end( SyckEmitter *e )
|
1153
|
-
{
|
1154
|
-
SyckLevel *lvl = syck_emitter_current_level( e );
|
1155
|
-
SyckLevel *parent = syck_emitter_parent_level( e );
|
1156
|
-
switch ( lvl->status )
|
1157
|
-
{
|
1158
|
-
case syck_lvl_seq:
|
1159
|
-
if ( lvl->ncount == 0 ) {
|
1160
|
-
syck_emitter_write( e, "[]\n", 3 );
|
1161
|
-
} else if ( parent->status == syck_lvl_mapx ) {
|
1162
|
-
syck_emitter_write( e, "\n", 1 );
|
1163
|
-
}
|
1164
|
-
break;
|
1165
|
-
|
1166
|
-
case syck_lvl_iseq:
|
1167
|
-
syck_emitter_write( e, "]\n", 1 );
|
1168
|
-
break;
|
1169
|
-
|
1170
|
-
case syck_lvl_map:
|
1171
|
-
if ( lvl->ncount == 0 ) {
|
1172
|
-
syck_emitter_write( e, "{}\n", 3 );
|
1173
|
-
} else if ( lvl->ncount % 2 == 1 ) {
|
1174
|
-
syck_emitter_write( e, ":\n", 1 );
|
1175
|
-
} else if ( parent->status == syck_lvl_mapx ) {
|
1176
|
-
syck_emitter_write( e, "\n", 1 );
|
1177
|
-
}
|
1178
|
-
break;
|
1179
|
-
|
1180
|
-
case syck_lvl_imap:
|
1181
|
-
syck_emitter_write( e, "}\n", 1 );
|
1182
|
-
break;
|
1183
|
-
|
1184
|
-
default: break;
|
1185
|
-
}
|
1186
|
-
}
|
1187
|
-
|
1188
|
-
/*
|
1189
|
-
* Fill markers table with emitter nodes in the
|
1190
|
-
* soon-to-be-emitted tree.
|
1191
|
-
*/
|
1192
|
-
SYMID
|
1193
|
-
syck_emitter_mark_node( SyckEmitter *e, st_data_t n )
|
1194
|
-
{
|
1195
|
-
SYMID oid = 0;
|
1196
|
-
char *anchor_name = NULL;
|
1197
|
-
|
1198
|
-
/*
|
1199
|
-
* Ensure markers table is initialized.
|
1200
|
-
*/
|
1201
|
-
if ( e->markers == NULL )
|
1202
|
-
{
|
1203
|
-
e->markers = st_init_numtable();
|
1204
|
-
}
|
1205
|
-
|
1206
|
-
/*
|
1207
|
-
* Markers table initially marks the string position of the
|
1208
|
-
* object. Doesn't yet create an anchor, simply notes the
|
1209
|
-
* position.
|
1210
|
-
*/
|
1211
|
-
if ( ! st_lookup( e->markers, n, (st_data_t *)&oid ) )
|
1212
|
-
{
|
1213
|
-
/*
|
1214
|
-
* Store all markers
|
1215
|
-
*/
|
1216
|
-
oid = e->markers->num_entries + 1;
|
1217
|
-
st_insert( e->markers, n, (st_data_t)oid );
|
1218
|
-
}
|
1219
|
-
else
|
1220
|
-
{
|
1221
|
-
if ( e->anchors == NULL )
|
1222
|
-
{
|
1223
|
-
e->anchors = st_init_numtable();
|
1224
|
-
}
|
1225
|
-
|
1226
|
-
if ( ! st_lookup( e->anchors, (st_data_t)oid, (void *)&anchor_name ) )
|
1227
|
-
{
|
1228
|
-
int idx = 0;
|
1229
|
-
const char *anc = ( e->anchor_format == NULL ? DEFAULT_ANCHOR_FORMAT : e->anchor_format );
|
1230
|
-
|
1231
|
-
/*
|
1232
|
-
* Second time hitting this object, let's give it an anchor
|
1233
|
-
*/
|
1234
|
-
idx = (int)(e->anchors->num_entries + 1);
|
1235
|
-
anchor_name = S_ALLOC_N( char, strlen( anc ) + 10 );
|
1236
|
-
S_MEMZERO( anchor_name, char, strlen( anc ) + 10 );
|
1237
|
-
sprintf( anchor_name, anc, idx );
|
1238
|
-
|
1239
|
-
/*
|
1240
|
-
* Insert into anchors table
|
1241
|
-
*/
|
1242
|
-
st_insert( e->anchors, (st_data_t)oid, (st_data_t)anchor_name );
|
1243
|
-
}
|
1244
|
-
}
|
1245
|
-
return oid;
|
1246
|
-
}
|
1247
|
-
|