00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "ruby/ruby.h"
00011 #include "ruby/encoding.h"
00012 #include "syck.h"
00013 #include <sys/types.h>
00014 #include <time.h>
00015
00016 typedef struct RVALUE {
00017 union {
00018 #if 0
00019 struct {
00020 unsigned long flags;
00021 struct RVALUE *next;
00022 } free;
00023 #endif
00024 struct RBasic basic;
00025 struct RObject object;
00026 struct RClass klass;
00027
00028
00029 struct RArray array;
00030
00031 struct RHash hash;
00032
00033 struct RStruct rstruct;
00034
00035
00036 } as;
00037 } RVALUE;
00038
00039 typedef struct {
00040 long hash;
00041 char *buffer;
00042 long length;
00043 long remaining;
00044 int printed;
00045 } bytestring_t;
00046
00047 #define RUBY_DOMAIN "ruby.yaml.org,2002"
00048
00049
00050
00051
00052 static ID s_new, s_utc, s_at, s_to_f, s_to_i, s_read, s_binmode, s_call, s_cmp, s_transfer, s_update, s_dup, s_haskey, s_match, s_keys, s_unpack, s_tr_bang, s_default_set, s_tag_read_class, s_tag_subclasses, s_resolver, s_push, s_emitter, s_level, s_detect_implicit, s_node_import, s_out, s_input, s_intern, s_transform, s_yaml_new, s_yaml_initialize, s_node_export, s_to_yaml, s_write, s_set_resolver, s_each;
00053 static ID s_tags, s_kind, s_name, s_options, s_type_id, s_type_id_set, s_style, s_style_set, s_value, s_value_set, s_parse;
00054 static VALUE sym_model, sym_generic, sym_input, sym_bytecode;
00055 static VALUE sym_scalar, sym_seq, sym_map;
00056 static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline;
00057 static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter, cDateTime;
00058 static VALUE oDefaultResolver, oGenericResolver;
00059
00060
00061
00062
00063 static double S_zero(void) { return 0.0; }
00064 static double S_one(void) { return 1.0; }
00065 static double S_inf(void) { return S_one() / S_zero(); }
00066 static double S_nan(void) { return S_zero() / S_zero(); }
00067
00068 static VALUE syck_node_transform( VALUE );
00069
00070
00071
00072
00073 SYMID rb_syck_load_handler _((SyckParser *, SyckNode *));
00074 void rb_syck_err_handler _((SyckParser *, const char *));
00075 SyckNode * rb_syck_bad_anchor_handler _((SyckParser *, char *));
00076 void rb_syck_output_handler _((SyckEmitter *, char *, long));
00077 void rb_syck_emitter_handler _((SyckEmitter *, st_data_t));
00078 int syck_parser_assign_io _((SyckParser *, VALUE *));
00079 VALUE syck_scalar_alloc _((VALUE class));
00080 VALUE syck_seq_alloc _((VALUE class));
00081 VALUE syck_map_alloc _((VALUE class));
00082
00083 struct parser_xtra {
00084 VALUE data;
00085 VALUE proc;
00086 VALUE resolver;
00087 int taint;
00088 };
00089
00090 struct emitter_xtra {
00091 VALUE oid;
00092 VALUE data;
00093 VALUE port;
00094 };
00095
00096
00097
00098
00099 VALUE
00100 rb_syck_compile(VALUE self, VALUE port)
00101 {
00102 SYMID oid;
00103 int taint;
00104 char *ret;
00105 VALUE bc;
00106 bytestring_t *sav = NULL;
00107 void *data = NULL;
00108
00109 SyckParser *parser = syck_new_parser();
00110 taint = syck_parser_assign_io(parser, &port);
00111 syck_parser_handler( parser, syck_yaml2byte_handler );
00112 syck_parser_error_handler( parser, NULL );
00113 syck_parser_implicit_typing( parser, 0 );
00114 syck_parser_taguri_expansion( parser, 0 );
00115 oid = syck_parse( parser );
00116 if (!syck_lookup_sym( parser, oid, &data )) {
00117 rb_raise(rb_eSyntaxError, "root node <%lx> not found", oid);
00118 }
00119 sav = data;
00120
00121 ret = S_ALLOCA_N( char, strlen( sav->buffer ) + 3 );
00122 ret[0] = '\0';
00123 strcat( ret, "D\n" );
00124 strcat( ret, sav->buffer );
00125
00126 syck_free_parser( parser );
00127
00128 bc = rb_str_new2( ret );
00129 if ( taint ) OBJ_TAINT( bc );
00130 return bc;
00131 }
00132
00133
00134
00135
00136 long
00137 rb_syck_io_str_read( char *buf, SyckIoStr *str, long max_size, long skip )
00138 {
00139 long len = 0;
00140
00141 ASSERT( str != NULL );
00142 max_size -= skip;
00143
00144 if ( max_size <= 0 ) max_size = 0;
00145 else
00146 {
00147
00148
00149
00150 VALUE src = (VALUE)str->ptr;
00151 VALUE n = LONG2NUM(max_size);
00152 VALUE str2 = rb_funcall2(src, s_read, 1, &n);
00153 if (!NIL_P(str2))
00154 {
00155 StringValue(str2);
00156 len = RSTRING_LEN(str2);
00157 memcpy( buf + skip, RSTRING_PTR(str2), len );
00158 }
00159 }
00160 len += skip;
00161 buf[len] = '\0';
00162 return len;
00163 }
00164
00165
00166
00167
00168
00169 int
00170 syck_parser_assign_io(SyckParser *parser, VALUE *pport)
00171 {
00172 int taint = Qtrue;
00173 VALUE tmp, port = *pport;
00174 if (!NIL_P(tmp = rb_check_string_type(port))) {
00175 taint = OBJ_TAINTED(port);
00176 port = tmp;
00177 syck_parser_str( parser, RSTRING_PTR(port), RSTRING_LEN(port), NULL );
00178 }
00179 else if (rb_respond_to(port, s_read)) {
00180 if (rb_respond_to(port, s_binmode)) {
00181 rb_funcall2(port, s_binmode, 0, 0);
00182 }
00183 syck_parser_str( parser, (char *)port, 0, rb_syck_io_str_read );
00184 }
00185 else {
00186 rb_raise(rb_eTypeError, "instance of IO needed");
00187 }
00188 *pport = port;
00189 return taint;
00190 }
00191
00192
00193
00194
00195 VALUE
00196 syck_get_hash_aref(VALUE hsh, VALUE key)
00197 {
00198 VALUE val = rb_hash_aref( hsh, key );
00199 if ( NIL_P( val ) )
00200 {
00201 val = rb_hash_new();
00202 rb_hash_aset(hsh, key, val);
00203 }
00204 return val;
00205 }
00206
00207
00208
00209
00210 struct mktime_arg {
00211 char *str;
00212 long len;
00213 };
00214
00215 SYMID
00216 mktime_do(struct mktime_arg *arg)
00217 {
00218 VALUE time;
00219 char *str = arg->str;
00220 long len = arg->len;
00221 char *ptr = str;
00222 VALUE year = INT2FIX(0);
00223 VALUE mon = INT2FIX(0);
00224 VALUE day = INT2FIX(0);
00225 VALUE hour = INT2FIX(0);
00226 VALUE min = INT2FIX(0);
00227 VALUE sec = INT2FIX(0);
00228 double usec;
00229
00230
00231 if ( ptr[0] != '\0' && len > 0 ) {
00232 year = INT2FIX(strtol(ptr, NULL, 10));
00233 }
00234
00235
00236 ptr += 4;
00237 if ( ptr[0] != '\0' && len > ptr - str ) {
00238 while ( !ISDIGIT( *ptr ) ) ptr++;
00239 mon = INT2FIX(strtol(ptr, NULL, 10));
00240 }
00241
00242
00243 ptr += 2;
00244 if ( ptr[0] != '\0' && len > ptr - str ) {
00245 while ( !ISDIGIT( *ptr ) ) ptr++;
00246 day = INT2FIX(strtol(ptr, NULL, 10));
00247 }
00248
00249
00250 ptr += 2;
00251 if ( ptr[0] != '\0' && len > ptr - str ) {
00252 while ( !ISDIGIT( *ptr ) ) ptr++;
00253 hour = INT2FIX(strtol(ptr, NULL, 10));
00254 }
00255
00256
00257 ptr += 2;
00258 if ( ptr[0] != '\0' && len > ptr - str ) {
00259 while ( !ISDIGIT( *ptr ) ) ptr++;
00260 min = INT2FIX(strtol(ptr, NULL, 10));
00261 }
00262
00263
00264 ptr += 2;
00265 if ( ptr[0] != '\0' && len > ptr - str ) {
00266 while ( !ISDIGIT( *ptr ) ) ptr++;
00267 sec = INT2FIX(strtol(ptr, NULL, 10));
00268 }
00269
00270
00271 ptr += 2;
00272 if ( len > ptr - str && *ptr == '.' )
00273 {
00274 char padded[] = "000000.000000";
00275 const int padding = 6;
00276 const int offset = padding + 1;
00277 const char *end = ptr + 1;
00278 const char *begin = end;
00279 int length;
00280 while ( isdigit( *end ) ) end++;
00281 length = (int)(end - begin) <= padding ? (int)(end - begin) : padding;
00282 MEMCPY(padded, begin, char, length);
00283 usec = strtod(padded, NULL);
00284 }
00285 else
00286 {
00287 usec = 0.0;
00288 }
00289
00290
00291 while ( len > ptr - str && *ptr != 'Z' && *ptr != '+' && *ptr != '-' && *ptr != '\0' ) ptr++;
00292 if ( len > ptr - str && ( *ptr == '-' || *ptr == '+' ) )
00293 {
00294 time_t tz_offset = strtol(ptr, NULL, 10) * 3600;
00295 VALUE tmp;
00296
00297 while ( *ptr != ':' && *ptr != '\0' ) ptr++;
00298 if ( *ptr == ':' )
00299 {
00300 ptr += 1;
00301 if ( tz_offset < 0 )
00302 {
00303 tz_offset -= strtol(ptr, NULL, 10) * 60;
00304 }
00305 else
00306 {
00307 tz_offset += strtol(ptr, NULL, 10) * 60;
00308 }
00309 }
00310
00311
00312 time = rb_funcall(rb_cTime, s_utc, 6, year, mon, day, hour, min, sec);
00313 tmp = rb_funcall(time, s_to_i, 0);
00314 tmp = rb_funcall(tmp, '-', 1, LONG2FIX(tz_offset));
00315 return rb_funcall(rb_cTime, s_at, 2, tmp, rb_float_new(usec));
00316 }
00317 else
00318 {
00319
00320 return rb_funcall(rb_cTime, s_utc, 7, year, mon, day, hour, min, sec, rb_float_new(usec));
00321 }
00322 }
00323
00324 SYMID
00325 mktime_r(struct mktime_arg *arg)
00326 {
00327 if (!cDateTime) {
00328
00329
00330
00331 rb_require("date");
00332 cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime"));
00333 }
00334 return rb_funcall(cDateTime, s_parse, 1, rb_str_new(arg->str, arg->len));
00335 }
00336
00337 SYMID
00338 rb_syck_mktime(char *str, long len)
00339 {
00340 struct mktime_arg a;
00341
00342 a.str = str;
00343 a.len = len;
00344 return rb_rescue2(mktime_do, (VALUE)&a, mktime_r, (VALUE)&a, rb_eArgError, NULL);
00345 }
00346
00347
00348
00349
00350
00351 VALUE
00352 syck_merge_i(VALUE entry, VALUE hsh )
00353 {
00354 VALUE tmp;
00355 if ( !NIL_P(tmp = rb_check_convert_type(entry, T_HASH, "Hash", "to_hash")) )
00356 {
00357 entry = tmp;
00358 rb_funcall( hsh, s_update, 1, entry );
00359 }
00360 return Qnil;
00361 }
00362
00363
00364
00365
00366 int
00367 yaml_org_handler( SyckNode *n, VALUE *ref )
00368 {
00369 char *type_id = n->type_id;
00370 int transferred = 0;
00371 long i = 0;
00372 VALUE obj = Qnil;
00373
00374 if ( type_id != NULL && strncmp( type_id, "tag:yaml.org,2002:", 18 ) == 0 )
00375 {
00376 type_id += 18;
00377 }
00378
00379 switch (n->kind)
00380 {
00381 case syck_str_kind:
00382 transferred = 1;
00383 if ( type_id == NULL )
00384 {
00385 obj = rb_str_new( n->data.str->ptr, n->data.str->len );
00386 }
00387 else if ( strcmp( type_id, "null" ) == 0 )
00388 {
00389 obj = Qnil;
00390 }
00391 else if ( strcmp( type_id, "binary" ) == 0 )
00392 {
00393 VALUE arr;
00394 obj = rb_str_new( n->data.str->ptr, n->data.str->len );
00395 rb_funcall( obj, s_tr_bang, 2, rb_str_new2( "\n\t " ), rb_str_new2( "" ) );
00396 arr = rb_funcall( obj, s_unpack, 1, rb_str_new2( "m" ) );
00397 obj = rb_ary_shift( arr );
00398 }
00399 else if ( strcmp( type_id, "bool#yes" ) == 0 )
00400 {
00401 obj = Qtrue;
00402 }
00403 else if ( strcmp( type_id, "bool#no" ) == 0 )
00404 {
00405 obj = Qfalse;
00406 }
00407 else if ( strcmp( type_id, "int#hex" ) == 0 )
00408 {
00409 syck_str_blow_away_commas( n );
00410 obj = rb_cstr2inum( n->data.str->ptr, 16 );
00411 }
00412 else if ( strcmp( type_id, "int#oct" ) == 0 )
00413 {
00414 syck_str_blow_away_commas( n );
00415 obj = rb_cstr2inum( n->data.str->ptr, 8 );
00416 }
00417 else if ( strcmp( type_id, "int#base60" ) == 0 )
00418 {
00419 char *ptr, *end;
00420 long sixty = 1;
00421 long total = 0;
00422 syck_str_blow_away_commas( n );
00423 ptr = n->data.str->ptr;
00424 end = n->data.str->ptr + n->data.str->len;
00425 while ( end > ptr )
00426 {
00427 long bnum = 0;
00428 char *colon = end - 1;
00429 while ( colon >= ptr && *colon != ':' )
00430 {
00431 colon--;
00432 }
00433 if ( colon >= ptr && *colon == ':' ) *colon = '\0';
00434
00435 bnum = strtol( colon + 1, NULL, 10 );
00436 total += bnum * sixty;
00437 sixty *= 60;
00438 end = colon;
00439 }
00440 obj = INT2FIX(total);
00441 }
00442 else if ( strncmp( type_id, "int", 3 ) == 0 )
00443 {
00444 syck_str_blow_away_commas( n );
00445 obj = rb_cstr2inum( n->data.str->ptr, 10 );
00446 }
00447 else if ( strcmp( type_id, "float#base60" ) == 0 )
00448 {
00449 char *ptr, *end;
00450 long sixty = 1;
00451 double total = 0.0;
00452 syck_str_blow_away_commas( n );
00453 ptr = n->data.str->ptr;
00454 end = n->data.str->ptr + n->data.str->len;
00455 while ( end > ptr )
00456 {
00457 double bnum = 0;
00458 char *colon = end - 1;
00459 while ( colon >= ptr && *colon != ':' )
00460 {
00461 colon--;
00462 }
00463 if ( colon >= ptr && *colon == ':' ) *colon = '\0';
00464
00465 bnum = strtod( colon + 1, NULL );
00466 total += bnum * sixty;
00467 sixty *= 60;
00468 end = colon;
00469 }
00470 obj = rb_float_new( total );
00471 }
00472 else if ( strcmp( type_id, "float#nan" ) == 0 )
00473 {
00474 obj = rb_float_new( S_nan() );
00475 }
00476 else if ( strcmp( type_id, "float#inf" ) == 0 )
00477 {
00478 obj = rb_float_new( S_inf() );
00479 }
00480 else if ( strcmp( type_id, "float#neginf" ) == 0 )
00481 {
00482 obj = rb_float_new( -S_inf() );
00483 }
00484 else if ( strncmp( type_id, "float", 5 ) == 0 )
00485 {
00486 double f;
00487 syck_str_blow_away_commas( n );
00488 f = strtod( n->data.str->ptr, NULL );
00489 obj = rb_float_new( f );
00490 }
00491 else if ( strcmp( type_id, "timestamp#iso8601" ) == 0 )
00492 {
00493 obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
00494 }
00495 else if ( strcmp( type_id, "timestamp#spaced" ) == 0 )
00496 {
00497 obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
00498 }
00499 else if ( strcmp( type_id, "timestamp#ymd" ) == 0 )
00500 {
00501 char *ptr = n->data.str->ptr;
00502 VALUE year, mon, day;
00503
00504
00505 ptr[4] = '\0';
00506 year = INT2FIX(strtol(ptr, NULL, 10));
00507
00508
00509 ptr += 4;
00510 while ( !ISDIGIT( *ptr ) ) ptr++;
00511 mon = INT2FIX(strtol(ptr, NULL, 10));
00512
00513
00514 ptr += 2;
00515 while ( !ISDIGIT( *ptr ) ) ptr++;
00516 day = INT2FIX(strtol(ptr, NULL, 10));
00517
00518 if ( !cDate ) {
00519
00520
00521
00522 rb_require( "date" );
00523 cDate = rb_const_get( rb_cObject, rb_intern("Date") );
00524 }
00525
00526 obj = rb_funcall( cDate, s_new, 3, year, mon, day );
00527 }
00528 else if ( strncmp( type_id, "timestamp", 9 ) == 0 )
00529 {
00530 obj = rb_syck_mktime( n->data.str->ptr, n->data.str->len );
00531 }
00532 else if ( strncmp( type_id, "merge", 5 ) == 0 )
00533 {
00534 obj = rb_funcall( cMergeKey, s_new, 0 );
00535 }
00536 else if ( strncmp( type_id, "default", 7 ) == 0 )
00537 {
00538 obj = rb_funcall( cDefaultKey, s_new, 0 );
00539 }
00540 else if ( n->data.str->style == scalar_plain &&
00541 n->data.str->len > 1 &&
00542 strncmp( n->data.str->ptr, ":", 1 ) == 0 )
00543 {
00544 obj = rb_funcall( oDefaultResolver, s_transfer, 2,
00545 rb_str_new2( "tag:ruby.yaml.org,2002:sym" ),
00546 rb_str_new( n->data.str->ptr + 1, n->data.str->len - 1 ) );
00547 }
00548 else if ( strcmp( type_id, "str" ) == 0 )
00549 {
00550 obj = rb_str_new( n->data.str->ptr, n->data.str->len );
00551 rb_enc_associate(obj, rb_utf8_encoding());
00552 }
00553 else
00554 {
00555 transferred = 0;
00556 obj = rb_str_new( n->data.str->ptr, n->data.str->len );
00557 }
00558 break;
00559
00560 case syck_seq_kind:
00561 if ( type_id == NULL || strcmp( type_id, "seq" ) == 0 )
00562 {
00563 transferred = 1;
00564 }
00565 obj = rb_ary_new2( n->data.list->idx );
00566 for ( i = 0; i < n->data.list->idx; i++ )
00567 {
00568 rb_ary_store( obj, i, syck_seq_read( n, i ) );
00569 }
00570 break;
00571
00572 case syck_map_kind:
00573 if ( type_id == NULL || strcmp( type_id, "map" ) == 0 )
00574 {
00575 transferred = 1;
00576 }
00577 obj = rb_hash_new();
00578 for ( i = 0; i < n->data.pairs->idx; i++ )
00579 {
00580 VALUE k = syck_map_read( n, map_key, i );
00581 VALUE v = syck_map_read( n, map_value, i );
00582 int skip_aset = 0;
00583
00584
00585
00586
00587 if ( rb_obj_is_kind_of( k, cMergeKey ) )
00588 {
00589 VALUE tmp;
00590 if ( !NIL_P(tmp = rb_check_convert_type(v, T_HASH, "Hash", "to_hash")) )
00591 {
00592 VALUE dup = rb_funcall( tmp, s_dup, 0 );
00593 rb_funcall( dup, s_update, 1, obj );
00594 obj = dup;
00595 skip_aset = 1;
00596 }
00597 else if ( !NIL_P(tmp = rb_check_array_type(v)) )
00598 {
00599 VALUE end = rb_ary_pop( tmp );
00600 VALUE tmph = rb_check_convert_type(end, T_HASH, "Hash", "to_hash");
00601 if ( !NIL_P(tmph) )
00602 {
00603 VALUE dup = rb_funcall( tmph, s_dup, 0 );
00604 tmp = rb_ary_reverse( tmp );
00605 rb_ary_push( tmp, obj );
00606 rb_block_call( tmp, s_each, 0, 0, syck_merge_i, dup );
00607 obj = dup;
00608 skip_aset = 1;
00609 }
00610 }
00611 }
00612 else if ( rb_obj_is_kind_of( k, cDefaultKey ) )
00613 {
00614 rb_funcall( obj, s_default_set, 1, v );
00615 skip_aset = 1;
00616 }
00617
00618 if ( ! skip_aset )
00619 {
00620 rb_hash_aset( obj, k, v );
00621 }
00622 }
00623 break;
00624 }
00625
00626 *ref = obj;
00627 return transferred;
00628 }
00629
00630 static void syck_node_mark( SyckNode *n );
00631
00632
00633
00634
00635
00636 SYMID
00637 rb_syck_load_handler(SyckParser *p, SyckNode *n)
00638 {
00639 VALUE obj = Qnil;
00640 struct parser_xtra *bonus = (struct parser_xtra *)p->bonus;
00641 VALUE resolver = bonus->resolver;
00642 if ( NIL_P( resolver ) )
00643 {
00644 resolver = oDefaultResolver;
00645 }
00646
00647
00648
00649
00650 obj = rb_funcall( resolver, s_node_import, 1, Data_Wrap_Struct( cNode, NULL, NULL, n ) );
00651
00652
00653
00654
00655 if (n->id > 0 && !NIL_P(obj))
00656 {
00657 MEMCPY((void *)n->id, (void *)obj, RVALUE, 1);
00658 MEMZERO((void *)obj, RVALUE, 1);
00659 obj = n->id;
00660 }
00661
00662 if ( bonus->taint) OBJ_TAINT( obj );
00663 if ( bonus->proc != 0 ) rb_funcall(bonus->proc, s_call, 1, obj);
00664
00665 rb_hash_aset(bonus->data, INT2FIX(RHASH_SIZE(bonus->data)), obj);
00666 return obj;
00667 }
00668
00669
00670
00671
00672 void
00673 rb_syck_err_handler(SyckParser *p, const char *msg)
00674 {
00675 char *endl = p->cursor;
00676
00677 while ( *endl != '\0' && *endl != '\n' )
00678 endl++;
00679
00680 endl[0] = '\0';
00681 rb_raise(rb_eArgError, "%s on line %d, col %"PRIdPTRDIFF": `%s'",
00682 msg,
00683 p->linect,
00684 p->cursor - p->lineptr,
00685 p->lineptr);
00686 }
00687
00688
00689
00690
00691 SyckNode *
00692 rb_syck_bad_anchor_handler(SyckParser *p, char *a)
00693 {
00694 VALUE anchor_name = rb_str_new2( a );
00695 SyckNode *badanc = syck_new_map( rb_str_new2( "name" ), anchor_name );
00696 badanc->type_id = syck_strndup( "tag:ruby.yaml.org,2002:object:YAML::Syck::BadAlias", 53 );
00697 return badanc;
00698 }
00699
00700
00701
00702
00703 void
00704 syck_set_model(VALUE p, VALUE input, VALUE model)
00705 {
00706 SyckParser *parser;
00707 Data_Get_Struct(p, SyckParser, parser);
00708 syck_parser_handler( parser, rb_syck_load_handler );
00709
00710 if ( model == sym_generic )
00711 {
00712 rb_funcall( p, s_set_resolver, 1, oGenericResolver );
00713 }
00714 syck_parser_implicit_typing( parser, 1 );
00715 syck_parser_taguri_expansion( parser, 1 );
00716
00717 if ( NIL_P( input ) )
00718 {
00719 input = rb_ivar_get( p, s_input );
00720 }
00721 if ( input == sym_bytecode )
00722 {
00723 syck_parser_set_input_type( parser, syck_bytecode_utf8 );
00724 }
00725 else
00726 {
00727 syck_parser_set_input_type( parser, syck_yaml_utf8 );
00728 }
00729 syck_parser_error_handler( parser, rb_syck_err_handler );
00730 syck_parser_bad_anchor_handler( parser, rb_syck_bad_anchor_handler );
00731 }
00732
00733 static int
00734 syck_st_mark_nodes( char *key, SyckNode *n, char *arg )
00735 {
00736 if ( n != (void *)1 ) syck_node_mark( n );
00737 return ST_CONTINUE;
00738 }
00739
00740
00741
00742
00743 static void
00744 syck_mark_parser(SyckParser *parser)
00745 {
00746 struct parser_xtra *bonus = (struct parser_xtra *)parser->bonus;
00747 rb_gc_mark_maybe(parser->root);
00748 rb_gc_mark_maybe(parser->root_on_error);
00749 rb_gc_mark( bonus->data );
00750 rb_gc_mark( bonus->proc );
00751 rb_gc_mark( bonus->resolver );
00752
00753 if ( parser->anchors != NULL )
00754 {
00755 st_foreach( parser->anchors, syck_st_mark_nodes, 0 );
00756 }
00757 if ( parser->bad_anchors != NULL )
00758 {
00759 st_foreach( parser->bad_anchors, syck_st_mark_nodes, 0 );
00760 }
00761 }
00762
00763
00764
00765
00766 void
00767 rb_syck_free_parser(SyckParser *p)
00768 {
00769 S_FREE( p->bonus );
00770 syck_free_parser(p);
00771 }
00772
00773
00774
00775
00776 VALUE syck_parser_s_alloc _((VALUE));
00777 VALUE
00778 syck_parser_s_alloc(VALUE class)
00779 {
00780 VALUE pobj;
00781 SyckParser *parser = syck_new_parser();
00782
00783 parser->bonus = S_ALLOC( struct parser_xtra );
00784 S_MEMZERO( parser->bonus, struct parser_xtra, 1 );
00785
00786 pobj = Data_Wrap_Struct( class, syck_mark_parser, rb_syck_free_parser, parser );
00787
00788 syck_parser_set_root_on_error( parser, Qnil );
00789
00790 return pobj;
00791 }
00792
00793
00794
00795
00796 static VALUE
00797 syck_parser_initialize(int argc, VALUE *argv, VALUE self)
00798 {
00799 VALUE options;
00800 if (rb_scan_args(argc, argv, "01", &options) == 0)
00801 {
00802 options = rb_hash_new();
00803 }
00804 else
00805 {
00806 Check_Type(options, T_HASH);
00807 }
00808 rb_ivar_set(self, s_options, options);
00809 rb_ivar_set(self, s_input, Qnil);
00810 return self;
00811 }
00812
00813
00814
00815
00816 static VALUE
00817 syck_parser_bufsize_set(VALUE self, VALUE size)
00818 {
00819 SyckParser *parser;
00820
00821 if ( rb_respond_to( size, s_to_i ) ) {
00822 int n = NUM2INT(rb_funcall(size, s_to_i, 0));
00823 Data_Get_Struct(self, SyckParser, parser);
00824 parser->bufsize = n;
00825 }
00826 return self;
00827 }
00828
00829
00830
00831
00832 static VALUE
00833 syck_parser_bufsize_get(VALUE self)
00834 {
00835 SyckParser *parser;
00836
00837 Data_Get_Struct(self, SyckParser, parser);
00838 return INT2FIX( parser->bufsize );
00839 }
00840
00841
00842
00843
00844 VALUE
00845 syck_parser_load(int argc, VALUE *argv, VALUE self)
00846 {
00847 VALUE port, proc, model, input;
00848 SyckParser *parser;
00849 struct parser_xtra *bonus;
00850
00851 rb_scan_args(argc, argv, "11", &port, &proc);
00852
00853 input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
00854 model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
00855 Data_Get_Struct(self, SyckParser, parser);
00856 syck_set_model( self, input, model );
00857
00858 bonus = (struct parser_xtra *)parser->bonus;
00859 bonus->taint = syck_parser_assign_io(parser, &port);
00860 bonus->data = rb_hash_new();
00861 bonus->resolver = rb_attr_get( self, s_resolver );
00862 if ( NIL_P( proc ) ) bonus->proc = 0;
00863 else bonus->proc = proc;
00864
00865 return syck_parse( parser );
00866 }
00867
00868
00869
00870
00871 VALUE
00872 syck_parser_load_documents(int argc, VALUE *argv, VALUE self)
00873 {
00874 VALUE port, proc, v, input, model;
00875 SyckParser *parser;
00876 struct parser_xtra *bonus;
00877
00878 rb_scan_args(argc, argv, "1&", &port, &proc);
00879
00880 input = rb_hash_aref( rb_attr_get( self, s_options ), sym_input );
00881 model = rb_hash_aref( rb_attr_get( self, s_options ), sym_model );
00882 Data_Get_Struct(self, SyckParser, parser);
00883 syck_set_model( self, input, model );
00884
00885 bonus = (struct parser_xtra *)parser->bonus;
00886 bonus->taint = syck_parser_assign_io(parser, &port);
00887 bonus->resolver = rb_attr_get( self, s_resolver );
00888 bonus->proc = 0;
00889
00890 while ( 1 )
00891 {
00892
00893 bonus->data = rb_hash_new();
00894
00895
00896 v = syck_parse( parser );
00897 if ( parser->eof == 1 )
00898 {
00899 break;
00900 }
00901
00902
00903 rb_funcall( proc, s_call, 1, v );
00904 }
00905
00906 return Qnil;
00907 }
00908
00909
00910
00911
00912 VALUE
00913 syck_parser_set_resolver(VALUE self, VALUE resolver)
00914 {
00915 rb_ivar_set( self, s_resolver, resolver );
00916 return self;
00917 }
00918
00919
00920
00921
00922 static VALUE
00923 syck_resolver_initialize(VALUE self)
00924 {
00925 rb_ivar_set(self, s_tags, rb_hash_new());
00926 return self;
00927 }
00928
00929
00930
00931
00932 VALUE
00933 syck_resolver_add_type(VALUE self, VALUE taguri, VALUE cls)
00934 {
00935 VALUE tags = rb_attr_get(self, s_tags);
00936 rb_hash_aset( tags, taguri, cls );
00937 return Qnil;
00938 }
00939
00940
00941
00942
00943 VALUE
00944 syck_resolver_use_types_at(VALUE self, VALUE hsh)
00945 {
00946 rb_ivar_set( self, s_tags, hsh );
00947 return Qnil;
00948 }
00949
00950
00951
00952
00953 VALUE
00954 syck_resolver_detect_implicit(VALUE self, VALUE val)
00955 {
00956 return rb_str_new2( "" );
00957 }
00958
00959
00960
00961
00962 VALUE
00963 syck_resolver_node_import(VALUE self, VALUE node)
00964 {
00965 SyckNode *n;
00966 VALUE obj = Qnil;
00967 int i = 0;
00968 Data_Get_Struct(node, SyckNode, n);
00969
00970 switch (n->kind)
00971 {
00972 case syck_str_kind:
00973 obj = rb_str_new( n->data.str->ptr, n->data.str->len );
00974 break;
00975
00976 case syck_seq_kind:
00977 obj = rb_ary_new2( n->data.list->idx );
00978 for ( i = 0; i < n->data.list->idx; i++ )
00979 {
00980 rb_ary_store( obj, i, syck_seq_read( n, i ) );
00981 }
00982 break;
00983
00984 case syck_map_kind:
00985 obj = rb_hash_new();
00986 for ( i = 0; i < n->data.pairs->idx; i++ )
00987 {
00988 VALUE k = syck_map_read( n, map_key, i );
00989 VALUE v = syck_map_read( n, map_value, i );
00990 int skip_aset = 0;
00991
00992
00993
00994
00995 if ( rb_obj_is_kind_of( k, cMergeKey ) )
00996 {
00997 if ( rb_obj_is_kind_of( v, rb_cHash ) )
00998 {
00999 VALUE dup = rb_funcall( v, s_dup, 0 );
01000 rb_funcall( dup, s_update, 1, obj );
01001 obj = dup;
01002 skip_aset = 1;
01003 }
01004 else if ( rb_obj_is_kind_of( v, rb_cArray ) )
01005 {
01006 VALUE end = rb_ary_pop( v );
01007 if ( rb_obj_is_kind_of( end, rb_cHash ) )
01008 {
01009 VALUE dup = rb_funcall( end, s_dup, 0 );
01010 v = rb_ary_reverse( v );
01011 rb_ary_push( v, obj );
01012 rb_block_call( v, s_each, 0, 0, syck_merge_i, dup );
01013 obj = dup;
01014 skip_aset = 1;
01015 }
01016 }
01017 }
01018 else if ( rb_obj_is_kind_of( k, cDefaultKey ) )
01019 {
01020 rb_funcall( obj, s_default_set, 1, v );
01021 skip_aset = 1;
01022 }
01023
01024 if ( ! skip_aset )
01025 {
01026 rb_hash_aset( obj, k, v );
01027 }
01028 }
01029 break;
01030 }
01031
01032 if ( n->type_id != NULL )
01033 {
01034 obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
01035 }
01036 return obj;
01037 }
01038
01039
01040
01041
01042 VALUE
01043 syck_set_ivars(VALUE vars, VALUE obj)
01044 {
01045 VALUE ivname = rb_ary_entry( vars, 0 );
01046 char *ivn;
01047 StringValue( ivname );
01048 ivn = S_ALLOCA_N( char, RSTRING_LEN(ivname) + 2 );
01049 ivn[0] = '@';
01050 ivn[1] = '\0';
01051 strncat( ivn, RSTRING_PTR(ivname), RSTRING_LEN(ivname) );
01052 rb_iv_set( obj, ivn, rb_ary_entry( vars, 1 ) );
01053 return Qnil;
01054 }
01055
01056
01057
01058
01059 VALUE
01060 syck_const_find(VALUE const_name)
01061 {
01062 VALUE tclass = rb_cObject;
01063 VALUE tparts = rb_str_split( const_name, "::" );
01064 int i = 0;
01065 for ( i = 0; i < RARRAY_LEN(tparts); i++ ) {
01066 VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) );
01067 if ( !rb_const_defined( tclass, tpart ) ) return Qnil;
01068 tclass = rb_const_get( tclass, tpart );
01069 }
01070 return tclass;
01071 }
01072
01073
01074
01075
01076 VALUE
01077 syck_resolver_transfer(VALUE self, VALUE type, VALUE val)
01078 {
01079 if (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0)
01080 {
01081 type = rb_funcall( self, s_detect_implicit, 1, val );
01082 }
01083
01084 if ( ! (NIL_P(type) || RSTRING_LEN(StringValue(type)) == 0) )
01085 {
01086 VALUE str_xprivate = rb_str_new2( "x-private" );
01087 VALUE colon = rb_str_new2( ":" );
01088 VALUE tags = rb_attr_get(self, s_tags);
01089 VALUE target_class = rb_hash_aref( tags, type );
01090 VALUE subclass = target_class;
01091 VALUE obj = Qnil;
01092
01093
01094
01095
01096 if ( NIL_P( target_class ) )
01097 {
01098 VALUE subclass_parts = rb_ary_new();
01099 VALUE parts = rb_str_split( type, ":" );
01100
01101 while ( RARRAY_LEN(parts) > 1 )
01102 {
01103 VALUE partial;
01104 rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) );
01105 partial = rb_ary_join( parts, colon );
01106 target_class = rb_hash_aref( tags, partial );
01107 if ( NIL_P( target_class ) )
01108 {
01109 rb_str_append( partial, colon );
01110 target_class = rb_hash_aref( tags, partial );
01111 }
01112
01113
01114
01115
01116 if ( ! NIL_P( target_class ) )
01117 {
01118 subclass = target_class;
01119 if ( RARRAY_LEN(subclass_parts) > 0 && rb_respond_to( target_class, s_tag_subclasses ) &&
01120 RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) )
01121 {
01122 VALUE subclass_v;
01123 subclass = rb_ary_join( subclass_parts, colon );
01124 subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass );
01125 subclass_v = syck_const_find( subclass );
01126
01127 if ( subclass_v != Qnil )
01128 {
01129 subclass = subclass_v;
01130 }
01131 else if ( rb_cObject == target_class && subclass_v == Qnil )
01132 {
01133 target_class = cYObject;
01134 type = subclass;
01135 subclass = cYObject;
01136 }
01137 else
01138 {
01139 rb_raise( rb_eTypeError, "invalid subclass" );
01140 }
01141 }
01142 break;
01143 }
01144 }
01145 }
01146
01147
01148
01149
01150
01151 if ( rb_respond_to( target_class, s_call ) )
01152 {
01153 obj = rb_funcall( target_class, s_call, 2, type, val );
01154 }
01155 else
01156 {
01157 if ( rb_respond_to( target_class, s_yaml_new ) )
01158 {
01159 obj = rb_funcall( target_class, s_yaml_new, 3, subclass, type, val );
01160 }
01161 else if ( !NIL_P( target_class ) )
01162 {
01163 if ( subclass == rb_cBignum )
01164 {
01165 obj = rb_str2inum( val, 10 );
01166 }
01167 else
01168 {
01169 obj = rb_obj_alloc( subclass );
01170 }
01171
01172 if ( rb_respond_to( obj, s_yaml_initialize ) )
01173 {
01174 rb_funcall( obj, s_yaml_initialize, 2, type, val );
01175 }
01176 else if ( !NIL_P( obj ) && rb_obj_is_instance_of( val, rb_cHash ) )
01177 {
01178 rb_block_call( val, s_each, 0, 0, syck_set_ivars, obj );
01179 }
01180 }
01181 else
01182 {
01183 VALUE parts = rb_str_split( type, ":" );
01184 VALUE scheme = rb_ary_shift( parts );
01185 if ( rb_str_cmp( scheme, str_xprivate ) == 0 )
01186 {
01187 VALUE name = rb_ary_join( parts, colon );
01188 obj = rb_funcall( cPrivateType, s_new, 2, name, val );
01189 }
01190 else
01191 {
01192 VALUE domain = rb_ary_shift( parts );
01193 VALUE name = rb_ary_join( parts, colon );
01194 obj = rb_funcall( cDomainType, s_new, 3, domain, name, val );
01195 }
01196 }
01197 }
01198 val = obj;
01199 }
01200
01201 return val;
01202 }
01203
01204
01205
01206
01207 VALUE
01208 syck_resolver_tagurize(VALUE self, VALUE val)
01209 {
01210 VALUE tmp = rb_check_string_type(val);
01211
01212 if ( !NIL_P(tmp) )
01213 {
01214 char *taguri = syck_type_id_to_uri( RSTRING_PTR(tmp) );
01215 val = rb_str_new2( taguri );
01216 S_FREE( taguri );
01217 }
01218
01219 return val;
01220 }
01221
01222
01223
01224
01225 VALUE
01226 syck_defaultresolver_detect_implicit(VALUE self, VALUE val)
01227 {
01228 const char *type_id;
01229 VALUE tmp = rb_check_string_type(val);
01230
01231 if ( !NIL_P(tmp) )
01232 {
01233 val = tmp;
01234 type_id = syck_match_implicit( RSTRING_PTR(val), RSTRING_LEN(val) );
01235 return rb_str_new2( type_id );
01236 }
01237
01238 return rb_str_new2( "" );
01239 }
01240
01241
01242
01243
01244 VALUE
01245 syck_defaultresolver_node_import(VALUE self, VALUE node)
01246 {
01247 SyckNode *n;
01248 VALUE obj;
01249 Data_Get_Struct( node, SyckNode, n );
01250 if ( !yaml_org_handler( n, &obj ) )
01251 {
01252 obj = rb_funcall( self, s_transfer, 2, rb_str_new2( n->type_id ), obj );
01253 }
01254 return obj;
01255 }
01256
01257
01258
01259
01260 VALUE
01261 syck_genericresolver_node_import(VALUE self, VALUE node)
01262 {
01263 SyckNode *n;
01264 int i = 0;
01265 VALUE t = Qnil, obj = Qnil, v = Qnil, style = Qnil;
01266 Data_Get_Struct(node, SyckNode, n);
01267
01268 if ( n->type_id != NULL )
01269 {
01270 t = rb_str_new2(n->type_id);
01271 }
01272
01273 switch (n->kind)
01274 {
01275 case syck_str_kind:
01276 {
01277 v = rb_str_new( n->data.str->ptr, n->data.str->len );
01278 rb_enc_associate(v, rb_utf8_encoding());
01279 if ( n->data.str->style == scalar_1quote )
01280 {
01281 style = sym_1quote;
01282 }
01283 else if ( n->data.str->style == scalar_2quote )
01284 {
01285 style = sym_2quote;
01286 }
01287 else if ( n->data.str->style == scalar_fold )
01288 {
01289 style = sym_fold;
01290 }
01291 else if ( n->data.str->style == scalar_literal )
01292 {
01293 style = sym_literal;
01294 }
01295 else if ( n->data.str->style == scalar_plain )
01296 {
01297 style = sym_plain;
01298 }
01299 obj = rb_funcall( cScalar, s_new, 3, t, v, style );
01300 }
01301 break;
01302
01303 case syck_seq_kind:
01304 v = rb_ary_new2( syck_seq_count( n ) );
01305 for ( i = 0; i < syck_seq_count( n ); i++ )
01306 {
01307 rb_ary_store( v, i, syck_seq_read( n, i ) );
01308 }
01309 if ( n->data.list->style == seq_inline )
01310 {
01311 style = sym_inline;
01312 }
01313 obj = rb_funcall( cSeq, s_new, 3, t, v, style );
01314 rb_iv_set(obj, "@kind", sym_seq);
01315 break;
01316
01317 case syck_map_kind:
01318 v = rb_hash_new();
01319 for ( i = 0; i < syck_map_count( n ); i++ )
01320 {
01321 rb_hash_aset( v, syck_map_read( n, map_key, i ), syck_map_read( n, map_value, i ) );
01322 }
01323 if ( n->data.pairs->style == map_inline )
01324 {
01325 style = sym_inline;
01326 }
01327 obj = rb_funcall( cMap, s_new, 3, t, v, style );
01328 rb_iv_set(obj, "@kind", sym_map);
01329 break;
01330 }
01331
01332 return obj;
01333 }
01334
01335
01336
01337
01338 VALUE
01339 syck_badalias_initialize(VALUE self, VALUE val)
01340 {
01341 rb_iv_set( self, "@name", val );
01342 return self;
01343 }
01344
01345
01346
01347
01348 VALUE
01349 syck_badalias_cmp(VALUE alias1, VALUE alias2)
01350 {
01351 VALUE str1 = rb_ivar_get( alias1, s_name );
01352 VALUE str2 = rb_ivar_get( alias2, s_name );
01353 VALUE val = rb_funcall( str1, s_cmp, 1, str2 );
01354 return val;
01355 }
01356
01357
01358
01359
01360 VALUE
01361 syck_domaintype_initialize(VALUE self, VALUE domain, VALUE type_id, VALUE val)
01362 {
01363 rb_iv_set( self, "@domain", domain );
01364 rb_iv_set( self, "@type_id", type_id );
01365 rb_iv_set( self, "@value", val );
01366 return self;
01367 }
01368
01369
01370
01371
01372 VALUE
01373 syck_yobject_initialize(VALUE self, VALUE klass, VALUE ivars)
01374 {
01375 rb_iv_set( self, "@class", klass );
01376 rb_iv_set( self, "@ivars", ivars );
01377 return self;
01378 }
01379
01380
01381
01382
01383 VALUE
01384 syck_privatetype_initialize(VALUE self, VALUE type_id, VALUE val)
01385 {
01386 rb_iv_set( self, "@type_id", type_id );
01387 rb_iv_set( self, "@value", val );
01388 return self;
01389 }
01390
01391
01392
01393
01394 static void
01395 syck_node_mark(SyckNode *n)
01396 {
01397 int i;
01398 rb_gc_mark_maybe( n->id );
01399 switch ( n->kind )
01400 {
01401 case syck_seq_kind:
01402 for ( i = 0; i < n->data.list->idx; i++ )
01403 {
01404 rb_gc_mark( syck_seq_read( n, i ) );
01405 }
01406 break;
01407
01408 case syck_map_kind:
01409 for ( i = 0; i < n->data.pairs->idx; i++ )
01410 {
01411 rb_gc_mark( syck_map_read( n, map_key, i ) );
01412 rb_gc_mark( syck_map_read( n, map_value, i ) );
01413 }
01414 break;
01415
01416 case syck_str_kind:
01417 default:
01418
01419 break;
01420 }
01421 #if 0
01422 if ( n->shortcut ) syck_node_mark( n->shortcut );
01423 #endif
01424 }
01425
01426
01427
01428
01429 VALUE
01430 syck_scalar_alloc(VALUE class)
01431 {
01432 SyckNode *node = syck_alloc_str();
01433 VALUE obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );
01434 node->id = obj;
01435 return obj;
01436 }
01437
01438
01439
01440
01441 VALUE
01442 syck_scalar_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
01443 {
01444 rb_iv_set( self, "@kind", sym_scalar );
01445 rb_funcall( self, s_type_id_set, 1, type_id );
01446 rb_funcall( self, s_value_set, 1, val );
01447 rb_funcall( self, s_style_set, 1, style );
01448 return self;
01449 }
01450
01451
01452
01453
01454 VALUE
01455 syck_scalar_style_set(VALUE self, VALUE style)
01456 {
01457 SyckNode *node;
01458 Data_Get_Struct( self, SyckNode, node );
01459
01460 if ( NIL_P( style ) )
01461 {
01462 node->data.str->style = scalar_none;
01463 }
01464 else if ( style == sym_1quote )
01465 {
01466 node->data.str->style = scalar_1quote;
01467 }
01468 else if ( style == sym_2quote )
01469 {
01470 node->data.str->style = scalar_2quote;
01471 }
01472 else if ( style == sym_fold )
01473 {
01474 node->data.str->style = scalar_fold;
01475 }
01476 else if ( style == sym_literal )
01477 {
01478 node->data.str->style = scalar_literal;
01479 }
01480 else if ( style == sym_plain )
01481 {
01482 node->data.str->style = scalar_plain;
01483 }
01484
01485 rb_iv_set( self, "@style", style );
01486 return self;
01487 }
01488
01489
01490
01491
01492 VALUE
01493 syck_scalar_value_set(VALUE self, VALUE val)
01494 {
01495 SyckNode *node;
01496 Data_Get_Struct( self, SyckNode, node );
01497
01498 StringValue( val );
01499 node->data.str->ptr = syck_strndup( RSTRING_PTR(val), RSTRING_LEN(val) );
01500 node->data.str->len = RSTRING_LEN(val);
01501 node->data.str->style = scalar_none;
01502
01503 rb_iv_set( self, "@value", val );
01504 return val;
01505 }
01506
01507
01508
01509
01510 VALUE
01511 syck_seq_alloc(VALUE class)
01512 {
01513 SyckNode *node;
01514 VALUE obj;
01515 node = syck_alloc_seq();
01516 obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );
01517 node->id = obj;
01518 return obj;
01519 }
01520
01521
01522
01523
01524 VALUE
01525 syck_seq_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
01526 {
01527 SyckNode *node;
01528 Data_Get_Struct( self, SyckNode, node );
01529
01530 rb_iv_set( self, "@kind", sym_seq );
01531 rb_funcall( self, s_type_id_set, 1, type_id );
01532 rb_funcall( self, s_value_set, 1, val );
01533 rb_funcall( self, s_style_set, 1, style );
01534 return self;
01535 }
01536
01537
01538
01539
01540 VALUE
01541 syck_seq_value_set(VALUE self, VALUE val)
01542 {
01543 SyckNode *node;
01544 Data_Get_Struct( self, SyckNode, node );
01545
01546 val = rb_check_array_type( val );
01547 if ( !NIL_P( val ) ) {
01548 int i;
01549 syck_seq_empty( node );
01550 for ( i = 0; i < RARRAY_LEN( val ); i++ )
01551 {
01552 syck_seq_add( node, rb_ary_entry(val, i) );
01553 }
01554 }
01555
01556 rb_iv_set( self, "@value", val );
01557 return val;
01558 }
01559
01560
01561
01562
01563 VALUE
01564 syck_seq_add_m(VALUE self, VALUE val)
01565 {
01566 SyckNode *node;
01567 VALUE emitter = rb_ivar_get( self, s_emitter );
01568 Data_Get_Struct( self, SyckNode, node );
01569
01570 if ( rb_respond_to( emitter, s_node_export ) ) {
01571 val = rb_funcall( emitter, s_node_export, 1, val );
01572 }
01573 syck_seq_add( node, val );
01574 rb_ary_push( rb_ivar_get( self, s_value ), val );
01575
01576 return self;
01577 }
01578
01579
01580
01581
01582 VALUE
01583 syck_seq_style_set(VALUE self, VALUE style)
01584 {
01585 SyckNode *node;
01586 Data_Get_Struct( self, SyckNode, node );
01587
01588 if ( style == sym_inline )
01589 {
01590 node->data.list->style = seq_inline;
01591 }
01592 else
01593 {
01594 node->data.list->style = seq_none;
01595 }
01596
01597 rb_iv_set( self, "@style", style );
01598 return self;
01599 }
01600
01601
01602
01603
01604 VALUE
01605 syck_map_alloc(VALUE class)
01606 {
01607 SyckNode *node;
01608 VALUE obj;
01609 node = syck_alloc_map();
01610 obj = Data_Wrap_Struct( class, syck_node_mark, syck_free_node, node );
01611 node->id = obj;
01612 return obj;
01613 }
01614
01615
01616
01617
01618 VALUE
01619 syck_map_initialize(VALUE self, VALUE type_id, VALUE val, VALUE style)
01620 {
01621 SyckNode *node;
01622 Data_Get_Struct( self, SyckNode, node );
01623
01624 if ( !NIL_P( val ) )
01625 {
01626 VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash");
01627 VALUE keys;
01628 int i;
01629 if ( NIL_P(hsh) )
01630 {
01631 rb_raise( rb_eTypeError, "wrong argument type" );
01632 }
01633
01634 keys = rb_funcall( hsh, s_keys, 0 );
01635 for ( i = 0; i < RARRAY_LEN(keys); i++ )
01636 {
01637 VALUE key = rb_ary_entry(keys, i);
01638 syck_map_add( node, key, rb_hash_aref(hsh, key) );
01639 }
01640 }
01641
01642 rb_iv_set( self, "@kind", sym_seq );
01643 rb_funcall( self, s_type_id_set, 1, type_id );
01644 rb_funcall( self, s_value_set, 1, val );
01645 rb_funcall( self, s_style_set, 1, style );
01646 return self;
01647 }
01648
01649
01650
01651
01652 VALUE
01653 syck_map_value_set(VALUE self, VALUE val)
01654 {
01655 SyckNode *node;
01656 Data_Get_Struct( self, SyckNode, node );
01657
01658 if ( !NIL_P( val ) )
01659 {
01660 VALUE hsh = rb_check_convert_type(val, T_HASH, "Hash", "to_hash");
01661 VALUE keys;
01662 int i;
01663 if ( NIL_P(hsh) )
01664 {
01665 rb_raise( rb_eTypeError, "wrong argument type" );
01666 }
01667
01668 syck_map_empty( node );
01669 keys = rb_funcall( hsh, s_keys, 0 );
01670 for ( i = 0; i < RARRAY_LEN(keys); i++ )
01671 {
01672 VALUE key = rb_ary_entry(keys, i);
01673 syck_map_add( node, key, rb_hash_aref(hsh, key) );
01674 }
01675 }
01676
01677 rb_iv_set( self, "@value", val );
01678 return val;
01679 }
01680
01681
01682
01683
01684 VALUE
01685 syck_map_add_m(VALUE self, VALUE key, VALUE val)
01686 {
01687 SyckNode *node;
01688 VALUE emitter = rb_ivar_get( self, s_emitter );
01689 Data_Get_Struct( self, SyckNode, node );
01690
01691 if ( rb_respond_to( emitter, s_node_export ) ) {
01692 key = rb_funcall( emitter, s_node_export, 1, key );
01693 val = rb_funcall( emitter, s_node_export, 1, val );
01694 }
01695 syck_map_add( node, key, val );
01696 rb_hash_aset( rb_ivar_get( self, s_value ), key, val );
01697
01698 return self;
01699 }
01700
01701
01702
01703
01704 VALUE
01705 syck_map_style_set(VALUE self, VALUE style)
01706 {
01707 SyckNode *node;
01708 Data_Get_Struct( self, SyckNode, node );
01709
01710 if ( style == sym_inline )
01711 {
01712 node->data.pairs->style = map_inline;
01713 }
01714 else
01715 {
01716 node->data.pairs->style = map_none;
01717 }
01718
01719 rb_iv_set( self, "@style", style );
01720 return self;
01721 }
01722
01723
01724
01725
01726 VALUE
01727 syck_node_init_copy(VALUE copy, VALUE orig)
01728 {
01729 SyckNode *copy_n;
01730 SyckNode *orig_n;
01731
01732 if ( copy == orig )
01733 return copy;
01734
01735 if ( TYPE( orig ) != T_DATA )
01736 {
01737 rb_raise( rb_eTypeError, "wrong argument type" );
01738 }
01739
01740 Data_Get_Struct( orig, SyckNode, orig_n );
01741 Data_Get_Struct( copy, SyckNode, copy_n );
01742 MEMCPY( copy_n, orig_n, SyckNode, 1 );
01743 return copy;
01744 }
01745
01746
01747
01748
01749 VALUE
01750 syck_node_type_id_set(VALUE self, VALUE type_id)
01751 {
01752 SyckNode *node;
01753 Data_Get_Struct( self, SyckNode, node );
01754
01755 S_FREE( node->type_id );
01756
01757 if ( !NIL_P( type_id ) ) {
01758 StringValue( type_id );
01759 node->type_id = syck_strndup( RSTRING_PTR(type_id), RSTRING_LEN(type_id) );
01760 }
01761
01762 rb_iv_set( self, "@type_id", type_id );
01763 return type_id;
01764 }
01765
01766
01767
01768
01769 VALUE
01770 syck_node_transform(VALUE self)
01771 {
01772 VALUE t;
01773 SyckNode *n = NULL;
01774 SyckNode *orig_n;
01775 Data_Get_Struct(self, SyckNode, orig_n);
01776 t = Data_Wrap_Struct( cNode, syck_node_mark, syck_free_node, 0 );
01777
01778 switch (orig_n->kind)
01779 {
01780 case syck_map_kind:
01781 {
01782 int i;
01783 DATA_PTR(t) = n = syck_alloc_map();
01784 for ( i = 0; i < orig_n->data.pairs->idx; i++ )
01785 {
01786 syck_map_add( n, rb_funcall( syck_map_read( orig_n, map_key, i ), s_transform, 0 ),
01787 rb_funcall( syck_map_read( orig_n, map_value, i ), s_transform, 0 ) );
01788 }
01789 }
01790 break;
01791
01792 case syck_seq_kind:
01793 {
01794 int i;
01795 DATA_PTR(t) = n = syck_alloc_seq();
01796 for ( i = 0; i < orig_n->data.list->idx; i++ )
01797 {
01798 syck_seq_add( n, rb_funcall( syck_seq_read( orig_n, i ), s_transform, 0 ) );
01799 }
01800 }
01801 break;
01802
01803 case syck_str_kind:
01804 DATA_PTR(t) = n = syck_new_str2( orig_n->data.str->ptr, orig_n->data.str->len, orig_n->data.str->style );
01805 break;
01806 }
01807
01808 if ( orig_n->type_id != NULL )
01809 {
01810 n->type_id = syck_strndup( orig_n->type_id, strlen( orig_n->type_id ) );
01811 }
01812 if ( orig_n->anchor != NULL )
01813 {
01814 n->anchor = syck_strndup( orig_n->anchor, strlen( orig_n->anchor ) );
01815 }
01816 n->id = t;
01817 return rb_funcall( oDefaultResolver, s_node_import, 1, t );
01818 }
01819
01820
01821
01822
01823
01824
01825 void
01826 rb_syck_emitter_handler(SyckEmitter *e, st_data_t data)
01827 {
01828 SyckNode *n;
01829 Data_Get_Struct((VALUE)data, SyckNode, n);
01830
01831 switch (n->kind)
01832 {
01833 case syck_map_kind:
01834 {
01835 int i;
01836 syck_emit_map( e, n->type_id, n->data.pairs->style );
01837 for ( i = 0; i < n->data.pairs->idx; i++ )
01838 {
01839 syck_emit_item( e, syck_map_read( n, map_key, i ) );
01840 syck_emit_item( e, syck_map_read( n, map_value, i ) );
01841 }
01842 syck_emit_end( e );
01843 }
01844 break;
01845
01846 case syck_seq_kind:
01847 {
01848 int i;
01849 syck_emit_seq( e, n->type_id, n->data.list->style );
01850 for ( i = 0; i < n->data.list->idx; i++ )
01851 {
01852 syck_emit_item( e, syck_seq_read( n, i ) );
01853 }
01854 syck_emit_end( e );
01855 }
01856 break;
01857
01858 case syck_str_kind:
01859 {
01860 syck_emit_scalar( e, n->type_id, n->data.str->style, 0, 0, 0, n->data.str->ptr, n->data.str->len );
01861 }
01862 break;
01863 }
01864 }
01865
01866
01867
01868
01869 void
01870 rb_syck_output_handler(SyckEmitter * emitter, char *str, long len)
01871 {
01872 struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus;
01873 VALUE dest = bonus->port;
01874 if (TYPE(dest) == T_STRING) {
01875 rb_str_cat( dest, str, len );
01876 } else {
01877 rb_io_write( dest, rb_str_new( str, len ) );
01878 }
01879 }
01880
01881
01882
01883
01884
01885 void
01886 syck_out_mark(VALUE emitter, VALUE node)
01887 {
01888 SyckEmitter *emitterPtr;
01889 struct emitter_xtra *bonus;
01890 Data_Get_Struct(emitter, SyckEmitter, emitterPtr);
01891 bonus = (struct emitter_xtra *)emitterPtr->bonus;
01892 rb_ivar_set( node, s_emitter, emitter );
01893
01894 if ( !NIL_P( bonus->oid ) ) {
01895 rb_hash_aset( bonus->data, bonus->oid, node );
01896 }
01897 }
01898
01899
01900
01901
01902 static void
01903 syck_mark_emitter(SyckEmitter *emitter)
01904 {
01905 struct emitter_xtra *bonus = (struct emitter_xtra *)emitter->bonus;
01906 rb_gc_mark( bonus->oid );
01907 rb_gc_mark( bonus->data );
01908 rb_gc_mark( bonus->port );
01909 }
01910
01911
01912
01913
01914 void
01915 rb_syck_free_emitter(SyckEmitter *e)
01916 {
01917 S_FREE( e->bonus );
01918 syck_free_emitter(e);
01919 }
01920
01921
01922
01923
01924 VALUE syck_emitter_s_alloc _((VALUE));
01925 VALUE
01926 syck_emitter_s_alloc(VALUE class)
01927 {
01928 VALUE pobj;
01929 SyckEmitter *emitter = syck_new_emitter();
01930
01931 emitter->bonus = S_ALLOC( struct emitter_xtra );
01932 S_MEMZERO( emitter->bonus, struct emitter_xtra, 1 );
01933
01934 pobj = Data_Wrap_Struct( class, syck_mark_emitter, rb_syck_free_emitter, emitter );
01935 syck_emitter_handler( emitter, rb_syck_emitter_handler );
01936 syck_output_handler( emitter, rb_syck_output_handler );
01937
01938 rb_ivar_set( pobj, s_out, rb_funcall( cOut, s_new, 1, pobj ) );
01939 return pobj;
01940 }
01941
01942 static VALUE
01943 id_hash_new(void)
01944 {
01945 VALUE hash;
01946 hash = rb_hash_new();
01947 rb_funcall(hash, rb_intern("compare_by_identity"), 0);
01948 return hash;
01949 }
01950
01951
01952
01953
01954 VALUE
01955 syck_emitter_reset(int argc, VALUE *argv, VALUE self)
01956 {
01957 VALUE options, tmp;
01958 SyckEmitter *emitter;
01959 struct emitter_xtra *bonus;
01960
01961 Data_Get_Struct(self, SyckEmitter, emitter);
01962 bonus = (struct emitter_xtra *)emitter->bonus;
01963
01964 bonus->oid = Qnil;
01965 bonus->port = rb_str_new2( "" );
01966 bonus->data = id_hash_new();
01967
01968 if (rb_scan_args(argc, argv, "01", &options) == 0)
01969 {
01970 options = rb_hash_new();
01971 rb_ivar_set(self, s_options, options);
01972 }
01973 else if ( !NIL_P(tmp = rb_check_string_type(options)) )
01974 {
01975 bonus->port = tmp;
01976 }
01977 else if ( rb_respond_to( options, s_write ) )
01978 {
01979 bonus->port = options;
01980 }
01981 else
01982 {
01983 Check_Type(options, T_HASH);
01984 rb_ivar_set(self, s_options, options);
01985 }
01986
01987 emitter->headless = 0;
01988 rb_ivar_set(self, s_level, INT2FIX(0));
01989 rb_ivar_set(self, s_resolver, Qnil);
01990 return self;
01991 }
01992
01993
01994
01995
01996 VALUE
01997 syck_emitter_emit(int argc, VALUE *argv, VALUE self)
01998 {
01999 VALUE oid, proc;
02000 SyckEmitter *emitter;
02001 struct emitter_xtra *bonus;
02002 SYMID symple;
02003 int level = FIX2INT(rb_ivar_get(self, s_level)) + 1;
02004 rb_ivar_set(self, s_level, INT2FIX(level));
02005
02006 rb_scan_args(argc, argv, "1&", &oid, &proc);
02007 Data_Get_Struct(self, SyckEmitter, emitter);
02008 bonus = (struct emitter_xtra *)emitter->bonus;
02009
02010
02011 bonus->oid = oid;
02012 if ( !NIL_P( oid ) && RTEST( rb_funcall( bonus->data, s_haskey, 1, oid ) ) ) {
02013 symple = rb_hash_aref( bonus->data, oid );
02014 } else {
02015 symple = rb_funcall( proc, s_call, 1, rb_ivar_get( self, s_out ) );
02016 }
02017 syck_emitter_mark_node( emitter, (st_data_t)symple );
02018
02019
02020 level -= 1;
02021 rb_ivar_set(self, s_level, INT2FIX(level));
02022 if ( level == 0 )
02023 {
02024 syck_emit(emitter, (st_data_t)symple);
02025 syck_emitter_flush(emitter, 0);
02026
02027 return bonus->port;
02028 }
02029
02030 return symple;
02031 }
02032
02033
02034
02035
02036 VALUE
02037 syck_emitter_node_export(VALUE self, VALUE node)
02038 {
02039 return rb_funcall( node, s_to_yaml, 1, self );
02040 }
02041
02042
02043
02044
02045 VALUE
02046 syck_emitter_set_resolver(VALUE self, VALUE resolver)
02047 {
02048 rb_ivar_set( self, s_resolver, resolver );
02049 return self;
02050 }
02051
02052
02053
02054
02055 VALUE
02056 syck_out_initialize(VALUE self, VALUE emitter)
02057 {
02058 rb_ivar_set( self, s_emitter, emitter );
02059 return self;
02060 }
02061
02062
02063
02064
02065 VALUE
02066 syck_out_map(int argc, VALUE *argv, VALUE self)
02067 {
02068 VALUE type_id, style, map;
02069 if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) {
02070 style = Qnil;
02071 }
02072 map = rb_funcall( cMap, s_new, 3, type_id, rb_hash_new(), style );
02073 syck_out_mark( rb_ivar_get( self, s_emitter ), map );
02074 rb_yield( map );
02075 return map;
02076 }
02077
02078
02079
02080
02081 VALUE
02082 syck_out_seq(int argc, VALUE *argv, VALUE self)
02083 {
02084 VALUE type_id, style, seq;
02085 if (rb_scan_args(argc, argv, "11", &type_id, &style) == 1) {
02086 style = Qnil;
02087 }
02088 seq = rb_funcall( cSeq, s_new, 3, type_id, rb_ary_new(), style );
02089 syck_out_mark( rb_ivar_get( self, s_emitter ), seq );
02090 rb_yield( seq );
02091 return seq;
02092 }
02093
02094
02095
02096
02097
02098
02099 VALUE
02100 syck_out_scalar(int argc, VALUE *argv, VALUE self)
02101 {
02102 VALUE type_id, str, style, scalar;
02103 rb_scan_args(argc, argv, "21", &type_id, &str, &style);
02104 scalar = rb_funcall( cScalar, s_new, 3, type_id, str, style );
02105 syck_out_mark( rb_ivar_get( self, s_emitter ), scalar );
02106 return scalar;
02107 }
02108
02109
02110
02111
02112 void
02113 Init_syck()
02114 {
02115 VALUE rb_syck = rb_define_module_under( rb_cObject, "Syck" );
02116 rb_define_module_function( rb_syck, "compile", rb_syck_compile, 1 );
02117
02118
02119
02120
02121 s_new = rb_intern("new");
02122 s_utc = rb_intern("utc");
02123 s_at = rb_intern("at");
02124 s_to_f = rb_intern("to_f");
02125 s_to_i = rb_intern("to_i");
02126 s_read = rb_intern("read");
02127 s_binmode = rb_intern("binmode");
02128 s_transfer = rb_intern("transfer");
02129 s_call = rb_intern("call");
02130 s_cmp = rb_intern("<=>");
02131 s_intern = rb_intern("intern");
02132 s_update = rb_intern("update");
02133 s_detect_implicit = rb_intern("detect_implicit");
02134 s_dup = rb_intern("dup");
02135 s_default_set = rb_intern("default=");
02136 s_match = rb_intern("match");
02137 s_push = rb_intern("push");
02138 s_haskey = rb_intern("has_key?");
02139 s_keys = rb_intern("keys");
02140 s_node_import = rb_intern("node_import");
02141 s_tr_bang = rb_intern("tr!");
02142 s_unpack = rb_intern("unpack");
02143 s_write = rb_intern("write");
02144 s_tag_read_class = rb_intern( "yaml_tag_read_class" );
02145 s_tag_subclasses = rb_intern( "yaml_tag_subclasses?" );
02146 s_emitter = rb_intern( "emitter" );
02147 s_set_resolver = rb_intern( "set_resolver" );
02148 s_node_export = rb_intern( "node_export" );
02149 s_to_yaml = rb_intern( "to_yaml" );
02150 s_transform = rb_intern( "transform" );
02151 s_yaml_new = rb_intern("yaml_new");
02152 s_yaml_initialize = rb_intern("yaml_initialize");
02153 s_each = rb_intern("each");
02154 s_parse = rb_intern("parse");
02155
02156 s_tags = rb_intern("@tags");
02157 s_name = rb_intern("@name");
02158 s_options = rb_intern("@options");
02159 s_kind = rb_intern("@kind");
02160 s_type_id = rb_intern("@type_id");
02161 s_type_id_set = rb_intern("type_id=");
02162 s_resolver = rb_intern("@resolver");
02163 s_level = rb_intern( "@level" );
02164 s_style = rb_intern("@style");
02165 s_style_set = rb_intern("style=");
02166 s_value = rb_intern("@value");
02167 s_value_set = rb_intern("value=");
02168 s_out = rb_intern("@out");
02169 s_input = rb_intern("@input");
02170
02171 sym_model = ID2SYM(rb_intern("Model"));
02172 sym_generic = ID2SYM(rb_intern("Generic"));
02173 sym_bytecode = ID2SYM(rb_intern("bytecode"));
02174 sym_map = ID2SYM(rb_intern("map"));
02175 sym_scalar = ID2SYM(rb_intern("scalar"));
02176 sym_seq = ID2SYM(rb_intern("seq"));
02177 sym_1quote = ID2SYM(rb_intern("quote1"));
02178 sym_2quote = ID2SYM(rb_intern("quote2"));
02179 sym_fold = ID2SYM(rb_intern("fold"));
02180 sym_literal = ID2SYM(rb_intern("literal"));
02181 sym_plain = ID2SYM(rb_intern("plain"));
02182 sym_inline = ID2SYM(rb_intern("inline"));
02183
02184
02185
02186
02187 cResolver = rb_define_class_under( rb_syck, "Resolver", rb_cObject );
02188 rb_define_attr( cResolver, "tags", 1, 1 );
02189 rb_define_method( cResolver, "initialize", syck_resolver_initialize, 0 );
02190 rb_define_method( cResolver, "add_type", syck_resolver_add_type, 2 );
02191 rb_define_method( cResolver, "use_types_at", syck_resolver_use_types_at, 1 );
02192 rb_define_method( cResolver, "detect_implicit", syck_resolver_detect_implicit, 1 );
02193 rb_define_method( cResolver, "transfer", syck_resolver_transfer, 2 );
02194 rb_define_method( cResolver, "node_import", syck_resolver_node_import, 1 );
02195 rb_define_method( cResolver, "tagurize", syck_resolver_tagurize, 1 );
02196
02197 rb_global_variable( &oDefaultResolver );
02198 oDefaultResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 );
02199 rb_define_singleton_method( oDefaultResolver, "node_import", syck_defaultresolver_node_import, 1 );
02200 rb_define_singleton_method( oDefaultResolver, "detect_implicit", syck_defaultresolver_detect_implicit, 1 );
02201 rb_define_const( rb_syck, "DefaultResolver", oDefaultResolver );
02202 rb_global_variable( &oGenericResolver );
02203 oGenericResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 );
02204 rb_define_singleton_method( oGenericResolver, "node_import", syck_genericresolver_node_import, 1 );
02205 rb_define_const( rb_syck, "GenericResolver", oGenericResolver );
02206
02207
02208
02209
02210 cParser = rb_define_class_under( rb_syck, "Parser", rb_cObject );
02211 rb_define_attr( cParser, "options", 1, 1 );
02212 rb_define_attr( cParser, "resolver", 1, 1 );
02213 rb_define_attr( cParser, "input", 1, 1 );
02214 rb_define_alloc_func( cParser, syck_parser_s_alloc );
02215 rb_define_method(cParser, "initialize", syck_parser_initialize, -1 );
02216 rb_define_method(cParser, "bufsize=", syck_parser_bufsize_set, 1 );
02217 rb_define_method(cParser, "bufsize", syck_parser_bufsize_get, 0 );
02218 rb_define_method(cParser, "load", syck_parser_load, -1);
02219 rb_define_method(cParser, "load_documents", syck_parser_load_documents, -1);
02220 rb_define_method(cParser, "set_resolver", syck_parser_set_resolver, 1);
02221
02222
02223
02224
02225 cNode = rb_define_class_under( rb_syck, "Node", rb_cObject );
02226 rb_define_method( cNode, "initialize_copy", syck_node_init_copy, 1 );
02227 rb_define_attr( cNode, "emitter", 1, 1 );
02228 rb_define_attr( cNode, "resolver", 1, 1 );
02229 rb_define_attr( cNode, "kind", 1, 0 );
02230 rb_define_attr( cNode, "type_id", 1, 0 );
02231 rb_define_attr( cNode, "value", 1, 0 );
02232 rb_define_method( cNode, "type_id=", syck_node_type_id_set, 1 );
02233 rb_define_method( cNode, "transform", syck_node_transform, 0);
02234
02235
02236
02237
02238
02239 cScalar = rb_define_class_under( rb_syck, "Scalar", cNode );
02240 rb_define_alloc_func( cScalar, syck_scalar_alloc );
02241 rb_define_method( cScalar, "initialize", syck_scalar_initialize, 3 );
02242 rb_define_method( cScalar, "value=", syck_scalar_value_set, 1 );
02243 rb_define_method( cScalar, "style=", syck_scalar_style_set, 1 );
02244 cSeq = rb_define_class_under( rb_syck, "Seq", cNode );
02245 rb_define_alloc_func( cSeq, syck_seq_alloc );
02246 rb_define_method( cSeq, "initialize", syck_seq_initialize, 3 );
02247 rb_define_method( cSeq, "value=", syck_seq_value_set, 1 );
02248 rb_define_method( cSeq, "add", syck_seq_add_m, 1 );
02249 rb_define_method( cSeq, "style=", syck_seq_style_set, 1 );
02250 cMap = rb_define_class_under( rb_syck, "Map", cNode );
02251 rb_define_alloc_func( cMap, syck_map_alloc );
02252 rb_define_method( cMap, "initialize", syck_map_initialize, 3 );
02253 rb_define_method( cMap, "value=", syck_map_value_set, 1 );
02254 rb_define_method( cMap, "add", syck_map_add_m, 2 );
02255 rb_define_method( cMap, "style=", syck_map_style_set, 1 );
02256
02257
02258
02259
02260 cPrivateType = rb_define_class_under( rb_syck, "PrivateType", rb_cObject );
02261 rb_define_attr( cPrivateType, "type_id", 1, 1 );
02262 rb_define_attr( cPrivateType, "value", 1, 1 );
02263 rb_define_method( cPrivateType, "initialize", syck_privatetype_initialize, 2);
02264
02265
02266
02267
02268 cDomainType = rb_define_class_under( rb_syck, "DomainType", rb_cObject );
02269 rb_define_attr( cDomainType, "domain", 1, 1 );
02270 rb_define_attr( cDomainType, "type_id", 1, 1 );
02271 rb_define_attr( cDomainType, "value", 1, 1 );
02272 rb_define_method( cDomainType, "initialize", syck_domaintype_initialize, 3);
02273
02274
02275
02276
02277 cYObject = rb_define_class_under( rb_syck, "Object", rb_cObject );
02278 rb_define_attr( cYObject, "class", 1, 1 );
02279 rb_define_attr( cYObject, "ivars", 1, 1 );
02280 rb_define_method( cYObject, "initialize", syck_yobject_initialize, 2);
02281 rb_define_method( cYObject, "yaml_initialize", syck_yobject_initialize, 2);
02282
02283
02284
02285
02286 cBadAlias = rb_define_class_under( rb_syck, "BadAlias", rb_cObject );
02287 rb_define_attr( cBadAlias, "name", 1, 1 );
02288 rb_define_method( cBadAlias, "initialize", syck_badalias_initialize, 1);
02289 rb_define_method( cBadAlias, "<=>", syck_badalias_cmp, 1);
02290 rb_include_module( cBadAlias, rb_const_get( rb_cObject, rb_intern("Comparable") ) );
02291
02292
02293
02294
02295 cMergeKey = rb_define_class_under( rb_syck, "MergeKey", rb_cObject );
02296
02297
02298
02299
02300 cDefaultKey = rb_define_class_under( rb_syck, "DefaultKey", rb_cObject );
02301
02302
02303
02304
02305 cOut = rb_define_class_under( rb_syck, "Out", rb_cObject );
02306 rb_define_attr( cOut, "emitter", 1, 1 );
02307 rb_define_method( cOut, "initialize", syck_out_initialize, 1 );
02308 rb_define_method( cOut, "map", syck_out_map, -1 );
02309 rb_define_method( cOut, "seq", syck_out_seq, -1 );
02310 rb_define_method( cOut, "scalar", syck_out_scalar, -1 );
02311
02312
02313
02314
02315 cEmitter = rb_define_class_under( rb_syck, "Emitter", rb_cObject );
02316 rb_define_attr( cEmitter, "level", 1, 1 );
02317 rb_define_alloc_func( cEmitter, syck_emitter_s_alloc );
02318 rb_define_method( cEmitter, "initialize", syck_emitter_reset, -1 );
02319 rb_define_method( cEmitter, "reset", syck_emitter_reset, -1 );
02320 rb_define_method( cEmitter, "emit", syck_emitter_emit, -1 );
02321 rb_define_method( cEmitter, "set_resolver", syck_emitter_set_resolver, 1);
02322 rb_define_method( cEmitter, "node_export", syck_emitter_node_export, 1);
02323 }
02324
02325