* class.c (rb_scan_args): Revamp rb_scan_args() to compute the
number of required and optional arguments precisely to prepare for a more informative error message. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d91f52ae8b
commit
ca292099a6
@ -1,3 +1,9 @@
|
|||||||
|
Wed Feb 25 00:05:13 2009 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* class.c (rb_scan_args): Revamp rb_scan_args() to compute the
|
||||||
|
number of required and optional arguments precisely to prepare
|
||||||
|
for a more informative error message.
|
||||||
|
|
||||||
Tue Feb 24 23:58:52 2009 Akinori MUSHA <knu@iDaemons.org>
|
Tue Feb 24 23:58:52 2009 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* array.c (rb_ary_index, rb_ary_rindex): Emit a warning that a
|
* array.c (rb_ary_index, rb_ary_rindex): Emit a warning that a
|
||||||
|
152
class.c
152
class.c
@ -920,112 +920,102 @@ rb_define_attr(VALUE klass, const char *name, int read, int write)
|
|||||||
int
|
int
|
||||||
rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
|
rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
int i = 0, postargc, nonpostargc;
|
int i;
|
||||||
const char *p = fmt, *q;
|
const char *p = fmt;
|
||||||
VALUE *var;
|
VALUE *var;
|
||||||
va_list vargs;
|
va_list vargs;
|
||||||
|
int f_var = 0, f_block = 0;
|
||||||
|
int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
|
||||||
|
int argi = 0;
|
||||||
|
|
||||||
|
if (ISDIGIT(*p)) {
|
||||||
|
n_lead = *p - '0';
|
||||||
|
p++;
|
||||||
|
if (ISDIGIT(*p)) {
|
||||||
|
n_opt = *p - '0';
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*p == '*') {
|
||||||
|
f_var = 1;
|
||||||
|
p++;
|
||||||
|
if (ISDIGIT(*p)) {
|
||||||
|
n_trail = *p - '0';
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*p == '&') {
|
||||||
|
f_block = 1;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (*p != '\0') {
|
||||||
|
rb_fatal("bad scan arg format: %s", fmt);
|
||||||
|
}
|
||||||
|
n_mand = n_lead + n_trail;
|
||||||
|
|
||||||
|
if (argc < n_mand)
|
||||||
|
goto argc_error;
|
||||||
|
|
||||||
va_start(vargs, fmt);
|
va_start(vargs, fmt);
|
||||||
|
|
||||||
/* check the trailing mandatory argument length in advance */
|
/* capture leading mandatory arguments */
|
||||||
if ((q = strchr(p, '*')) != NULL && ISDIGIT(*++q)) {
|
for (i = n_lead; i-- > 0; ) {
|
||||||
postargc = *q - '0';
|
var = va_arg(vargs, VALUE *);
|
||||||
nonpostargc = argc - postargc;
|
if (var) *var = argv[argi];
|
||||||
|
argi++;
|
||||||
}
|
}
|
||||||
else {
|
/* capture optional arguments */
|
||||||
postargc = 0;
|
for (i = n_opt; i-- > 0; ) {
|
||||||
nonpostargc = argc;
|
var = va_arg(vargs, VALUE *);
|
||||||
}
|
if (argi < argc - n_trail) {
|
||||||
|
if (var) *var = argv[argi];
|
||||||
if (*p == '*') {
|
argi++;
|
||||||
if (nonpostargc < 0)
|
|
||||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
|
|
||||||
argc, postargc);
|
|
||||||
goto rest_arg;
|
|
||||||
}
|
|
||||||
else if (ISDIGIT(*p)) {
|
|
||||||
/* leading mandatory arguments */
|
|
||||||
int n = *p - '0';
|
|
||||||
|
|
||||||
if (nonpostargc < n)
|
|
||||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
|
|
||||||
argc, n + postargc);
|
|
||||||
for (; n-- > 0; i++) {
|
|
||||||
var = va_arg(vargs, VALUE*);
|
|
||||||
if (var) *var = argv[i];
|
|
||||||
}
|
}
|
||||||
p++;
|
else {
|
||||||
}
|
if (var) *var = Qnil;
|
||||||
else {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* optional arguments (typically with default values) */
|
|
||||||
if (ISDIGIT(*p)) {
|
|
||||||
int n = *p - '0';
|
|
||||||
|
|
||||||
for (; n-- > 0; ) {
|
|
||||||
var = va_arg(vargs, VALUE*);
|
|
||||||
if (i < nonpostargc) {
|
|
||||||
if (var) *var = argv[i];
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (var) *var = Qnil;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
|
/* capture variable length arguments */
|
||||||
|
if (f_var) {
|
||||||
|
int n_var = argc - argi - n_trail;
|
||||||
|
|
||||||
if (*p == '*') {
|
var = va_arg(vargs, VALUE *);
|
||||||
rest_arg:
|
if (0 < n_var) {
|
||||||
/* variable length arguments (the <*rest> part) */
|
if (var) *var = rb_ary_new4(n_var, &argv[argi]);
|
||||||
var = va_arg(vargs, VALUE*);
|
argi += n_var;
|
||||||
if (i < nonpostargc) {
|
|
||||||
if (var) *var = rb_ary_new4(nonpostargc-i, argv+i);
|
|
||||||
i = nonpostargc;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (var) *var = rb_ary_new();
|
if (var) *var = rb_ary_new();
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
|
|
||||||
if (0 < postargc) {
|
|
||||||
/* trailing mandatory arguments */
|
|
||||||
int n = postargc;
|
|
||||||
|
|
||||||
for (; n-- > 0; i++) {
|
|
||||||
var = va_arg(vargs, VALUE*);
|
|
||||||
if (var) *var = argv[i];
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
/* capture trailing mandatory arguments */
|
||||||
if (*p == '&') {
|
for (i = n_trail; i-- > 0; ) {
|
||||||
/* iterator block */
|
var = va_arg(vargs, VALUE *);
|
||||||
var = va_arg(vargs, VALUE*);
|
if (var) *var = argv[argi];
|
||||||
|
argi++;
|
||||||
|
}
|
||||||
|
/* capture iterator block */
|
||||||
|
if (f_block) {
|
||||||
|
var = va_arg(vargs, VALUE *);
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
*var = rb_block_proc();
|
*var = rb_block_proc();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*var = Qnil;
|
*var = Qnil;
|
||||||
}
|
}
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
va_end(vargs);
|
va_end(vargs);
|
||||||
|
|
||||||
if (*p != '\0') {
|
if (argi < argc)
|
||||||
goto error;
|
goto argc_error;
|
||||||
}
|
|
||||||
|
|
||||||
if (i < argc) {
|
|
||||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return argc;
|
return argc;
|
||||||
|
|
||||||
error:
|
argc_error:
|
||||||
rb_fatal("bad scan arg format: %s", fmt);
|
if (0 < n_opt)
|
||||||
return 0;
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)",
|
||||||
|
argc, n_mand, n_mand + n_opt, f_var ? "+" : "");
|
||||||
|
else
|
||||||
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)",
|
||||||
|
argc, n_mand, f_var ? "+" : "");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user