summaryrefslogtreecommitdiff
path: root/spec/ruby/optional/capi/ext/util_spec.c
blob: d99ed12e14b8a1648bf157f4aa8fab4d36fc8498 (plain)
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
#include "ruby.h"
#include "rubyspec.h"

#ifdef __cplusplus
extern "C" {
#endif

VALUE util_spec_rb_scan_args(VALUE self, VALUE argv, VALUE fmt, VALUE expected, VALUE acc) {
  int i, result, argc = (int)RARRAY_LEN(argv);
  VALUE args[6], failed, a1, a2, a3, a4, a5, a6;

  failed = rb_intern("failed");
  a1 = a2 = a3 = a4 = a5 = a6 = failed;

  for(i = 0; i < argc; i++) {
    args[i] = rb_ary_entry(argv, i);
  }

  result = rb_scan_args(argc, args, RSTRING_PTR(fmt), &a1, &a2, &a3, &a4, &a5, &a6);

  switch(NUM2INT(expected)) {
  case 6:
    rb_ary_unshift(acc, a6);
    /* FALLTHROUGH */
  case 5:
    rb_ary_unshift(acc, a5);
    /* FALLTHROUGH */
  case 4:
    rb_ary_unshift(acc, a4);
    /* FALLTHROUGH */
  case 3:
    rb_ary_unshift(acc, a3);
    /* FALLTHROUGH */
  case 2:
    rb_ary_unshift(acc, a2);
    /* FALLTHROUGH */
  case 1:
    rb_ary_unshift(acc, a1);
    break;
  default:
    rb_raise(rb_eException, "unexpected number of arguments returned by rb_scan_args");
  }

  return INT2NUM(result);
}

static VALUE util_spec_rb_long2int(VALUE self, VALUE n) {
  return INT2NUM(rb_long2int(NUM2LONG(n)));
}

static VALUE util_spec_rb_iter_break(VALUE self) {
  rb_iter_break();
  return Qnil;
}

static VALUE util_spec_rb_sourcefile(VALUE self) {
  return rb_str_new2(rb_sourcefile());
}

static VALUE util_spec_rb_sourceline(VALUE self) {
  return INT2NUM(rb_sourceline());
}

void Init_util_spec(void) {
  VALUE cls = rb_define_class("CApiUtilSpecs", rb_cObject);
  rb_define_method(cls, "rb_scan_args", util_spec_rb_scan_args, 4);
  rb_define_method(cls, "rb_long2int", util_spec_rb_long2int, 1);
  rb_define_method(cls, "rb_iter_break", util_spec_rb_iter_break, 0);
  rb_define_method(cls, "rb_sourcefile", util_spec_rb_sourcefile, 0);
  rb_define_method(cls, "rb_sourceline", util_spec_rb_sourceline, 0);
}

#ifdef __cplusplus
}
#endif