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