File: kwarg.c

package info (click to toggle)
ruby-pgplot 0.1.3-9
  • links: PTS, VCS
  • area: contrib
  • in suites: jessie, jessie-kfreebsd
  • size: 480 kB
  • ctags: 118
  • sloc: ruby: 1,382; ansic: 73; makefile: 37
file content (95 lines) | stat: -rw-r--r-- 2,066 bytes parent folder | download | duplicates (2)
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);
}