net-proto 1.0.6 → 1.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/CHANGES +9 -0
- data/MANIFEST +6 -6
- data/README +22 -15
- data/Rakefile +7 -58
- data/doc/netproto.txt +14 -17
- data/examples/example_net_proto.rb +11 -11
- data/lib/generic/net/proto.rb +145 -0
- data/lib/linux/net/proto.rb +140 -0
- data/lib/net/proto.rb +10 -0
- data/lib/net/proto/common.rb +37 -0
- data/lib/sunos/net/proto.rb +134 -0
- data/net-proto.gemspec +3 -6
- data/test/test_net_proto.rb +52 -45
- metadata +40 -27
- data/ext/extconf.rb +0 -19
- data/ext/generic/generic.c +0 -168
- data/ext/linux/linux.c +0 -175
- data/ext/sunos/sunos.c +0 -160
- data/ext/version.h +0 -2
- data/ext/windows/windows.c +0 -86
data/ext/extconf.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'mkmf'
|
2
|
-
require 'fileutils'
|
3
|
-
require 'rbconfig'
|
4
|
-
|
5
|
-
Dir.mkdir('net') unless File.exists?('net')
|
6
|
-
|
7
|
-
case Config::CONFIG['host_os']
|
8
|
-
when /sunos|solaris/i
|
9
|
-
have_library('socket')
|
10
|
-
FileUtils.cp('sunos/sunos.c', 'net/proto.c')
|
11
|
-
when /linux/i
|
12
|
-
FileUtils.cp('linux/linux.c', 'net/proto.c')
|
13
|
-
when /win32|windows|dos|mingw|cygwin/i
|
14
|
-
FileUtils.cp('windows/windows.c', 'net/proto.c')
|
15
|
-
else
|
16
|
-
FileUtils.cp('generic/generic.c', 'net/proto.c')
|
17
|
-
end
|
18
|
-
|
19
|
-
create_makefile('net/proto', 'net')
|
data/ext/generic/generic.c
DELETED
@@ -1,168 +0,0 @@
|
|
1
|
-
/*******************************************************
|
2
|
-
* proto.c (generic.c)
|
3
|
-
*******************************************************/
|
4
|
-
#include <ruby.h>
|
5
|
-
#include <version.h>
|
6
|
-
#include <netdb.h>
|
7
|
-
#include <string.h>
|
8
|
-
|
9
|
-
#ifdef __cplusplus
|
10
|
-
extern "C"
|
11
|
-
{
|
12
|
-
#endif
|
13
|
-
|
14
|
-
VALUE sProto;
|
15
|
-
|
16
|
-
/*
|
17
|
-
* call-seq:
|
18
|
-
* Net::Proto.getprotobyname(name)
|
19
|
-
*
|
20
|
-
* Given a protocol string, returns the corresponding number, or nil if not
|
21
|
-
* found.
|
22
|
-
*
|
23
|
-
* Examples:
|
24
|
-
*
|
25
|
-
* Net::Proto.getprotobyname("tcp") # => 6
|
26
|
-
* Net::Proto.getprotobyname("bogus") # => nil
|
27
|
-
*/
|
28
|
-
static VALUE np_getprotobyname(VALUE klass, VALUE v_proto_name){
|
29
|
-
struct protoent* p;
|
30
|
-
VALUE v_proto_num = Qnil;
|
31
|
-
|
32
|
-
SafeStringValue(v_proto_name);
|
33
|
-
|
34
|
-
setprotoent(0);
|
35
|
-
p = getprotobyname(StringValuePtr(v_proto_name));
|
36
|
-
|
37
|
-
if(p)
|
38
|
-
v_proto_num = INT2FIX(p->p_proto);
|
39
|
-
|
40
|
-
endprotoent();
|
41
|
-
|
42
|
-
return v_proto_num;
|
43
|
-
}
|
44
|
-
|
45
|
-
/*
|
46
|
-
* call-seq:
|
47
|
-
* Proto.getprotobynumber(num)
|
48
|
-
*
|
49
|
-
* Given a protocol number, returns the corresponding string, or nil if not
|
50
|
-
* found.
|
51
|
-
*
|
52
|
-
* Examples:
|
53
|
-
*
|
54
|
-
* Net::Proto.getprotobynumber(6) # => "tcp"
|
55
|
-
* Net::Proto.getprotobynumber(999) # => nil
|
56
|
-
*/
|
57
|
-
static VALUE np_getprotobynumber(VALUE klass, VALUE v_proto_num){
|
58
|
-
struct protoent* p;
|
59
|
-
VALUE v_proto_name = Qnil;
|
60
|
-
|
61
|
-
setprotoent(0);
|
62
|
-
p = getprotobynumber(NUM2INT(v_proto_num));
|
63
|
-
|
64
|
-
if(p)
|
65
|
-
v_proto_name = rb_str_new2(p->p_name);
|
66
|
-
|
67
|
-
endprotoent();
|
68
|
-
|
69
|
-
return v_proto_name;
|
70
|
-
}
|
71
|
-
|
72
|
-
/*
|
73
|
-
* call-seq:
|
74
|
-
* Proto.getprotoent
|
75
|
-
* Proto.getprotoent{ |struct| ... }
|
76
|
-
*
|
77
|
-
* In block form, yields each entry from /etc/protocols as a struct of type
|
78
|
-
* Proto::ProtoStruct. In non-block form, returns an array of
|
79
|
-
* Proto::ProtoStruct objects.
|
80
|
-
*
|
81
|
-
* The fields are 'name' (a String), 'aliases' (an Array of String's,
|
82
|
-
* though often only one element), and 'proto' (a Fixnum).
|
83
|
-
*
|
84
|
-
* Example:
|
85
|
-
*
|
86
|
-
* Net::Proto.getprotoent.each{ |prot|
|
87
|
-
* p prot.name
|
88
|
-
* p prot.aliases
|
89
|
-
* p prot.proto
|
90
|
-
* }
|
91
|
-
*
|
92
|
-
*/
|
93
|
-
static VALUE np_getprotoent(VALUE klass){
|
94
|
-
struct protoent* p;
|
95
|
-
VALUE v_aliases = Qnil;
|
96
|
-
VALUE v_array = Qnil;
|
97
|
-
VALUE v_struct = Qnil;
|
98
|
-
|
99
|
-
p = malloc(sizeof(struct protoent));
|
100
|
-
|
101
|
-
if(!rb_block_given_p())
|
102
|
-
v_array = rb_ary_new();
|
103
|
-
|
104
|
-
setprotoent(0);
|
105
|
-
|
106
|
-
while((p = getprotoent())){
|
107
|
-
v_aliases = rb_ary_new();
|
108
|
-
|
109
|
-
#ifdef __MACH__ or #ifdef __APPLE__
|
110
|
-
char **aliases = p->p_aliases;
|
111
|
-
while(*aliases){
|
112
|
-
rb_ary_push(v_aliases, rb_str_new2(*aliases));
|
113
|
-
aliases++;
|
114
|
-
}
|
115
|
-
#else
|
116
|
-
while(*p->p_aliases){
|
117
|
-
rb_ary_push(v_aliases, rb_str_new2(*p->p_aliases));
|
118
|
-
(void)p->p_aliases++;
|
119
|
-
}
|
120
|
-
#endif
|
121
|
-
|
122
|
-
v_struct = rb_struct_new(sProto,
|
123
|
-
rb_str_new2(p->p_name),
|
124
|
-
v_aliases,
|
125
|
-
INT2FIX(p->p_proto)
|
126
|
-
);
|
127
|
-
|
128
|
-
OBJ_FREEZE(v_struct); /* This is read-only data */
|
129
|
-
|
130
|
-
if(rb_block_given_p())
|
131
|
-
rb_yield(v_struct);
|
132
|
-
else
|
133
|
-
rb_ary_push(v_array, v_struct);
|
134
|
-
}
|
135
|
-
|
136
|
-
free(p);
|
137
|
-
endprotoent();
|
138
|
-
|
139
|
-
return v_array; /* nil if a block is given */
|
140
|
-
}
|
141
|
-
|
142
|
-
void Init_proto(){
|
143
|
-
VALUE mNet, cProto;
|
144
|
-
|
145
|
-
/* The Net module serves only as a namespace */
|
146
|
-
mNet = rb_define_module("Net");
|
147
|
-
|
148
|
-
/* The Proto class encapsulates network protocol information */
|
149
|
-
cProto = rb_define_class_under(mNet, "Proto", rb_cObject);
|
150
|
-
|
151
|
-
/* Structure definitions */
|
152
|
-
sProto = rb_struct_define("ProtoStruct", "name", "aliases", "proto", 0);
|
153
|
-
|
154
|
-
/* Class methods */
|
155
|
-
rb_define_singleton_method(cProto, "getprotobyname", np_getprotobyname, 1);
|
156
|
-
rb_define_singleton_method(cProto, "getprotobynumber", np_getprotobynumber, 1);
|
157
|
-
rb_define_singleton_method(cProto, "getprotoent", np_getprotoent, 0);
|
158
|
-
|
159
|
-
/* There is no constructor */
|
160
|
-
rb_funcall(cProto, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
|
161
|
-
|
162
|
-
/* 1.0.4: The version of this library. This is a string, not a number */
|
163
|
-
rb_define_const(cProto, "VERSION", rb_str_new2(NET_PROTO_VERSION));
|
164
|
-
}
|
165
|
-
|
166
|
-
#ifdef __cplusplus
|
167
|
-
}
|
168
|
-
#endif
|
data/ext/linux/linux.c
DELETED
@@ -1,175 +0,0 @@
|
|
1
|
-
/*******************************************************
|
2
|
-
* proto.c (linux.c)
|
3
|
-
*******************************************************/
|
4
|
-
#include <ruby.h>
|
5
|
-
#include <version.h>
|
6
|
-
#include <netdb.h>
|
7
|
-
#include <string.h>
|
8
|
-
|
9
|
-
#ifdef __cplusplus
|
10
|
-
extern "C"
|
11
|
-
{
|
12
|
-
#endif
|
13
|
-
|
14
|
-
#define BUF_SIZE 8192
|
15
|
-
|
16
|
-
VALUE sProto;
|
17
|
-
|
18
|
-
/*
|
19
|
-
* call-seq:
|
20
|
-
* Proto.getprotobyname(name)
|
21
|
-
*
|
22
|
-
* Given a protocol string, returns the corresponding number, or nil if not
|
23
|
-
* found.
|
24
|
-
*
|
25
|
-
* Examples:
|
26
|
-
*
|
27
|
-
* Net::Proto.getprotobyname("tcp") # => 6
|
28
|
-
* Net::Proto.getprotobyname("bogus") # => nil
|
29
|
-
*/
|
30
|
-
static VALUE np_getprotobyname(VALUE klass, VALUE v_proto_name){
|
31
|
-
struct protoent* p;
|
32
|
-
char buffer[BUF_SIZE];
|
33
|
-
VALUE v_proto_num = Qnil;
|
34
|
-
|
35
|
-
SafeStringValue(v_proto_name);
|
36
|
-
|
37
|
-
p = malloc(sizeof(struct protoent));
|
38
|
-
|
39
|
-
setprotoent(0);
|
40
|
-
getprotobyname_r(StringValuePtr(v_proto_name), p, buffer, BUF_SIZE, &p);
|
41
|
-
|
42
|
-
if(p){
|
43
|
-
v_proto_num = INT2FIX(p->p_proto);
|
44
|
-
free(p);
|
45
|
-
}
|
46
|
-
|
47
|
-
endprotoent();
|
48
|
-
return v_proto_num;
|
49
|
-
}
|
50
|
-
|
51
|
-
/*
|
52
|
-
* call-seq:
|
53
|
-
* Proto.getprotobynumber(num)
|
54
|
-
*
|
55
|
-
* Given a protocol number, returns the corresponding string, or nil if not
|
56
|
-
* found.
|
57
|
-
*
|
58
|
-
* Examples:
|
59
|
-
*
|
60
|
-
* Net::Proto.getprotobynumber(6) # => "tcp"
|
61
|
-
* Net::Proto.getprotobynumber(999) # => nil
|
62
|
-
*/
|
63
|
-
static VALUE np_getprotobynumber(VALUE klass, VALUE v_proto_num){
|
64
|
-
struct protoent* p;
|
65
|
-
char buffer[BUF_SIZE];
|
66
|
-
char* proto_name;
|
67
|
-
VALUE v_proto_name = Qnil;
|
68
|
-
|
69
|
-
p = malloc(sizeof(struct protoent));
|
70
|
-
|
71
|
-
setprotoent(0);
|
72
|
-
getprotobynumber_r(NUM2INT(v_proto_num), p, buffer, BUF_SIZE, &p);
|
73
|
-
|
74
|
-
if(p){
|
75
|
-
v_proto_name = rb_str_new2(proto_name = p->p_name);
|
76
|
-
free(p);
|
77
|
-
}
|
78
|
-
|
79
|
-
endprotoent();
|
80
|
-
return v_proto_name;
|
81
|
-
}
|
82
|
-
|
83
|
-
/*
|
84
|
-
* call-seq:
|
85
|
-
* Proto.getprotoent
|
86
|
-
* Proto.getprotoent{ |struct| ... }
|
87
|
-
*
|
88
|
-
* In block form, yields each entry from /etc/protocols as a struct of type
|
89
|
-
* Proto::ProtoStruct. In non-block form, returns an array of
|
90
|
-
* Proto::ProtoStruct objects.
|
91
|
-
|
92
|
-
* The fields are 'name' (a String), 'aliases' (an Array of String's,
|
93
|
-
* though often only one element), and 'proto' (a Fixnum).
|
94
|
-
*
|
95
|
-
* Example:
|
96
|
-
*
|
97
|
-
* Net::Proto.getprotoent.each{ |prot|
|
98
|
-
* p prot.name
|
99
|
-
* p prot.aliases
|
100
|
-
* p prot.proto
|
101
|
-
* }
|
102
|
-
*/
|
103
|
-
static VALUE np_getprotoent(VALUE klass){
|
104
|
-
struct protoent* p;
|
105
|
-
struct protoent* q;
|
106
|
-
char buffer[BUF_SIZE];
|
107
|
-
VALUE v_alias_array = Qnil;
|
108
|
-
VALUE v_array = Qnil;
|
109
|
-
VALUE v_struct = Qnil;
|
110
|
-
|
111
|
-
p = malloc(sizeof(struct protoent));
|
112
|
-
q = malloc(sizeof(struct protoent));
|
113
|
-
|
114
|
-
if(!rb_block_given_p())
|
115
|
-
v_array = rb_ary_new();
|
116
|
-
|
117
|
-
setprotoent(0);
|
118
|
-
|
119
|
-
while(!getprotoent_r(p, buffer, BUF_SIZE, &q)){
|
120
|
-
v_alias_array = rb_ary_new();
|
121
|
-
|
122
|
-
while((*p->p_aliases)){
|
123
|
-
rb_ary_push(v_alias_array, rb_str_new2(*p->p_aliases));
|
124
|
-
(void)*p->p_aliases++;
|
125
|
-
}
|
126
|
-
|
127
|
-
v_struct = rb_struct_new(sProto,
|
128
|
-
rb_str_new2(p->p_name),
|
129
|
-
v_alias_array,
|
130
|
-
INT2FIX(p->p_proto)
|
131
|
-
);
|
132
|
-
|
133
|
-
OBJ_FREEZE(v_struct); /* This is read-only data */
|
134
|
-
|
135
|
-
if(rb_block_given_p())
|
136
|
-
rb_yield(v_struct);
|
137
|
-
else
|
138
|
-
rb_ary_push(v_array, v_struct);
|
139
|
-
}
|
140
|
-
|
141
|
-
free(p);
|
142
|
-
free(q);
|
143
|
-
|
144
|
-
endprotoent();
|
145
|
-
|
146
|
-
return v_array; /* nil if a block was given */
|
147
|
-
}
|
148
|
-
|
149
|
-
void Init_proto(){
|
150
|
-
VALUE mNet, cProto;
|
151
|
-
|
152
|
-
/* The Net module serves as a namespace only */
|
153
|
-
mNet = rb_define_module("Net");
|
154
|
-
|
155
|
-
/* The Proto class encapsulates network protocol information */
|
156
|
-
cProto = rb_define_class_under(mNet, "Proto", rb_cObject);
|
157
|
-
|
158
|
-
/* Structure definitions */
|
159
|
-
sProto = rb_struct_define("ProtoStruct", "name", "aliases", "proto", 0);
|
160
|
-
|
161
|
-
/* There is no constructor */
|
162
|
-
rb_funcall(cProto, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
|
163
|
-
|
164
|
-
/* Class methods */
|
165
|
-
rb_define_singleton_method(cProto, "getprotobyname", np_getprotobyname, 1);
|
166
|
-
rb_define_singleton_method(cProto, "getprotobynumber", np_getprotobynumber, 1);
|
167
|
-
rb_define_singleton_method(cProto, "getprotoent", np_getprotoent, 0);
|
168
|
-
|
169
|
-
/* 1.0.4: The version of this library. This is a string, not a number */
|
170
|
-
rb_define_const(cProto, "VERSION", rb_str_new2(NET_PROTO_VERSION));
|
171
|
-
}
|
172
|
-
|
173
|
-
#ifdef __cplusplus
|
174
|
-
}
|
175
|
-
#endif
|
data/ext/sunos/sunos.c
DELETED
@@ -1,160 +0,0 @@
|
|
1
|
-
/*******************************************************
|
2
|
-
* proto.c (sunos.c)
|
3
|
-
*******************************************************/
|
4
|
-
#include <ruby.h>
|
5
|
-
#include <version.h>
|
6
|
-
#include <netdb.h>
|
7
|
-
#include <string.h>
|
8
|
-
|
9
|
-
#ifdef __cplusplus
|
10
|
-
extern "C"
|
11
|
-
{
|
12
|
-
#endif
|
13
|
-
|
14
|
-
#define BUF_SIZE 8192
|
15
|
-
|
16
|
-
VALUE sProto;
|
17
|
-
|
18
|
-
/*
|
19
|
-
* call-seq:
|
20
|
-
* Proto.getprotobyname(name)
|
21
|
-
*
|
22
|
-
* Given a protocol string, returns the corresponding number, or nil if not
|
23
|
-
* found.
|
24
|
-
*
|
25
|
-
* Examples:
|
26
|
-
*
|
27
|
-
* Net::Proto.getprotobyname("tcp") # => 6
|
28
|
-
* Net::Proto.getprotobyname("bogus") # => nil
|
29
|
-
*/
|
30
|
-
static VALUE np_getprotobyname(VALUE klass, VALUE v_proto_name){
|
31
|
-
struct protoent p;
|
32
|
-
char buffer[BUF_SIZE];
|
33
|
-
VALUE v_proto_num = Qnil;
|
34
|
-
|
35
|
-
SafeStringValue(v_proto_name);
|
36
|
-
|
37
|
-
setprotoent(0);
|
38
|
-
|
39
|
-
if(getprotobyname_r(StringValuePtr(v_proto_name),&p,buffer,BUF_SIZE) != NULL)
|
40
|
-
v_proto_num = INT2FIX(p.p_proto);
|
41
|
-
|
42
|
-
endprotoent();
|
43
|
-
|
44
|
-
return v_proto_num;
|
45
|
-
}
|
46
|
-
|
47
|
-
/*
|
48
|
-
* call-seq:
|
49
|
-
* Proto.getprotobynumber(num)
|
50
|
-
*
|
51
|
-
* Given a protocol number, returns the corresponding string, or nil if not
|
52
|
-
* found.
|
53
|
-
*
|
54
|
-
* Examples:
|
55
|
-
*
|
56
|
-
* Net::Proto.getprotobynumber(6) # => "tcp"
|
57
|
-
* Net::Proto.getprotobynumber(999) # => nil
|
58
|
-
*/
|
59
|
-
static VALUE np_getprotobynumber(VALUE klass, VALUE v_proto_num){
|
60
|
-
struct protoent p;
|
61
|
-
char buffer[BUF_SIZE];
|
62
|
-
VALUE v_proto_name = Qnil;
|
63
|
-
|
64
|
-
setprotoent(0);
|
65
|
-
|
66
|
-
if(getprotobynumber_r(NUM2INT(v_proto_num),&p,buffer,BUF_SIZE) != NULL)
|
67
|
-
v_proto_name = rb_str_new2(p.p_name);
|
68
|
-
|
69
|
-
endprotoent();
|
70
|
-
|
71
|
-
return v_proto_name;
|
72
|
-
}
|
73
|
-
|
74
|
-
/*
|
75
|
-
* call-seq:
|
76
|
-
* Proto.getprotoent
|
77
|
-
* Proto.getprotoent{ |struct| ... }
|
78
|
-
*
|
79
|
-
* In block form, yields each entry from /etc/protocols as a struct of type
|
80
|
-
* Proto::ProtoStruct. In non-block form, returns an array of
|
81
|
-
* Proto::ProtoStruct objects.
|
82
|
-
|
83
|
-
* The fields are 'name' (a String), 'aliases' (an Array of String's,
|
84
|
-
* though often only one element), and 'proto' (a Fixnum).
|
85
|
-
*
|
86
|
-
* Example:
|
87
|
-
*
|
88
|
-
* Net::Proto.getprotoent.each{ |prot|
|
89
|
-
* p prot.name
|
90
|
-
* p prot.aliases
|
91
|
-
* p prot.proto
|
92
|
-
* }
|
93
|
-
*/
|
94
|
-
static VALUE np_getprotoent(){
|
95
|
-
struct protoent p;
|
96
|
-
char buffer[BUF_SIZE];
|
97
|
-
VALUE v_alias_array = Qnil;
|
98
|
-
VALUE v_array = Qnil;
|
99
|
-
VALUE v_struct = Qnil;
|
100
|
-
|
101
|
-
if(!rb_block_given_p())
|
102
|
-
v_array = rb_ary_new();
|
103
|
-
|
104
|
-
setprotoent(0);
|
105
|
-
|
106
|
-
while(getprotoent_r(&p, buffer, BUF_SIZE)){
|
107
|
-
v_alias_array = rb_ary_new();
|
108
|
-
|
109
|
-
while(*p.p_aliases){
|
110
|
-
rb_ary_push(v_alias_array ,rb_str_new2(*p.p_aliases));
|
111
|
-
(void)p.p_aliases++;
|
112
|
-
}
|
113
|
-
|
114
|
-
v_struct = rb_struct_new(sProto,
|
115
|
-
rb_str_new2(p.p_name),
|
116
|
-
v_alias_array,
|
117
|
-
INT2FIX(p.p_proto)
|
118
|
-
);
|
119
|
-
|
120
|
-
OBJ_FREEZE(v_struct); /* This is read-only data */
|
121
|
-
|
122
|
-
if(rb_block_given_p())
|
123
|
-
rb_yield(v_struct);
|
124
|
-
else
|
125
|
-
rb_ary_push(v_array, v_struct);
|
126
|
-
}
|
127
|
-
|
128
|
-
endprotoent();
|
129
|
-
|
130
|
-
return v_array; /* nil unless a block is given */
|
131
|
-
}
|
132
|
-
|
133
|
-
void Init_proto()
|
134
|
-
{
|
135
|
-
VALUE mNet, cProto;
|
136
|
-
|
137
|
-
/* The Net module serves only as a namespace */
|
138
|
-
mNet = rb_define_module("Net");
|
139
|
-
|
140
|
-
/* The Proto class encapsulates information associated for network protocol entries */
|
141
|
-
cProto = rb_define_class_under(mNet, "Proto", rb_cObject);
|
142
|
-
|
143
|
-
/* Structure definitions */
|
144
|
-
sProto = rb_struct_define("ProtoStruct", "name", "aliases", "proto", 0);
|
145
|
-
|
146
|
-
/* There is no constructor */
|
147
|
-
rb_funcall(cProto, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
|
148
|
-
|
149
|
-
/* Class methods */
|
150
|
-
rb_define_singleton_method(cProto, "getprotobyname", np_getprotobyname,1);
|
151
|
-
rb_define_singleton_method(cProto, "getprotobynumber", np_getprotobynumber,1);
|
152
|
-
rb_define_singleton_method(cProto, "getprotoent", np_getprotoent,0);
|
153
|
-
|
154
|
-
/* 1.0.4: The version of this library. This a string, not a number */
|
155
|
-
rb_define_const(cProto, "VERSION", rb_str_new2(NET_PROTO_VERSION));
|
156
|
-
}
|
157
|
-
|
158
|
-
#ifdef __cplusplus
|
159
|
-
}
|
160
|
-
#endif
|