RInotify 0.9-i586-linux

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/ext/rinotify.c ADDED
@@ -0,0 +1,289 @@
1
+ /*****************************************************
2
+ * copyright (C) 2007 by Rob Merrell
3
+ * rob@migrob.com
4
+ *
5
+ * ***************************************************/
6
+
7
+ #include "ruby.h"
8
+ #include "rinotify.h"
9
+ #include "rinotify_event.h"
10
+
11
+ #include <sys/inotify.h>
12
+ #include <sys/time.h>
13
+ #include <sys/ioctl.h>
14
+ #include <unistd.h>
15
+
16
+ // extension entry point
17
+ void Init_rinotify() {
18
+ rb_cRInotify = rb_define_class("RInotify", rb_cObject);
19
+ rb_cRInotifyEvent = rb_define_class("RInotifyEvent", rb_cObject);
20
+
21
+ // initialize all of the events
22
+ rinotify_declare_events(rb_cRInotify);
23
+
24
+
25
+ // RInotify.new
26
+ rb_define_alloc_func(rb_cRInotify, rb_rinotify_new);
27
+
28
+ // RInotify.version
29
+ rb_define_method(rb_cRInotify, "version", rb_rinotify_version, 0);
30
+
31
+ // RInotify.close
32
+ rb_define_method(rb_cRInotify, "close", rb_rinotify_close, 0);
33
+
34
+ // RInotify.add_watch
35
+ rb_define_method(rb_cRInotify, "add_watch", rb_rinotify_add_watch, 2);
36
+
37
+ // RInotify.rm_watch
38
+ rb_define_method(rb_cRInotify, "rm_watch", rb_rinotify_rm_watch, 1);
39
+
40
+ // RInotify.wait_for_events
41
+ rb_define_method(rb_cRInotify, "wait_for_events", rb_rinotify_wait_for_events, 1);
42
+
43
+ // RInotify.each_event
44
+ rb_define_method(rb_cRInotify, "each_event", rb_rinotify_each_event, 0);
45
+
46
+ // RInotify.watch_descriptors
47
+ rb_define_method(rb_cRInotify, "watch_descriptors", rb_rinotify_watch_descriptors, 0);
48
+
49
+ // RInotify.event_queue_size
50
+ rb_define_method(rb_cRInotify, "event_queue_size", rb_rinotify_queue_size, 0);
51
+
52
+
53
+ /* The following methods are implemented in rinotify_event.c */
54
+
55
+ // RInotifyEvent.name
56
+ rb_define_method(rb_cRInotifyEvent, "name", rb_rinotify_event_name, 0);
57
+
58
+ // RInotifyEvent.watch_descriptor
59
+ rb_define_method(rb_cRInotifyEvent, "watch_descriptor", rb_rinotify_event_watch_descriptor, 0);
60
+
61
+ // RInotifyEvent.check_mask
62
+ rb_define_method(rb_cRInotifyEvent, "check_mask", rb_rinotify_event_check_mask, 1);
63
+ }
64
+
65
+
66
+ static VALUE rb_rinotify_new(VALUE klass) {
67
+ VALUE initialized_class;
68
+
69
+ // initialize inotify
70
+ int *inotify = NULL;
71
+ inotify = malloc(sizeof(int));
72
+ *inotify = inotify_init();
73
+
74
+ if (*inotify < 0)
75
+ rb_sys_fail("inotify_init");
76
+
77
+ // make sure free is called because we malloc'd above
78
+ initialized_class = Data_Wrap_Struct(klass, NULL, free, inotify);
79
+
80
+ // initialize all of the instance variables for this class
81
+ rinotify_declare_instance_vars(initialized_class);
82
+
83
+ return initialized_class;
84
+ }
85
+
86
+
87
+ static VALUE rb_rinotify_version(VALUE self) {
88
+ return rb_str_new2(CURRENT_VERSION);
89
+ }
90
+
91
+
92
+ static VALUE rb_rinotify_close(VALUE self) {
93
+ int *inotify = NULL, close_return;
94
+ Data_Get_Struct(self, int, inotify);
95
+
96
+ // close and clean up inotify
97
+ close_return = close(*inotify);
98
+ if (close_return)
99
+ rb_sys_fail("close");
100
+
101
+ return Qnil;
102
+ }
103
+
104
+
105
+ static VALUE rb_rinotify_add_watch(VALUE self, VALUE filename, VALUE event_masks) {
106
+ int *inotify = NULL, watch_desc;
107
+ VALUE watch_desc_id, watch_descriptor_list;
108
+ Data_Get_Struct(self, int, inotify);
109
+
110
+ // add the watch
111
+ watch_desc = inotify_add_watch(*inotify, RSTRING(filename)->ptr, NUM2INT(event_masks));
112
+ if (watch_desc < 0)
113
+ rb_sys_fail("add_watch");
114
+
115
+ watch_desc_id = INT2NUM(watch_desc);
116
+
117
+ // add the watch descriptor to our list
118
+ watch_descriptor_list = rb_iv_get(self, "@watch_descriptors");
119
+ rb_hash_aset(watch_descriptor_list, watch_desc_id, filename);
120
+
121
+ return watch_desc_id;
122
+ }
123
+
124
+
125
+ static VALUE rb_rinotify_rm_watch(VALUE self, VALUE watch_desc) {
126
+ int *inotify = NULL, rm_return;
127
+ Data_Get_Struct(self, int, inotify);
128
+
129
+ // remove the watch
130
+ rm_return = inotify_rm_watch(*inotify, NUM2INT(watch_desc));
131
+ if (rm_return < 0)
132
+ rb_sys_fail("rm_watch");
133
+
134
+ return INT2NUM(rm_return);
135
+ }
136
+
137
+
138
+ static VALUE rb_rinotify_wait_for_events(VALUE self, VALUE time_value) {
139
+ struct timeval time;
140
+ fd_set rfds;
141
+ int select_ret, *inotify = NULL;
142
+
143
+ Data_Get_Struct(self, int, inotify);
144
+
145
+ // set the timout value
146
+ time.tv_sec = NUM2INT(time_value);
147
+ time.tv_usec = 0;
148
+
149
+ // add inotify to the file descriptor set
150
+ FD_ZERO(&rfds);
151
+ FD_SET(*inotify, &rfds);
152
+
153
+ select_ret = rb_thread_select(*inotify + 1, &rfds, NULL, NULL, &time);
154
+
155
+ if (select_ret < 0)
156
+ rb_sys_fail("select");
157
+
158
+ // no events are available and we have timed out
159
+ else if (!select_ret)
160
+ return Qfalse;
161
+
162
+ // events are available
163
+ else if (FD_ISSET(*inotify, &rfds))
164
+ return Qtrue;
165
+
166
+ // to keep the compiler happy...
167
+ return Qfalse;
168
+ }
169
+
170
+
171
+ static VALUE rb_rinotify_each_event(VALUE self) {
172
+ struct inotify_event *event = NULL, *tmp_event = NULL;
173
+ int *inotify = NULL, i = 0, len;
174
+ char buffer[BUFFER_SIZE];
175
+
176
+ Data_Get_Struct(self, int, inotify);
177
+
178
+ len = read(*inotify, buffer, BUFFER_SIZE);
179
+
180
+ // read each event
181
+ while (i < len) {
182
+ tmp_event = (struct inotify_event *) &buffer[i];
183
+
184
+ // copy the tmp_event into our malloc'd event so that it doesn't
185
+ // go out of scope after we yield the object
186
+ event = malloc(EVENT_SIZE + tmp_event->len);
187
+ memmove(event, tmp_event, EVENT_SIZE + tmp_event->len);
188
+
189
+ // construct the RInotifyEvent object
190
+ rb_yield(rb_rinotify_event_new(event));
191
+
192
+ i += EVENT_SIZE + event->len;
193
+ }
194
+
195
+ return Qnil;
196
+ }
197
+
198
+
199
+ static VALUE rb_rinotify_watch_descriptors(VALUE self) {
200
+ return rb_iv_get(self, "@watch_descriptors");
201
+ }
202
+
203
+
204
+ static VALUE rb_rinotify_queue_size(VALUE self) {
205
+ int *inotify = NULL, return_val;
206
+ unsigned int queue_size;
207
+
208
+ Data_Get_Struct(self, int, inotify);
209
+
210
+ // get the queue size
211
+ return_val = ioctl(*inotify, FIONREAD, &queue_size);
212
+
213
+ if (return_val < 0)
214
+ rb_sys_fail("event_queue_size");
215
+
216
+ return UINT2NUM(queue_size);
217
+ }
218
+
219
+
220
+ static void rinotify_declare_events(VALUE klass) {
221
+ // watch events
222
+ rb_const_set(klass, rb_intern("IN_ACCESS"), INT2NUM(IN_ACCESS));
223
+ rb_const_set(klass, rb_intern("ACCESS"), INT2NUM(IN_ACCESS));
224
+
225
+ rb_const_set(klass, rb_intern("IN_MODIFY"), INT2NUM(IN_MODIFY));
226
+ rb_const_set(klass, rb_intern("MODIFY"), INT2NUM(IN_MODIFY));
227
+
228
+ rb_const_set(klass, rb_intern("IN_ATTRIB"), INT2NUM(IN_ATTRIB));
229
+ rb_const_set(klass, rb_intern("ATTRIB"), INT2NUM(IN_ATTRIB));
230
+
231
+ rb_const_set(klass, rb_intern("IN_CLOSE_WRITE"), INT2NUM(IN_CLOSE_WRITE));
232
+ rb_const_set(klass, rb_intern("CLOSE_WRITE"), INT2NUM(IN_CLOSE_WRITE));
233
+
234
+ rb_const_set(klass, rb_intern("IN_CLOSE_NOWRITE"), INT2NUM(IN_CLOSE_NOWRITE));
235
+ rb_const_set(klass, rb_intern("CLOSE_NOWRITE"), INT2NUM(IN_CLOSE_NOWRITE));
236
+
237
+ rb_const_set(klass, rb_intern("IN_OPEN"), INT2NUM(IN_OPEN));
238
+ rb_const_set(klass, rb_intern("OPEN"), INT2NUM(IN_OPEN));
239
+
240
+ rb_const_set(klass, rb_intern("IN_MOVED_FROM"), INT2NUM(IN_MOVED_FROM));
241
+ rb_const_set(klass, rb_intern("MOVED_FROM"), INT2NUM(IN_MOVED_FROM));
242
+
243
+ rb_const_set(klass, rb_intern("IN_MOVED_TO"), INT2NUM(IN_MOVED_TO));
244
+ rb_const_set(klass, rb_intern("MOVED_TO"), INT2NUM(IN_MOVED_TO));
245
+
246
+ rb_const_set(klass, rb_intern("IN_CREATE"), INT2NUM(IN_CREATE));
247
+ rb_const_set(klass, rb_intern("CREATE"), INT2NUM(IN_CREATE));
248
+
249
+ rb_const_set(klass, rb_intern("IN_DELETE"), INT2NUM(IN_DELETE));
250
+ rb_const_set(klass, rb_intern("DELETE"), INT2NUM(IN_DELETE));
251
+
252
+ rb_const_set(klass, rb_intern("IN_DELETE_SELF"), INT2NUM(IN_DELETE_SELF));
253
+ rb_const_set(klass, rb_intern("DELETE_SELF"), INT2NUM(IN_DELETE_SELF));
254
+
255
+ // sent by any watch
256
+ rb_const_set(klass, rb_intern("IN_UNMOUNT"), INT2NUM(IN_UNMOUNT));
257
+ rb_const_set(klass, rb_intern("UNMOUNT"), INT2NUM(IN_UNMOUNT));
258
+
259
+ rb_const_set(klass, rb_intern("IN_Q_OVERFLOW"), INT2NUM(IN_Q_OVERFLOW));
260
+ rb_const_set(klass, rb_intern("Q_OVERFLOW"), INT2NUM(IN_Q_OVERFLOW));
261
+
262
+ rb_const_set(klass, rb_intern("IN_IGNORED"), INT2NUM(IN_IGNORED));
263
+ rb_const_set(klass, rb_intern("IGNORED"), INT2NUM(IN_IGNORED));
264
+
265
+ // helper events
266
+ rb_const_set(klass, rb_intern("IN_CLOSE"), INT2NUM(IN_CLOSE));
267
+ rb_const_set(klass, rb_intern("CLOSE"), INT2NUM(IN_CLOSE));
268
+
269
+ rb_const_set(klass, rb_intern("IN_MOVE"), INT2NUM(IN_MOVE));
270
+ rb_const_set(klass, rb_intern("MOVE"), INT2NUM(IN_MOVE));
271
+
272
+ // special flags
273
+ rb_const_set(klass, rb_intern("IN_ISDIR"), INT2NUM(IN_ISDIR));
274
+ rb_const_set(klass, rb_intern("ISDIR"), INT2NUM(IN_ISDIR));
275
+
276
+ rb_const_set(klass, rb_intern("IN_ONESHOT"), INT2NUM(IN_ONESHOT));
277
+ rb_const_set(klass, rb_intern("ONESHOT"), INT2NUM(IN_ONESHOT));
278
+
279
+ rb_const_set(klass, rb_intern("IN_ALL_EVENTS"), INT2NUM(IN_ALL_EVENTS));
280
+ rb_const_set(klass, rb_intern("ALL_EVENTS"), INT2NUM(IN_ALL_EVENTS));
281
+ }
282
+
283
+
284
+ static void rinotify_declare_instance_vars(VALUE klass) {
285
+ // Array: holds a listing of all watch descriptors and the filename or directory name
286
+ // that they happen to be watching
287
+ VALUE watch_descriptors = rb_hash_new();
288
+ rb_iv_set(klass, "@watch_descriptors", watch_descriptors);
289
+ }
data/ext/rinotify.h ADDED
@@ -0,0 +1,163 @@
1
+ /*****************************************************
2
+ * copyright (C) 2007 by Rob Merrell
3
+ * rob@migrob.com
4
+ *
5
+ * ***************************************************/
6
+
7
+ #ifndef RINOTIFY_H
8
+ #define RINOTIFY_H
9
+
10
+ #include "ruby.h"
11
+ #include <sys/inotify.h>
12
+
13
+ #define CURRENT_VERSION "0.9"
14
+ #define EVENT_SIZE sizeof(struct inotify_event)
15
+ #define BUFFER_SIZE 16384
16
+
17
+ // RInotify class
18
+ static VALUE rb_cRInotify;
19
+
20
+ /* Non Ruby-implimented Prototypes */
21
+
22
+ // declare the inotify events as constants
23
+ static void rinotify_declare_events(VALUE);
24
+
25
+ // declare any instance variables we will need
26
+ static void rinotify_declare_instance_vars(VALUE);
27
+
28
+
29
+
30
+ /* Ruby Prototypes */
31
+
32
+ /*
33
+ * call-seq:
34
+ * RInotify.new -> RInotify
35
+ *
36
+ * Returns a new RInotify object.
37
+ *
38
+ * Example Usage:
39
+ * @rinotify = RInotify.new
40
+ */
41
+ static VALUE rb_rinotify_new(VALUE);
42
+
43
+
44
+ /*
45
+ * call-seq:
46
+ * RInotify.version -> String
47
+ *
48
+ * Returns the current version.
49
+ *
50
+ * Example Usage:
51
+ * @rinotify.version => "0.1.0"
52
+ */
53
+ static VALUE rb_rinotify_version(VALUE);
54
+
55
+
56
+ /*
57
+ * call-seq:
58
+ * RInotify.close -> nil
59
+ *
60
+ * Clean up and close inotify.
61
+ *
62
+ * Example Usage:
63
+ * @rinotify.close
64
+ */
65
+ static VALUE rb_rinotify_close(VALUE);
66
+
67
+
68
+ /*
69
+ * call-seq:
70
+ * RInotify.add_watch(filename, event masks) -> watch descriptor
71
+ *
72
+ * Adds a watch on a file or directory.
73
+ *
74
+ * The event masks are simple a bitmask and should be joined like:
75
+ * RInotify::OPEN | RInotify::MODIFY
76
+ *
77
+ * Example Usage:
78
+ * @rinotify = RInotify.new
79
+ * @rinotify.add_watch("/home/rob/Desktop/my_file.txt", RInotify::MODIFY | RInotify::DELETE_SELF | RInotify::OPEN)
80
+ */
81
+ static VALUE rb_rinotify_add_watch(VALUE, VALUE, VALUE);
82
+
83
+
84
+ /*
85
+ * call-seq:
86
+ * RInotify.rm_watch(watch descriptor) -> closed watch descriptor
87
+ *
88
+ * Remove a watch descriptor. Note that this is not a necessary step
89
+ * when closing inotify.
90
+ *
91
+ * Example Usage:
92
+ * @rinotify = RInotify.new
93
+ * wd = @rinotify.add_watch("/home/rob/Desktop/my_file.txt", RInotify::MODIFY | RInotify::DELETE_SELF | RInotify::OPEN)
94
+ * @rinotify.rm_watch(wd)
95
+ */
96
+ static VALUE rb_rinotify_rm_watch(VALUE, VALUE);
97
+
98
+
99
+ /*
100
+ * call-seq:
101
+ * RInotify.wait_for_events(seconds to time out) -> true or false
102
+ *
103
+ * Waits for events to be received from inotify.
104
+ * Returns true when there are events waiting in the queue
105
+ * and false if not.
106
+ *
107
+ * Example Usage:
108
+ * @rinotify = RInotify.new
109
+ * @rinotify.add_watch("/home/rob/Desktop/my_file.txt", RInotify::MODIFY | RInotify::DELETE_SELF | RInotify::OPEN)
110
+ *
111
+ * # set time out at 5 seconds
112
+ * has_events = @rinotify.wait_for_events(5)
113
+ */
114
+ static VALUE rb_rinotify_wait_for_events(VALUE, VALUE);
115
+
116
+
117
+ /*
118
+ * call-seq:
119
+ * RInotify.each_event -> RInotifyEvent
120
+ *
121
+ * Yields an RInotifyEvent object in a block
122
+ *
123
+ * Example Usage:
124
+ * has_events = @rinotify.wait_for_events(5)
125
+ * if has_events
126
+ * @rinotify.each_event {|revent|
127
+ * ...
128
+ * }
129
+ * end
130
+ */
131
+ static VALUE rb_rinotify_each_event(VALUE);
132
+
133
+
134
+ /*
135
+ * call-seq:
136
+ * RInotify.watch_descriptors -> Hash(watch descriptor, file name)
137
+ *
138
+ * Returns a hash of all watch_descriptors and file name of each file or directory
139
+ * being watched.
140
+ *
141
+ * Example Usage:
142
+ * @rinotify.watch_descriptors => [1, "/home/rob/Desktop/my_file.txt"]
143
+ */
144
+ static VALUE rb_rinotify_watch_descriptors(VALUE);
145
+
146
+
147
+ /*
148
+ * call-seq:
149
+ * RInotify.event_queue_size -> Fixnum
150
+ *
151
+ * Returns the current size of the event queue. This is useful if you want to throttle
152
+ * your event checks
153
+ *
154
+ * Example Usage:
155
+ * while (queue_size < 128)
156
+ * if @rinotify.wait_for_events(5)
157
+ * queue_size = @rinotify.event_queue_size
158
+ * end
159
+ * end
160
+ */
161
+ static VALUE rb_rinotify_queue_size(VALUE);
162
+
163
+ #endif
@@ -0,0 +1,55 @@
1
+ #include "ruby.h"
2
+ #include "rinotify_event.h"
3
+
4
+ #include <sys/inotify.h>
5
+
6
+ VALUE rb_rinotify_event_new(struct inotify_event *event) {
7
+ VALUE rinotify_event;
8
+
9
+ // initialize the object
10
+ rinotify_event = Data_Wrap_Struct(rb_cRInotifyEvent, NULL, free, event);
11
+ rb_obj_call_init(rinotify_event, 0, NULL);
12
+
13
+ return rinotify_event;
14
+ }
15
+
16
+
17
+ VALUE rb_rinotify_event_name(VALUE self) {
18
+ VALUE name;
19
+ struct inotify_event *event;
20
+ Data_Get_Struct(self, struct inotify_event, event);
21
+
22
+ // if watching for events in a directory inotify will tell us the name
23
+ if (event->len) {
24
+ name = rb_str_new2(event->name);
25
+ } else {
26
+ // watching a single file doesn't waste space with a filename so return nil
27
+ name = Qnil;
28
+ }
29
+
30
+ return name;
31
+ }
32
+
33
+
34
+ VALUE rb_rinotify_event_watch_descriptor(VALUE self) {
35
+ struct inotify_event *event;
36
+ Data_Get_Struct(self, struct inotify_event, event);
37
+
38
+ return INT2NUM(event->wd);
39
+ }
40
+
41
+
42
+ VALUE rb_rinotify_event_check_mask(VALUE self, VALUE masks) {
43
+ VALUE return_val;
44
+ struct inotify_event *event;
45
+ Data_Get_Struct(self, struct inotify_event, event);
46
+
47
+ // check if the mask is part of the event
48
+ if (event->mask & NUM2INT(masks))
49
+ return_val = Qtrue;
50
+ else
51
+ return_val = Qfalse;
52
+
53
+ return return_val;
54
+ }
55
+
@@ -0,0 +1,60 @@
1
+ /*****************************************************
2
+ * copyright (C) 2007 by Rob Merrell
3
+ * rob@migrob.com
4
+ *
5
+ * ***************************************************/
6
+
7
+ #ifndef RINOTIFY_EVENT_H
8
+ #define RINOTIFY_EVENT_H
9
+
10
+ #include "ruby.h"
11
+ #include <sys/inotify.h>
12
+
13
+ // RInotifyEvent class
14
+ VALUE rb_cRInotifyEvent;
15
+
16
+ /* Ruby Prototypes */
17
+
18
+ // returns a new RInotifyEvent object. This method should only be called by RInotify.each_event
19
+ VALUE rb_rinotify_event_new(struct inotify_event*);
20
+
21
+
22
+ /*
23
+ * call-seq:
24
+ * RInotifyEvent.name -> event name
25
+ *
26
+ * Returns the name of the event if the watched file is a directory. If it is a file
27
+ * nil is returned. In this case the event name can be found by looking the watch descriptor
28
+ * up using RInotify.watch_descriptors.
29
+ *
30
+ * Example Usage:
31
+ * rinotify_event.name -> "/home/rob/desktop/tmp/test"
32
+ */
33
+ VALUE rb_rinotify_event_name(VALUE);
34
+
35
+
36
+ /*
37
+ * call-seq:
38
+ * RInotifyEvent.watch_descriptor -> event watch descriptor
39
+ *
40
+ * Returns the watch descriptor that the event belongs to.
41
+ *
42
+ * Example Usage:
43
+ * rinotify_event.watch_descriptor -> 1
44
+ */
45
+ VALUE rb_rinotify_event_watch_descriptor(VALUE);
46
+
47
+
48
+ /*
49
+ * call-seq:
50
+ * RInotifyEvent.check_mask(mask) -> boolean
51
+ *
52
+ * Returns true or false if the current event contains the mask(s)
53
+ *
54
+ * Example Usage:
55
+ * rinotify_event->check_mask(RInotify::MODIFY) -> true
56
+ * rinotify_event->check_mask(RInotify::DELETE_SELF) -> false
57
+ */
58
+ VALUE rb_rinotify_event_check_mask(VALUE, VALUE);
59
+
60
+ #endif
data/extconf.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile('rinotify', 'ext')
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: RInotify
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.9"
7
+ date: 2007-04-17 00:00:00 -06:00
8
+ summary: A Ruby wrapper for Linux's inotify
9
+ require_paths:
10
+ - .
11
+ email: rob@migrob.com
12
+ homepage: http://rinotify.migrob.com
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: RInotify
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: i586-linux
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Rob Merrell
31
+ files:
32
+ - ext/rinotify_event.c
33
+ - ext/rinotify.c
34
+ - ext/rinotify_event.h
35
+ - ext/rinotify.h
36
+ test_files: []
37
+
38
+ rdoc_options: []
39
+
40
+ extra_rdoc_files: []
41
+
42
+ executables: []
43
+
44
+ extensions:
45
+ - extconf.rb
46
+ requirements: []
47
+
48
+ dependencies: []
49
+