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.
- data/.gitignore +2 -1
- data/ext/php_embed/convert.c +222 -231
- data/ext/php_embed/convert.h +5 -9
- data/ext/php_embed/extconf.rb +107 -4
- data/ext/php_embed/php.c +195 -205
- data/ext/php_embed/php.ini +1861 -0
- data/ext/php_embed/php_embed.h +21 -0
- data/ext/php_embed/value.c +191 -130
- data/ext/php_embed/value.h +2 -5
- data/lib/php_embed/version.rb +1 -1
- data/spec/require.php +5 -0
- data/spec/value_spec.rb +22 -0
- metadata +6 -2
@@ -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
|
+
|
data/ext/php_embed/value.c
CHANGED
@@ -1,192 +1,253 @@
|
|
1
1
|
#include <string.h>
|
2
|
-
#include
|
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*
|
11
|
-
|
12
|
-
|
13
|
-
|
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*
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
29
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
59
|
-
pv->value = value_to_zval(value);
|
110
|
+
free(call_args);
|
60
111
|
|
61
|
-
|
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
|
-
|
126
|
+
return convert_value_to_php_string(value);
|
66
127
|
}
|
67
128
|
|
68
129
|
VALUE php_value_to_string(VALUE self) {
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
159
|
+
return Qnil;
|
92
160
|
}
|
93
161
|
|
94
162
|
VALUE php_value_to_float(VALUE self) {
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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
|
-
|
170
|
+
return Qnil;
|
105
171
|
}
|
106
172
|
|
107
173
|
VALUE php_value_to_boolean(VALUE self) {
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
185
|
+
return Qnil;
|
121
186
|
}
|
122
187
|
|
123
188
|
VALUE php_value_to_array(VALUE self) {
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
}
|
189
|
+
zval *zv = get_zval(self);
|
190
|
+
|
191
|
+
if (zv) {
|
192
|
+
return zval_to_array(zv);
|
193
|
+
}
|
130
194
|
|
131
|
-
|
195
|
+
return Qnil;
|
132
196
|
}
|
133
197
|
|
134
198
|
VALUE php_value_to_hash(VALUE self) {
|
135
|
-
|
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
|
-
|
146
|
-
|
147
|
-
|
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
|
-
|
157
|
-
|
158
|
-
|
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
|
-
|
161
|
-
|
162
|
-
|
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
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
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
|
-
|
230
|
+
return cmp_ret == 0 ? Qtrue : Qfalse;
|
171
231
|
}
|
172
232
|
|
173
233
|
void init_php_value() {
|
174
234
|
#if 0
|
175
|
-
|
235
|
+
mPhpEmbed = rb_define_module("PhpEmbed");
|
176
236
|
#endif
|
177
237
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
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
|
}
|
data/ext/php_embed/value.h
CHANGED
@@ -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*
|
7
|
+
VALUE new_php_embed_value(zval *value);
|
11
8
|
|
12
9
|
typedef struct {
|
13
|
-
|
10
|
+
zval *value;
|
14
11
|
} php_value;
|
15
12
|
|
16
13
|
#endif
|
data/lib/php_embed/version.rb
CHANGED
data/spec/require.php
ADDED
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
|
|