summaryrefslogtreecommitdiff
path: root/spec/ruby/optional/capi/ext/class_spec.c
blob: e62b9efe2e0ca9ed819bec0091509f8caba94b20 (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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "ruby.h"
#include "rubyspec.h"

#include <stdio.h>
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

static VALUE class_spec_call_super_method(VALUE self) {
  return rb_call_super(0, 0);
}

static VALUE class_spec_define_call_super_method(VALUE self, VALUE obj, VALUE str_name) {
  rb_define_method(obj, RSTRING_PTR(str_name), class_spec_call_super_method, 0);
  return Qnil;
}

static VALUE class_spec_rb_class_path(VALUE self, VALUE klass) {
  return rb_class_path(klass);
}

static VALUE class_spec_rb_class_name(VALUE self, VALUE klass) {
  return rb_class_name(klass);
}

static VALUE class_spec_rb_class2name(VALUE self, VALUE klass) {
  return rb_str_new2( rb_class2name(klass) );
}

static VALUE class_spec_rb_path2class(VALUE self, VALUE path) {
  return rb_path2class(RSTRING_PTR(path));
}

static VALUE class_spec_rb_path_to_class(VALUE self, VALUE path) {
  return rb_path_to_class(path);
}

static VALUE class_spec_rb_class_new(VALUE self, VALUE super) {
  return rb_class_new(super);
}

static VALUE class_spec_rb_class_new_instance(VALUE self,
                                      VALUE nargs, VALUE args,
                                      VALUE klass) {
  int c_nargs = FIX2INT(nargs);
  VALUE *c_args = (VALUE*)alloca(sizeof(VALUE) * c_nargs);
  int i;

  for (i = 0; i < c_nargs; i++)
    c_args[i] = rb_ary_entry(args, i);

  return rb_class_new_instance(c_nargs, c_args, klass);
}

static VALUE class_spec_rb_class_real(VALUE self, VALUE object) {
  if(rb_type_p(object, T_FIXNUM)) {
    return INT2FIX(rb_class_real(FIX2INT(object)));
  } else {
    return rb_class_real(CLASS_OF(object));
  }
}

static VALUE class_spec_rb_class_superclass(VALUE self, VALUE klass) {
  return rb_class_superclass(klass);
}

static VALUE class_spec_cvar_defined(VALUE self, VALUE klass, VALUE id) {
  ID as_id = rb_intern(StringValuePtr(id));
  return rb_cvar_defined(klass, as_id);
}

static VALUE class_spec_cvar_get(VALUE self, VALUE klass, VALUE name) {
  return rb_cvar_get(klass, rb_intern(StringValuePtr(name)));
}

static VALUE class_spec_cvar_set(VALUE self, VALUE klass, VALUE name, VALUE val) {
  rb_cvar_set(klass, rb_intern(StringValuePtr(name)), val);
  return Qnil;
}

static VALUE class_spec_cv_get(VALUE self, VALUE klass, VALUE name) {
  return rb_cv_get(klass, StringValuePtr(name));
}

static VALUE class_spec_cv_set(VALUE self, VALUE klass, VALUE name, VALUE val) {
  rb_cv_set(klass, StringValuePtr(name), val);

  return Qnil;
}

VALUE class_spec_define_attr(VALUE self, VALUE klass, VALUE sym, VALUE read, VALUE write) {
  int int_read, int_write;
  int_read = read == Qtrue ? 1 : 0;
  int_write = write == Qtrue ? 1 : 0;
  rb_define_attr(klass, rb_id2name(SYM2ID(sym)), int_read, int_write);
  return Qnil;
}

static VALUE class_spec_rb_define_class(VALUE self, VALUE name, VALUE super) {
  if(NIL_P(super)) super = 0;
  return rb_define_class(RSTRING_PTR(name), super);
}

static VALUE class_spec_rb_define_class_under(VALUE self, VALUE outer,
                                                 VALUE name, VALUE super) {
  if(NIL_P(super)) super = 0;
  return rb_define_class_under(outer, RSTRING_PTR(name), super);
}

static VALUE class_spec_rb_define_class_id_under(VALUE self, VALUE outer,
                                                 VALUE name, VALUE super) {
  if(NIL_P(super)) super = 0;
  return rb_define_class_id_under(outer, SYM2ID(name), super);
}

static VALUE class_spec_define_class_variable(VALUE self, VALUE klass, VALUE name, VALUE val) {
  rb_define_class_variable(klass, StringValuePtr(name), val);
  return Qnil;
}

static VALUE class_spec_include_module(VALUE self, VALUE klass, VALUE module) {
  rb_include_module(klass, module);
  return klass;
}

static VALUE class_spec_method_var_args_1(int argc, VALUE *argv, VALUE self) {
  VALUE ary = rb_ary_new();
  int i;
  for (i = 0; i < argc; i++) {
    rb_ary_push(ary, argv[i]);
  }
  return ary;
}

static VALUE class_spec_method_var_args_2(VALUE self, VALUE argv) {
  return argv;
}

void Init_class_spec(void) {
  VALUE cls = rb_define_class("CApiClassSpecs", rb_cObject);
  rb_define_method(cls, "define_call_super_method", class_spec_define_call_super_method, 2);
  rb_define_method(cls, "rb_class_path", class_spec_rb_class_path, 1);
  rb_define_method(cls, "rb_class_name", class_spec_rb_class_name, 1);
  rb_define_method(cls, "rb_class2name", class_spec_rb_class2name, 1);
  rb_define_method(cls, "rb_path2class", class_spec_rb_path2class, 1);
  rb_define_method(cls, "rb_path_to_class", class_spec_rb_path_to_class, 1);
  rb_define_method(cls, "rb_class_new", class_spec_rb_class_new, 1);
  rb_define_method(cls, "rb_class_new_instance", class_spec_rb_class_new_instance, 3);
  rb_define_method(cls, "rb_class_real", class_spec_rb_class_real, 1);
  rb_define_method(cls, "rb_class_superclass", class_spec_rb_class_superclass, 1);
  rb_define_method(cls, "rb_cvar_defined", class_spec_cvar_defined, 2);
  rb_define_method(cls, "rb_cvar_get", class_spec_cvar_get, 2);
  rb_define_method(cls, "rb_cvar_set", class_spec_cvar_set, 3);
  rb_define_method(cls, "rb_cv_get", class_spec_cv_get, 2);
  rb_define_method(cls, "rb_cv_set", class_spec_cv_set, 3);
  rb_define_method(cls, "rb_define_attr", class_spec_define_attr, 4);
  rb_define_method(cls, "rb_define_class", class_spec_rb_define_class, 2);
  rb_define_method(cls, "rb_define_class_under", class_spec_rb_define_class_under, 3);
  rb_define_method(cls, "rb_define_class_id_under", class_spec_rb_define_class_id_under, 3);
  rb_define_method(cls, "rb_define_class_variable", class_spec_define_class_variable, 3);
  rb_define_method(cls, "rb_include_module", class_spec_include_module, 2);
  rb_define_method(cls, "rb_method_varargs_1", class_spec_method_var_args_1, -1);
  rb_define_method(cls, "rb_method_varargs_2", class_spec_method_var_args_2, -2);
}

#ifdef __cplusplus
}
#endif