$search
00001 #include <stdio.h> 00002 #include <math.h> 00003 #include <ruby.h> 00004 #include <typelib/value.hh> 00005 #include <test/test_cimport.1> 00006 #include <math.h> 00007 00008 using namespace Typelib; 00009 00010 static bool do_check_struct_A_value(A const& a) 00011 { 00012 if (a.a == 10 && a.b == 20 && a.c == 30 && a.d == 40) 00013 return true; 00014 printf("do_check_struct_A_value failed: a=%i, b=%i, c=%i, d=%i\n", 00015 (int)a.a, (int)a.b, (int)a.c, (int)a.d); 00016 return false; 00017 } 00018 00019 static void do_set_struct_A_value(A& a) 00020 { 00021 a.a = 10; 00022 a.b = 20; 00023 a.c = 30; 00024 a.d = 40; 00025 } 00026 /* 00027 * This file provides the C-side of the test_rb_value testsuite 00028 */ 00029 00030 static VALUE check_struct_A_value(VALUE self, VALUE ra) 00031 { 00032 Value* value = 0; 00033 Data_Get_Struct(ra, Value, value); 00034 00035 A& a(*reinterpret_cast<A*>(value->getData())); 00036 if (do_check_struct_A_value(a)) 00037 return Qtrue; 00038 return Qfalse; 00039 } 00040 00041 static VALUE set_struct_A_value(VALUE self, VALUE ra) 00042 { 00043 Value* value = 0; 00044 Data_Get_Struct(ra, Value, value); 00045 00046 A& a(*reinterpret_cast<A*>(value->getData())); 00047 do_set_struct_A_value(a); 00048 return ra; 00049 } 00050 00051 static VALUE check_B_c_value(VALUE self, VALUE rb) 00052 { 00053 Value* value = 0; 00054 Data_Get_Struct(rb, Value, value); 00055 00056 B& b(*reinterpret_cast<B*>(value->getData())); 00057 for (int i = 0; i < 100; ++i) 00058 if (fabs(b.c[i] - float(i) / 10.0f) > 0.001) 00059 return Qfalse; 00060 return Qtrue; 00061 } 00062 00063 static void do_set_B_c_value(B& b) 00064 { 00065 for (int i = 0; i < 100; ++i) 00066 b.c[i] = float(i) / 10.0f; 00067 } 00068 00069 static VALUE set_B_c_value(VALUE self, VALUE rb) 00070 { 00071 Value* value = 0; 00072 Data_Get_Struct(rb, Value, value); 00073 00074 B& b(*reinterpret_cast<B*>(value->getData())); 00075 do_set_B_c_value(b); 00076 return Qnil; 00077 } 00078 00079 static VALUE fill_multi_dim_array(VALUE self, VALUE rb) 00080 { 00081 Value* value = 0; 00082 Data_Get_Struct(rb, Value, value); 00083 00084 TestMultiDimArray& b(*reinterpret_cast<TestMultiDimArray*>(value->getData())); 00085 for (int y = 0; y < 10; ++y) 00086 for (int x = 0; x < 10; ++x) 00087 b.fields[y][x] = x + y * 10; 00088 00089 return Qnil; 00090 } 00091 00092 extern "C" { 00093 00094 void Init_libtest_ruby() 00095 { 00096 rb_define_method(rb_mKernel, "check_B_c_value", RUBY_METHOD_FUNC(check_B_c_value), 1); 00097 rb_define_method(rb_mKernel, "set_B_c_value", RUBY_METHOD_FUNC(set_B_c_value), 1); 00098 rb_define_method(rb_mKernel, "check_struct_A_value", RUBY_METHOD_FUNC(check_struct_A_value), 1); 00099 rb_define_method(rb_mKernel, "set_struct_A_value", RUBY_METHOD_FUNC(set_struct_A_value), 1); 00100 rb_define_method(rb_mKernel, "fill_multi_dim_array", RUBY_METHOD_FUNC(fill_multi_dim_array), 1); 00101 } 00102 00103 void test_simple_function_call() { } 00104 00105 void generate_nand(double* value) 00106 { *value = 1.0/0.0; } 00107 void generate_nanf(float* value) 00108 { *value = 1.0f/0.0f; } 00109 void test_numeric_argument_passing(char a, short b, int c, long d, long long e, float f, double g) 00110 { 00111 if (a != 1 || b != 2 || c != 3 || d != 4 || e != 5 || f != 6 || g != 7) 00112 rb_raise(rb_eArgError, "failed to pass numeric arguments"); 00113 } 00114 char test_returns_numeric_argument_char(char value) { return value; } 00115 short test_returns_numeric_argument_short(short value) { return value; } 00116 int test_returns_numeric_argument_int(int value) { return value; } 00117 long test_returns_numeric_argument_long(long value) { return value; } 00118 int64_t test_returns_numeric_argument_int64_t(int64_t value) { return value; } 00119 float test_returns_numeric_argument_float(float value) { return value; } 00120 double test_returns_numeric_argument_double(double value) { return value; } 00121 void test_returns_argument(int* holder) { *holder = 42; } 00122 00123 00124 void test_pointer_argument(A* a) 00125 { 00126 if (!do_check_struct_A_value(*a)) 00127 rb_raise(rb_eArgError, "error in passing structure as pointer"); 00128 } 00129 00130 struct A* test_returns_pointer() 00131 { 00132 static A a; 00133 do_set_struct_A_value(a); 00134 return &a; 00135 } 00136 00137 void test_modifies_argument(int* value) 00138 { 00139 if (*value != 0) 00140 rb_raise(rb_eArgError, "invalid argument value"); 00141 *value = 42; 00142 } 00143 00144 00145 int test_immediate_to_pointer(double* value) { return *value == 0.5; } 00146 00147 void test_ptr_argument_changes(struct B* b) 00148 { do_set_B_c_value(*b); } 00149 00150 void test_arg_input_output(int* value, INPUT_OUTPUT_MODE mode) 00151 { 00152 if (mode == BOTH && *value != 10) 00153 { 00154 *value = 0; 00155 return; 00156 } 00157 *value = 5; 00158 } 00159 00160 void test_enum_io_handling(INPUT_OUTPUT_MODE* mode) 00161 { 00162 switch(*mode) 00163 { 00164 case BOTH: 00165 *mode = OUTPUT; 00166 break; 00167 case OUTPUT: 00168 *mode = BOTH; 00169 break; 00170 } 00171 } 00172 00173 static int opaque_handler; 00174 OPAQUE_TYPE test_opaque_handling() 00175 { return &opaque_handler; } 00176 00177 int check_opaque_value(OPAQUE_TYPE handler, int check) 00178 { return (handler == test_opaque_handling()) ? check : 0; } 00179 00180 void test_string_argument(char const* value) 00181 { 00182 if (strcmp(value, "test")) 00183 rb_raise(rb_eArgError, "bad string argument"); 00184 } 00185 00186 static const char* static_string = "string_return"; 00187 const char* test_string_return() 00188 { return static_string; } 00189 void test_string_argument_modification(char* str, int buffer_length) 00190 { strcpy(str, static_string); } 00191 void test_string_as_array(char str[256]) 00192 { strcpy(str, static_string); } 00193 00194 DEFINE_STR id; 00195 int test_id_handling(DEFINE_ID* new_id, int check) 00196 { 00197 *new_id = &id; 00198 return check; 00199 } 00200 int check_id_value(DEFINE_ID test_id, int check) 00201 { 00202 printf("check_id_value, test_id=%p, &id=%p\n", test_id, &id); 00203 return (test_id == &id) ? check : 0; 00204 } 00205 00206 void test_null_return_value(DEFINE_ID* test_id, int check) 00207 { 00208 *test_id = 0; 00209 } 00210 00211 void test_void_argument(void* value, int check) 00212 { *static_cast<int*>(value) = check; } 00213 } 00214 00215