00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "ruby.h"
00014 #include "rubysig.h"
00015 #include "node.h"
00016 #include "st.h"
00017 #include <ctype.h>
00018
00019 extern st_table *rb_class_tbl;
00020
00021 VALUE
00022 rb_class_boot(super)
00023 VALUE super;
00024 {
00025 NEWOBJ(klass, struct RClass);
00026 OBJSETUP(klass, rb_cClass, T_CLASS);
00027
00028 klass->super = super;
00029 klass->iv_tbl = 0;
00030 klass->m_tbl = 0;
00031 klass->m_tbl = st_init_numtable();
00032
00033 OBJ_INFECT(klass, super);
00034 return (VALUE)klass;
00035 }
00036
00037 VALUE
00038 rb_class_new(super)
00039 VALUE super;
00040 {
00041 Check_Type(super, T_CLASS);
00042 if (super == rb_cClass) {
00043 rb_raise(rb_eTypeError, "can't make subclass of Class");
00044 }
00045 if (FL_TEST(super, FL_SINGLETON)) {
00046 rb_raise(rb_eTypeError, "can't make subclass of virtual class");
00047 }
00048 return rb_class_boot(super);
00049 }
00050
00051 static int
00052 clone_method(mid, body, tbl)
00053 ID mid;
00054 NODE *body;
00055 st_table *tbl;
00056 {
00057 st_insert(tbl, mid, (st_data_t)NEW_METHOD(body->nd_body, body->nd_noex));
00058 return ST_CONTINUE;
00059 }
00060
00061
00062 VALUE
00063 rb_mod_init_copy(clone, orig)
00064 VALUE clone, orig;
00065 {
00066 rb_obj_init_copy(clone, orig);
00067 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
00068 RBASIC(clone)->klass = rb_singleton_class_clone(orig);
00069 }
00070 RCLASS(clone)->super = RCLASS(orig)->super;
00071 if (RCLASS(orig)->iv_tbl) {
00072 ID id;
00073
00074 RCLASS(clone)->iv_tbl = st_copy(RCLASS(orig)->iv_tbl);
00075 id = rb_intern("__classpath__");
00076 st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
00077 id = rb_intern("__classid__");
00078 st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
00079 }
00080 if (RCLASS(orig)->m_tbl) {
00081 RCLASS(clone)->m_tbl = st_init_numtable();
00082 st_foreach(RCLASS(orig)->m_tbl, clone_method,
00083 (st_data_t)RCLASS(clone)->m_tbl);
00084 }
00085
00086 return clone;
00087 }
00088
00089
00090 VALUE
00091 rb_class_init_copy(clone, orig)
00092 VALUE clone, orig;
00093 {
00094 if (RCLASS(clone)->super != 0) {
00095 rb_raise(rb_eTypeError, "already initialized class");
00096 }
00097 if (FL_TEST(orig, FL_SINGLETON)) {
00098 rb_raise(rb_eTypeError, "can't copy singleton class");
00099 }
00100 return rb_mod_init_copy(clone, orig);
00101 }
00102
00103 VALUE
00104 rb_singleton_class_clone(obj)
00105 VALUE obj;
00106 {
00107 VALUE klass = RBASIC(obj)->klass;
00108
00109 if (!FL_TEST(klass, FL_SINGLETON))
00110 return klass;
00111 else {
00112
00113 NEWOBJ(clone, struct RClass);
00114 OBJSETUP(clone, 0, RBASIC(klass)->flags);
00115
00116 if (BUILTIN_TYPE(obj) == T_CLASS) {
00117 RBASIC(clone)->klass = (VALUE)clone;
00118 }
00119 else {
00120 RBASIC(clone)->klass = rb_singleton_class_clone(klass);
00121 }
00122
00123 clone->super = RCLASS(klass)->super;
00124 clone->iv_tbl = 0;
00125 clone->m_tbl = 0;
00126 if (RCLASS(klass)->iv_tbl) {
00127 clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
00128 }
00129 clone->m_tbl = st_init_numtable();
00130 st_foreach(RCLASS(klass)->m_tbl, clone_method,
00131 (st_data_t)clone->m_tbl);
00132 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
00133 FL_SET(clone, FL_SINGLETON);
00134 return (VALUE)clone;
00135 }
00136 }
00137
00138 void
00139 rb_singleton_class_attached(klass, obj)
00140 VALUE klass, obj;
00141 {
00142 if (FL_TEST(klass, FL_SINGLETON)) {
00143 if (!RCLASS(klass)->iv_tbl) {
00144 RCLASS(klass)->iv_tbl = st_init_numtable();
00145 }
00146 st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
00147 }
00148 }
00149
00150 VALUE
00151 rb_make_metaclass(obj, super)
00152 VALUE obj, super;
00153 {
00154 VALUE klass = rb_class_boot(super);
00155 FL_SET(klass, FL_SINGLETON);
00156 RBASIC(obj)->klass = klass;
00157 rb_singleton_class_attached(klass, obj);
00158 if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) {
00159 RBASIC(klass)->klass = klass;
00160 RCLASS(klass)->super = RBASIC(rb_class_real(RCLASS(obj)->super))->klass;
00161 }
00162 else {
00163 VALUE metasuper = RBASIC(rb_class_real(super))->klass;
00164
00165
00166 if (metasuper) {
00167 RBASIC(klass)->klass = metasuper;
00168 }
00169 }
00170
00171 return klass;
00172 }
00173
00174 VALUE
00175 rb_define_class_id(id, super)
00176 ID id;
00177 VALUE super;
00178 {
00179 VALUE klass;
00180
00181 if (!super) super = rb_cObject;
00182 klass = rb_class_new(super);
00183 rb_make_metaclass(klass, RBASIC(super)->klass);
00184
00185 return klass;
00186 }
00187
00188 void
00189 rb_check_inheritable(super)
00190 VALUE super;
00191 {
00192 if (TYPE(super) != T_CLASS) {
00193 rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
00194 rb_obj_classname(super));
00195 }
00196 if (RBASIC(super)->flags & FL_SINGLETON) {
00197 rb_raise(rb_eTypeError, "can't make subclass of virtual class");
00198 }
00199 }
00200
00201 VALUE
00202 rb_class_inherited(super, klass)
00203 VALUE super, klass;
00204 {
00205 if (!super) super = rb_cObject;
00206 return rb_funcall(super, rb_intern("inherited"), 1, klass);
00207 }
00208
00209 VALUE
00210 rb_define_class(name, super)
00211 const char *name;
00212 VALUE super;
00213 {
00214 VALUE klass;
00215 ID id;
00216
00217 id = rb_intern(name);
00218 if (rb_const_defined(rb_cObject, id)) {
00219 klass = rb_const_get(rb_cObject, id);
00220 if (TYPE(klass) != T_CLASS) {
00221 rb_raise(rb_eTypeError, "%s is not a class", name);
00222 }
00223 if (rb_class_real(RCLASS(klass)->super) != super) {
00224 rb_name_error(id, "%s is already defined", name);
00225 }
00226 return klass;
00227 }
00228 if (!super) {
00229 rb_warn("no super class for `%s', Object assumed", name);
00230 }
00231 klass = rb_define_class_id(id, super);
00232 st_add_direct(rb_class_tbl, id, klass);
00233 rb_name_class(klass, id);
00234 rb_const_set(rb_cObject, id, klass);
00235 rb_class_inherited(super, klass);
00236
00237 return klass;
00238 }
00239
00240 VALUE
00241 rb_define_class_under(outer, name, super)
00242 VALUE outer;
00243 const char *name;
00244 VALUE super;
00245 {
00246 VALUE klass;
00247 ID id;
00248
00249 id = rb_intern(name);
00250 if (rb_const_defined_at(outer, id)) {
00251 klass = rb_const_get_at(outer, id);
00252 if (TYPE(klass) != T_CLASS) {
00253 rb_raise(rb_eTypeError, "%s is not a class", name);
00254 }
00255 if (rb_class_real(RCLASS(klass)->super) != super) {
00256 rb_name_error(id, "%s is already defined", name);
00257 }
00258 return klass;
00259 }
00260 if (!super) {
00261 rb_warn("no super class for `%s::%s', Object assumed",
00262 rb_class2name(outer), name);
00263 }
00264 klass = rb_define_class_id(id, super);
00265 rb_set_class_path(klass, outer, name);
00266 rb_const_set(outer, id, klass);
00267 rb_class_inherited(super, klass);
00268
00269 return klass;
00270 }
00271
00272 VALUE
00273 rb_module_new()
00274 {
00275 NEWOBJ(mdl, struct RClass);
00276 OBJSETUP(mdl, rb_cModule, T_MODULE);
00277
00278 mdl->super = 0;
00279 mdl->iv_tbl = 0;
00280 mdl->m_tbl = 0;
00281 mdl->m_tbl = st_init_numtable();
00282
00283 return (VALUE)mdl;
00284 }
00285
00286 VALUE
00287 rb_define_module_id(id)
00288 ID id;
00289 {
00290 VALUE mdl;
00291
00292 mdl = rb_module_new();
00293 rb_name_class(mdl, id);
00294
00295 return mdl;
00296 }
00297
00298 VALUE
00299 rb_define_module(name)
00300 const char *name;
00301 {
00302 VALUE module;
00303 ID id;
00304
00305 id = rb_intern(name);
00306 if (rb_const_defined(rb_cObject, id)) {
00307 module = rb_const_get(rb_cObject, id);
00308 if (TYPE(module) == T_MODULE)
00309 return module;
00310 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
00311 }
00312 module = rb_define_module_id(id);
00313 st_add_direct(rb_class_tbl, id, module);
00314 rb_const_set(rb_cObject, id, module);
00315
00316 return module;
00317 }
00318
00319 VALUE
00320 rb_define_module_under(outer, name)
00321 VALUE outer;
00322 const char *name;
00323 {
00324 VALUE module;
00325 ID id;
00326
00327 id = rb_intern(name);
00328 if (rb_const_defined_at(outer, id)) {
00329 module = rb_const_get_at(outer, id);
00330 if (TYPE(module) == T_MODULE)
00331 return module;
00332 rb_raise(rb_eTypeError, "%s::%s is not a module",
00333 rb_class2name(outer), rb_obj_classname(module));
00334 }
00335 module = rb_define_module_id(id);
00336 rb_const_set(outer, id, module);
00337 rb_set_class_path(module, outer, name);
00338
00339 return module;
00340 }
00341
00342 static VALUE
00343 include_class_new(module, super)
00344 VALUE module, super;
00345 {
00346 NEWOBJ(klass, struct RClass);
00347 OBJSETUP(klass, rb_cClass, T_ICLASS);
00348
00349 if (BUILTIN_TYPE(module) == T_ICLASS) {
00350 module = RBASIC(module)->klass;
00351 }
00352 if (!RCLASS(module)->iv_tbl) {
00353 RCLASS(module)->iv_tbl = st_init_numtable();
00354 }
00355 klass->iv_tbl = RCLASS(module)->iv_tbl;
00356 klass->m_tbl = RCLASS(module)->m_tbl;
00357 klass->super = super;
00358 if (TYPE(module) == T_ICLASS) {
00359 RBASIC(klass)->klass = RBASIC(module)->klass;
00360 }
00361 else {
00362 RBASIC(klass)->klass = module;
00363 }
00364 OBJ_INFECT(klass, module);
00365 OBJ_INFECT(klass, super);
00366
00367 return (VALUE)klass;
00368 }
00369
00370 void
00371 rb_include_module(klass, module)
00372 VALUE klass, module;
00373 {
00374 VALUE p, c;
00375 int changed = 0;
00376
00377 rb_frozen_class_p(klass);
00378 if (!OBJ_TAINTED(klass)) {
00379 rb_secure(4);
00380 }
00381
00382 if (NIL_P(module)) return;
00383 if (klass == module) return;
00384
00385 if (TYPE(module) != T_MODULE) {
00386 Check_Type(module, T_MODULE);
00387 }
00388
00389 OBJ_INFECT(klass, module);
00390 c = klass;
00391 while (module) {
00392 int superclass_seen = Qfalse;
00393
00394 if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
00395 rb_raise(rb_eArgError, "cyclic include detected");
00396
00397 for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
00398 switch (BUILTIN_TYPE(p)) {
00399 case T_ICLASS:
00400 if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
00401 if (!superclass_seen) {
00402 c = p;
00403 }
00404 goto skip;
00405 }
00406 break;
00407 case T_CLASS:
00408 superclass_seen = Qtrue;
00409 break;
00410 }
00411 }
00412 c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
00413 changed = 1;
00414 skip:
00415 module = RCLASS(module)->super;
00416 }
00417 if (changed) rb_clear_cache();
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 VALUE
00438 rb_mod_included_modules(mod)
00439 VALUE mod;
00440 {
00441 VALUE ary = rb_ary_new();
00442 VALUE p;
00443
00444 for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
00445 if (BUILTIN_TYPE(p) == T_ICLASS) {
00446 rb_ary_push(ary, RBASIC(p)->klass);
00447 }
00448 }
00449 return ary;
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 VALUE
00472 rb_mod_include_p(mod, mod2)
00473 VALUE mod;
00474 VALUE mod2;
00475 {
00476 VALUE p;
00477
00478 Check_Type(mod2, T_MODULE);
00479 for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
00480 if (BUILTIN_TYPE(p) == T_ICLASS) {
00481 if (RBASIC(p)->klass == mod2) return Qtrue;
00482 }
00483 }
00484 return Qfalse;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 VALUE
00504 rb_mod_ancestors(mod)
00505 VALUE mod;
00506 {
00507 VALUE p, ary = rb_ary_new();
00508
00509 for (p = mod; p; p = RCLASS(p)->super) {
00510 if (FL_TEST(p, FL_SINGLETON))
00511 continue;
00512 if (BUILTIN_TYPE(p) == T_ICLASS) {
00513 rb_ary_push(ary, RBASIC(p)->klass);
00514 }
00515 else {
00516 rb_ary_push(ary, p);
00517 }
00518 }
00519 return ary;
00520 }
00521
00522 #define VISI(x) ((x)&NOEX_MASK)
00523 #define VISI_CHECK(x,f) (VISI(x) == (f))
00524
00525 static int
00526 ins_methods_push(name, type, ary, visi)
00527 ID name;
00528 long type;
00529 VALUE ary;
00530 long visi;
00531 {
00532 if (type == -1) return ST_CONTINUE;
00533 switch (visi) {
00534 case NOEX_PRIVATE:
00535 case NOEX_PROTECTED:
00536 case NOEX_PUBLIC:
00537 visi = (type == visi);
00538 break;
00539 default:
00540 visi = (type != NOEX_PRIVATE);
00541 break;
00542 }
00543 if (visi) {
00544 rb_ary_push(ary, rb_str_new2(rb_id2name(name)));
00545 }
00546 return ST_CONTINUE;
00547 }
00548
00549 static int
00550 ins_methods_i(name, type, ary)
00551 ID name;
00552 long type;
00553 VALUE ary;
00554 {
00555 return ins_methods_push(name, type, ary, -1);
00556 }
00557
00558 static int
00559 ins_methods_prot_i(name, type, ary)
00560 ID name;
00561 long type;
00562 VALUE ary;
00563 {
00564 return ins_methods_push(name, type, ary, NOEX_PROTECTED);
00565 }
00566
00567 static int
00568 ins_methods_priv_i(name, type, ary)
00569 ID name;
00570 long type;
00571 VALUE ary;
00572 {
00573 return ins_methods_push(name, type, ary, NOEX_PRIVATE);
00574 }
00575
00576 static int
00577 ins_methods_pub_i(name, type, ary)
00578 ID name;
00579 long type;
00580 VALUE ary;
00581 {
00582 return ins_methods_push(name, type, ary, NOEX_PUBLIC);
00583 }
00584
00585 static int
00586 method_entry(key, body, list)
00587 ID key;
00588 NODE *body;
00589 st_table *list;
00590 {
00591 long type;
00592
00593 if (key == ID_ALLOCATOR) return ST_CONTINUE;
00594 if (!st_lookup(list, key, 0)) {
00595 if (!body->nd_body) type = -1;
00596 else type = VISI(body->nd_noex);
00597 st_add_direct(list, key, type);
00598 }
00599 return ST_CONTINUE;
00600 }
00601
00602 static VALUE
00603 class_instance_method_list(argc, argv, mod, func)
00604 int argc;
00605 VALUE *argv;
00606 VALUE mod;
00607 int (*func) (ID, long, VALUE);
00608 {
00609 VALUE ary;
00610 int recur;
00611 st_table *list;
00612
00613 if (argc == 0) {
00614 recur = Qtrue;
00615 }
00616 else {
00617 VALUE r;
00618 rb_scan_args(argc, argv, "01", &r);
00619 recur = RTEST(r);
00620 }
00621
00622 list = st_init_numtable();
00623 for (; mod; mod = RCLASS(mod)->super) {
00624 st_foreach(RCLASS(mod)->m_tbl, method_entry, (st_data_t)list);
00625 if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
00626 if (FL_TEST(mod, FL_SINGLETON)) continue;
00627 if (!recur) break;
00628 }
00629 ary = rb_ary_new();
00630 st_foreach(list, func, ary);
00631 st_free_table(list);
00632
00633 return ary;
00634 }
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 VALUE
00664 rb_class_instance_methods(argc, argv, mod)
00665 int argc;
00666 VALUE *argv;
00667 VALUE mod;
00668 {
00669 return class_instance_method_list(argc, argv, mod, ins_methods_i);
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 VALUE
00682 rb_class_protected_instance_methods(argc, argv, mod)
00683 int argc;
00684 VALUE *argv;
00685 VALUE mod;
00686 {
00687 return class_instance_method_list(argc, argv, mod, ins_methods_prot_i);
00688 }
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 VALUE
00708 rb_class_private_instance_methods(argc, argv, mod)
00709 int argc;
00710 VALUE *argv;
00711 VALUE mod;
00712 {
00713 return class_instance_method_list(argc, argv, mod, ins_methods_priv_i);
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725 VALUE
00726 rb_class_public_instance_methods(argc, argv, mod)
00727 int argc;
00728 VALUE *argv;
00729 VALUE mod;
00730 {
00731 return class_instance_method_list(argc, argv, mod, ins_methods_pub_i);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 VALUE
00767 rb_obj_singleton_methods(argc, argv, obj)
00768 int argc;
00769 VALUE *argv;
00770 VALUE obj;
00771 {
00772 VALUE recur, ary, klass;
00773 st_table *list;
00774
00775 rb_scan_args(argc, argv, "01", &recur);
00776 if (argc == 0) {
00777 recur = Qtrue;
00778 }
00779 klass = CLASS_OF(obj);
00780 list = st_init_numtable();
00781 if (klass && FL_TEST(klass, FL_SINGLETON)) {
00782 st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
00783 klass = RCLASS(klass)->super;
00784 }
00785 if (RTEST(recur)) {
00786 while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
00787 st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
00788 klass = RCLASS(klass)->super;
00789 }
00790 }
00791 ary = rb_ary_new();
00792 st_foreach(list, ins_methods_i, ary);
00793 st_free_table(list);
00794
00795 return ary;
00796 }
00797
00798 void
00799 rb_define_method_id(klass, name, func, argc)
00800 VALUE klass;
00801 ID name;
00802 VALUE (*func)();
00803 int argc;
00804 {
00805 rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
00806 }
00807
00808 void
00809 rb_define_method(klass, name, func, argc)
00810 VALUE klass;
00811 const char *name;
00812 VALUE (*func)();
00813 int argc;
00814 {
00815 ID id = rb_intern(name);
00816 int ex = NOEX_PUBLIC;
00817
00818
00819 rb_add_method(klass, id, NEW_CFUNC(func, argc), ex);
00820 }
00821
00822 void
00823 rb_define_protected_method(klass, name, func, argc)
00824 VALUE klass;
00825 const char *name;
00826 VALUE (*func)();
00827 int argc;
00828 {
00829 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED);
00830 }
00831
00832 void
00833 rb_define_private_method(klass, name, func, argc)
00834 VALUE klass;
00835 const char *name;
00836 VALUE (*func)();
00837 int argc;
00838 {
00839 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
00840 }
00841
00842 void
00843 rb_undef_method(klass, name)
00844 VALUE klass;
00845 const char *name;
00846 {
00847 rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
00848 }
00849
00850 #define SPECIAL_SINGLETON(x,c) do {\
00851 if (obj == (x)) {\
00852 return c;\
00853 }\
00854 } while (0)
00855
00856 VALUE
00857 rb_singleton_class(obj)
00858 VALUE obj;
00859 {
00860 VALUE klass;
00861
00862 if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
00863 rb_raise(rb_eTypeError, "can't define singleton");
00864 }
00865 if (rb_special_const_p(obj)) {
00866 SPECIAL_SINGLETON(Qnil, rb_cNilClass);
00867 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
00868 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
00869 rb_bug("unknown immediate %ld", obj);
00870 }
00871
00872 DEFER_INTS;
00873 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
00874 rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
00875 klass = RBASIC(obj)->klass;
00876 }
00877 else {
00878 klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
00879 }
00880 if (OBJ_TAINTED(obj)) {
00881 OBJ_TAINT(klass);
00882 }
00883 else {
00884 FL_UNSET(klass, FL_TAINT);
00885 }
00886 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
00887 ALLOW_INTS;
00888
00889 return klass;
00890 }
00891
00892 void
00893 rb_define_singleton_method(obj, name, func, argc)
00894 VALUE obj;
00895 const char *name;
00896 VALUE (*func)();
00897 int argc;
00898 {
00899 rb_define_method(rb_singleton_class(obj), name, func, argc);
00900 }
00901
00902 void
00903 rb_define_module_function(module, name, func, argc)
00904 VALUE module;
00905 const char *name;
00906 VALUE (*func)();
00907 int argc;
00908 {
00909 rb_define_private_method(module, name, func, argc);
00910 rb_define_singleton_method(module, name, func, argc);
00911 }
00912
00913 void
00914 rb_define_global_function(name, func, argc)
00915 const char *name;
00916 VALUE (*func)();
00917 int argc;
00918 {
00919 rb_define_module_function(rb_mKernel, name, func, argc);
00920 }
00921
00922 void
00923 rb_define_alias(klass, name1, name2)
00924 VALUE klass;
00925 const char *name1, *name2;
00926 {
00927 rb_alias(klass, rb_intern(name1), rb_intern(name2));
00928 }
00929
00930 void
00931 rb_define_attr(klass, name, read, write)
00932 VALUE klass;
00933 const char *name;
00934 int read, write;
00935 {
00936 rb_attr(klass, rb_intern(name), read, write, Qfalse);
00937 }
00938
00939 #ifdef HAVE_STDARG_PROTOTYPES
00940 #include <stdarg.h>
00941 #define va_init_list(a,b) va_start(a,b)
00942 #else
00943 #include <varargs.h>
00944 #define va_init_list(a,b) va_start(a)
00945 #endif
00946
00947 int
00948 #ifdef HAVE_STDARG_PROTOTYPES
00949 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
00950 #else
00951 rb_scan_args(argc, argv, fmt, va_alist)
00952 int argc;
00953 const VALUE *argv;
00954 const char *fmt;
00955 va_dcl
00956 #endif
00957 {
00958 int n, i = 0;
00959 const char *p = fmt;
00960 VALUE *var;
00961 va_list vargs;
00962
00963 va_init_list(vargs, fmt);
00964
00965 if (*p == '*') goto rest_arg;
00966
00967 if (ISDIGIT(*p)) {
00968 n = *p - '0';
00969 if (n > argc)
00970 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, n);
00971 for (i=0; i<n; i++) {
00972 var = va_arg(vargs, VALUE*);
00973 if (var) *var = argv[i];
00974 }
00975 p++;
00976 }
00977 else {
00978 goto error;
00979 }
00980
00981 if (ISDIGIT(*p)) {
00982 n = i + *p - '0';
00983 for (; i<n; i++) {
00984 var = va_arg(vargs, VALUE*);
00985 if (argc > i) {
00986 if (var) *var = argv[i];
00987 }
00988 else {
00989 if (var) *var = Qnil;
00990 }
00991 }
00992 p++;
00993 }
00994
00995 if(*p == '*') {
00996 rest_arg:
00997 var = va_arg(vargs, VALUE*);
00998 if (argc > i) {
00999 if (var) *var = rb_ary_new4(argc-i, argv+i);
01000 i = argc;
01001 }
01002 else {
01003 if (var) *var = rb_ary_new();
01004 }
01005 p++;
01006 }
01007
01008 if (*p == '&') {
01009 var = va_arg(vargs, VALUE*);
01010 if (rb_block_given_p()) {
01011 *var = rb_block_proc();
01012 }
01013 else {
01014 *var = Qnil;
01015 }
01016 p++;
01017 }
01018 va_end(vargs);
01019
01020 if (*p != '\0') {
01021 goto error;
01022 }
01023
01024 if (argc > i) {
01025 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, i);
01026 }
01027
01028 return argc;
01029
01030 error:
01031 rb_fatal("bad scan arg format: %s", fmt);
01032 return 0;
01033 }
01034