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