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
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