erlix 0.5.0a
Sign up to get free protection for your applications and to get access to all the features.
- data/_extconf.rb +27 -0
- data/configure +27 -0
- data/extconf.rb +17 -0
- data/findei.erl +6 -0
- data/src/erlix.c +30 -0
- data/src/erlix_atom.c +62 -0
- data/src/erlix_binary.c +67 -0
- data/src/erlix_connection.c +247 -0
- data/src/erlix_connection.h +47 -0
- data/src/erlix_float.c +65 -0
- data/src/erlix_int.c +64 -0
- data/src/erlix_list.c +262 -0
- data/src/erlix_message.c +122 -0
- data/src/erlix_node.c +83 -0
- data/src/erlix_node.h +39 -0
- data/src/erlix_pid.c +68 -0
- data/src/erlix_ref.c +59 -0
- data/src/erlix_term.c +362 -0
- data/src/erlix_term.h +118 -0
- data/src/erlix_tuple.c +215 -0
- data/src/erlix_uint.c +63 -0
- metadata +66 -0
data/src/erlix_node.c
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
/*
|
2
|
+
* project : erlix
|
3
|
+
* author : kdr2
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <string.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <unistd.h>
|
10
|
+
|
11
|
+
#include "erlix_node.h"
|
12
|
+
|
13
|
+
|
14
|
+
ErlixNode *erlix_node=NULL;
|
15
|
+
|
16
|
+
VALUE erlix_mErlixNode;
|
17
|
+
|
18
|
+
VALUE erlix_node_init(VALUE self,VALUE sname,VALUE cookie){
|
19
|
+
VALUE str_name;
|
20
|
+
int creation;
|
21
|
+
struct in_addr self_addr;
|
22
|
+
char host[64];
|
23
|
+
int nn_len;
|
24
|
+
char *nname;
|
25
|
+
if(erlix_node!=NULL){
|
26
|
+
rb_raise(rb_eException,"Erlix::Node has been inited already!");
|
27
|
+
return Qnil;
|
28
|
+
}
|
29
|
+
str_name=StringValue(sname);
|
30
|
+
creation=rand()%100;
|
31
|
+
self_addr.s_addr=htonl(INADDR_ANY);
|
32
|
+
memset(host,0,64);
|
33
|
+
if(gethostname(host,64)!=0){
|
34
|
+
rb_raise(rb_eException,"gethostname error!");
|
35
|
+
return Qnil;
|
36
|
+
}
|
37
|
+
nn_len=strlen(host)+RSTRING_LEN(str_name)+2;
|
38
|
+
nname=(char*)malloc(nn_len);
|
39
|
+
memset(nname,0,nn_len);
|
40
|
+
sprintf(nname,"%s@%s",RSTRING_PTR(str_name),host);
|
41
|
+
if(!erl_connect_xinit(host,
|
42
|
+
RSTRING_PTR(str_name),
|
43
|
+
nname,
|
44
|
+
&self_addr,
|
45
|
+
NIL_P(cookie)?NULL:RSTRING_PTR(cookie),
|
46
|
+
creation)){
|
47
|
+
free(nname);
|
48
|
+
rb_raise(rb_eException,"erl_connect_xinit error!");
|
49
|
+
return Qnil;
|
50
|
+
}
|
51
|
+
free(nname);
|
52
|
+
erlix_node=(ErlixNode*)malloc(sizeof(ErlixNode));
|
53
|
+
return self;
|
54
|
+
}
|
55
|
+
|
56
|
+
VALUE erlix_node_inited(VALUE self){
|
57
|
+
if(erlix_node==NULL)return Qfalse;
|
58
|
+
return Qtrue;
|
59
|
+
}
|
60
|
+
|
61
|
+
VALUE erlix_node_name(VALUE self){
|
62
|
+
if(erlix_node==NULL)return Qnil;
|
63
|
+
return rb_str_new2(erl_thisnodename());
|
64
|
+
}
|
65
|
+
|
66
|
+
VALUE erlix_node_creation(VALUE self){
|
67
|
+
if(erlix_node==NULL)return Qnil;
|
68
|
+
return INT2FIX(erl_thiscreation());
|
69
|
+
}
|
70
|
+
|
71
|
+
//TODO
|
72
|
+
VALUE erlix_node_publish(VALUE self);
|
73
|
+
|
74
|
+
//TODO
|
75
|
+
VALUE erlix_node_accept(VALUE self);
|
76
|
+
|
77
|
+
void init_erlix_node(VALUE erlix){
|
78
|
+
erlix_mErlixNode=rb_define_module_under(erlix,ERLIX_NODE_MOD);
|
79
|
+
rb_define_module_function(erlix_mErlixNode,"init",erlix_node_init,2);
|
80
|
+
rb_define_module_function(erlix_mErlixNode,"init?",erlix_node_inited,0);
|
81
|
+
rb_define_module_function(erlix_mErlixNode,"name",erlix_node_name,0);
|
82
|
+
rb_define_module_function(erlix_mErlixNode,"creation",erlix_node_creation,0);
|
83
|
+
}
|
data/src/erlix_node.h
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
/*
|
2
|
+
* project : erlix
|
3
|
+
* author : kdr2
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
|
7
|
+
#ifndef ERLIX_NODE_H_
|
8
|
+
#define ERLIX_NODE_H_
|
9
|
+
|
10
|
+
#include "ruby.h"
|
11
|
+
|
12
|
+
#include "ei.h"
|
13
|
+
#include "erl_interface.h"
|
14
|
+
|
15
|
+
#include "erlix_term.h"
|
16
|
+
|
17
|
+
#define ERLIX_NODE_MOD "Node"
|
18
|
+
|
19
|
+
extern const char *erl_thisnodename(void);
|
20
|
+
extern short erl_thiscreation(void);
|
21
|
+
|
22
|
+
typedef struct _erlix_node{
|
23
|
+
unsigned long status;
|
24
|
+
int listen_fd;
|
25
|
+
}ErlixNode;
|
26
|
+
|
27
|
+
|
28
|
+
VALUE erlix_node_init(VALUE self,VALUE sname,VALUE cookie);
|
29
|
+
VALUE erlix_node_inited(VALUE self);
|
30
|
+
VALUE erlix_node_name(VALUE self);
|
31
|
+
VALUE erlix_node_creation(VALUE self);
|
32
|
+
|
33
|
+
VALUE erlix_node_publish(VALUE self);
|
34
|
+
|
35
|
+
VALUE erlix_node_accept(VALUE self);
|
36
|
+
|
37
|
+
void init_erlix_node();
|
38
|
+
|
39
|
+
#endif /* ERLIX_CONNECTION_H_ */
|
data/src/erlix_pid.c
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
/*
|
2
|
+
* project : erlix
|
3
|
+
* author : kdr2
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <string.h>
|
8
|
+
|
9
|
+
#include "erlix_term.h"
|
10
|
+
#include "erlix_node.h"
|
11
|
+
#include "erlix_connection.h"
|
12
|
+
|
13
|
+
VALUE erlix_cErlixPid;
|
14
|
+
|
15
|
+
extern const char *erl_thisnodename(void);
|
16
|
+
extern short erl_thiscreation(void);
|
17
|
+
extern ErlixNode *erlix_node;
|
18
|
+
|
19
|
+
VALUE erlix_pid_alloc(VALUE klass){
|
20
|
+
ErlixTerm* pid;
|
21
|
+
VALUE obj;
|
22
|
+
pid=new_erlix_term();
|
23
|
+
pid->type=TYPE_PID;
|
24
|
+
obj=Data_Wrap_Struct(klass,0,free_erlix_term,pid);
|
25
|
+
return obj;
|
26
|
+
}
|
27
|
+
|
28
|
+
static VALUE erlix_pid_init(VALUE self,VALUE econn){
|
29
|
+
ErlixTerm* pid;
|
30
|
+
ErlixConnection* conn;
|
31
|
+
if(erlix_node==NULL){
|
32
|
+
rb_raise(rb_eException,"call Erlix::Node.init(name,cookie) first please!");
|
33
|
+
return Qnil;
|
34
|
+
}
|
35
|
+
|
36
|
+
if((TYPE(econn)!=T_DATA || RDATA(econn)->dfree!=(RUBY_DATA_FUNC)free_erlix_connection)){
|
37
|
+
rb_raise(rb_eTypeError,"the argument is not an Erlix::Connection");
|
38
|
+
}
|
39
|
+
Data_Get_Struct(self,ErlixTerm,pid);
|
40
|
+
Data_Get_Struct(econn,ErlixConnection,conn);
|
41
|
+
pid->term=erl_mk_pid(erl_thisnodename(),conn->sock_fd,rand()%16,erl_thiscreation());
|
42
|
+
return self;
|
43
|
+
}
|
44
|
+
|
45
|
+
static VALUE erlix_pid_inspect(VALUE self){
|
46
|
+
VALUE ret=rb_str_new2("#<Erlix::Pid:");
|
47
|
+
ID concat=rb_intern("concat");
|
48
|
+
rb_funcall(ret,concat,1,rb_funcall(self,rb_intern("to_s"),0));
|
49
|
+
rb_funcall(ret,concat,1,rb_str_new2(">"));
|
50
|
+
return ret;
|
51
|
+
}
|
52
|
+
|
53
|
+
static VALUE erlix_pid_etype(VALUE self){
|
54
|
+
return rb_str_new2("pid");
|
55
|
+
}
|
56
|
+
|
57
|
+
void init_erlix_pid(VALUE erlix){
|
58
|
+
erlix_cErlixPid=rb_define_class_under(erlix,"Pid",rb_cObject);
|
59
|
+
|
60
|
+
rb_define_alloc_func(erlix_cErlixPid,erlix_pid_alloc);
|
61
|
+
rb_define_method(erlix_cErlixPid,"initialize",erlix_pid_init,1);
|
62
|
+
rb_define_method(erlix_cErlixPid,"inspect",erlix_pid_inspect,0);
|
63
|
+
rb_define_method(erlix_cErlixPid,"etype",erlix_pid_etype,0);
|
64
|
+
|
65
|
+
rb_include_module(erlix_cErlixPid,erlix_mErlixTerm);
|
66
|
+
}
|
67
|
+
|
68
|
+
|
data/src/erlix_ref.c
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
/*
|
2
|
+
* project : erlix
|
3
|
+
* author : kdr2
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <string.h>
|
10
|
+
#include <time.h>
|
11
|
+
|
12
|
+
#include "erlix_term.h"
|
13
|
+
|
14
|
+
VALUE erlix_cErlixRef;
|
15
|
+
extern const char *erl_thisnodename(void);
|
16
|
+
extern short erl_thiscreation(void);
|
17
|
+
|
18
|
+
VALUE erlix_ref_alloc(VALUE klass){
|
19
|
+
ErlixTerm* eref;
|
20
|
+
VALUE obj;
|
21
|
+
eref=new_erlix_term();
|
22
|
+
eref->type=TYPE_REF;
|
23
|
+
obj=Data_Wrap_Struct(klass,0,free_erlix_term,eref);
|
24
|
+
return obj;
|
25
|
+
}
|
26
|
+
|
27
|
+
static VALUE erlix_ref_init(VALUE self){
|
28
|
+
ErlixTerm* eref;
|
29
|
+
Data_Get_Struct(self,ErlixTerm,eref);
|
30
|
+
//TODO
|
31
|
+
eref->term=erl_mk_long_ref(erl_thisnodename(),rand(),rand(),time(NULL),erl_thiscreation());
|
32
|
+
return self;
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE erlix_ref_inspect(VALUE self){
|
36
|
+
VALUE ret=rb_str_new2("#<Erlix::Ref:");
|
37
|
+
ID concat=rb_intern("concat");
|
38
|
+
rb_funcall(ret,concat,1,rb_funcall(self,rb_intern("to_s"),0));
|
39
|
+
rb_funcall(ret,concat,1,rb_str_new2(">"));
|
40
|
+
return ret;
|
41
|
+
}
|
42
|
+
|
43
|
+
static VALUE erlix_ref_etype(VALUE self){
|
44
|
+
return rb_str_new2("ref");
|
45
|
+
}
|
46
|
+
|
47
|
+
void init_erlix_ref(VALUE erlix){
|
48
|
+
erlix_cErlixRef=rb_define_class_under(erlix,"Ref",rb_cObject);
|
49
|
+
|
50
|
+
rb_define_alloc_func(erlix_cErlixRef,erlix_ref_alloc);
|
51
|
+
rb_define_method(erlix_cErlixRef,"initialize",erlix_ref_init,0);
|
52
|
+
rb_define_method(erlix_cErlixRef,"inspect",erlix_ref_inspect,0);
|
53
|
+
rb_define_method(erlix_cErlixRef,"etype",erlix_ref_etype,0);
|
54
|
+
|
55
|
+
rb_include_module(erlix_cErlixRef,erlix_mErlixTerm);
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
|
data/src/erlix_term.c
ADDED
@@ -0,0 +1,362 @@
|
|
1
|
+
/*
|
2
|
+
* project : erlix
|
3
|
+
* author : kdr2
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <ctype.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
|
10
|
+
#include "erlix_term.h"
|
11
|
+
|
12
|
+
VALUE erlix_mErlixTerm;
|
13
|
+
|
14
|
+
ErlixTerm* new_erlix_term(){
|
15
|
+
ErlixTerm* ret=(ErlixTerm*)malloc(sizeof(ErlixTerm));
|
16
|
+
memset(ret, 0, sizeof(ErlixTerm));
|
17
|
+
return ret;
|
18
|
+
}
|
19
|
+
|
20
|
+
void free_erlix_term(void* ptr){
|
21
|
+
ErlixTerm* eterm=ptr;
|
22
|
+
//TODO
|
23
|
+
//flags
|
24
|
+
//erl_free_term(eterm->term);
|
25
|
+
if(eterm && eterm->term){
|
26
|
+
erl_free_compound(eterm->term);
|
27
|
+
free(eterm);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
//initialize_copy
|
32
|
+
static VALUE erlix_term_init_copy(VALUE copy,VALUE orig){
|
33
|
+
ErlixTerm *tcopy,*tsrc;
|
34
|
+
if(copy==orig)return copy;
|
35
|
+
if(!IS_ETERM(orig)){
|
36
|
+
rb_raise(rb_eTypeError,"wrong argument type!");
|
37
|
+
}
|
38
|
+
Data_Get_Struct(copy,ErlixTerm,tcopy);
|
39
|
+
Data_Get_Struct(orig,ErlixTerm,tsrc);
|
40
|
+
tcopy->flags=tsrc->flags;
|
41
|
+
tcopy->type=tsrc->type;
|
42
|
+
tcopy->term=erl_copy_term(tsrc->term);
|
43
|
+
|
44
|
+
return copy;
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
//obj.to_s
|
49
|
+
static void fill_string(VALUE *str,ETERM *ep);
|
50
|
+
VALUE erlix_term_to_str(VALUE self){
|
51
|
+
ErlixTerm *eterm;
|
52
|
+
ETERM *ep;
|
53
|
+
VALUE ret;
|
54
|
+
Data_Get_Struct(self,ErlixTerm,eterm);
|
55
|
+
ep=eterm->term;
|
56
|
+
ret=rb_str_new2("");
|
57
|
+
fill_string(&ret,ep);
|
58
|
+
return ret;
|
59
|
+
}
|
60
|
+
|
61
|
+
static int is_printable_list(const ETERM* term)
|
62
|
+
{
|
63
|
+
ETERM* head;
|
64
|
+
while (ERL_TYPE(term) == ERL_LIST) {
|
65
|
+
head = (ETERM*)(ERL_CONS_HEAD(term));
|
66
|
+
if (ERL_INT_VALUE(head)<0 || ERL_INT_VALUE(head)>255) {
|
67
|
+
return 0;
|
68
|
+
}
|
69
|
+
if (ERL_INT_VALUE(head) < ' ') {
|
70
|
+
switch (ERL_INT_VALUE(head)) {
|
71
|
+
case '\n':
|
72
|
+
case '\r':
|
73
|
+
case '\t':
|
74
|
+
case '\v':
|
75
|
+
case '\b':
|
76
|
+
case '\f':
|
77
|
+
break;
|
78
|
+
default:
|
79
|
+
return 0;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
term = (ETERM*)(ERL_CONS_TAIL(term));
|
83
|
+
}
|
84
|
+
return ERL_IS_EMPTY_LIST(term);
|
85
|
+
}
|
86
|
+
|
87
|
+
static void fill_printable_list(VALUE *str, const ETERM* ep){
|
88
|
+
int c;
|
89
|
+
char tmp_buf[9];
|
90
|
+
ID concat=rb_intern("concat");
|
91
|
+
rb_funcall(*str,concat,1,rb_str_new2("\""));
|
92
|
+
while (ERL_IS_CONS(ep)) {
|
93
|
+
c = ERL_INT_VALUE((ETERM*)ERL_CONS_HEAD(ep));
|
94
|
+
if (c >= ' ') {
|
95
|
+
memset(tmp_buf,0,9);
|
96
|
+
tmp_buf[0]=c;
|
97
|
+
tmp_buf[1]=0;
|
98
|
+
rb_funcall(*str,concat,1,rb_str_new2(tmp_buf));
|
99
|
+
}
|
100
|
+
else {
|
101
|
+
if(c=='\n'){
|
102
|
+
rb_funcall(*str,concat,1,rb_str_new2("\\n"));
|
103
|
+
}else if(c=='\r'){
|
104
|
+
rb_funcall(*str,concat,1,rb_str_new2("\\r"));
|
105
|
+
}else if(c=='\t'){
|
106
|
+
rb_funcall(*str,concat,1,rb_str_new2("\\t"));
|
107
|
+
}else if(c=='\v'){
|
108
|
+
rb_funcall(*str,concat,1,rb_str_new2("\\v"));
|
109
|
+
}else if(c=='\b'){
|
110
|
+
rb_funcall(*str,concat,1,rb_str_new2("\\b"));
|
111
|
+
}else if(c=='\f'){
|
112
|
+
rb_funcall(*str,concat,1,rb_str_new2("\\f"));
|
113
|
+
}else{
|
114
|
+
memset(tmp_buf,0,9);
|
115
|
+
sprintf(tmp_buf,"\\%o",c);
|
116
|
+
rb_funcall(*str,concat,1,rb_str_new2(tmp_buf));
|
117
|
+
}
|
118
|
+
}
|
119
|
+
ep = (ETERM*)ERL_CONS_TAIL(ep);
|
120
|
+
}
|
121
|
+
rb_funcall(*str,concat,1,rb_str_new2("\""));
|
122
|
+
}
|
123
|
+
|
124
|
+
|
125
|
+
static void fill_string(VALUE *str,ETERM *ep){
|
126
|
+
ID concat=rb_intern("concat");
|
127
|
+
|
128
|
+
int j,i,doquote;
|
129
|
+
|
130
|
+
if (!ep) return;
|
131
|
+
|
132
|
+
j = i = doquote = 0;
|
133
|
+
|
134
|
+
if(ERL_IS_ATOM(ep)){
|
135
|
+
/* FIXME: what if some weird locale is in use? */
|
136
|
+
if (!islower((int)ERL_ATOM_PTR(ep)[0]))
|
137
|
+
doquote = 1;
|
138
|
+
for (i = 0; !doquote && i < ERL_ATOM_SIZE(ep); i++){
|
139
|
+
doquote = !(isalnum((int)ERL_ATOM_PTR(ep)[i])
|
140
|
+
|| (ERL_ATOM_PTR(ep)[i] == '_'));
|
141
|
+
}
|
142
|
+
if (doquote) {
|
143
|
+
rb_funcall(*str,concat,1,rb_str_new2("\'"));
|
144
|
+
}
|
145
|
+
rb_funcall(*str,concat,1,rb_str_new2(ERL_ATOM_PTR(ep)));
|
146
|
+
if(doquote){
|
147
|
+
rb_funcall(*str,concat,1,rb_str_new2("\'"));
|
148
|
+
}
|
149
|
+
}else if(ERL_IS_PID(ep)){
|
150
|
+
char tmp_buf_pid[24];
|
151
|
+
memset(tmp_buf_pid,0,24);
|
152
|
+
sprintf(tmp_buf_pid,"<%d.%d.%d>",ERL_PID_NUMBER(ep), ERL_PID_SERIAL(ep),ERL_PID_CREATION(ep));
|
153
|
+
rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_pid));
|
154
|
+
}else if(ERL_IS_PORT(ep)){
|
155
|
+
rb_funcall(*str,concat,1,rb_str_new2("#Port"));
|
156
|
+
}else if(ERL_IS_REF(ep)){
|
157
|
+
rb_funcall(*str,concat,1,rb_str_new2("#Ref"));
|
158
|
+
}else if(ERL_IS_EMPTY_LIST(ep)){
|
159
|
+
rb_funcall(*str,concat,1,rb_str_new2("[]"));
|
160
|
+
}else if(ERL_IS_LIST(ep)){
|
161
|
+
if (is_printable_list(ep)) {
|
162
|
+
fill_printable_list(str,ep);
|
163
|
+
} else {
|
164
|
+
rb_funcall(*str,concat,1,rb_str_new2("["));
|
165
|
+
ETERM *tl=ep,*hd,*tmp;
|
166
|
+
while (ERL_IS_CONS(tl)){
|
167
|
+
hd=erl_hd(tl);
|
168
|
+
fill_string(str,hd);
|
169
|
+
//erl_free_term(hd);
|
170
|
+
tmp = erl_tl(tl);
|
171
|
+
//if(tl!=ep)erl_free_term(tl);
|
172
|
+
tl=tmp;
|
173
|
+
if (ERL_IS_CONS(tl)) {
|
174
|
+
rb_funcall(*str,concat,1,rb_str_new2(","));
|
175
|
+
}
|
176
|
+
}
|
177
|
+
if (!ERL_IS_EMPTY_LIST(tl)) {
|
178
|
+
rb_funcall(*str,concat,1,rb_str_new2("|"));
|
179
|
+
fill_string(str, tl);
|
180
|
+
}else{
|
181
|
+
//erl_free_term(tl);
|
182
|
+
}
|
183
|
+
rb_funcall(*str,concat,1,rb_str_new2("]"));
|
184
|
+
}
|
185
|
+
}else if(ERL_IS_TUPLE(ep)){
|
186
|
+
rb_funcall(*str,concat,1,rb_str_new2("{"));
|
187
|
+
for (i=0; i < ERL_TUPLE_SIZE(ep); i++) {
|
188
|
+
ETERM *e=erl_element(i+1,ep);
|
189
|
+
fill_string(str,e);
|
190
|
+
//erl_free_term(e);
|
191
|
+
if (i != ERL_TUPLE_SIZE(ep)-1) {
|
192
|
+
rb_funcall(*str,concat,1,rb_str_new2(","));
|
193
|
+
}
|
194
|
+
}
|
195
|
+
rb_funcall(*str,concat,1,rb_str_new2("}"));
|
196
|
+
}else if(ERL_IS_BINARY(ep)){
|
197
|
+
rb_funcall(*str,concat,1,rb_str_new2("#Bin"));
|
198
|
+
}else if(ERL_IS_INTEGER(ep)){
|
199
|
+
char tmp_buf_num[24];
|
200
|
+
memset(tmp_buf_num,0,24);
|
201
|
+
sprintf(tmp_buf_num,"%d", ERL_INT_VALUE(ep));
|
202
|
+
rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_num));
|
203
|
+
}else if(ERL_IS_UNSIGNED_INTEGER(ep)){
|
204
|
+
char tmp_buf_unum[24];
|
205
|
+
memset(tmp_buf_unum,0,24);
|
206
|
+
sprintf(tmp_buf_unum,"%u", ERL_INT_UVALUE(ep));
|
207
|
+
rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_unum));
|
208
|
+
}else if(ERL_IS_FLOAT(ep)){
|
209
|
+
char tmp_buf_float[24];
|
210
|
+
memset(tmp_buf_float,0,24);
|
211
|
+
sprintf(tmp_buf_float,"%f", ERL_FLOAT_VALUE(ep));
|
212
|
+
rb_funcall(*str,concat,1,rb_str_new2(tmp_buf_float));
|
213
|
+
}else{
|
214
|
+
rb_funcall(*str,concat,1,rb_str_new2("*Unknow*"));
|
215
|
+
//rb_raise(rb_eException,"ErlixTerm.to_s: Bad type of term !");
|
216
|
+
}
|
217
|
+
}
|
218
|
+
|
219
|
+
static VALUE erlix_term_eql(VALUE left,VALUE right){
|
220
|
+
ErlixTerm *el,*er;
|
221
|
+
Data_Get_Struct(left,ErlixTerm,el);
|
222
|
+
Data_Get_Struct(right,ErlixTerm,er);
|
223
|
+
if(erl_match(el->term, er->term)){
|
224
|
+
return Qtrue;
|
225
|
+
}
|
226
|
+
return Qfalse;
|
227
|
+
}
|
228
|
+
|
229
|
+
static VALUE erlix_term_match(VALUE self,VALUE string){
|
230
|
+
VALUE ret;
|
231
|
+
VALUE pattern=StringValue(string);
|
232
|
+
ErlixTerm *et;
|
233
|
+
Data_Get_Struct(self,ErlixTerm,et);
|
234
|
+
ETERM *epattern = erl_format(RSTRING_PTR(pattern));
|
235
|
+
if(erl_match(epattern,et->term)){
|
236
|
+
ret=Qtrue;
|
237
|
+
}else{
|
238
|
+
ret=Qfalse;
|
239
|
+
}
|
240
|
+
erl_free_term(epattern);
|
241
|
+
return ret;
|
242
|
+
}
|
243
|
+
|
244
|
+
static VALUE erlix_term_mget(VALUE self,VALUE string,VALUE e){
|
245
|
+
VALUE ret;
|
246
|
+
VALUE pattern=StringValue(string);
|
247
|
+
VALUE t=StringValue(e);
|
248
|
+
ErlixTerm *et;
|
249
|
+
Data_Get_Struct(self,ErlixTerm,et);
|
250
|
+
ETERM *epattern = erl_format(RSTRING_PTR(pattern));
|
251
|
+
if(erl_match(epattern,et->term)){
|
252
|
+
ETERM *ep = erl_var_content(epattern,RSTRING_PTR(e));
|
253
|
+
if(ep==NULL){
|
254
|
+
ret=Qnil;
|
255
|
+
}else{
|
256
|
+
ret=erlix_term(ep);
|
257
|
+
}
|
258
|
+
}else{
|
259
|
+
ret=Qnil;
|
260
|
+
}
|
261
|
+
erl_free_term(epattern);
|
262
|
+
return ret;
|
263
|
+
}
|
264
|
+
|
265
|
+
ETERM *erlix_auto_conv(VALUE v){
|
266
|
+
if(SYMBOL_P(v)){
|
267
|
+
return erl_mk_atom(rb_id2name(SYM2ID(v)));
|
268
|
+
}else if(FIXNUM_P(v)){
|
269
|
+
return erl_mk_int(FIX2INT(v));
|
270
|
+
}else if(TYPE(v)==T_FLOAT){
|
271
|
+
return erl_mk_float(NUM2DBL(v));
|
272
|
+
}else if(TYPE(v)==T_STRING){
|
273
|
+
return erl_mk_estring(RSTRING_PTR(v),RSTRING_LEN(v));
|
274
|
+
}
|
275
|
+
return NULL;
|
276
|
+
}
|
277
|
+
|
278
|
+
unsigned long erlix_term_type(ETERM *t){
|
279
|
+
if(ERL_IS_INTEGER(t))return TYPE_INT;
|
280
|
+
if(ERL_IS_UNSIGNED_INTEGER(t))return TYPE_UINT;
|
281
|
+
if(ERL_IS_FLOAT(t))return TYPE_FLOAT;
|
282
|
+
if(ERL_IS_ATOM(t))return TYPE_ATOM;
|
283
|
+
if(ERL_IS_PID(t))return TYPE_PID;
|
284
|
+
if(ERL_IS_PORT(t))return TYPE_PORT;
|
285
|
+
if(ERL_IS_REF(t))return TYPE_REF;
|
286
|
+
if(ERL_IS_TUPLE(t))return TYPE_TUPLE;
|
287
|
+
if(ERL_IS_BINARY(t))return TYPE_BINARY;
|
288
|
+
if(ERL_IS_LIST(t))return TYPE_LIST;
|
289
|
+
if(ERL_IS_EMPTY_LIST(t))return TYPE_EMPTY_LIST;
|
290
|
+
if(ERL_IS_CONS(t))return TYPE_CONS;
|
291
|
+
return 0;
|
292
|
+
}
|
293
|
+
|
294
|
+
VALUE erlix_term(ETERM *term){
|
295
|
+
unsigned long type=erlix_term_type(term);
|
296
|
+
VALUE ret;
|
297
|
+
ErlixTerm *eterm;
|
298
|
+
if(type==TYPE_INT){
|
299
|
+
ret=erlix_int_alloc(erlix_cErlixInt);
|
300
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
301
|
+
eterm->term=term;
|
302
|
+
return ret;
|
303
|
+
}else if(type==TYPE_UINT){
|
304
|
+
ret=erlix_uint_alloc(erlix_cErlixUInt);
|
305
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
306
|
+
eterm->term=term;
|
307
|
+
return ret;
|
308
|
+
}else if(type==TYPE_FLOAT){
|
309
|
+
ret=erlix_float_alloc(erlix_cErlixFloat);
|
310
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
311
|
+
eterm->term=term;
|
312
|
+
return ret;
|
313
|
+
}else if(type==TYPE_PID){
|
314
|
+
ret=erlix_pid_alloc(erlix_cErlixPid);
|
315
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
316
|
+
eterm->term=term;
|
317
|
+
return ret;
|
318
|
+
}else if(type==TYPE_REF){
|
319
|
+
ret=erlix_ref_alloc(erlix_cErlixRef);
|
320
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
321
|
+
eterm->term=term;
|
322
|
+
return ret;
|
323
|
+
}else if(type==TYPE_ATOM){
|
324
|
+
ret=erlix_atom_alloc(erlix_cErlixAtom);
|
325
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
326
|
+
eterm->term=term;
|
327
|
+
return ret;
|
328
|
+
}else if(type==TYPE_LIST){
|
329
|
+
ret=erlix_list_alloc(erlix_cErlixList);
|
330
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
331
|
+
eterm->term=term;
|
332
|
+
return ret;
|
333
|
+
}else if(type==TYPE_TUPLE){
|
334
|
+
ret=erlix_tuple_alloc(erlix_cErlixTuple);
|
335
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
336
|
+
eterm->term=term;
|
337
|
+
return ret;
|
338
|
+
}else if(type==TYPE_BINARY){
|
339
|
+
ret=erlix_binary_alloc(erlix_cErlixBinary);
|
340
|
+
Data_Get_Struct(ret,ErlixTerm,eterm);
|
341
|
+
eterm->term=term;
|
342
|
+
return ret;
|
343
|
+
}else{
|
344
|
+
rb_raise(rb_eException,"Unknow Erlang Type!");
|
345
|
+
//TODO OTHER TYPE!!!
|
346
|
+
return Qnil;
|
347
|
+
}
|
348
|
+
}
|
349
|
+
|
350
|
+
|
351
|
+
void init_erlix_term(VALUE erlix){
|
352
|
+
erlix_mErlixTerm=rb_define_module_under(erlix, "Term");
|
353
|
+
rb_define_method(erlix_mErlixTerm,"initialize_copy",erlix_term_init_copy,1);
|
354
|
+
rb_define_method(erlix_mErlixTerm,"eql?",erlix_term_eql,1);
|
355
|
+
rb_define_method(erlix_mErlixTerm,"to_s",erlix_term_to_str,0);
|
356
|
+
rb_define_method(erlix_mErlixTerm,"match",erlix_term_match,1);
|
357
|
+
rb_define_method(erlix_mErlixTerm,"mget",erlix_term_mget,2);
|
358
|
+
rb_define_method(erlix_mErlixTerm,"==",erlix_term_eql,1);
|
359
|
+
}
|
360
|
+
|
361
|
+
|
362
|
+
|