class.c
DEFINITIONS
This source file includes following functions.
- rb_class_boot
- rb_class_new
- clone_method
- rb_mod_clone
- rb_mod_dup
- rb_singleton_class_clone
- rb_singleton_class_attached
- rb_make_metaclass
- rb_define_class_id
- rb_class_inherited
- rb_define_class
- rb_define_class_under
- rb_module_new
- rb_define_module_id
- rb_define_module
- rb_define_module_under
- include_class_new
- rb_include_module
- rb_mod_included_modules
- rb_mod_include_p
- rb_mod_ancestors
- ins_methods_i
- ins_methods_prot_i
- ins_methods_priv_i
- method_list
- rb_class_instance_methods
- rb_class_protected_instance_methods
- rb_class_private_instance_methods
- rb_obj_singleton_methods
- rb_define_method_id
- rb_define_method
- rb_define_protected_method
- rb_define_private_method
- rb_undef_method
- rb_singleton_class
- rb_define_singleton_method
- rb_define_module_function
- rb_define_global_function
- rb_define_alias
- rb_define_attr
- rb_scan_args
1
2
3
4
5
6
7
8
9
10
11
12
13 #include "ruby.h"
14 #include "rubysig.h"
15 #include "node.h"
16 #include "st.h"
17 #include <ctype.h>
18
19 extern st_table *rb_class_tbl;
20
21 VALUE
22 rb_class_boot(super)
23 VALUE super;
24 {
25 NEWOBJ(klass, struct RClass);
26 OBJSETUP(klass, rb_cClass, T_CLASS);
27
28 klass->super = super;
29 klass->iv_tbl = 0;
30 klass->m_tbl = 0;
31 klass->m_tbl = st_init_numtable();
32
33 OBJ_INFECT(klass, super);
34 return (VALUE)klass;
35 }
36
37 VALUE
38 rb_class_new(super)
39 VALUE super;
40 {
41 Check_Type(super, T_CLASS);
42 if (super == rb_cClass) {
43 rb_raise(rb_eTypeError, "can't make subclass of Class");
44 }
45 if (FL_TEST(super, FL_SINGLETON)) {
46 rb_raise(rb_eTypeError, "can't make subclass of virtual class");
47 }
48 return rb_class_boot(super);
49 }
50
51 static int
52 clone_method(mid, body, tbl)
53 ID mid;
54 NODE *body;
55 st_table *tbl;
56 {
57 st_insert(tbl, mid, NEW_METHOD(body->nd_body, body->nd_noex));
58 return ST_CONTINUE;
59 }
60
61 VALUE
62 rb_mod_clone(module)
63 VALUE module;
64 {
65 NEWOBJ(clone, struct RClass);
66 CLONESETUP(clone, module);
67
68 RCLASS(clone)->super = RCLASS(module)->super;
69 if (RCLASS(module)->iv_tbl) {
70 ID id;
71
72 RCLASS(clone)->iv_tbl = st_copy(RCLASS(module)->iv_tbl);
73 id = rb_intern("__classpath__");
74 st_delete(RCLASS(clone)->iv_tbl, &id, 0);
75 id = rb_intern("__classid__");
76 st_delete(RCLASS(clone)->iv_tbl, &id, 0);
77 }
78 if (RCLASS(module)->m_tbl) {
79 RCLASS(clone)->m_tbl = st_init_numtable();
80 st_foreach(RCLASS(module)->m_tbl, clone_method, RCLASS(clone)->m_tbl);
81 }
82
83 return (VALUE)clone;
84 }
85
86 VALUE
87 rb_mod_dup(mod)
88 VALUE mod;
89 {
90 VALUE dup = rb_mod_clone(mod);
91
92 RBASIC(dup)->flags = RBASIC(mod)->flags & (T_MASK|FL_TAINT|FL_SINGLETON);
93 return dup;
94 }
95
96 VALUE
97 rb_singleton_class_clone(obj)
98 VALUE obj;
99 {
100 VALUE klass = RBASIC(obj)->klass;
101
102 if (!FL_TEST(klass, FL_SINGLETON))
103 return klass;
104 else {
105
106 NEWOBJ(clone, struct RClass);
107 OBJSETUP(clone, 0, RBASIC(klass)->flags);
108
109 if (BUILTIN_TYPE(obj) == T_CLASS) {
110 RBASIC(clone)->klass = (VALUE)clone;
111 }
112 else {
113 RBASIC(clone)->klass = rb_singleton_class_clone(klass);
114 }
115
116 clone->super = RCLASS(klass)->super;
117 clone->iv_tbl = 0;
118 clone->m_tbl = 0;
119 if (RCLASS(klass)->iv_tbl) {
120 clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
121 }
122 clone->m_tbl = st_init_numtable();
123 st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
124 rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
125 FL_SET(clone, FL_SINGLETON);
126 return (VALUE)clone;
127 }
128 }
129
130 void
131 rb_singleton_class_attached(klass, obj)
132 VALUE klass, obj;
133 {
134 if (FL_TEST(klass, FL_SINGLETON)) {
135 if (!RCLASS(klass)->iv_tbl) {
136 RCLASS(klass)->iv_tbl = st_init_numtable();
137 }
138 st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
139 }
140 }
141
142 VALUE
143 rb_make_metaclass(obj, super)
144 VALUE obj, super;
145 {
146 VALUE klass = rb_class_boot(super);
147 FL_SET(klass, FL_SINGLETON);
148 RBASIC(obj)->klass = klass;
149 rb_singleton_class_attached(klass, obj);
150 if (BUILTIN_TYPE(obj) == T_CLASS) {
151 RBASIC(klass)->klass = klass;
152 if (FL_TEST(obj, FL_SINGLETON)) {
153 RCLASS(klass)->super = RBASIC(rb_class_real(RCLASS(obj)->super))->klass;
154 }
155 }
156
157 return klass;
158 }
159
160 VALUE
161 rb_define_class_id(id, super)
162 ID id;
163 VALUE super;
164 {
165 VALUE klass;
166
167 if (!super) super = rb_cObject;
168 klass = rb_class_new(super);
169 rb_name_class(klass, id);
170 rb_make_metaclass(klass, RBASIC(super)->klass);
171
172 return klass;
173 }
174
175 VALUE
176 rb_class_inherited(super, klass)
177 VALUE super, klass;
178 {
179 if (!super) super = rb_cObject;
180 return rb_funcall(super, rb_intern("inherited"), 1, klass);
181 }
182
183 VALUE
184 rb_define_class(name, super)
185 const char *name;
186 VALUE super;
187 {
188 VALUE klass;
189 ID id;
190
191 id = rb_intern(name);
192 if (rb_autoload_defined(id)) {
193 rb_autoload_load(id);
194 }
195 if (rb_const_defined(rb_cObject, id)) {
196 klass = rb_const_get(rb_cObject, id);
197 if (TYPE(klass) != T_CLASS) {
198 rb_raise(rb_eTypeError, "%s is not a class", name);
199 }
200 if (rb_class_real(RCLASS(klass)->super) != super) {
201 rb_name_error(id, "%s is already defined", name);
202 }
203 return klass;
204 }
205 if (!super) {
206 rb_warn("no super class for `%s', Object assumed", name);
207 }
208 klass = rb_define_class_id(id, super);
209 rb_class_inherited(super, klass);
210 st_add_direct(rb_class_tbl, id, klass);
211
212 return klass;
213 }
214
215 VALUE
216 rb_define_class_under(outer, name, super)
217 VALUE outer;
218 const char *name;
219 VALUE super;
220 {
221 VALUE klass;
222 ID id;
223
224 id = rb_intern(name);
225 if (rb_const_defined_at(outer, id)) {
226 klass = rb_const_get(outer, id);
227 if (TYPE(klass) != T_CLASS) {
228 rb_raise(rb_eTypeError, "%s is not a class", name);
229 }
230 if (rb_class_real(RCLASS(klass)->super) != super) {
231 rb_name_error(id, "%s is already defined", name);
232 }
233 return klass;
234 }
235 if (!super) {
236 rb_warn("no super class for `%s::%s', Object assumed",
237 rb_class2name(outer), name);
238 }
239 klass = rb_define_class_id(id, super);
240 rb_set_class_path(klass, outer, name);
241 rb_class_inherited(super, klass);
242 rb_const_set(outer, id, klass);
243
244 return klass;
245 }
246
247 VALUE
248 rb_module_new()
249 {
250 NEWOBJ(mdl, struct RClass);
251 OBJSETUP(mdl, rb_cModule, T_MODULE);
252
253 mdl->super = 0;
254 mdl->iv_tbl = 0;
255 mdl->m_tbl = 0;
256 mdl->m_tbl = st_init_numtable();
257
258 return (VALUE)mdl;
259 }
260
261 VALUE
262 rb_define_module_id(id)
263 ID id;
264 {
265 VALUE mdl;
266
267 mdl = rb_module_new();
268 rb_name_class(mdl, id);
269
270 return mdl;
271 }
272
273 VALUE
274 rb_define_module(name)
275 const char *name;
276 {
277 VALUE module;
278 ID id;
279
280 id = rb_intern(name);
281 if (rb_autoload_defined(id)) {
282 rb_autoload_load(id);
283 }
284 if (rb_const_defined(rb_cObject, id)) {
285 module = rb_const_get(rb_cObject, id);
286 if (TYPE(module) == T_MODULE)
287 return module;
288 rb_raise(rb_eTypeError, "%s is not a module", rb_class2name(CLASS_OF(module)));
289 }
290 module = rb_define_module_id(id);
291 st_add_direct(rb_class_tbl, id, module);
292
293 return module;
294 }
295
296 VALUE
297 rb_define_module_under(outer, name)
298 VALUE outer;
299 const char *name;
300 {
301 VALUE module;
302 ID id;
303
304 id = rb_intern(name);
305 if (rb_const_defined_at(outer, id)) {
306 module = rb_const_get(outer, id);
307 if (TYPE(module) == T_MODULE)
308 return module;
309 rb_raise(rb_eTypeError, "%s::%s is not a module",
310 rb_class2name(outer), rb_class2name(CLASS_OF(module)));
311 }
312 module = rb_define_module_id(id);
313 rb_const_set(outer, id, module);
314 rb_set_class_path(module, outer, name);
315
316 return module;
317 }
318
319 static VALUE
320 include_class_new(module, super)
321 VALUE module, super;
322 {
323 NEWOBJ(klass, struct RClass);
324 OBJSETUP(klass, rb_cClass, T_ICLASS);
325
326 if (BUILTIN_TYPE(module) == T_ICLASS) {
327 module = RBASIC(module)->klass;
328 }
329 if (!RCLASS(module)->iv_tbl) {
330 RCLASS(module)->iv_tbl = st_init_numtable();
331 }
332 klass->iv_tbl = RCLASS(module)->iv_tbl;
333 klass->m_tbl = RCLASS(module)->m_tbl;
334 klass->super = super;
335 if (TYPE(module) == T_ICLASS) {
336 RBASIC(klass)->klass = RBASIC(module)->klass;
337 }
338 else {
339 RBASIC(klass)->klass = module;
340 }
341 OBJ_INFECT(klass, module);
342 OBJ_INFECT(klass, super);
343
344 return (VALUE)klass;
345 }
346
347 void
348 rb_include_module(klass, module)
349 VALUE klass, module;
350 {
351 VALUE p, c;
352 int changed = 0;
353
354 rb_frozen_class_p(klass);
355 if (!OBJ_TAINTED(klass)) {
356 rb_secure(4);
357 }
358
359 if (NIL_P(module)) return;
360 if (klass == module) return;
361
362 switch (TYPE(module)) {
363 case T_MODULE:
364 case T_CLASS:
365 case T_ICLASS:
366 break;
367 default:
368 Check_Type(module, T_MODULE);
369 }
370
371 OBJ_INFECT(klass, module);
372 c = klass;
373 while (module) {
374 int superclass_seen = Qfalse;
375
376 if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
377 rb_raise(rb_eArgError, "cyclic include detected");
378
379 for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
380 switch (BUILTIN_TYPE(p)) {
381 case T_ICLASS:
382 if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
383 if (!superclass_seen) {
384 c = p;
385 }
386 goto skip;
387 }
388 break;
389 case T_CLASS:
390 superclass_seen = Qtrue;
391 break;
392 }
393 }
394 c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
395 changed = 1;
396 skip:
397 module = RCLASS(module)->super;
398 }
399 if (changed) rb_clear_cache();
400 }
401
402 VALUE
403 rb_mod_included_modules(mod)
404 VALUE mod;
405 {
406 VALUE ary = rb_ary_new();
407 VALUE p;
408
409 for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
410 if (BUILTIN_TYPE(p) == T_ICLASS) {
411 rb_ary_push(ary, RBASIC(p)->klass);
412 }
413 }
414 return ary;
415 }
416
417 VALUE
418 rb_mod_include_p(mod, mod2)
419 VALUE mod;
420 VALUE mod2;
421 {
422 VALUE p;
423
424 Check_Type(mod2, T_MODULE);
425 for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
426 if (BUILTIN_TYPE(p) == T_ICLASS) {
427 if (RBASIC(p)->klass == mod2) return Qtrue;
428 }
429 }
430 return Qfalse;
431 }
432
433 VALUE
434 rb_mod_ancestors(mod)
435 VALUE mod;
436 {
437 VALUE ary = rb_ary_new();
438 VALUE p;
439
440 for (p = mod; p; p = RCLASS(p)->super) {
441 if (FL_TEST(p, FL_SINGLETON))
442 continue;
443 if (BUILTIN_TYPE(p) == T_ICLASS) {
444 rb_ary_push(ary, RBASIC(p)->klass);
445 }
446 else {
447 rb_ary_push(ary, p);
448 }
449 }
450 return ary;
451 }
452
453 static int
454 ins_methods_i(key, body, ary)
455 ID key;
456 NODE *body;
457 VALUE ary;
458 {
459 if ((body->nd_noex&(NOEX_PRIVATE|NOEX_PROTECTED)) == 0) {
460 VALUE name = rb_str_new2(rb_id2name(key));
461
462 if (!rb_ary_includes(ary, name)) {
463 if (!body->nd_body) {
464 rb_ary_push(ary, Qnil);
465 }
466 rb_ary_push(ary, name);
467 }
468 }
469 else if (body->nd_body && nd_type(body->nd_body) == NODE_ZSUPER) {
470 rb_ary_push(ary, Qnil);
471 rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
472 }
473 return ST_CONTINUE;
474 }
475
476 static int
477 ins_methods_prot_i(key, body, ary)
478 ID key;
479 NODE *body;
480 VALUE ary;
481 {
482 if (!body->nd_body) {
483 rb_ary_push(ary, Qnil);
484 rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
485 }
486 else if (body->nd_noex & NOEX_PROTECTED) {
487 VALUE name = rb_str_new2(rb_id2name(key));
488
489 if (!rb_ary_includes(ary, name)) {
490 rb_ary_push(ary, name);
491 }
492 }
493 else if (nd_type(body->nd_body) == NODE_ZSUPER) {
494 rb_ary_push(ary, Qnil);
495 rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
496 }
497 return ST_CONTINUE;
498 }
499
500 static int
501 ins_methods_priv_i(key, body, ary)
502 ID key;
503 NODE *body;
504 VALUE ary;
505 {
506 if (!body->nd_body) {
507 rb_ary_push(ary, Qnil);
508 rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
509 }
510 else if (body->nd_noex & NOEX_PRIVATE) {
511 VALUE name = rb_str_new2(rb_id2name(key));
512
513 if (!rb_ary_includes(ary, name)) {
514 rb_ary_push(ary, name);
515 }
516 }
517 else if (nd_type(body->nd_body) == NODE_ZSUPER) {
518 rb_ary_push(ary, Qnil);
519 rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
520 }
521 return ST_CONTINUE;
522 }
523
524 static VALUE
525 method_list(mod, option, func)
526 VALUE mod;
527 int option;
528 int (*func)();
529 {
530 VALUE ary;
531 VALUE klass;
532 VALUE *p, *q, *pend;
533
534 ary = rb_ary_new();
535 for (klass = mod; klass; klass = RCLASS(klass)->super) {
536 st_foreach(RCLASS(klass)->m_tbl, func, ary);
537 if (!option) break;
538 }
539 p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
540 while (p < pend) {
541 if (*p == Qnil) {
542 p+=2;
543 continue;
544 }
545 *q++ = *p++;
546 }
547 RARRAY(ary)->len = q - RARRAY(ary)->ptr;
548 return ary;
549 }
550
551 VALUE
552 rb_class_instance_methods(argc, argv, mod)
553 int argc;
554 VALUE *argv;
555 VALUE mod;
556 {
557 VALUE option;
558
559 rb_scan_args(argc, argv, "01", &option);
560 return method_list(mod, RTEST(option), ins_methods_i);
561 }
562
563 VALUE
564 rb_class_protected_instance_methods(argc, argv, mod)
565 int argc;
566 VALUE *argv;
567 VALUE mod;
568 {
569 VALUE option;
570
571 rb_scan_args(argc, argv, "01", &option);
572 return method_list(mod, RTEST(option), ins_methods_prot_i);
573 }
574
575 VALUE
576 rb_class_private_instance_methods(argc, argv, mod)
577 int argc;
578 VALUE *argv;
579 VALUE mod;
580 {
581 VALUE option;
582
583 rb_scan_args(argc, argv, "01", &option);
584 return method_list(mod, RTEST(option), ins_methods_priv_i);
585 }
586
587 VALUE
588 rb_obj_singleton_methods(argc, argv, obj)
589 int argc;
590 VALUE *argv;
591 VALUE obj;
592 {
593 VALUE all;
594 VALUE ary;
595 VALUE klass;
596 VALUE *p, *q, *pend;
597
598 rb_scan_args(argc, argv, "01", &all);
599 ary = rb_ary_new();
600 klass = CLASS_OF(obj);
601 while (klass && FL_TEST(klass, FL_SINGLETON)) {
602 st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
603 klass = RCLASS(klass)->super;
604 }
605 if (RTEST(all)) {
606 while (klass && TYPE(klass) == T_ICLASS) {
607 st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
608 klass = RCLASS(klass)->super;
609 }
610 }
611 p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
612 while (p < pend) {
613 if (*p == Qnil) {
614 p+=2;
615 continue;
616 }
617 *q++ = *p++;
618 }
619 RARRAY(ary)->len = q - RARRAY(ary)->ptr;
620
621 return ary;
622 }
623
624 void
625 rb_define_method_id(klass, name, func, argc)
626 VALUE klass;
627 ID name;
628 VALUE (*func)();
629 int argc;
630 {
631 rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC|NOEX_CFUNC);
632 }
633
634 void
635 rb_define_method(klass, name, func, argc)
636 VALUE klass;
637 const char *name;
638 VALUE (*func)();
639 int argc;
640 {
641 ID id = rb_intern(name);
642
643 rb_add_method(klass, id, NEW_CFUNC(func, argc),
644 ((name[0] == 'i' && id == rb_intern("initialize"))?
645 NOEX_PRIVATE:NOEX_PUBLIC)|NOEX_CFUNC);
646 }
647
648 void
649 rb_define_protected_method(klass, name, func, argc)
650 VALUE klass;
651 const char *name;
652 VALUE (*func)();
653 int argc;
654 {
655 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
656 NOEX_PROTECTED|NOEX_CFUNC);
657 }
658
659 void
660 rb_define_private_method(klass, name, func, argc)
661 VALUE klass;
662 const char *name;
663 VALUE (*func)();
664 int argc;
665 {
666 rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
667 NOEX_PRIVATE|NOEX_CFUNC);
668 }
669
670 void
671 rb_undef_method(klass, name)
672 VALUE klass;
673 const char *name;
674 {
675 rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
676 }
677
678 #define SPECIAL_SINGLETON(x,c) do {\
679 if (obj == (x)) {\
680 return c;\
681 }\
682 } while (0)
683
684 VALUE
685 rb_singleton_class(obj)
686 VALUE obj;
687 {
688 VALUE klass;
689
690 if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
691 rb_raise(rb_eTypeError, "can't define singleton");
692 }
693 if (rb_special_const_p(obj)) {
694 SPECIAL_SINGLETON(Qnil, rb_cNilClass);
695 SPECIAL_SINGLETON(Qfalse, rb_cFalseClass);
696 SPECIAL_SINGLETON(Qtrue, rb_cTrueClass);
697 rb_bug("unknown immediate %ld", obj);
698 }
699
700 DEFER_INTS;
701 if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
702 (BUILTIN_TYPE(obj) == T_CLASS ||
703 rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj)) {
704 klass = RBASIC(obj)->klass;
705 }
706 else {
707 klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
708 }
709 if (OBJ_TAINTED(obj)) {
710 OBJ_TAINT(klass);
711 }
712 else {
713 FL_UNSET(klass, FL_TAINT);
714 }
715 if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
716 ALLOW_INTS;
717
718 return klass;
719 }
720
721 void
722 rb_define_singleton_method(obj, name, func, argc)
723 VALUE obj;
724 const char *name;
725 VALUE (*func)();
726 int argc;
727 {
728 rb_define_method(rb_singleton_class(obj), name, func, argc);
729 }
730
731 void
732 rb_define_module_function(module, name, func, argc)
733 VALUE module;
734 const char *name;
735 VALUE (*func)();
736 int argc;
737 {
738 rb_define_private_method(module, name, func, argc);
739 rb_define_singleton_method(module, name, func, argc);
740 }
741
742 void
743 rb_define_global_function(name, func, argc)
744 const char *name;
745 VALUE (*func)();
746 int argc;
747 {
748 rb_define_module_function(rb_mKernel, name, func, argc);
749 }
750
751 void
752 rb_define_alias(klass, name1, name2)
753 VALUE klass;
754 const char *name1, *name2;
755 {
756 rb_alias(klass, rb_intern(name1), rb_intern(name2));
757 }
758
759 void
760 rb_define_attr(klass, name, read, write)
761 VALUE klass;
762 const char *name;
763 int read, write;
764 {
765 rb_attr(klass, rb_intern(name), read, write, Qfalse);
766 }
767
768 #ifdef HAVE_STDARG_PROTOTYPES
769 #include <stdarg.h>
770 #define va_init_list(a,b) va_start(a,b)
771 #else
772 #include <varargs.h>
773 #define va_init_list(a,b) va_start(a)
774 #endif
775
776 int
777 #ifdef HAVE_STDARG_PROTOTYPES
778 rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
779 #else
780 rb_scan_args(argc, argv, fmt, va_alist)
781 int argc;
782 const VALUE *argv;
783 const char *fmt;
784 va_dcl
785 #endif
786 {
787 int n, i = 0;
788 const char *p = fmt;
789 VALUE *var;
790 va_list vargs;
791
792 va_init_list(vargs, fmt);
793
794 if (*p == '*') goto rest_arg;
795
796 if (ISDIGIT(*p)) {
797 n = *p - '0';
798 if (n > argc)
799 rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, n);
800 for (i=0; i<n; i++) {
801 var = va_arg(vargs, VALUE*);
802 if (var) *var = argv[i];
803 }
804 p++;
805 }
806 else {
807 goto error;
808 }
809
810 if (ISDIGIT(*p)) {
811 n = i + *p - '0';
812 for (; i<n; i++) {
813 var = va_arg(vargs, VALUE*);
814 if (argc > i) {
815 if (var) *var = argv[i];
816 }
817 else {
818 if (var) *var = Qnil;
819 }
820 }
821 p++;
822 }
823
824 if(*p == '*') {
825 rest_arg:
826 var = va_arg(vargs, VALUE*);
827 if (argc > i) {
828 if (var) *var = rb_ary_new4(argc-i, argv+i);
829 i = argc;
830 }
831 else {
832 if (var) *var = rb_ary_new();
833 }
834 p++;
835 }
836
837 if (*p == '&') {
838 var = va_arg(vargs, VALUE*);
839 if (rb_block_given_p()) {
840 *var = rb_f_lambda();
841 }
842 else {
843 *var = Qnil;
844 }
845 p++;
846 }
847 va_end(vargs);
848
849 if (*p != '\0') {
850 goto error;
851 }
852
853 if (argc > i) {
854 rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)", argc, i);
855 }
856
857 return argc;
858
859 error:
860 rb_fatal("bad scan arg format: %s", fmt);
861 return 0;
862 }