1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
/*
kwarg.c : Process keyword arguments for Ruby
Copyright (c) 2001 Masahiro TANAKA <masa@ir.isas.ac.jp>
This program is free software.
You can distribute/modify this program
under the same terms as Ruby itself.
NO WARRANTY.
*/
#include <ruby.h>
#ifndef RUBY_19
#ifndef RSTRING_PTR
#define RSTRING_PTR(a) (RSTRING(a)->ptr)
#endif
#ifndef RSTRING_LEN
#define RSTRING_LEN(a) (RSTRING(a)->len)
#endif
#ifndef RARRAY_PTR
#define RARRAY_PTR(s) (RARRAY(s)->ptr)
#endif
#ifndef RARRAY_LEN
#define RARRAY_LEN(s) (RARRAY(s)->len)
#endif
#ifndef StringValuePtr
#define StringValuePtr(s) STR2CSTR(s)
#endif
#endif
/* void rb_scan_kw_args __((VALUE, ...)); */
static VALUE
kw_hash_i(i, tmp)
VALUE i, tmp;
{
VALUE key;
key = RARRAY_PTR(i)[0];
if (TYPE(key)==T_SYMBOL) {
key = rb_funcall(key, rb_intern("id2name"), 0);
} else
if (TYPE(key)!=T_STRING) {
rb_raise(rb_eArgError, "keywords must be String or Symbol");
}
rb_hash_aset(tmp, key, RARRAY_PTR(i)[1]);
return Qnil;
}
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
#include <varargs.h>
#define va_init_list(a,b) va_start(a)
#endif
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_scan_kw_args(VALUE hash, ...)
#else
rb_scan_kw_args(hash, va_alist)
VALUE hash;
va_dcl
#endif
{
char *key;
VALUE *var, val, str, tmp;
va_list vargs;
va_init_list(vargs, hash);
tmp = rb_hash_new();
if (TYPE(hash) == T_HASH)
rb_iterate(rb_each, hash, kw_hash_i, tmp);
else if (hash != Qnil)
rb_fatal("rb_san_kw_args: non-hash arg passed");
for (;;) {
key = va_arg(vargs, char*);
if (!key) break;
var = va_arg(vargs, VALUE*);
str = rb_str_new2(key);
val = rb_funcall(tmp, rb_intern("delete"), 1, str);
if (var) *var = val;
}
if (rb_funcall(tmp, rb_intern("empty?"), 0)==Qfalse) {
val = rb_funcall(tmp, rb_intern("keys"), 0);
val = rb_funcall(val, rb_intern("join"), 1, rb_str_new2(","));
rb_raise(rb_eArgError, "unknown keywords: %s",StringValuePtr(val));
}
va_end(vargs);
}
|