Ruby  2.5.0dev(2017-10-22revision60238)
pointer.c
Go to the documentation of this file.
1 /* -*- C -*-
2  * $Id$
3  */
4 
5 #include <ruby/ruby.h>
6 #include <ruby/io.h>
7 #include <ctype.h>
8 #include <fiddle.h>
9 
10 #ifdef PRIsVALUE
11 # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
12 # define RB_OBJ_STRING(obj) (obj)
13 #else
14 # define PRIsVALUE "s"
15 # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
16 # define RB_OBJ_STRING(obj) StringValueCStr(obj)
17 #endif
18 
20 
21 typedef void (*freefunc_t)(void*);
22 
23 struct ptr_data {
24  void *ptr;
25  long size;
27  VALUE wrap[2];
28 };
29 
30 #define RPTR_DATA(obj) ((struct ptr_data *)(DATA_PTR(obj)))
31 
32 static inline freefunc_t
33 get_freefunc(VALUE func, volatile VALUE *wrap)
34 {
35  VALUE addrnum;
36  if (NIL_P(func)) {
37  *wrap = 0;
38  return NULL;
39  }
40  addrnum = rb_Integer(func);
41  *wrap = (addrnum != func) ? func : 0;
42  return (freefunc_t)(VALUE)NUM2PTR(addrnum);
43 }
44 
45 static ID id_to_ptr;
46 
47 static void
48 fiddle_ptr_mark(void *ptr)
49 {
50  struct ptr_data *data = ptr;
51  if (data->wrap[0]) {
52  rb_gc_mark(data->wrap[0]);
53  }
54  if (data->wrap[1]) {
55  rb_gc_mark(data->wrap[1]);
56  }
57 }
58 
59 static void
60 fiddle_ptr_free(void *ptr)
61 {
62  struct ptr_data *data = ptr;
63  if (data->ptr) {
64  if (data->free) {
65  (*(data->free))(data->ptr);
66  }
67  }
68  xfree(ptr);
69 }
70 
71 static size_t
72 fiddle_ptr_memsize(const void *ptr)
73 {
74  const struct ptr_data *data = ptr;
75  return sizeof(*data) + data->size;
76 }
77 
78 static const rb_data_type_t fiddle_ptr_data_type = {
79  "fiddle/pointer",
80  {fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,},
81 };
82 
83 static VALUE
84 rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
85 {
86  struct ptr_data *data;
87  VALUE val;
88 
89  val = TypedData_Make_Struct(klass, struct ptr_data, &fiddle_ptr_data_type, data);
90  data->ptr = ptr;
91  data->free = func;
92  data->size = size;
93  OBJ_TAINT(val);
94 
95  return val;
96 }
97 
98 static VALUE
99 rb_fiddle_ptr_new(void *ptr, long size, freefunc_t func)
100 {
101  return rb_fiddle_ptr_new2(rb_cPointer, ptr, size, func);
102 }
103 
104 static VALUE
105 rb_fiddle_ptr_malloc(long size, freefunc_t func)
106 {
107  void *ptr;
108 
109  ptr = ruby_xmalloc((size_t)size);
110  memset(ptr,0,(size_t)size);
111  return rb_fiddle_ptr_new(ptr, size, func);
112 }
113 
114 static void *
115 rb_fiddle_ptr2cptr(VALUE val)
116 {
117  struct ptr_data *data;
118  void *ptr;
119 
120  if (rb_obj_is_kind_of(val, rb_cPointer)) {
121  TypedData_Get_Struct(val, struct ptr_data, &fiddle_ptr_data_type, data);
122  ptr = data->ptr;
123  }
124  else if (val == Qnil) {
125  ptr = NULL;
126  }
127  else{
128  rb_raise(rb_eTypeError, "Fiddle::Pointer was expected");
129  }
130 
131  return ptr;
132 }
133 
134 static VALUE
135 rb_fiddle_ptr_s_allocate(VALUE klass)
136 {
137  VALUE obj;
138  struct ptr_data *data;
139 
140  obj = TypedData_Make_Struct(klass, struct ptr_data, &fiddle_ptr_data_type, data);
141  data->ptr = 0;
142  data->size = 0;
143  data->free = 0;
144 
145  return obj;
146 }
147 
148 /*
149  * call-seq:
150  * Fiddle::Pointer.new(address) => fiddle_cptr
151  * new(address, size) => fiddle_cptr
152  * new(address, size, freefunc) => fiddle_cptr
153  *
154  * Create a new pointer to +address+ with an optional +size+ and +freefunc+.
155  *
156  * +freefunc+ will be called when the instance is garbage collected.
157  */
158 static VALUE
159 rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
160 {
161  VALUE ptr, sym, size, wrap = 0, funcwrap = 0;
162  struct ptr_data *data;
163  void *p = NULL;
164  freefunc_t f = NULL;
165  long s = 0;
166 
167  if (rb_scan_args(argc, argv, "12", &ptr, &size, &sym) >= 1) {
168  VALUE addrnum = rb_Integer(ptr);
169  if (addrnum != ptr) wrap = ptr;
170  p = NUM2PTR(addrnum);
171  }
172  if (argc >= 2) {
173  s = NUM2LONG(size);
174  }
175  if (argc >= 3) {
176  f = get_freefunc(sym, &funcwrap);
177  }
178 
179  if (p) {
180  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
181  if (data->ptr && data->free) {
182  /* Free previous memory. Use of inappropriate initialize may cause SEGV. */
183  (*(data->free))(data->ptr);
184  }
185  data->wrap[0] = wrap;
186  data->wrap[1] = funcwrap;
187  data->ptr = p;
188  data->size = s;
189  data->free = f;
190  }
191 
192  return Qnil;
193 }
194 
195 /*
196  * call-seq:
197  *
198  * Fiddle::Pointer.malloc(size, freefunc = nil) => fiddle pointer instance
199  *
200  * Allocate +size+ bytes of memory and associate it with an optional
201  * +freefunc+ that will be called when the pointer is garbage collected.
202  *
203  * +freefunc+ must be an address pointing to a function or an instance of
204  * Fiddle::Function
205  */
206 static VALUE
207 rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
208 {
209  VALUE size, sym, obj, wrap = 0;
210  long s;
211  freefunc_t f;
212 
213  switch (rb_scan_args(argc, argv, "11", &size, &sym)) {
214  case 1:
215  s = NUM2LONG(size);
216  f = NULL;
217  break;
218  case 2:
219  s = NUM2LONG(size);
220  f = get_freefunc(sym, &wrap);
221  break;
222  default:
223  rb_bug("rb_fiddle_ptr_s_malloc");
224  }
225 
226  obj = rb_fiddle_ptr_malloc(s,f);
227  if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
228 
229  return obj;
230 }
231 
232 /*
233  * call-seq: to_i
234  *
235  * Returns the integer memory location of this pointer.
236  */
237 static VALUE
238 rb_fiddle_ptr_to_i(VALUE self)
239 {
240  struct ptr_data *data;
241 
242  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
243  return PTR2NUM(data->ptr);
244 }
245 
246 /*
247  * call-seq: to_value
248  *
249  * Cast this pointer to a ruby object.
250  */
251 static VALUE
252 rb_fiddle_ptr_to_value(VALUE self)
253 {
254  struct ptr_data *data;
255  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
256  return (VALUE)(data->ptr);
257 }
258 
259 /*
260  * call-seq: ptr
261  *
262  * Returns a new Fiddle::Pointer instance that is a dereferenced pointer for
263  * this pointer.
264  *
265  * Analogous to the star operator in C.
266  */
267 static VALUE
268 rb_fiddle_ptr_ptr(VALUE self)
269 {
270  struct ptr_data *data;
271 
272  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
273  return rb_fiddle_ptr_new(*((void**)(data->ptr)),0,0);
274 }
275 
276 /*
277  * call-seq: ref
278  *
279  * Returns a new Fiddle::Pointer instance that is a reference pointer for this
280  * pointer.
281  *
282  * Analogous to the ampersand operator in C.
283  */
284 static VALUE
285 rb_fiddle_ptr_ref(VALUE self)
286 {
287  struct ptr_data *data;
288 
289  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
290  return rb_fiddle_ptr_new(&(data->ptr),0,0);
291 }
292 
293 /*
294  * call-seq: null?
295  *
296  * Returns +true+ if this is a null pointer.
297  */
298 static VALUE
299 rb_fiddle_ptr_null_p(VALUE self)
300 {
301  struct ptr_data *data;
302 
303  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
304  return data->ptr ? Qfalse : Qtrue;
305 }
306 
307 /*
308  * call-seq: free=(function)
309  *
310  * Set the free function for this pointer to +function+ in the given
311  * Fiddle::Function.
312  */
313 static VALUE
314 rb_fiddle_ptr_free_set(VALUE self, VALUE val)
315 {
316  struct ptr_data *data;
317 
318  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
319  data->free = get_freefunc(val, &data->wrap[1]);
320 
321  return Qnil;
322 }
323 
324 /*
325  * call-seq: free => Fiddle::Function
326  *
327  * Get the free function for this pointer.
328  *
329  * Returns a new instance of Fiddle::Function.
330  *
331  * See Fiddle::Function.new
332  */
333 static VALUE
334 rb_fiddle_ptr_free_get(VALUE self)
335 {
336  struct ptr_data *pdata;
337  VALUE address;
338  VALUE arg_types;
339  VALUE ret_type;
340 
341  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata);
342 
343  if (!pdata->free)
344  return Qnil;
345 
346  address = PTR2NUM(pdata->free);
347  ret_type = INT2NUM(TYPE_VOID);
348  arg_types = rb_ary_new();
349  rb_ary_push(arg_types, INT2NUM(TYPE_VOIDP));
350 
351  return rb_fiddle_new_function(address, arg_types, ret_type);
352 }
353 
354 /*
355  * call-seq:
356  *
357  * ptr.to_s => string
358  * ptr.to_s(len) => string
359  *
360  * Returns the pointer contents as a string.
361  *
362  * When called with no arguments, this method will return the contents until
363  * the first NULL byte.
364  *
365  * When called with +len+, a string of +len+ bytes will be returned.
366  *
367  * See to_str
368  */
369 static VALUE
370 rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self)
371 {
372  struct ptr_data *data;
373  VALUE arg1, val;
374  int len;
375 
376  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
377  switch (rb_scan_args(argc, argv, "01", &arg1)) {
378  case 0:
379  val = rb_tainted_str_new2((char*)(data->ptr));
380  break;
381  case 1:
382  len = NUM2INT(arg1);
383  val = rb_tainted_str_new((char*)(data->ptr), len);
384  break;
385  default:
386  rb_bug("rb_fiddle_ptr_to_s");
387  }
388 
389  return val;
390 }
391 
392 /*
393  * call-seq:
394  *
395  * ptr.to_str => string
396  * ptr.to_str(len) => string
397  *
398  * Returns the pointer contents as a string.
399  *
400  * When called with no arguments, this method will return the contents with the
401  * length of this pointer's +size+.
402  *
403  * When called with +len+, a string of +len+ bytes will be returned.
404  *
405  * See to_s
406  */
407 static VALUE
408 rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self)
409 {
410  struct ptr_data *data;
411  VALUE arg1, val;
412  int len;
413 
414  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
415  switch (rb_scan_args(argc, argv, "01", &arg1)) {
416  case 0:
417  val = rb_tainted_str_new((char*)(data->ptr),data->size);
418  break;
419  case 1:
420  len = NUM2INT(arg1);
421  val = rb_tainted_str_new((char*)(data->ptr), len);
422  break;
423  default:
424  rb_bug("rb_fiddle_ptr_to_str");
425  }
426 
427  return val;
428 }
429 
430 /*
431  * call-seq: inspect
432  *
433  * Returns a string formatted with an easily readable representation of the
434  * internal state of the pointer.
435  */
436 static VALUE
437 rb_fiddle_ptr_inspect(VALUE self)
438 {
439  struct ptr_data *data;
440 
441  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
442  return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>",
443  RB_OBJ_CLASSNAME(self), data, data->ptr, data->size, data->free);
444 }
445 
446 /*
447  * call-seq:
448  * ptr == other => true or false
449  * ptr.eql?(other) => true or false
450  *
451  * Returns true if +other+ wraps the same pointer, otherwise returns
452  * false.
453  */
454 static VALUE
455 rb_fiddle_ptr_eql(VALUE self, VALUE other)
456 {
457  void *ptr1, *ptr2;
458 
459  if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qfalse;
460 
461  ptr1 = rb_fiddle_ptr2cptr(self);
462  ptr2 = rb_fiddle_ptr2cptr(other);
463 
464  return ptr1 == ptr2 ? Qtrue : Qfalse;
465 }
466 
467 /*
468  * call-seq:
469  * ptr <=> other => -1, 0, 1, or nil
470  *
471  * Returns -1 if less than, 0 if equal to, 1 if greater than +other+.
472  *
473  * Returns nil if +ptr+ cannot be compared to +other+.
474  */
475 static VALUE
476 rb_fiddle_ptr_cmp(VALUE self, VALUE other)
477 {
478  void *ptr1, *ptr2;
479  SIGNED_VALUE diff;
480 
481  if(!rb_obj_is_kind_of(other, rb_cPointer)) return Qnil;
482 
483  ptr1 = rb_fiddle_ptr2cptr(self);
484  ptr2 = rb_fiddle_ptr2cptr(other);
485  diff = (SIGNED_VALUE)ptr1 - (SIGNED_VALUE)ptr2;
486  if (!diff) return INT2FIX(0);
487  return diff > 0 ? INT2NUM(1) : INT2NUM(-1);
488 }
489 
490 /*
491  * call-seq:
492  * ptr + n => new cptr
493  *
494  * Returns a new pointer instance that has been advanced +n+ bytes.
495  */
496 static VALUE
497 rb_fiddle_ptr_plus(VALUE self, VALUE other)
498 {
499  void *ptr;
500  long num, size;
501 
502  ptr = rb_fiddle_ptr2cptr(self);
503  size = RPTR_DATA(self)->size;
504  num = NUM2LONG(other);
505  return rb_fiddle_ptr_new((char *)ptr + num, size - num, 0);
506 }
507 
508 /*
509  * call-seq:
510  * ptr - n => new cptr
511  *
512  * Returns a new pointer instance that has been moved back +n+ bytes.
513  */
514 static VALUE
515 rb_fiddle_ptr_minus(VALUE self, VALUE other)
516 {
517  void *ptr;
518  long num, size;
519 
520  ptr = rb_fiddle_ptr2cptr(self);
521  size = RPTR_DATA(self)->size;
522  num = NUM2LONG(other);
523  return rb_fiddle_ptr_new((char *)ptr - num, size + num, 0);
524 }
525 
526 /*
527  * call-seq:
528  * ptr[index] -> an_integer
529  * ptr[start, length] -> a_string
530  *
531  * Returns integer stored at _index_.
532  *
533  * If _start_ and _length_ are given, a string containing the bytes from
534  * _start_ of _length_ will be returned.
535  */
536 static VALUE
537 rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
538 {
539  VALUE arg0, arg1;
540  VALUE retval = Qnil;
541  size_t offset, len;
542  struct ptr_data *data;
543 
544  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
545  if (!data->ptr) rb_raise(rb_eFiddleError, "NULL pointer dereference");
546  switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){
547  case 1:
548  offset = NUM2ULONG(arg0);
549  retval = INT2NUM(*((char *)data->ptr + offset));
550  break;
551  case 2:
552  offset = NUM2ULONG(arg0);
553  len = NUM2ULONG(arg1);
554  retval = rb_tainted_str_new((char *)data->ptr + offset, len);
555  break;
556  default:
557  rb_bug("rb_fiddle_ptr_aref()");
558  }
559  return retval;
560 }
561 
562 /*
563  * call-seq:
564  * ptr[index] = int -> int
565  * ptr[start, length] = string or cptr or addr -> string or dl_cptr or addr
566  *
567  * Set the value at +index+ to +int+.
568  *
569  * Or, set the memory at +start+ until +length+ with the contents of +string+,
570  * the memory from +dl_cptr+, or the memory pointed at by the memory address
571  * +addr+.
572  */
573 static VALUE
574 rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self)
575 {
576  VALUE arg0, arg1, arg2;
577  VALUE retval = Qnil;
578  size_t offset, len;
579  void *mem;
580  struct ptr_data *data;
581 
582  TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
583  if (!data->ptr) rb_raise(rb_eFiddleError, "NULL pointer dereference");
584  switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){
585  case 2:
586  offset = NUM2ULONG(arg0);
587  ((char*)data->ptr)[offset] = NUM2UINT(arg1);
588  retval = arg1;
589  break;
590  case 3:
591  offset = NUM2ULONG(arg0);
592  len = NUM2ULONG(arg1);
593  if (RB_TYPE_P(arg2, T_STRING)) {
594  mem = StringValuePtr(arg2);
595  }
596  else if( rb_obj_is_kind_of(arg2, rb_cPointer) ){
597  mem = rb_fiddle_ptr2cptr(arg2);
598  }
599  else{
600  mem = NUM2PTR(arg2);
601  }
602  memcpy((char *)data->ptr + offset, mem, len);
603  retval = arg2;
604  break;
605  default:
606  rb_bug("rb_fiddle_ptr_aset()");
607  }
608  return retval;
609 }
610 
611 /*
612  * call-seq: size=(size)
613  *
614  * Set the size of this pointer to +size+
615  */
616 static VALUE
617 rb_fiddle_ptr_size_set(VALUE self, VALUE size)
618 {
619  RPTR_DATA(self)->size = NUM2LONG(size);
620  return size;
621 }
622 
623 /*
624  * call-seq: size
625  *
626  * Get the size of this pointer.
627  */
628 static VALUE
629 rb_fiddle_ptr_size_get(VALUE self)
630 {
631  return LONG2NUM(RPTR_DATA(self)->size);
632 }
633 
634 /*
635  * call-seq:
636  * Fiddle::Pointer[val] => cptr
637  * to_ptr(val) => cptr
638  *
639  * Get the underlying pointer for ruby object +val+ and return it as a
640  * Fiddle::Pointer object.
641  */
642 static VALUE
643 rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
644 {
645  VALUE ptr, wrap = val, vptr;
646 
647  if (RTEST(rb_obj_is_kind_of(val, rb_cIO))){
648  rb_io_t *fptr;
649  FILE *fp;
650  GetOpenFile(val, fptr);
651  fp = rb_io_stdio_file(fptr);
652  ptr = rb_fiddle_ptr_new(fp, 0, NULL);
653  }
654  else if (RTEST(rb_obj_is_kind_of(val, rb_cString))){
655  char *str = StringValuePtr(val);
656  ptr = rb_fiddle_ptr_new(str, RSTRING_LEN(val), NULL);
657  }
658  else if ((vptr = rb_check_funcall(val, id_to_ptr, 0, 0)) != Qundef){
659  if (rb_obj_is_kind_of(vptr, rb_cPointer)){
660  ptr = vptr;
661  wrap = 0;
662  }
663  else{
664  rb_raise(rb_eFiddleError, "to_ptr should return a Fiddle::Pointer object");
665  }
666  }
667  else{
668  VALUE num = rb_Integer(val);
669  if (num == val) wrap = 0;
670  ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
671  }
672  OBJ_INFECT(ptr, val);
673  if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
674  return ptr;
675 }
676 
677 void
679 {
680  id_to_ptr = rb_intern("to_ptr");
681 
682  /* Document-class: Fiddle::Pointer
683  *
684  * Fiddle::Pointer is a class to handle C pointers
685  *
686  */
688  rb_define_alloc_func(rb_cPointer, rb_fiddle_ptr_s_allocate);
689  rb_define_singleton_method(rb_cPointer, "malloc", rb_fiddle_ptr_s_malloc, -1);
690  rb_define_singleton_method(rb_cPointer, "to_ptr", rb_fiddle_ptr_s_to_ptr, 1);
691  rb_define_singleton_method(rb_cPointer, "[]", rb_fiddle_ptr_s_to_ptr, 1);
692  rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1);
693  rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1);
694  rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0);
695  rb_define_method(rb_cPointer, "to_i", rb_fiddle_ptr_to_i, 0);
696  rb_define_method(rb_cPointer, "to_int", rb_fiddle_ptr_to_i, 0);
697  rb_define_method(rb_cPointer, "to_value", rb_fiddle_ptr_to_value, 0);
698  rb_define_method(rb_cPointer, "ptr", rb_fiddle_ptr_ptr, 0);
699  rb_define_method(rb_cPointer, "+@", rb_fiddle_ptr_ptr, 0);
700  rb_define_method(rb_cPointer, "ref", rb_fiddle_ptr_ref, 0);
701  rb_define_method(rb_cPointer, "-@", rb_fiddle_ptr_ref, 0);
702  rb_define_method(rb_cPointer, "null?", rb_fiddle_ptr_null_p, 0);
703  rb_define_method(rb_cPointer, "to_s", rb_fiddle_ptr_to_s, -1);
704  rb_define_method(rb_cPointer, "to_str", rb_fiddle_ptr_to_str, -1);
705  rb_define_method(rb_cPointer, "inspect", rb_fiddle_ptr_inspect, 0);
706  rb_define_method(rb_cPointer, "<=>", rb_fiddle_ptr_cmp, 1);
707  rb_define_method(rb_cPointer, "==", rb_fiddle_ptr_eql, 1);
708  rb_define_method(rb_cPointer, "eql?", rb_fiddle_ptr_eql, 1);
709  rb_define_method(rb_cPointer, "+", rb_fiddle_ptr_plus, 1);
710  rb_define_method(rb_cPointer, "-", rb_fiddle_ptr_minus, 1);
711  rb_define_method(rb_cPointer, "[]", rb_fiddle_ptr_aref, -1);
712  rb_define_method(rb_cPointer, "[]=", rb_fiddle_ptr_aset, -1);
713  rb_define_method(rb_cPointer, "size", rb_fiddle_ptr_size_get, 0);
714  rb_define_method(rb_cPointer, "size=", rb_fiddle_ptr_size_set, 1);
715 
716  /* Document-const: NULL
717  *
718  * A NULL pointer
719  */
720  rb_define_const(mFiddle, "NULL", rb_fiddle_ptr_new(0, 0, 0));
721 }
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:1927
void rb_bug(const char *fmt,...)
Definition: error.c:521
freefunc_t free
Definition: pointer.c:26
#define TYPE_VOIDP
Definition: fiddle.h:108
VALUE mFiddle
Definition: fiddle.c:3
#define INT2NUM(x)
Definition: ruby.h:1538
#define NUM2INT(x)
Definition: ruby.h:684
#define NUM2UINT(x)
Definition: ruby.h:685
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define Qtrue
Definition: ruby.h:437
Definition: io.h:62
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1183
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:924
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_Integer(VALUE)
Equivalent to Kernel#Integer in Ruby.
Definition: object.c:3148
void rb_gc_mark(VALUE ptr)
Definition: gc.c:4464
#define GetOpenFile(obj, fp)
Definition: io.h:120
#define sym(x)
Definition: date_core.c:3721
VALUE rb_eFiddleError
Definition: fiddle.c:4
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
Definition: object.c:842
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
VALUE rb_ary_new(void)
Definition: array.c:499
#define NIL_P(v)
Definition: ruby.h:451
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2691
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
void(* freefunc_t)(void *)
Definition: pointer.c:21
VALUE wrap[2]
Definition: pointer.c:27
void * ptr
Definition: pointer.c:24
RUBY_EXTERN VALUE rb_cIO
Definition: ruby.h:1913
#define RSTRING_LEN(str)
Definition: ruby.h:971
#define RB_OBJ_CLASSNAME(obj)
Definition: pointer.c:11
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1452
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
#define Qnil
Definition: ruby.h:438
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_eTypeError
Definition: error.c:801
#define PTR2NUM(x)
Definition: conversions.h:36
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
Definition: vm_eval.c:389
#define rb_tainted_str_new2
Definition: intern.h:839
#define NUM2PTR(x)
Definition: conversions.h:37
#define LONG2NUM(x)
Definition: ruby.h:1573
register unsigned int len
Definition: zonetab.h:51
void * ruby_xmalloc(size_t size)
Definition: gc.c:7997
#define f
#define INT2FIX(i)
Definition: ruby.h:232
VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type)
Definition: function.c:67
#define TYPE_VOID
Definition: fiddle.h:107
#define NUM2ULONG(x)
Definition: ruby.h:658
#define RTEST(v)
Definition: ruby.h:450
#define T_STRING
Definition: ruby.h:496
#define OBJ_INFECT(x, s)
Definition: ruby.h:1302
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1175
FILE * rb_io_stdio_file(rb_io_t *fptr)
Definition: io.c:7676
VALUE rb_cPointer
Definition: pointer.c:19
#define StringValuePtr(v)
Definition: ruby.h:570
#define RPTR_DATA(obj)
Definition: pointer.c:30
void Init_fiddle_pointer(void)
Definition: pointer.c:678
void void xfree(void *)
VALUE rb_tainted_str_new(const char *, long)
Definition: string.c:854
#define rb_intern(str)
#define NULL
Definition: _sdbm.c:102
#define Qundef
Definition: ruby.h:439
#define OBJ_TAINT(x)
Definition: ruby.h:1298
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
long size
Definition: pointer.c:25
#define NUM2LONG(x)
Definition: ruby.h:648
char ** argv
Definition: ruby.c:188
#define SIGNED_VALUE
Definition: ruby.h:87