php_embed 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ #ifndef PHP_EMBED_HEADER
2
+ #define PHP_EMBED_HEADER
3
+
4
+ #include <ruby.h>
5
+ #include <php.h>
6
+ #include "value.h"
7
+ #include "convert.h"
8
+
9
+ extern VALUE mPhpEmbed;
10
+ extern VALUE rb_ePhpEmbedStanderdError;
11
+ extern VALUE rb_ePhpEmbedSyntaxError;
12
+ extern VALUE rb_ePhpEmbedMissingError;
13
+
14
+ extern void ***tsrm_ls;
15
+
16
+ int eval_php_code(char *code);
17
+ int eval_and_return_php_code(char *code, VALUE *return_value);
18
+
19
+ #endif
20
+
21
+
@@ -1,192 +1,253 @@
1
1
  #include <string.h>
2
- #include <ruby.h>
3
- #include <php.h>
4
- #include "value.h"
5
- #include "convert.h"
2
+ #include "php_embed.h"
6
3
 
7
- extern mPhpEmbed;
8
4
  VALUE cPhpEmbedValue;
9
5
 
10
- static void php_value_mark(php_value* pv) {
11
- if (pv) {
12
- pv->value = NULL;
13
- //rb_gc_mark(pv->value);
14
- }
6
+ static void php_value_mark(php_value *pv) {
7
+ if (pv) {
8
+ pv->value = NULL;
9
+ //rb_gc_mark(pv->value);
10
+ }
15
11
  }
16
12
 
17
- static void php_value_free(php_value* pv) {
18
- if (pv) {
19
- if (NULL != pv->value) {
20
- zval_dtor(pv->value);
21
- FREE_ZVAL(pv->value);
13
+ static void php_value_free(php_value *pv) {
14
+ if (pv) {
15
+ if (pv->value != NULL) {
16
+ zval_dtor(pv->value);
17
+ FREE_ZVAL(pv->value);
18
+ }
19
+ xfree(pv);
22
20
  }
23
- xfree(pv);
24
- }
25
21
  }
26
22
 
27
23
  static VALUE php_value_alloc(VALUE klass) {
28
- php_value * pv;
29
- return Data_Make_Struct(klass, php_value, php_value_mark, php_value_free, pv);
24
+ php_value *pv;
25
+ return Data_Make_Struct(klass, php_value, php_value_mark, php_value_free, pv);
30
26
  }
31
27
 
28
+ static zval *get_zval(VALUE value) {
29
+ php_value *pv;
30
+ Data_Get_Struct(value, php_value, pv);
31
+ return pv->value;
32
+ }
32
33
 
33
- VALUE new_php_embed_value(zval* value) {
34
+ static void set_zval(VALUE value, zval *zv) {
35
+ php_value *pv;
36
+ Data_Get_Struct(value, php_value, pv);
37
+ pv->value = zv;
38
+ }
34
39
 
35
- VALUE new_value;
36
- php_value* pv;
37
- zval* new_zval;
38
- VALUE arg = INT2FIX(0);
39
40
 
40
- ALLOC_ZVAL(new_zval);
41
- *new_zval = *value;
42
- zval_copy_ctor(new_zval);
43
- INIT_PZVAL(new_zval);
44
-
45
- new_value = php_value_alloc(cPhpEmbedValue);
46
- Data_Get_Struct(new_value, php_value, pv);
47
- pv->value = new_zval;
41
+ VALUE new_php_embed_value(zval *value) {
48
42
 
49
- return new_value;
50
- }
43
+ VALUE new_value;
44
+ zval* new_zval;
45
+ VALUE arg = INT2FIX(0);
51
46
 
47
+ ALLOC_ZVAL(new_zval);
48
+ *new_zval = *value;
49
+ zval_copy_ctor(new_zval);
50
+ INIT_PZVAL(new_zval);
51
+
52
+ new_value = php_value_alloc(cPhpEmbedValue);
53
+ set_zval(new_value, new_zval);
54
+
55
+ return new_value;
56
+ }
52
57
 
53
58
  VALUE php_value_initialize(VALUE self, VALUE value) {
54
- php_value* pv;
55
- zval* retval;
56
- VALUE code;
59
+ zval* retval;
60
+ VALUE code;
61
+
62
+ set_zval(self, value_to_zval(value));
63
+ return Qnil;
64
+ }
65
+
66
+ VALUE php_value_callable(VALUE self) {
67
+ char *error;
68
+ zend_bool retval;
69
+
70
+ retval = zend_is_callable_ex(get_zval(self), NULL, 0, NULL, NULL, NULL, &error TSRMLS_CC);
71
+ if (error) {
72
+ efree(error);
73
+ }
74
+
75
+ return (retval) ? Qtrue : Qfalse;
76
+ }
77
+
78
+ VALUE php_value_call(int argc, VALUE *argv, VALUE self) {
79
+ char *is_callable_error;
80
+ zend_fcall_info fci;
81
+ zend_fcall_info_cache fcc;
82
+ zval ***call_args;
83
+ zval **zval_array;
84
+ zval *retval_ptr = NULL;
85
+ int i, call_result;
86
+ VALUE args, retval;
87
+
88
+ rb_scan_args(argc, argv, "*", &args);
89
+
90
+ if (zend_fcall_info_init(get_zval(self), 0, &fci, &fcc, NULL, &is_callable_error TSRMLS_CC) == FAILURE) {
91
+ VALUE err = rb_str_new2(is_callable_error);
92
+ efree(is_callable_error);
93
+ rb_raise(rb_eRuntimeError, "no callable: %s", err);
94
+ }
95
+
96
+ zval_array = (zval**)malloc(sizeof(zval*) * argc);
97
+ call_args = (zval***)malloc(sizeof(zval**) * argc);
98
+ for(i=0; i<argc; ++i) {
99
+ zval_array[i] = value_to_zval(RARRAY_PTR(args)[i]);
100
+ call_args[i] = &zval_array[i];
101
+ }
102
+
103
+ fci.retval_ptr_ptr = &retval_ptr;
104
+ fci.param_count = argc;
105
+ fci.params = call_args;
106
+
107
+ call_result = zend_call_function(&fci, &fcc TSRMLS_CC);
108
+ retval = new_php_embed_value(retval_ptr);
57
109
 
58
- Data_Get_Struct(self, php_value, pv);
59
- pv->value = value_to_zval(value);
110
+ free(call_args);
60
111
 
61
- return Qnil;
112
+ for(i=0; i<argc-1; ++i) {
113
+ zval_dtor(zval_array[i]);
114
+ FREE_ZVAL(zval_array[i]);
115
+ }
116
+ free(zval_array);
117
+
118
+ if (FAILURE == call_result) {
119
+ rb_raise(rb_eRuntimeError, "function call fairure");
120
+ }
121
+
122
+ return retval;
62
123
  }
63
124
 
64
125
  VALUE php_value_to_php(VALUE self, VALUE value) {
65
- return convert_value_to_php_string(value);
126
+ return convert_value_to_php_string(value);
66
127
  }
67
128
 
68
129
  VALUE php_value_to_string(VALUE self) {
69
- php_value* pv;
70
- Data_Get_Struct(self, php_value, pv);
71
-
72
-
73
- if (pv->value) {
74
- convert_to_string(pv->value);
75
- return rb_str_new(Z_STRVAL_P(pv->value), Z_STRLEN_P(pv->value));
76
- }
130
+ zval *zv = get_zval(self);
131
+
132
+ if (zv) {
133
+ convert_to_string(zv);
134
+ return rb_str_new(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
135
+ }
136
+
137
+ return Qnil;
138
+ }
77
139
 
78
- return Qnil;
140
+ VALUE php_value_eval(VALUE self, VALUE src) {
141
+ VALUE return_value;
142
+ char *code = StringValueCStr(src);
143
+
144
+ if (eval_and_return_php_code(code, &return_value) == FAILURE) {
145
+ rb_raise(rb_ePhpEmbedStanderdError, "eval failed");
146
+ }
147
+
148
+ return return_value;
79
149
  }
80
150
 
81
151
  VALUE php_value_to_integer(VALUE self) {
82
- php_value* pv;
83
- Data_Get_Struct(self, php_value, pv);
84
-
85
-
86
- if (pv->value) {
87
- convert_to_long(pv->value);
88
- return rb_fix_new(Z_LVAL_P(pv->value));
89
- }
152
+ zval *zv = get_zval(self);
153
+
154
+ if (zv) {
155
+ convert_to_long(zv);
156
+ return rb_fix_new(Z_LVAL_P(zv));
157
+ }
90
158
 
91
- return Qnil;
159
+ return Qnil;
92
160
  }
93
161
 
94
162
  VALUE php_value_to_float(VALUE self) {
95
- php_value* pv;
96
- Data_Get_Struct(self, php_value, pv);
97
-
98
-
99
- if (pv->value) {
100
- convert_to_double(pv->value);
101
- return rb_float_new(Z_DVAL_P(pv->value));
102
- }
163
+ zval *zv = get_zval(self);
164
+
165
+ if (zv) {
166
+ convert_to_double(zv);
167
+ return rb_float_new(Z_DVAL_P(zv));
168
+ }
103
169
 
104
- return Qnil;
170
+ return Qnil;
105
171
  }
106
172
 
107
173
  VALUE php_value_to_boolean(VALUE self) {
108
- php_value* pv;
109
- Data_Get_Struct(self, php_value, pv);
110
-
111
- if (pv->value) {
112
- convert_to_boolean(pv->value);
113
- if (Z_LVAL_P(pv->value)) {
114
- return Qtrue;
115
- } else {
116
- return Qfalse;
174
+ zval *zv = get_zval(self);
175
+
176
+ if (zv) {
177
+ convert_to_boolean(zv);
178
+ if (Z_LVAL_P(zv)) {
179
+ return Qtrue;
180
+ } else {
181
+ return Qfalse;
182
+ }
117
183
  }
118
- }
119
184
 
120
- return Qnil;
185
+ return Qnil;
121
186
  }
122
187
 
123
188
  VALUE php_value_to_array(VALUE self) {
124
- php_value* pv;
125
- Data_Get_Struct(self, php_value, pv);
126
-
127
- if (pv->value) {
128
- return zval_to_array(pv->value);
129
- }
189
+ zval *zv = get_zval(self);
190
+
191
+ if (zv) {
192
+ return zval_to_array(zv);
193
+ }
130
194
 
131
- return Qnil;
195
+ return Qnil;
132
196
  }
133
197
 
134
198
  VALUE php_value_to_hash(VALUE self) {
135
- php_value* pv;
136
- Data_Get_Struct(self, php_value, pv);
137
-
138
- if (pv->value) {
139
- return zval_to_hash(pv->value);
140
- }
141
-
142
- return Qnil;
143
- }
199
+ zval *zv = get_zval(self);
144
200
 
145
- VALUE php_value_obj_equal(VALUE self, VALUE rhs) {
146
- php_value* pv;
147
- zval* rhs_zv;
148
- zval* result;
149
- int cmp_ret;
201
+ if (zv) {
202
+ return zval_to_hash(zv);
203
+ }
150
204
 
151
- Data_Get_Struct(self, php_value, pv);
152
- if (pv->value == NULL) {
153
205
  return Qnil;
154
- }
206
+ }
155
207
 
156
- if (CLASS_OF(rhs) == cPhpEmbedValue) {
157
- php_value* rhs_pv;
158
- Data_Get_Struct(rhs, php_value, rhs_pv);
208
+ VALUE php_value_obj_equal(VALUE self, VALUE rhs) {
209
+ zval *lhs_zv;
210
+ zval *rhs_zv;
211
+ zval *result;
212
+ int cmp_ret;
213
+
214
+ lhs_zv = get_zval(self);
215
+ if (lhs_zv == NULL) {
216
+ return Qnil;
217
+ }
159
218
 
160
- rhs_zv = rhs_pv->value;
161
- } else {
162
- rhs_zv = value_to_zval(rhs);
163
- }
219
+ if (cPhpEmbedValue == CLASS_OF(rhs)) {
220
+ rhs_zv = get_zval(rhs);
221
+ } else {
222
+ rhs_zv = value_to_zval(rhs);
223
+ }
164
224
 
165
- MAKE_STD_ZVAL(result);
166
- compare_function(result, pv->value, rhs_zv);
167
- cmp_ret = Z_LVAL_P(result);
168
- FREE_ZVAL(result);
225
+ MAKE_STD_ZVAL(result);
226
+ compare_function(result, lhs_zv, rhs_zv TSRMLS_CC);
227
+ cmp_ret = Z_LVAL_P(result);
228
+ FREE_ZVAL(result);
169
229
 
170
- return cmp_ret == 0 ? Qtrue: Qfalse;
230
+ return cmp_ret == 0 ? Qtrue : Qfalse;
171
231
  }
172
232
 
173
233
  void init_php_value() {
174
234
  #if 0
175
- mPhpEmbed = rb_define_module("PhpEmbed");
235
+ mPhpEmbed = rb_define_module("PhpEmbed");
176
236
  #endif
177
237
 
178
- cPhpEmbedValue = rb_define_class_under(mPhpEmbed, "Value", rb_cObject);
179
- rb_define_alloc_func(cPhpEmbedValue, php_value_alloc);
180
- rb_define_method(cPhpEmbedValue, "initialize", php_value_initialize, 1);
181
- rb_define_method(cPhpEmbedValue, "to_s", php_value_to_string, 0);
182
- rb_define_method(cPhpEmbedValue, "to_i", php_value_to_integer, 0);
183
- rb_define_method(cPhpEmbedValue, "to_f", php_value_to_float, 0);
184
- rb_define_method(cPhpEmbedValue, "to_b", php_value_to_boolean, 0);
185
- rb_define_method(cPhpEmbedValue, "to_a", php_value_to_array, 0);
186
- rb_define_method(cPhpEmbedValue, "to_h", php_value_to_hash, 0);
187
- rb_define_method(cPhpEmbedValue, "==", php_value_obj_equal, 1);
188
-
189
- rb_define_singleton_method(cPhpEmbedValue, "to_php", php_value_to_php, 1);
190
-
191
-
238
+ cPhpEmbedValue = rb_define_class_under(mPhpEmbed, "Value", rb_cObject);
239
+ rb_define_alloc_func(cPhpEmbedValue, php_value_alloc);
240
+ rb_define_method(cPhpEmbedValue, "initialize", php_value_initialize, 1);
241
+ rb_define_method(cPhpEmbedValue, "callable?", php_value_callable, 0);
242
+ rb_define_method(cPhpEmbedValue, "call", php_value_call, -1);
243
+ rb_define_method(cPhpEmbedValue, "to_s", php_value_to_string, 0);
244
+ rb_define_method(cPhpEmbedValue, "to_i", php_value_to_integer, 0);
245
+ rb_define_method(cPhpEmbedValue, "to_f", php_value_to_float, 0);
246
+ rb_define_method(cPhpEmbedValue, "to_b", php_value_to_boolean, 0);
247
+ rb_define_method(cPhpEmbedValue, "to_a", php_value_to_array, 0);
248
+ rb_define_method(cPhpEmbedValue, "to_h", php_value_to_hash, 0);
249
+ rb_define_method(cPhpEmbedValue, "==", php_value_obj_equal, 1);
250
+
251
+ rb_define_singleton_method(cPhpEmbedValue, "to_php", php_value_to_php, 1);
252
+ rb_define_singleton_method(cPhpEmbedValue, "eval", php_value_eval, 1);
192
253
  }
@@ -1,16 +1,13 @@
1
1
  #ifndef PHP_EMBED_VALUE
2
2
  #define PHP_EMBED_VALUE
3
3
 
4
- #include <ruby.h>
5
- #include <php.h>
6
-
7
4
  extern VALUE cPhpEmbedValue;
8
5
 
9
6
  void init_php_value();
10
- VALUE new_php_embed_value(zval* value);
7
+ VALUE new_php_embed_value(zval *value);
11
8
 
12
9
  typedef struct {
13
- zval* value;
10
+ zval *value;
14
11
  } php_value;
15
12
 
16
13
  #endif
@@ -1,3 +1,3 @@
1
1
  module PhpEmbed
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.2"
3
3
  end
data/spec/require.php ADDED
@@ -0,0 +1,5 @@
1
+ <?php
2
+ function required_function() {
3
+ return 'ok';
4
+ }
5
+
data/spec/value_spec.rb CHANGED
@@ -96,5 +96,27 @@ describe PhpEmbed::Value do
96
96
  PhpEmbed::Value.new(1).should == 1
97
97
  PhpEmbed::Value.new('a').should == 'a'
98
98
  end
99
+
100
+ it 'callable' do
101
+ f = PhpEmbed::Value.new('is_array')
102
+ f.callable?.should == true
103
+ f.call([]).should == true
104
+ f.call(0).should == false
105
+ end
106
+
107
+ it 'eval value' do
108
+ PhpEmbed::Value.eval('array(1)').to_a.should == [1]
109
+ end
110
+
111
+ it 'eval closure' do
112
+ f = PhpEmbed::Value.eval <<EOS
113
+ function($a, $b){
114
+ return $a * $b;
115
+ }
116
+ EOS
117
+ f.callable?.should == true
118
+ f.call(2,3).should == 6
119
+ end
120
+
99
121
  end
100
122