php_embed 0.0.3 → 0.1.0
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 +6 -0
- data/Rakefile +2 -5
- data/ext/php_embed/convert.c +271 -0
- data/ext/php_embed/convert.h +14 -0
- data/ext/php_embed/php.c +100 -136
- data/ext/php_embed/value.c +192 -0
- data/ext/php_embed/value.h +17 -0
- data/lib/php_embed.rb +3 -1
- data/lib/php_embed/version.rb +1 -1
- data/php_embed.gemspec +4 -1
- data/spec/php_spec.rb +46 -18
- data/spec/value_spec.rb +100 -0
- metadata +42 -7
- data/ext/php_embed/php_embed_value.c +0 -156
- data/ext/php_embed/php_embed_value.h +0 -13
- data/spec/php_value_spec.rb +0 -29
data/.gitignore
CHANGED
data/Rakefile
CHANGED
@@ -0,0 +1,271 @@
|
|
1
|
+
#include "value.h"
|
2
|
+
#include "convert.h"
|
3
|
+
|
4
|
+
|
5
|
+
VALUE zval_to_array(zval* zv) {
|
6
|
+
HashTable* ht;
|
7
|
+
HashPosition pos;
|
8
|
+
zval** data;
|
9
|
+
VALUE ret;
|
10
|
+
|
11
|
+
convert_to_array(zv);
|
12
|
+
ht = Z_ARRVAL_P(zv);
|
13
|
+
|
14
|
+
ret = rb_ary_new2(zend_hash_num_elements(ht));
|
15
|
+
|
16
|
+
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
17
|
+
while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&data, &pos)) {
|
18
|
+
rb_ary_push(ret, new_php_embed_value(*data));
|
19
|
+
zend_hash_move_forward_ex(ht, &pos);
|
20
|
+
}
|
21
|
+
return ret;
|
22
|
+
}
|
23
|
+
|
24
|
+
VALUE zval_to_hash(zval* zv) {
|
25
|
+
HashTable* ht;
|
26
|
+
HashPosition pos;
|
27
|
+
zval** data;
|
28
|
+
VALUE ret;
|
29
|
+
|
30
|
+
convert_to_array(zv);
|
31
|
+
ht = Z_ARRVAL_P(zv);
|
32
|
+
|
33
|
+
ret = rb_hash_new();
|
34
|
+
|
35
|
+
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
36
|
+
while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&data, &pos)) {
|
37
|
+
char* key_str;
|
38
|
+
uint key_len;
|
39
|
+
ulong num_index;
|
40
|
+
VALUE key = Qnil;
|
41
|
+
VALUE val = new_php_embed_value(*data);
|
42
|
+
|
43
|
+
switch(zend_hash_get_current_key_ex(ht, &key_str, &key_len, &num_index, 0, &pos)) {
|
44
|
+
case HASH_KEY_IS_STRING:
|
45
|
+
//key = rb_str_new(key_str, key_len);
|
46
|
+
key = rb_str_new_cstr(key_str);
|
47
|
+
break;
|
48
|
+
case HASH_KEY_IS_LONG:
|
49
|
+
key = LONG2NUM(num_index);
|
50
|
+
break;
|
51
|
+
}
|
52
|
+
|
53
|
+
rb_hash_aset(ret, key, val);
|
54
|
+
zend_hash_move_forward_ex(ht, &pos);
|
55
|
+
}
|
56
|
+
return ret;
|
57
|
+
}
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
static int hash_to_php_string_array(VALUE key, VALUE value, VALUE ary) {
|
62
|
+
VALUE k,v,r;
|
63
|
+
int key_type;
|
64
|
+
|
65
|
+
if (key == Qundef) {
|
66
|
+
return ST_CONTINUE;
|
67
|
+
}
|
68
|
+
|
69
|
+
key_type = TYPE(key);
|
70
|
+
if (T_FIXNUM != key_type && T_BIGNUM != key_type
|
71
|
+
&& T_STRING != key_type && T_SYMBOL != key_type) {
|
72
|
+
rb_raise(rb_eRuntimeError, "invalid key (%d)", key_type);
|
73
|
+
}
|
74
|
+
|
75
|
+
k = convert_value_to_php_string(key);
|
76
|
+
r = rb_str_new_cstr(RSTRING_PTR(k));
|
77
|
+
rb_str_cat2(r, "=>");
|
78
|
+
v = convert_value_to_php_string(value);
|
79
|
+
rb_str_cat2(r, RSTRING_PTR(v));
|
80
|
+
|
81
|
+
rb_ary_push(ary, r);
|
82
|
+
return ST_CONTINUE;
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
static int hash_to_zval(VALUE key, VALUE value, VALUE zval_array) {
|
87
|
+
zval *v;
|
88
|
+
zval *ary;
|
89
|
+
|
90
|
+
if (key == Qundef) {
|
91
|
+
return ST_CONTINUE;
|
92
|
+
}
|
93
|
+
|
94
|
+
ary = (zval*)zval_array;
|
95
|
+
v = value_to_zval(value);
|
96
|
+
|
97
|
+
if (Qtrue == key) {
|
98
|
+
zend_hash_index_update(Z_ARRVAL_P(ary), 1, &v, sizeof(zval *), NULL);
|
99
|
+
return ST_CONTINUE;
|
100
|
+
}
|
101
|
+
|
102
|
+
if (Qfalse == key || Qnil == key) {
|
103
|
+
zend_hash_index_update(Z_ARRVAL_P(ary), 0, &v, sizeof(zval *), NULL);
|
104
|
+
return ST_CONTINUE;
|
105
|
+
}
|
106
|
+
|
107
|
+
if (T_FIXNUM == TYPE(key)) {
|
108
|
+
int idx = FIX2INT(key);
|
109
|
+
zend_hash_index_update(Z_ARRVAL_P(ary), idx, &v, sizeof(zval *), NULL);
|
110
|
+
return ST_CONTINUE;
|
111
|
+
}
|
112
|
+
|
113
|
+
switch (TYPE(key)) {
|
114
|
+
case T_BIGNUM:
|
115
|
+
key = rb_big2str(key, 10);
|
116
|
+
break;
|
117
|
+
case T_SYMBOL:
|
118
|
+
key = rb_sym_to_s(key);
|
119
|
+
break;
|
120
|
+
case T_STRING:
|
121
|
+
key = rb_string_value(&key);
|
122
|
+
break;
|
123
|
+
default:
|
124
|
+
rb_raise(rb_eRuntimeError, "invalid key (%d)", TYPE(key));
|
125
|
+
}
|
126
|
+
|
127
|
+
//ZEND_HANDLE_NUMERIC(RSTRING_PTR(key), RSTRING_LEN(key), zend_hash_index_update(Z_ARRVAL_P(ary), idx, &v, sizeof(zval *), NULL));
|
128
|
+
zend_symtable_update(Z_ARRVAL_P(ary), RSTRING_PTR(key), RSTRING_LEN(key) + 1, &v, sizeof(zval *), NULL);
|
129
|
+
|
130
|
+
return ST_CONTINUE;
|
131
|
+
}
|
132
|
+
|
133
|
+
|
134
|
+
VALUE convert_value_to_php_string(VALUE v) {
|
135
|
+
switch (TYPE(v)) {
|
136
|
+
case T_FALSE:
|
137
|
+
return rb_str_new_cstr("false");
|
138
|
+
case T_TRUE:
|
139
|
+
return rb_str_new_cstr("true");
|
140
|
+
case T_UNDEF:
|
141
|
+
case T_NIL:
|
142
|
+
return rb_str_new_cstr("null");
|
143
|
+
case T_FIXNUM:
|
144
|
+
return rb_fix2str(v, 10);
|
145
|
+
case T_BIGNUM:
|
146
|
+
return rb_big2str(v, 10);
|
147
|
+
case T_FLOAT:
|
148
|
+
return rb_funcall(v, rb_intern("to_s"), 0);
|
149
|
+
case T_ARRAY:
|
150
|
+
{
|
151
|
+
int i;
|
152
|
+
VALUE ret = rb_str_new_cstr("array(");
|
153
|
+
for(i=0;i<RARRAY_LEN(v);++i) {
|
154
|
+
VALUE p = convert_value_to_php_string(RARRAY_PTR(v)[i]);
|
155
|
+
if (T_STRING == TYPE(p)) {
|
156
|
+
rb_str_cat2(ret, StringValuePtr(p));
|
157
|
+
}
|
158
|
+
if (i != RARRAY_LEN(v)-1) {
|
159
|
+
rb_str_cat2(ret, ",");
|
160
|
+
}
|
161
|
+
}
|
162
|
+
rb_str_cat2(ret, ")");
|
163
|
+
return ret;
|
164
|
+
}
|
165
|
+
case T_HASH:
|
166
|
+
{
|
167
|
+
VALUE ret = rb_str_new_cstr("array(");
|
168
|
+
VALUE ary = rb_ary_new();
|
169
|
+
|
170
|
+
rb_hash_foreach(v, hash_to_php_string_array, ary);
|
171
|
+
|
172
|
+
{
|
173
|
+
int i;
|
174
|
+
int len = RARRAY_LEN(ary);
|
175
|
+
|
176
|
+
VALUE* p = RARRAY_PTR(ary);
|
177
|
+
for(i=0; i<len; ++i) {
|
178
|
+
rb_str_cat2(ret, StringValuePtr(p[i]));
|
179
|
+
if (i != len-1) {
|
180
|
+
rb_str_cat2(ret, ",");
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
rb_str_cat2(ret, ")");
|
185
|
+
return ret;
|
186
|
+
}
|
187
|
+
case T_SYMBOL:
|
188
|
+
{
|
189
|
+
VALUE symbol_str = rb_sym_to_s(v);
|
190
|
+
VALUE ret = rb_str_new_cstr("'");
|
191
|
+
rb_str_cat2(ret, StringValuePtr(symbol_str));
|
192
|
+
rb_str_cat2(ret, "'");
|
193
|
+
return ret;
|
194
|
+
}
|
195
|
+
case T_STRING:
|
196
|
+
{
|
197
|
+
VALUE ret = rb_str_new_cstr("'");
|
198
|
+
rb_str_cat2(ret, StringValuePtr(v));
|
199
|
+
rb_str_cat2(ret, "'");
|
200
|
+
return ret;
|
201
|
+
}
|
202
|
+
default:
|
203
|
+
rb_raise(rb_eRuntimeError, "no implemented");
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
207
|
+
zval* value_to_zval(VALUE v) {
|
208
|
+
zval* zv;
|
209
|
+
MAKE_STD_ZVAL(zv);
|
210
|
+
|
211
|
+
switch (TYPE(v)) {
|
212
|
+
case T_FALSE:
|
213
|
+
ZVAL_FALSE(zv);
|
214
|
+
return zv;
|
215
|
+
case T_TRUE:
|
216
|
+
ZVAL_TRUE(zv);
|
217
|
+
return zv;
|
218
|
+
case T_UNDEF:
|
219
|
+
case T_NIL:
|
220
|
+
ZVAL_NULL(zv);
|
221
|
+
return zv;
|
222
|
+
case T_FIXNUM:
|
223
|
+
ZVAL_LONG(zv, rb_fix2int(v));
|
224
|
+
return zv;
|
225
|
+
case T_BIGNUM:
|
226
|
+
ZVAL_LONG(zv, rb_big2long(v)); // FIXME: bignum over long
|
227
|
+
return zv;
|
228
|
+
case T_FLOAT:
|
229
|
+
ZVAL_DOUBLE(zv, RFLOAT_VALUE(v));
|
230
|
+
return zv;
|
231
|
+
case T_ARRAY:
|
232
|
+
{
|
233
|
+
int i;
|
234
|
+
array_init(zv);
|
235
|
+
for(i=0;i<RARRAY_LEN(v);++i) {
|
236
|
+
zval *add = value_to_zval(RARRAY_PTR(v)[i]);
|
237
|
+
zend_hash_next_index_insert(Z_ARRVAL_P(zv), &add, sizeof(zval*), NULL);
|
238
|
+
}
|
239
|
+
return zv;
|
240
|
+
}
|
241
|
+
case T_HASH:
|
242
|
+
{
|
243
|
+
array_init(zv);
|
244
|
+
rb_hash_foreach(v, hash_to_zval, (VALUE)zv);
|
245
|
+
return zv;
|
246
|
+
}
|
247
|
+
case T_SYMBOL:
|
248
|
+
{
|
249
|
+
VALUE symbol_str = rb_sym_to_s(v);
|
250
|
+
ZVAL_STRINGL(zv, StringValuePtr(symbol_str), RSTRING_LEN(symbol_str), 1);
|
251
|
+
return zv;
|
252
|
+
}
|
253
|
+
case T_STRING:
|
254
|
+
{
|
255
|
+
ZVAL_STRINGL(zv, StringValuePtr(v), RSTRING_LEN(v), 1);
|
256
|
+
return zv;
|
257
|
+
}
|
258
|
+
default:
|
259
|
+
{
|
260
|
+
if (CLASS_OF(v) == cPhpEmbedValue) {
|
261
|
+
php_value* pv;
|
262
|
+
Data_Get_Struct(v, php_value, pv);
|
263
|
+
MAKE_COPY_ZVAL(&pv->value, zv);
|
264
|
+
return zv;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
FREE_ZVAL(zv);
|
268
|
+
rb_raise(rb_eRuntimeError, "no implemented");
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#ifndef PHP_EMBED_CONVERT
|
2
|
+
#define PHP_EMBED_CONVERT
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <php.h>
|
6
|
+
|
7
|
+
|
8
|
+
VALUE zval_to_hash(zval* zv);
|
9
|
+
VALUE zval_to_array(zval* zv);
|
10
|
+
|
11
|
+
VALUE convert_value_to_php_string(VALUE v);
|
12
|
+
zval* value_to_zval(VALUE v);
|
13
|
+
|
14
|
+
#endif
|
data/ext/php_embed/php.c
CHANGED
@@ -1,13 +1,19 @@
|
|
1
1
|
#include <stdio.h>
|
2
2
|
#include <ruby.h>
|
3
3
|
#include <sapi/embed/php_embed.h>
|
4
|
-
|
5
|
-
#include
|
6
|
-
VALUE zval_to_value(zval* val);
|
4
|
+
#include "value.h"
|
5
|
+
#include "convert.h"
|
7
6
|
|
8
7
|
static VALUE callback_output = Qnil;
|
9
8
|
static VALUE callback_error = Qnil;
|
10
9
|
|
10
|
+
|
11
|
+
VALUE mPhpEmbed;
|
12
|
+
|
13
|
+
VALUE rb_ePhpEmbedStanderdError;
|
14
|
+
VALUE rb_ePhpEmbedSyntaxError;
|
15
|
+
VALUE rb_ePhpEmbedMissingError;
|
16
|
+
|
11
17
|
static int php_ub_write(const char *str, unsigned int str_length TSRMLS_DC)
|
12
18
|
{
|
13
19
|
if (!NIL_P(callback_output)) {
|
@@ -32,113 +38,6 @@ static void php_sapi_error(int type, const char *fmt, ...)
|
|
32
38
|
va_end(va);
|
33
39
|
}
|
34
40
|
|
35
|
-
static int is_array_convertable(HashTable* ht) {
|
36
|
-
HashPosition pos;
|
37
|
-
char *string_key;
|
38
|
-
ulong num_index;
|
39
|
-
ulong index = 0;
|
40
|
-
|
41
|
-
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
42
|
-
do {
|
43
|
-
switch(zend_hash_get_current_key_ex(ht, &string_key, NULL, &num_index, 0, &pos)) {
|
44
|
-
case HASH_KEY_IS_STRING:
|
45
|
-
return 0;
|
46
|
-
case HASH_KEY_NON_EXISTANT:
|
47
|
-
return 1;
|
48
|
-
case HASH_KEY_IS_LONG:
|
49
|
-
if (num_index != index) {
|
50
|
-
return 0;
|
51
|
-
}
|
52
|
-
++index;
|
53
|
-
}
|
54
|
-
} while(SUCCESS == zend_hash_move_forward_ex(ht, &pos));
|
55
|
-
return 1;
|
56
|
-
}
|
57
|
-
|
58
|
-
static VALUE hash_to_array(HashTable* ht) {
|
59
|
-
HashPosition pos;
|
60
|
-
zval** data;
|
61
|
-
VALUE ret;
|
62
|
-
|
63
|
-
ret = rb_ary_new2(zend_hash_num_elements(ht));
|
64
|
-
|
65
|
-
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
66
|
-
while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&data, &pos)) {
|
67
|
-
VALUE t = zval_to_value(*data);
|
68
|
-
rb_ary_push(ret, t);
|
69
|
-
zend_hash_move_forward_ex(ht, &pos);
|
70
|
-
}
|
71
|
-
return ret;
|
72
|
-
}
|
73
|
-
|
74
|
-
static VALUE hash_to_hash(HashTable* ht) {
|
75
|
-
HashPosition pos;
|
76
|
-
zval** data;
|
77
|
-
VALUE ret;
|
78
|
-
|
79
|
-
ret = rb_hash_new();
|
80
|
-
|
81
|
-
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
82
|
-
while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&data, &pos)) {
|
83
|
-
char* string_key;
|
84
|
-
ulong num_index;
|
85
|
-
VALUE key = Qnil;
|
86
|
-
VALUE val = zval_to_value(*data);
|
87
|
-
|
88
|
-
switch(zend_hash_get_current_key_ex(ht, &string_key, NULL, &num_index, 0, &pos)) {
|
89
|
-
case HASH_KEY_IS_STRING:
|
90
|
-
key = rb_str_new_cstr(string_key);
|
91
|
-
break;
|
92
|
-
case HASH_KEY_IS_LONG:
|
93
|
-
key = LONG2NUM(num_index);
|
94
|
-
break;
|
95
|
-
}
|
96
|
-
|
97
|
-
rb_hash_aset(ret, key, val);
|
98
|
-
zend_hash_move_forward_ex(ht, &pos);
|
99
|
-
}
|
100
|
-
return ret;
|
101
|
-
}
|
102
|
-
|
103
|
-
|
104
|
-
VALUE zval_to_value(zval* val) {
|
105
|
-
VALUE r;
|
106
|
-
|
107
|
-
switch(Z_TYPE_P(val)) {
|
108
|
-
case IS_NULL:
|
109
|
-
return Qnil;
|
110
|
-
case IS_BOOL:
|
111
|
-
return (zval_is_true(val)) ? Qtrue : Qfalse;
|
112
|
-
case IS_LONG:
|
113
|
-
return INT2NUM(Z_LVAL_P(val));
|
114
|
-
case IS_DOUBLE:
|
115
|
-
return DBL2NUM(Z_DVAL_P(val));
|
116
|
-
case IS_ARRAY:
|
117
|
-
case IS_CONSTANT_ARRAY:
|
118
|
-
{
|
119
|
-
HashTable* ht = Z_ARRVAL_P(val);
|
120
|
-
|
121
|
-
if (0 == zend_hash_num_elements(ht)) {
|
122
|
-
return rb_ary_new();
|
123
|
-
}
|
124
|
-
|
125
|
-
if (is_array_convertable(ht)) {
|
126
|
-
return hash_to_array(ht);
|
127
|
-
}
|
128
|
-
|
129
|
-
return hash_to_hash(ht);
|
130
|
-
}
|
131
|
-
case IS_OBJECT:
|
132
|
-
case IS_RESOURCE:
|
133
|
-
case IS_CONSTANT:
|
134
|
-
convert_to_string(val);
|
135
|
-
case IS_STRING:
|
136
|
-
return rb_str_new(Z_STRVAL_P(val), Z_STRLEN_P(val));
|
137
|
-
default:
|
138
|
-
return Qnil;
|
139
|
-
}
|
140
|
-
}
|
141
|
-
|
142
41
|
int eval_php_code(char* code) {
|
143
42
|
int ret = 0;
|
144
43
|
|
@@ -159,7 +58,8 @@ int eval_and_return_php_code(char* code, VALUE* return_value) {
|
|
159
58
|
if (zend_eval_string(code, &retval, (char*)"" TSRMLS_CC) == FAILURE) {
|
160
59
|
err = 1;
|
161
60
|
} else {
|
162
|
-
|
61
|
+
//*return_value = zval_to_value(&retval);
|
62
|
+
*return_value = new_php_embed_value(&retval);
|
163
63
|
zval_dtor(&retval);
|
164
64
|
}
|
165
65
|
|
@@ -172,52 +72,114 @@ int eval_and_return_php_code(char* code, VALUE* return_value) {
|
|
172
72
|
|
173
73
|
VALUE php_eval(VALUE self, VALUE code) {
|
174
74
|
if (eval_php_code(StringValuePtr(code))) {
|
175
|
-
rb_raise(
|
75
|
+
rb_raise(rb_ePhpEmbedSyntaxError, "invalid code");
|
176
76
|
}
|
177
77
|
|
178
78
|
return Qnil;
|
179
79
|
}
|
180
80
|
|
81
|
+
|
82
|
+
zend_function* php_find_function(char* name) {
|
83
|
+
char* lcname;
|
84
|
+
int name_len;
|
85
|
+
int found;
|
86
|
+
zend_function *func;
|
87
|
+
|
88
|
+
name_len = strlen(name);
|
89
|
+
lcname = zend_str_tolower_dup(name, name_len);
|
90
|
+
|
91
|
+
name = lcname;
|
92
|
+
if ('\\' == lcname[0]) {
|
93
|
+
name = &lcname[1];
|
94
|
+
name_len--;
|
95
|
+
}
|
96
|
+
|
97
|
+
found = (SUCCESS == zend_hash_find(EG(function_table), name, name_len+1, (void**)&func));
|
98
|
+
efree(lcname);
|
99
|
+
|
100
|
+
if (found) {
|
101
|
+
return func;
|
102
|
+
}
|
103
|
+
|
104
|
+
return NULL;
|
105
|
+
}
|
106
|
+
|
107
|
+
|
108
|
+
|
181
109
|
VALUE php_call(int argc, VALUE *argv, VALUE self) {
|
182
|
-
VALUE
|
183
|
-
|
184
|
-
|
110
|
+
VALUE name, args, retval;
|
111
|
+
zend_function* func;
|
112
|
+
int call_result, i;
|
113
|
+
zval *retval_ptr;
|
114
|
+
zend_fcall_info fci;
|
115
|
+
zend_fcall_info_cache fcc;
|
116
|
+
zval ***call_args;
|
117
|
+
zval **zval_array;
|
118
|
+
|
119
|
+
rb_scan_args(argc, argv, "1*", &name, &args);
|
120
|
+
|
121
|
+
if (T_SYMBOL == TYPE(name)) {
|
122
|
+
name = rb_sym_to_s(name);
|
123
|
+
}
|
185
124
|
|
186
|
-
|
125
|
+
if (T_STRING != TYPE(name)) {
|
126
|
+
rb_raise(rb_eArgError, "invalid function name");
|
127
|
+
}
|
187
128
|
|
188
|
-
|
189
|
-
|
129
|
+
|
130
|
+
func = php_find_function(StringValueCStr(name));
|
131
|
+
if (!func) {
|
132
|
+
rb_raise(rb_ePhpEmbedMissingError, "function not found");
|
190
133
|
}
|
191
134
|
|
192
|
-
|
193
|
-
|
135
|
+
zval_array = (zval**)malloc(sizeof(zval*) * argc-1);
|
136
|
+
call_args = (zval***)malloc(sizeof(zval**) * argc-1);
|
137
|
+
for(i=0; i<argc-1; ++i) {
|
138
|
+
zval_array[i] = value_to_zval(RARRAY_PTR(args)[i]);
|
139
|
+
call_args[i] = &zval_array[i];
|
194
140
|
}
|
141
|
+
|
142
|
+
fci.size = sizeof(fci);
|
143
|
+
fci.function_table = NULL;
|
144
|
+
fci.function_name = NULL;
|
145
|
+
fci.symbol_table = NULL;
|
146
|
+
fci.object_ptr = NULL;
|
147
|
+
fci.retval_ptr_ptr = &retval_ptr;
|
148
|
+
fci.param_count = argc-1;
|
149
|
+
fci.params = call_args;
|
150
|
+
fci.no_separation = 1;
|
151
|
+
|
152
|
+
fcc.initialized = 1;
|
153
|
+
fcc.function_handler = func;
|
154
|
+
fcc.calling_scope = EG(scope);
|
155
|
+
fcc.called_scope = NULL;
|
156
|
+
fcc.object_ptr = NULL;
|
157
|
+
|
158
|
+
call_result = zend_call_function(&fci, &fcc TSRMLS_CC);
|
159
|
+
retval = new_php_embed_value(retval_ptr);
|
160
|
+
|
161
|
+
free(call_args);
|
195
162
|
|
196
|
-
arg_str = rb_str_new_cstr("");
|
197
163
|
for(i=0; i<argc-1; ++i) {
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
if (i != argc-2) {
|
202
|
-
rb_str_cat2(arg_str, ",");
|
203
|
-
}
|
164
|
+
zval_dtor(zval_array[i]);
|
165
|
+
FREE_ZVAL(zval_array[i]);
|
204
166
|
}
|
167
|
+
free(zval_array);
|
205
168
|
|
206
|
-
|
207
|
-
|
208
|
-
if (eval_and_return_php_code(call_str, &retval)) {
|
209
|
-
rb_raise(rb_eRuntimeError, "eval error");
|
169
|
+
if (FAILURE == call_result) {
|
170
|
+
rb_raise(rb_ePhpEmbedStanderdError, "function call fairure");
|
210
171
|
}
|
211
172
|
|
212
173
|
return retval;
|
213
174
|
}
|
214
175
|
|
215
|
-
VALUE
|
176
|
+
VALUE php_require(VALUE self, VALUE file) {
|
216
177
|
VALUE retval = Qtrue;
|
217
178
|
zend_file_handle handle;
|
218
179
|
|
219
180
|
if (T_STRING != TYPE(file)) {
|
220
|
-
rb_raise(
|
181
|
+
rb_raise(rb_eArgError, "file must be string");
|
182
|
+
return Qnil;
|
221
183
|
}
|
222
184
|
|
223
185
|
handle.type = ZEND_HANDLE_FILENAME;
|
@@ -232,7 +194,6 @@ VALUE php_run(VALUE self, VALUE file) {
|
|
232
194
|
} zend_end_try();
|
233
195
|
|
234
196
|
return retval;
|
235
|
-
|
236
197
|
}
|
237
198
|
|
238
199
|
VALUE php_fetch_variable(VALUE self, VALUE name) {
|
@@ -277,7 +238,6 @@ void shutdown_php_embed() {
|
|
277
238
|
php_embed_shutdown(TSRMLS_C);
|
278
239
|
}
|
279
240
|
|
280
|
-
VALUE mPhpEmbed;
|
281
241
|
|
282
242
|
Init_php() {
|
283
243
|
|
@@ -289,7 +249,7 @@ Init_php() {
|
|
289
249
|
|
290
250
|
rb_define_singleton_method(mPhpEmbed, "eval", php_eval, 1);
|
291
251
|
rb_define_singleton_method(mPhpEmbed, "call", php_call, -1);
|
292
|
-
rb_define_singleton_method(mPhpEmbed, "
|
252
|
+
rb_define_singleton_method(mPhpEmbed, "require", php_require, 1);
|
293
253
|
rb_define_singleton_method(mPhpEmbed, "fetchVariable", php_fetch_variable, 1);
|
294
254
|
rb_define_singleton_method(mPhpEmbed, "setOutputHandler", php_set_output_handler, 1);
|
295
255
|
rb_define_singleton_method(mPhpEmbed, "setErrorHandler", php_set_error_handler, 1);
|
@@ -301,6 +261,10 @@ Init_php() {
|
|
301
261
|
initialize_php_embed();
|
302
262
|
atexit(shutdown_php_embed);
|
303
263
|
|
264
|
+
|
265
|
+
rb_ePhpEmbedStanderdError = rb_define_class_under(mPhpEmbed, "StanderdError", rb_eException);
|
266
|
+
rb_ePhpEmbedSyntaxError = rb_define_class_under(mPhpEmbed, "SyntaxError", rb_ePhpEmbedStanderdError);
|
267
|
+
rb_ePhpEmbedMissingError = rb_define_class_under(mPhpEmbed, "MissingError", rb_ePhpEmbedStanderdError);
|
304
268
|
/*
|
305
269
|
zend_try {
|
306
270
|
zend_alter_ini_entry((char*)"display_errors", sizeof("display_errors")
|
@@ -0,0 +1,192 @@
|
|
1
|
+
#include <string.h>
|
2
|
+
#include <ruby.h>
|
3
|
+
#include <php.h>
|
4
|
+
#include "value.h"
|
5
|
+
#include "convert.h"
|
6
|
+
|
7
|
+
extern mPhpEmbed;
|
8
|
+
VALUE cPhpEmbedValue;
|
9
|
+
|
10
|
+
static void php_value_mark(php_value* pv) {
|
11
|
+
if (pv) {
|
12
|
+
pv->value = NULL;
|
13
|
+
//rb_gc_mark(pv->value);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
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);
|
22
|
+
}
|
23
|
+
xfree(pv);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
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);
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
VALUE new_php_embed_value(zval* value) {
|
34
|
+
|
35
|
+
VALUE new_value;
|
36
|
+
php_value* pv;
|
37
|
+
zval* new_zval;
|
38
|
+
VALUE arg = INT2FIX(0);
|
39
|
+
|
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;
|
48
|
+
|
49
|
+
return new_value;
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
VALUE php_value_initialize(VALUE self, VALUE value) {
|
54
|
+
php_value* pv;
|
55
|
+
zval* retval;
|
56
|
+
VALUE code;
|
57
|
+
|
58
|
+
Data_Get_Struct(self, php_value, pv);
|
59
|
+
pv->value = value_to_zval(value);
|
60
|
+
|
61
|
+
return Qnil;
|
62
|
+
}
|
63
|
+
|
64
|
+
VALUE php_value_to_php(VALUE self, VALUE value) {
|
65
|
+
return convert_value_to_php_string(value);
|
66
|
+
}
|
67
|
+
|
68
|
+
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
|
+
}
|
77
|
+
|
78
|
+
return Qnil;
|
79
|
+
}
|
80
|
+
|
81
|
+
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
|
+
}
|
90
|
+
|
91
|
+
return Qnil;
|
92
|
+
}
|
93
|
+
|
94
|
+
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
|
+
}
|
103
|
+
|
104
|
+
return Qnil;
|
105
|
+
}
|
106
|
+
|
107
|
+
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;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
return Qnil;
|
121
|
+
}
|
122
|
+
|
123
|
+
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
|
+
}
|
130
|
+
|
131
|
+
return Qnil;
|
132
|
+
}
|
133
|
+
|
134
|
+
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
|
+
}
|
144
|
+
|
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;
|
150
|
+
|
151
|
+
Data_Get_Struct(self, php_value, pv);
|
152
|
+
if (pv->value == NULL) {
|
153
|
+
return Qnil;
|
154
|
+
}
|
155
|
+
|
156
|
+
if (CLASS_OF(rhs) == cPhpEmbedValue) {
|
157
|
+
php_value* rhs_pv;
|
158
|
+
Data_Get_Struct(rhs, php_value, rhs_pv);
|
159
|
+
|
160
|
+
rhs_zv = rhs_pv->value;
|
161
|
+
} else {
|
162
|
+
rhs_zv = value_to_zval(rhs);
|
163
|
+
}
|
164
|
+
|
165
|
+
MAKE_STD_ZVAL(result);
|
166
|
+
compare_function(result, pv->value, rhs_zv);
|
167
|
+
cmp_ret = Z_LVAL_P(result);
|
168
|
+
FREE_ZVAL(result);
|
169
|
+
|
170
|
+
return cmp_ret == 0 ? Qtrue: Qfalse;
|
171
|
+
}
|
172
|
+
|
173
|
+
void init_php_value() {
|
174
|
+
#if 0
|
175
|
+
mPhpEmbed = rb_define_module("PhpEmbed");
|
176
|
+
#endif
|
177
|
+
|
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
|
+
|
192
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#ifndef PHP_EMBED_VALUE
|
2
|
+
#define PHP_EMBED_VALUE
|
3
|
+
|
4
|
+
#include <ruby.h>
|
5
|
+
#include <php.h>
|
6
|
+
|
7
|
+
extern VALUE cPhpEmbedValue;
|
8
|
+
|
9
|
+
void init_php_value();
|
10
|
+
VALUE new_php_embed_value(zval* value);
|
11
|
+
|
12
|
+
typedef struct {
|
13
|
+
zval* value;
|
14
|
+
} php_value;
|
15
|
+
|
16
|
+
#endif
|
17
|
+
|
data/lib/php_embed.rb
CHANGED
data/lib/php_embed/version.rb
CHANGED
data/php_embed.gemspec
CHANGED
@@ -13,7 +13,10 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
14
14
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
15
|
gem.name = "php_embed"
|
16
|
-
gem.require_paths = ['lib']
|
16
|
+
gem.require_paths = ['lib', 'ext']
|
17
17
|
gem.version = PhpEmbed::VERSION
|
18
18
|
|
19
|
+
gem.add_development_dependency 'rspec'
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
|
19
22
|
end
|
data/spec/php_spec.rb
CHANGED
@@ -7,27 +7,41 @@ describe PhpEmbed do
|
|
7
7
|
it 'raise error with invalid PhpEmbed code' do
|
8
8
|
proc {
|
9
9
|
PhpEmbed.eval("i n v a l i d")
|
10
|
-
}.should raise_error
|
10
|
+
}.should raise_error(PhpEmbed::SyntaxError)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
14
|
describe 'eval and call' do
|
15
|
-
it '
|
16
|
-
PhpEmbed.eval('function
|
17
|
-
PhpEmbed.call('
|
15
|
+
it 'return fixnum' do
|
16
|
+
PhpEmbed.eval('function ret_1(){ return 1; }');
|
17
|
+
PhpEmbed.call('ret_1').should == 1;
|
18
18
|
end
|
19
|
-
it '
|
20
|
-
PhpEmbed.eval('function
|
21
|
-
PhpEmbed.call('
|
22
|
-
PhpEmbed.call('hoge2', 'a').should == 'a';
|
23
|
-
PhpEmbed.call('hoge2', []).should == [];
|
24
|
-
PhpEmbed.call('hoge2', [1]).should == [1];
|
25
|
-
PhpEmbed.call('hoge2', {0=>1,1=>2}).should == [1,2];
|
26
|
-
PhpEmbed.call('hoge2', {10=>2}).should == {10=>2};
|
27
|
-
PhpEmbed.call('hoge2', {'a'=>1}).should == {'a'=>1};
|
19
|
+
it 'return string' do
|
20
|
+
PhpEmbed.eval('function ret_string(){ return "string"; }');
|
21
|
+
PhpEmbed.call('ret_string').should == 'string';
|
28
22
|
end
|
29
|
-
|
23
|
+
it 'return array' do
|
24
|
+
PhpEmbed.eval('function ret_array(){ return array(1,2); }');
|
25
|
+
PhpEmbed.call('ret_array').to_a.should == [1,2];
|
26
|
+
end
|
27
|
+
it 'return hash' do
|
28
|
+
PhpEmbed.eval('function ret_hash(){ return array("a"=>1,"b"=>2); }');
|
29
|
+
PhpEmbed.call('ret_hash').to_a.should == [1, 2];
|
30
|
+
PhpEmbed.call('ret_hash').to_h.should == {'a'=>1,'b'=>2};
|
31
|
+
end
|
32
|
+
it 'return arg' do
|
33
|
+
PhpEmbed.eval('function ret_arg($arg){ return $arg; }');
|
34
|
+
PhpEmbed.call('ret_arg', 1).should == 1;
|
35
|
+
PhpEmbed.call('ret_arg', 'a').should == 'a';
|
36
|
+
PhpEmbed.call('ret_arg', []).to_a.should == [];
|
37
|
+
PhpEmbed.call('ret_arg', [1]).to_a.should == [1];
|
38
|
+
PhpEmbed.call('ret_arg', {0=>1,1=>2}).to_a.should == [1,2];
|
39
|
+
PhpEmbed.call('ret_arg', {10=>2}).to_h.should == {10=>2};
|
40
|
+
PhpEmbed.call('ret_arg', {'a'=>1}).to_h.should == {'a'=>1};
|
30
41
|
|
42
|
+
PhpEmbed.call('ret_arg', PhpEmbed::Value('a')).should == 'a';
|
43
|
+
end
|
44
|
+
end
|
31
45
|
|
32
46
|
describe 'call' do
|
33
47
|
it 'bin2hex return hex string' do
|
@@ -49,13 +63,17 @@ describe PhpEmbed do
|
|
49
63
|
end
|
50
64
|
|
51
65
|
it 'call with array' do
|
52
|
-
PhpEmbed.call("array_diff", [1,2,3,4,5], [3,4]).should == {0=>1,1=>2,4=>5}
|
66
|
+
PhpEmbed.call("array_diff", [1,2,3,4,5], [3,4]).to_h.should == {0=>1,1=>2,4=>5}
|
53
67
|
end
|
54
68
|
|
69
|
+
it 'call by symbol' do
|
70
|
+
PhpEmbed.call(:intval, 123).should == 123
|
71
|
+
end
|
72
|
+
|
55
73
|
it 'raise error with invalid PhpEmbed code' do
|
56
74
|
proc {
|
57
75
|
PhpEmbed.call("i n v a l i d")
|
58
|
-
}.should raise_error
|
76
|
+
}.should raise_error(PhpEmbed::MissingError)
|
59
77
|
end
|
60
78
|
end
|
61
79
|
|
@@ -83,7 +101,17 @@ describe PhpEmbed do
|
|
83
101
|
end
|
84
102
|
end
|
85
103
|
|
86
|
-
|
87
|
-
|
104
|
+
describe 'require' do
|
105
|
+
it 'require' do
|
106
|
+
PhpEmbed.require(File.dirname(File.expand_path(__FILE__)) + '/require.php')
|
107
|
+
PhpEmbed.call(:required_function).should == 'ok'
|
108
|
+
end
|
109
|
+
it 'invalid argument' do
|
110
|
+
proc {
|
111
|
+
PhpEmbed.require(nil)
|
112
|
+
}.should raise_error(ArgumentError)
|
113
|
+
end
|
114
|
+
end
|
88
115
|
|
116
|
+
end
|
89
117
|
|
data/spec/value_spec.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'php_embed'
|
3
|
+
|
4
|
+
describe PhpEmbed::Value do
|
5
|
+
it 'convert nil' do
|
6
|
+
PhpEmbed::Value.to_php(nil).should == 'null'
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'convert boolean' do
|
10
|
+
PhpEmbed::Value.to_php(false).should == 'false'
|
11
|
+
PhpEmbed::Value.to_php(true).should == 'true'
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'convert scalar' do
|
15
|
+
PhpEmbed::Value.to_php(1).should == '1'
|
16
|
+
PhpEmbed::Value.to_php("a").should == "'a'"
|
17
|
+
PhpEmbed::Value.to_php(:a).should == "'a'"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'convert array' do
|
21
|
+
PhpEmbed::Value.to_php([]).should == 'array()'
|
22
|
+
PhpEmbed::Value.to_php([1,2,3]).should == 'array(1,2,3)'
|
23
|
+
PhpEmbed::Value.to_php(['a', 'b']).should == "array('a','b')"
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'convert hash' do
|
27
|
+
PhpEmbed::Value.to_php({}).should == 'array()'
|
28
|
+
PhpEmbed::Value.to_php({1=>'a'}).should == "array(1=>'a')"
|
29
|
+
PhpEmbed::Value.to_php({'a'=>1}).should == "array('a'=>1)"
|
30
|
+
PhpEmbed::Value.to_php({:a=>1}).should == "array('a'=>1)"
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
it 'to_s' do
|
35
|
+
PhpEmbed::Value.new('test').to_s.should == 'test'
|
36
|
+
PhpEmbed::Value.new(:test).to_s.should == 'test'
|
37
|
+
|
38
|
+
PhpEmbed::Value.new(123).to_s.should == '123'
|
39
|
+
PhpEmbed::Value.new(nil).to_s.should == ''
|
40
|
+
|
41
|
+
PhpEmbed::Value.new(false).to_s.should == ''
|
42
|
+
PhpEmbed::Value.new(true).to_s.should == '1'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'to_i' do
|
46
|
+
PhpEmbed::Value.new('test').to_i.should == 0
|
47
|
+
PhpEmbed::Value.new('10test').to_i.should == 10
|
48
|
+
|
49
|
+
PhpEmbed::Value.new(123).to_i.should == 123
|
50
|
+
PhpEmbed::Value.new(nil).to_i.should == 0
|
51
|
+
PhpEmbed::Value.new(true).to_i.should == 1
|
52
|
+
PhpEmbed::Value.new(false).to_i.should == 0
|
53
|
+
PhpEmbed::Value.new(12.3).to_i.should == 12
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'to_b' do
|
57
|
+
PhpEmbed::Value.new(0).to_b.should be false
|
58
|
+
PhpEmbed::Value.new([]).to_b.should be false
|
59
|
+
PhpEmbed::Value.new({}).to_b.should be false
|
60
|
+
PhpEmbed::Value.new(true).to_b.should be true
|
61
|
+
PhpEmbed::Value.new(false).to_b.should be false
|
62
|
+
PhpEmbed::Value.new(nil).to_b.should be false
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'to_a' do
|
66
|
+
PhpEmbed::Value.new([]).to_a.should == []
|
67
|
+
PhpEmbed::Value.new([1]).to_a.should == [PhpEmbed::Value.new(1)]
|
68
|
+
PhpEmbed::Value.new([1,"2",nil]).to_a
|
69
|
+
.should == [PhpEmbed::Value.new(1), PhpEmbed::Value.new("2"), PhpEmbed::Value(nil)]
|
70
|
+
PhpEmbed::Value.new({1=>1, 2=>2}).to_a.should == [1,2]
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'to_h' do
|
74
|
+
PhpEmbed::Value.new([]).to_h.should == {}
|
75
|
+
PhpEmbed::Value.new([1,"2",nil]).to_h
|
76
|
+
.should == {0=>PhpEmbed::Value.new(1), 1=>PhpEmbed::Value.new("2"), 2=>PhpEmbed::Value(nil)}
|
77
|
+
PhpEmbed::Value.new({a:1}).to_h
|
78
|
+
.should == {'a'=>PhpEmbed::Value.new(1)}
|
79
|
+
PhpEmbed::Value.new({1=>1, 2=>2}).to_h.should == {1=>1,2=>2}
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'to_f' do
|
83
|
+
PhpEmbed::Value.new('test').to_f.should == 0
|
84
|
+
PhpEmbed::Value.new(12.3).to_f.should == 12.3
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'equqal' do
|
88
|
+
PhpEmbed::Value.new(true).should == PhpEmbed::Value.new(true)
|
89
|
+
PhpEmbed::Value.new(false).should == PhpEmbed::Value.new(false)
|
90
|
+
|
91
|
+
PhpEmbed::Value.new(nil).should == PhpEmbed::Value.new(false)
|
92
|
+
|
93
|
+
PhpEmbed::Value.new(nil).should == nil
|
94
|
+
PhpEmbed::Value.new(true).should == true
|
95
|
+
PhpEmbed::Value.new(false).should == false
|
96
|
+
PhpEmbed::Value.new(1).should == 1
|
97
|
+
PhpEmbed::Value.new('a').should == 'a'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: php_embed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,40 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
12
|
+
date: 2013-01-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
14
46
|
description: execute PHP code in Ruby code
|
15
47
|
email:
|
16
48
|
- do.hiroaki@gmail.com
|
@@ -24,21 +56,24 @@ files:
|
|
24
56
|
- LICENSE
|
25
57
|
- README.md
|
26
58
|
- Rakefile
|
59
|
+
- ext/php_embed/convert.c
|
60
|
+
- ext/php_embed/convert.h
|
27
61
|
- ext/php_embed/extconf.rb
|
28
62
|
- ext/php_embed/php.c
|
29
|
-
- ext/php_embed/
|
30
|
-
- ext/php_embed/
|
63
|
+
- ext/php_embed/value.c
|
64
|
+
- ext/php_embed/value.h
|
31
65
|
- lib/php_embed.rb
|
32
66
|
- lib/php_embed/version.rb
|
33
67
|
- php_embed.gemspec
|
34
68
|
- spec/php_spec.rb
|
35
|
-
- spec/
|
69
|
+
- spec/value_spec.rb
|
36
70
|
homepage: https://github.com/do-aki/php_embed
|
37
71
|
licenses: []
|
38
72
|
post_install_message:
|
39
73
|
rdoc_options: []
|
40
74
|
require_paths:
|
41
75
|
- lib
|
76
|
+
- ext
|
42
77
|
required_ruby_version: !ruby/object:Gem::Requirement
|
43
78
|
none: false
|
44
79
|
requirements:
|
@@ -59,4 +94,4 @@ specification_version: 3
|
|
59
94
|
summary: execute PHP code in Ruby code
|
60
95
|
test_files:
|
61
96
|
- spec/php_spec.rb
|
62
|
-
- spec/
|
97
|
+
- spec/value_spec.rb
|
@@ -1,156 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <php.h>
|
3
|
-
#include <php_embed_value.h>
|
4
|
-
|
5
|
-
static void php_value_mark(php_value* pv) {
|
6
|
-
if (pv) {
|
7
|
-
rb_gc_mark(pv->value);
|
8
|
-
}
|
9
|
-
}
|
10
|
-
|
11
|
-
static void php_value_free(php_value* pv) {
|
12
|
-
if (pv) {
|
13
|
-
xfree(pv);
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
static VALUE php_value_alloc(VALUE klass) {
|
18
|
-
php_value * pv;
|
19
|
-
return Data_Make_Struct(klass, php_value, php_value_mark, php_value_free, pv);
|
20
|
-
}
|
21
|
-
|
22
|
-
static int hash_to_php_string_array(VALUE key, VALUE value, VALUE ary) {
|
23
|
-
VALUE k,v,r;
|
24
|
-
int key_type;
|
25
|
-
|
26
|
-
if (key == Qundef) {
|
27
|
-
return ST_CONTINUE;
|
28
|
-
}
|
29
|
-
|
30
|
-
key_type = TYPE(key);
|
31
|
-
if (T_FIXNUM != key_type && T_BIGNUM != key_type
|
32
|
-
&& T_STRING != key_type && T_SYMBOL != key_type) {
|
33
|
-
rb_raise(rb_eRuntimeError, "invalid key (%d)", key_type);
|
34
|
-
}
|
35
|
-
|
36
|
-
k = convert_value_into_php_string(key);
|
37
|
-
r = rb_str_new_cstr(RSTRING_PTR(k));
|
38
|
-
rb_str_cat2(r, "=>");
|
39
|
-
v = convert_value_into_php_string(value);
|
40
|
-
rb_str_cat2(r, RSTRING_PTR(v));
|
41
|
-
|
42
|
-
rb_ary_push(ary, r);
|
43
|
-
return ST_CONTINUE;
|
44
|
-
}
|
45
|
-
|
46
|
-
VALUE convert_value_into_php_string(VALUE v) {
|
47
|
-
switch (TYPE(v)) {
|
48
|
-
case T_FALSE:
|
49
|
-
return rb_str_new_cstr("false");
|
50
|
-
case T_TRUE:
|
51
|
-
return rb_str_new_cstr("true");
|
52
|
-
case T_UNDEF:
|
53
|
-
case T_NIL:
|
54
|
-
return rb_str_new_cstr("null");
|
55
|
-
case T_FIXNUM:
|
56
|
-
return rb_fix2str(v, 10);
|
57
|
-
case T_BIGNUM:
|
58
|
-
return rb_big2str(v, 10);
|
59
|
-
case T_FLOAT:
|
60
|
-
return rb_funcall(v, rb_intern("to_s"), 0);
|
61
|
-
case T_ARRAY:
|
62
|
-
{
|
63
|
-
int i;
|
64
|
-
VALUE ret = rb_str_new_cstr("array(");
|
65
|
-
for(i=0;i<RARRAY_LEN(v);++i) {
|
66
|
-
VALUE p = convert_value_into_php_string(RARRAY_PTR(v)[i]);
|
67
|
-
if (T_STRING == TYPE(p)) {
|
68
|
-
rb_str_cat2(ret, StringValuePtr(p));
|
69
|
-
}
|
70
|
-
if (i != RARRAY_LEN(v)-1) {
|
71
|
-
rb_str_cat2(ret, ",");
|
72
|
-
}
|
73
|
-
}
|
74
|
-
rb_str_cat2(ret, ")");
|
75
|
-
return ret;
|
76
|
-
}
|
77
|
-
case T_HASH:
|
78
|
-
{
|
79
|
-
VALUE ret = rb_str_new_cstr("array(");
|
80
|
-
VALUE ary = rb_ary_new();
|
81
|
-
|
82
|
-
rb_hash_foreach(v, hash_to_php_string_array, ary);
|
83
|
-
|
84
|
-
{
|
85
|
-
int i;
|
86
|
-
int len = RARRAY_LEN(ary);
|
87
|
-
|
88
|
-
VALUE* p = RARRAY_PTR(ary);
|
89
|
-
for(i=0; i<len; ++i) {
|
90
|
-
rb_str_cat2(ret, StringValuePtr(p[i]));
|
91
|
-
if (i != len-1) {
|
92
|
-
rb_str_cat2(ret, ",");
|
93
|
-
}
|
94
|
-
}
|
95
|
-
}
|
96
|
-
rb_str_cat2(ret, ")");
|
97
|
-
return ret;
|
98
|
-
}
|
99
|
-
case T_SYMBOL:
|
100
|
-
{
|
101
|
-
VALUE symbol_str = rb_sym_to_s(v);
|
102
|
-
VALUE ret = rb_str_new_cstr("'");
|
103
|
-
rb_str_cat2(ret, StringValuePtr(symbol_str));
|
104
|
-
rb_str_cat2(ret, "'");
|
105
|
-
return ret;
|
106
|
-
}
|
107
|
-
case T_STRING:
|
108
|
-
{
|
109
|
-
VALUE ret = rb_str_new_cstr("'");
|
110
|
-
rb_str_cat2(ret, StringValuePtr(v));
|
111
|
-
rb_str_cat2(ret, "'");
|
112
|
-
return ret;
|
113
|
-
}
|
114
|
-
default:
|
115
|
-
rb_raise(rb_eRuntimeError, "no implemented");
|
116
|
-
}
|
117
|
-
}
|
118
|
-
|
119
|
-
|
120
|
-
VALUE php_value_initialize(VALUE self, VALUE value) {
|
121
|
-
php_value* pv;
|
122
|
-
Data_Get_Struct(self, php_value, pv);
|
123
|
-
|
124
|
-
pv->value = value;
|
125
|
-
return Qnil;
|
126
|
-
}
|
127
|
-
|
128
|
-
VALUE php_value_to_string(VALUE self) {
|
129
|
-
VALUE ret;
|
130
|
-
php_value* pv;
|
131
|
-
Data_Get_Struct(self, php_value, pv);
|
132
|
-
|
133
|
-
return convert_value_into_php_string(pv->value);
|
134
|
-
}
|
135
|
-
|
136
|
-
VALUE php_value_parse_php_string(VALUE self, VALUE php_string) {
|
137
|
-
return Qnil;
|
138
|
-
}
|
139
|
-
|
140
|
-
|
141
|
-
extern mPhpEmbed;
|
142
|
-
VALUE cPhpEmbedValue;
|
143
|
-
void init_php_value() {
|
144
|
-
#if 0
|
145
|
-
mPhpEmbed = rb_define_module("PhpEmbed");
|
146
|
-
#endif
|
147
|
-
|
148
|
-
cPhpEmbedValue = rb_define_class_under(mPhpEmbed, "Value", rb_cObject);
|
149
|
-
rb_define_alloc_func(cPhpEmbedValue, php_value_alloc);
|
150
|
-
rb_define_method(cPhpEmbedValue, "initialize", php_value_initialize, 1);
|
151
|
-
rb_define_method(cPhpEmbedValue, "to_s", php_value_to_string, 0);
|
152
|
-
|
153
|
-
rb_define_singleton_method(cPhpEmbedValue, "parse", php_value_parse_php_string, 1);
|
154
|
-
|
155
|
-
|
156
|
-
}
|
data/spec/php_value_spec.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
describe PhpEmbed::Value do
|
2
|
-
it 'convert nil' do
|
3
|
-
PhpEmbed::Value.new(nil).to_s.should == 'null';
|
4
|
-
end
|
5
|
-
it 'convert boolean' do
|
6
|
-
PhpEmbed::Value.new(false).to_s.should == 'false';
|
7
|
-
PhpEmbed::Value.new(true).to_s.should == 'true';
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'convert scalar' do
|
11
|
-
PhpEmbed::Value.new(1).to_s.should == '1';
|
12
|
-
PhpEmbed::Value.new("a").to_s.should == "'a'";
|
13
|
-
PhpEmbed::Value.new(:a).to_s.should == "'a'";
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'convert array' do
|
17
|
-
PhpEmbed::Value.new([]).to_s.should == 'array()';
|
18
|
-
PhpEmbed::Value.new([1,2,3]).to_s.should == 'array(1,2,3)';
|
19
|
-
PhpEmbed::Value.new(['a', 'b']).to_s.should == "array('a','b')";
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'convert hash' do
|
23
|
-
PhpEmbed::Value.new({}).to_s.should == 'array()';
|
24
|
-
PhpEmbed::Value.new({1=>'a'}).to_s.should == "array(1=>'a')";
|
25
|
-
PhpEmbed::Value.new({'a'=>1}).to_s.should == "array('a'=>1)";
|
26
|
-
PhpEmbed::Value.new({:a=>1}).to_s.should == "array('a'=>1)";
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|