php_embed 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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