* io.c (rb_pipe_internal): new function for handling EMFILE and ENFILE
[ruby-svn.git] / class.c
blob0d612a5e87756a6b516c5e646c610a0b5acd5935
1 /**********************************************************************
3 class.c -
5 $Author$
6 created at: Tue Aug 10 15:05:44 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
10 **********************************************************************/
12 #include "ruby/ruby.h"
13 #include "ruby/signal.h"
14 #include "ruby/node.h"
15 #include "ruby/st.h"
16 #include <ctype.h>
18 extern st_table *rb_class_tbl;
20 static VALUE
21 class_alloc(VALUE flags, VALUE klass)
23 rb_classext_t *ext = ALLOC(rb_classext_t);
24 NEWOBJ(obj, struct RClass);
25 OBJSETUP(obj, klass, flags);
26 obj->ptr = ext;
27 RCLASS_IV_TBL(obj) = 0;
28 RCLASS_M_TBL(obj) = 0;
29 RCLASS_SUPER(obj) = 0;
30 RCLASS_IV_INDEX_TBL(obj) = 0;
31 return (VALUE)obj;
34 VALUE
35 rb_class_boot(VALUE super)
37 VALUE klass = class_alloc(T_CLASS, rb_cClass);
39 RCLASS_SUPER(klass) = super;
40 RCLASS_M_TBL(klass) = st_init_numtable();
42 OBJ_INFECT(klass, super);
43 return (VALUE)klass;
46 void
47 rb_check_inheritable(VALUE super)
49 if (TYPE(super) != T_CLASS) {
50 rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
51 rb_obj_classname(super));
53 if (RBASIC(super)->flags & FL_SINGLETON) {
54 rb_raise(rb_eTypeError, "can't make subclass of singleton class");
58 VALUE
59 rb_class_new(VALUE super)
61 Check_Type(super, T_CLASS);
62 rb_check_inheritable(super);
63 if (super == rb_cClass) {
64 rb_raise(rb_eTypeError, "can't make subclass of Class");
66 return rb_class_boot(super);
69 struct clone_method_data {
70 st_table *tbl;
71 VALUE klass;
74 static int
75 clone_method(ID mid, NODE *body, struct clone_method_data *data)
77 if (body == 0) {
78 st_insert(data->tbl, mid, 0);
80 else {
81 st_insert(data->tbl, mid,
82 (st_data_t)
83 NEW_FBODY(
84 NEW_METHOD(body->nd_body->nd_body,
85 data->klass, /* TODO */
86 body->nd_body->nd_noex),
87 0));
89 return ST_CONTINUE;
92 /* :nodoc: */
93 VALUE
94 rb_mod_init_copy(VALUE clone, VALUE orig)
96 rb_obj_init_copy(clone, orig);
97 if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
98 RBASIC(clone)->klass = rb_singleton_class_clone(orig);
100 RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
101 if (RCLASS_IV_TBL(orig)) {
102 ID id;
104 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
105 CONST_ID(id, "__classpath__");
106 st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
107 CONST_ID(id, "__classid__");
108 st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
110 if (RCLASS_M_TBL(orig)) {
111 struct clone_method_data data;
112 data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
113 data.klass = clone;
114 st_foreach(RCLASS_M_TBL(orig), clone_method,
115 (st_data_t)&data);
118 return clone;
121 /* :nodoc: */
122 VALUE
123 rb_class_init_copy(VALUE clone, VALUE orig)
125 if (RCLASS_SUPER(clone) != 0) {
126 rb_raise(rb_eTypeError, "already initialized class");
128 if (FL_TEST(orig, FL_SINGLETON)) {
129 rb_raise(rb_eTypeError, "can't copy singleton class");
131 return rb_mod_init_copy(clone, orig);
134 VALUE
135 rb_singleton_class_clone(VALUE obj)
137 VALUE klass = RBASIC(obj)->klass;
139 if (!FL_TEST(klass, FL_SINGLETON))
140 return klass;
141 else {
142 struct clone_method_data data;
143 /* copy singleton(unnamed) class */
144 VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
146 if (BUILTIN_TYPE(obj) == T_CLASS) {
147 RBASIC(clone)->klass = (VALUE)clone;
149 else {
150 RBASIC(clone)->klass = rb_singleton_class_clone(klass);
153 RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
154 if (RCLASS_IV_TBL(klass)) {
155 RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
157 RCLASS_M_TBL(clone) = st_init_numtable();
158 data.tbl = RCLASS_M_TBL(clone);
159 data.klass = (VALUE)clone;
160 st_foreach(RCLASS_M_TBL(klass), clone_method,
161 (st_data_t)&data);
162 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
163 FL_SET(clone, FL_SINGLETON);
164 return (VALUE)clone;
168 void
169 rb_singleton_class_attached(VALUE klass, VALUE obj)
171 if (FL_TEST(klass, FL_SINGLETON)) {
172 ID attached;
173 if (!RCLASS_IV_TBL(klass)) {
174 RCLASS_IV_TBL(klass) = st_init_numtable();
176 CONST_ID(attached, "__attached__");
177 st_insert(RCLASS_IV_TBL(klass), attached, obj);
181 VALUE
182 rb_make_metaclass(VALUE obj, VALUE super)
184 if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) {
185 return RBASIC(obj)->klass = rb_cClass;
187 else {
188 VALUE metasuper;
189 VALUE klass = rb_class_boot(super);
191 FL_SET(klass, FL_SINGLETON);
192 RBASIC(obj)->klass = klass;
193 rb_singleton_class_attached(klass, obj);
195 metasuper = RBASIC(rb_class_real(super))->klass;
196 /* metaclass of a superclass may be NULL at boot time */
197 if (metasuper) {
198 RBASIC(klass)->klass = metasuper;
200 return klass;
204 VALUE
205 rb_define_class_id(ID id, VALUE super)
207 VALUE klass;
209 if (!super) super = rb_cObject;
210 klass = rb_class_new(super);
211 rb_make_metaclass(klass, RBASIC(super)->klass);
213 return klass;
216 VALUE
217 rb_class_inherited(VALUE super, VALUE klass)
219 ID inherited;
220 if (!super) super = rb_cObject;
221 CONST_ID(inherited, "inherited");
222 return rb_funcall(super, inherited, 1, klass);
225 VALUE
226 rb_define_class(const char *name, VALUE super)
228 VALUE klass;
229 ID id;
231 id = rb_intern(name);
232 if (rb_const_defined(rb_cObject, id)) {
233 klass = rb_const_get(rb_cObject, id);
234 if (TYPE(klass) != T_CLASS) {
235 rb_raise(rb_eTypeError, "%s is not a class", name);
237 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
238 rb_name_error(id, "%s is already defined", name);
240 return klass;
242 if (!super) {
243 rb_warn("no super class for `%s', Object assumed", name);
245 klass = rb_define_class_id(id, super);
246 st_add_direct(rb_class_tbl, id, klass);
247 rb_name_class(klass, id);
248 rb_const_set(rb_cObject, id, klass);
249 rb_class_inherited(super, klass);
251 return klass;
254 VALUE
255 rb_define_class_under(VALUE outer, const char *name, VALUE super)
257 VALUE klass;
258 ID id;
260 id = rb_intern(name);
261 if (rb_const_defined_at(outer, id)) {
262 klass = rb_const_get_at(outer, id);
263 if (TYPE(klass) != T_CLASS) {
264 rb_raise(rb_eTypeError, "%s is not a class", name);
266 if (rb_class_real(RCLASS_SUPER(klass)) != super) {
267 rb_name_error(id, "%s is already defined", name);
269 return klass;
271 if (!super) {
272 rb_warn("no super class for `%s::%s', Object assumed",
273 rb_class2name(outer), name);
275 klass = rb_define_class_id(id, super);
276 rb_set_class_path(klass, outer, name);
277 rb_const_set(outer, id, klass);
278 rb_class_inherited(super, klass);
280 return klass;
283 VALUE
284 rb_module_new(void)
286 VALUE mdl = class_alloc(T_MODULE, rb_cModule);
288 RCLASS_M_TBL(mdl) = st_init_numtable();
290 return (VALUE)mdl;
293 VALUE
294 rb_define_module_id(ID id)
296 VALUE mdl;
298 mdl = rb_module_new();
299 rb_name_class(mdl, id);
301 return mdl;
304 VALUE
305 rb_define_module(const char *name)
307 VALUE module;
308 ID id;
310 id = rb_intern(name);
311 if (rb_const_defined(rb_cObject, id)) {
312 module = rb_const_get(rb_cObject, id);
313 if (TYPE(module) == T_MODULE)
314 return module;
315 rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module));
317 module = rb_define_module_id(id);
318 st_add_direct(rb_class_tbl, id, module);
319 rb_const_set(rb_cObject, id, module);
321 return module;
324 VALUE
325 rb_define_module_under(VALUE outer, const char *name)
327 VALUE module;
328 ID id;
330 id = rb_intern(name);
331 if (rb_const_defined_at(outer, id)) {
332 module = rb_const_get_at(outer, id);
333 if (TYPE(module) == T_MODULE)
334 return module;
335 rb_raise(rb_eTypeError, "%s::%s is not a module",
336 rb_class2name(outer), rb_obj_classname(module));
338 module = rb_define_module_id(id);
339 rb_const_set(outer, id, module);
340 rb_set_class_path(module, outer, name);
342 return module;
345 static VALUE
346 include_class_new(VALUE module, VALUE super)
348 VALUE klass = class_alloc(T_ICLASS, rb_cClass);
350 if (BUILTIN_TYPE(module) == T_ICLASS) {
351 module = RBASIC(module)->klass;
353 if (!RCLASS_IV_TBL(module)) {
354 RCLASS_IV_TBL(module) = st_init_numtable();
356 RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
357 RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
358 RCLASS_SUPER(klass) = super;
359 if (TYPE(module) == T_ICLASS) {
360 RBASIC(klass)->klass = RBASIC(module)->klass;
362 else {
363 RBASIC(klass)->klass = module;
365 OBJ_INFECT(klass, module);
366 OBJ_INFECT(klass, super);
368 return (VALUE)klass;
371 void
372 rb_include_module(VALUE klass, VALUE module)
374 VALUE p, c;
375 int changed = 0;
377 rb_frozen_class_p(klass);
378 if (!OBJ_TAINTED(klass)) {
379 rb_secure(4);
382 if (TYPE(module) != T_MODULE) {
383 Check_Type(module, T_MODULE);
386 OBJ_INFECT(klass, module);
387 c = klass;
388 while (module) {
389 int superclass_seen = Qfalse;
391 if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
392 rb_raise(rb_eArgError, "cyclic include detected");
393 /* ignore if the module included already in superclasses */
394 for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
395 switch (BUILTIN_TYPE(p)) {
396 case T_ICLASS:
397 if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
398 if (!superclass_seen) {
399 c = p; /* move insertion point */
401 goto skip;
403 break;
404 case T_CLASS:
405 superclass_seen = Qtrue;
406 break;
409 c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
410 changed = 1;
411 skip:
412 module = RCLASS_SUPER(module);
414 if (changed) rb_clear_cache();
418 * call-seq:
419 * mod.included_modules -> array
421 * Returns the list of modules included in <i>mod</i>.
423 * module Mixin
424 * end
426 * module Outer
427 * include Mixin
428 * end
430 * Mixin.included_modules #=> []
431 * Outer.included_modules #=> [Mixin]
434 VALUE
435 rb_mod_included_modules(VALUE mod)
437 VALUE ary = rb_ary_new();
438 VALUE p;
440 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
441 if (BUILTIN_TYPE(p) == T_ICLASS) {
442 rb_ary_push(ary, RBASIC(p)->klass);
445 return ary;
449 * call-seq:
450 * mod.include?(module) => true or false
452 * Returns <code>true</code> if <i>module</i> is included in
453 * <i>mod</i> or one of <i>mod</i>'s ancestors.
455 * module A
456 * end
457 * class B
458 * include A
459 * end
460 * class C < B
461 * end
462 * B.include?(A) #=> true
463 * C.include?(A) #=> true
464 * A.include?(A) #=> false
467 VALUE
468 rb_mod_include_p(VALUE mod, VALUE mod2)
470 VALUE p;
472 Check_Type(mod2, T_MODULE);
473 for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
474 if (BUILTIN_TYPE(p) == T_ICLASS) {
475 if (RBASIC(p)->klass == mod2) return Qtrue;
478 return Qfalse;
482 * call-seq:
483 * mod.ancestors -> array
485 * Returns a list of modules included in <i>mod</i> (including
486 * <i>mod</i> itself).
488 * module Mod
489 * include Math
490 * include Comparable
491 * end
493 * Mod.ancestors #=> [Mod, Comparable, Math]
494 * Math.ancestors #=> [Math]
497 VALUE
498 rb_mod_ancestors(VALUE mod)
500 VALUE p, ary = rb_ary_new();
502 for (p = mod; p; p = RCLASS_SUPER(p)) {
503 if (FL_TEST(p, FL_SINGLETON))
504 continue;
505 if (BUILTIN_TYPE(p) == T_ICLASS) {
506 rb_ary_push(ary, RBASIC(p)->klass);
508 else {
509 rb_ary_push(ary, p);
512 return ary;
515 #define VISI(x) ((x)&NOEX_MASK)
516 #define VISI_CHECK(x,f) (VISI(x) == (f))
518 static int
519 ins_methods_push(ID name, long type, VALUE ary, long visi)
521 if (type == -1) return ST_CONTINUE;
523 switch (visi) {
524 case NOEX_PRIVATE:
525 case NOEX_PROTECTED:
526 case NOEX_PUBLIC:
527 visi = (type == visi);
528 break;
529 default:
530 visi = (type != NOEX_PRIVATE);
531 break;
533 if (visi) {
534 rb_ary_push(ary, ID2SYM(name));
536 return ST_CONTINUE;
539 static int
540 ins_methods_i(ID name, long type, VALUE ary)
542 return ins_methods_push(name, type, ary, -1); /* everything but private */
545 static int
546 ins_methods_prot_i(ID name, long type, VALUE ary)
548 return ins_methods_push(name, type, ary, NOEX_PROTECTED);
551 static int
552 ins_methods_priv_i(ID name, long type, VALUE ary)
554 return ins_methods_push(name, type, ary, NOEX_PRIVATE);
557 static int
558 ins_methods_pub_i(ID name, long type, VALUE ary)
560 return ins_methods_push(name, type, ary, NOEX_PUBLIC);
563 static int
564 method_entry(ID key, NODE *body, st_table *list)
566 long type;
568 if (key == ID_ALLOCATOR) {
569 return ST_CONTINUE;
572 if (!st_lookup(list, key, 0)) {
573 if (body ==0 || !body->nd_body->nd_body) {
574 type = -1; /* none */
576 else {
577 type = VISI(body->nd_body->nd_noex);
579 st_add_direct(list, key, type);
581 return ST_CONTINUE;
584 static VALUE
585 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, long, VALUE))
587 VALUE ary;
588 int recur;
589 st_table *list;
591 if (argc == 0) {
592 recur = Qtrue;
594 else {
595 VALUE r;
596 rb_scan_args(argc, argv, "01", &r);
597 recur = RTEST(r);
600 list = st_init_numtable();
601 for (; mod; mod = RCLASS_SUPER(mod)) {
602 st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
603 if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
604 if (FL_TEST(mod, FL_SINGLETON)) continue;
605 if (!recur) break;
607 ary = rb_ary_new();
608 st_foreach(list, func, ary);
609 st_free_table(list);
611 return ary;
615 * call-seq:
616 * mod.instance_methods(include_super=true) => array
618 * Returns an array containing the names of public instance methods in
619 * the receiver. For a module, these are the public methods; for a
620 * class, they are the instance (not singleton) methods. With no
621 * argument, or with an argument that is <code>false</code>, the
622 * instance methods in <i>mod</i> are returned, otherwise the methods
623 * in <i>mod</i> and <i>mod</i>'s superclasses are returned.
625 * module A
626 * def method1() end
627 * end
628 * class B
629 * def method2() end
630 * end
631 * class C < B
632 * def method3() end
633 * end
635 * A.instance_methods #=> [:method1]
636 * B.instance_methods(false) #=> [:method2]
637 * C.instance_methods(false) #=> [:method3]
638 * C.instance_methods(true).length #=> 43
641 VALUE
642 rb_class_instance_methods(int argc, VALUE *argv, VALUE mod)
644 return class_instance_method_list(argc, argv, mod, ins_methods_i);
648 * call-seq:
649 * mod.protected_instance_methods(include_super=true) => array
651 * Returns a list of the protected instance methods defined in
652 * <i>mod</i>. If the optional parameter is not <code>false</code>, the
653 * methods of any ancestors are included.
656 VALUE
657 rb_class_protected_instance_methods(int argc, VALUE *argv, VALUE mod)
659 return class_instance_method_list(argc, argv, mod, ins_methods_prot_i);
663 * call-seq:
664 * mod.private_instance_methods(include_super=true) => array
666 * Returns a list of the private instance methods defined in
667 * <i>mod</i>. If the optional parameter is not <code>false</code>, the
668 * methods of any ancestors are included.
670 * module Mod
671 * def method1() end
672 * private :method1
673 * def method2() end
674 * end
675 * Mod.instance_methods #=> [:method2]
676 * Mod.private_instance_methods #=> [:method1]
679 VALUE
680 rb_class_private_instance_methods(int argc, VALUE *argv, VALUE mod)
682 return class_instance_method_list(argc, argv, mod, ins_methods_priv_i);
686 * call-seq:
687 * mod.public_instance_methods(include_super=true) => array
689 * Returns a list of the public instance methods defined in <i>mod</i>.
690 * If the optional parameter is not <code>false</code>, the methods of
691 * any ancestors are included.
694 VALUE
695 rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)
697 return class_instance_method_list(argc, argv, mod, ins_methods_pub_i);
701 * call-seq:
702 * obj.singleton_methods(all=true) => array
704 * Returns an array of the names of singleton methods for <i>obj</i>.
705 * If the optional <i>all</i> parameter is true, the list will include
706 * methods in modules included in <i>obj</i>.
708 * module Other
709 * def three() end
710 * end
712 * class Single
713 * def Single.four() end
714 * end
716 * a = Single.new
718 * def a.one()
719 * end
721 * class << a
722 * include Other
723 * def two()
724 * end
725 * end
727 * Single.singleton_methods #=> [:four]
728 * a.singleton_methods(false) #=> [:two, :one]
729 * a.singleton_methods #=> [:two, :one, :three]
732 VALUE
733 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
735 VALUE recur, ary, klass;
736 st_table *list;
738 if (argc == 0) {
739 recur = Qtrue;
741 else {
742 rb_scan_args(argc, argv, "01", &recur);
744 klass = CLASS_OF(obj);
745 list = st_init_numtable();
746 if (klass && FL_TEST(klass, FL_SINGLETON)) {
747 st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
748 klass = RCLASS_SUPER(klass);
750 if (RTEST(recur)) {
751 while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
752 st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
753 klass = RCLASS_SUPER(klass);
756 ary = rb_ary_new();
757 st_foreach(list, ins_methods_i, ary);
758 st_free_table(list);
760 return ary;
763 void
764 rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int argc)
766 rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
769 void
770 rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
772 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC);
775 void
776 rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
778 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED);
781 void
782 rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
784 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
787 void
788 rb_undef_method(VALUE klass, const char *name)
790 rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
793 #define SPECIAL_SINGLETON(x,c) do {\
794 if (obj == (x)) {\
795 return c;\
797 } while (0)
799 VALUE
800 rb_singleton_class(VALUE obj)
802 VALUE klass;
804 if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
805 rb_raise(rb_eTypeError, "can't define singleton");
807 if (rb_special_const_p(obj)) {
808 SPECIAL_SINGLETON(Qnil, rb_cNilClass);
809 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
810 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
811 rb_bug("unknown immediate %ld", obj);
814 DEFER_INTS;
815 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
816 rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
817 klass = RBASIC(obj)->klass;
819 else {
820 klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
822 if (OBJ_TAINTED(obj)) {
823 OBJ_TAINT(klass);
825 else {
826 FL_UNSET(klass, FL_TAINT);
828 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
829 ALLOW_INTS;
831 return klass;
834 void
835 rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
837 rb_define_method(rb_singleton_class(obj), name, func, argc);
840 void
841 rb_define_module_function(VALUE module, const char *name, VALUE (*func)(ANYARGS), int argc)
843 rb_define_private_method(module, name, func, argc);
844 rb_define_singleton_method(module, name, func, argc);
847 void
848 rb_define_global_function(const char *name, VALUE (*func)(ANYARGS), int argc)
850 rb_define_module_function(rb_mKernel, name, func, argc);
853 void
854 rb_define_alias(VALUE klass, const char *name1, const char *name2)
856 rb_alias(klass, rb_intern(name1), rb_intern(name2));
859 void
860 rb_define_attr(VALUE klass, const char *name, int read, int write)
862 rb_attr(klass, rb_intern(name), read, write, Qfalse);
865 #include <stdarg.h>
868 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
870 int n, i = 0;
871 const char *p = fmt;
872 VALUE *var;
873 va_list vargs;
875 va_start(vargs, fmt);
877 if (*p == '*') goto rest_arg;
879 if (ISDIGIT(*p)) {
880 n = *p - '0';
881 if (n > argc)
882 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, n);
883 for (i=0; i<n; i++) {
884 var = va_arg(vargs, VALUE*);
885 if (var) *var = argv[i];
887 p++;
889 else {
890 goto error;
893 if (ISDIGIT(*p)) {
894 n = i + *p - '0';
895 for (; i<n; i++) {
896 var = va_arg(vargs, VALUE*);
897 if (argc > i) {
898 if (var) *var = argv[i];
900 else {
901 if (var) *var = Qnil;
904 p++;
907 if(*p == '*') {
908 rest_arg:
909 var = va_arg(vargs, VALUE*);
910 if (argc > i) {
911 if (var) *var = rb_ary_new4(argc-i, argv+i);
912 i = argc;
914 else {
915 if (var) *var = rb_ary_new();
917 p++;
920 if (*p == '&') {
921 var = va_arg(vargs, VALUE*);
922 if (rb_block_given_p()) {
923 *var = rb_block_proc();
925 else {
926 *var = Qnil;
928 p++;
930 va_end(vargs);
932 if (*p != '\0') {
933 goto error;
936 if (argc > i) {
937 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, i);
940 return argc;
942 error:
943 rb_fatal("bad scan arg format: %s", fmt);
944 return 0;