msieve 0.1.0-x86-mingw32

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.
@@ -0,0 +1,94 @@
1
+ msieve Ruby gem
2
+ ===============
3
+
4
+ This gem (library) provides Ruby bindings for the msieve library, "A Library for Factoring Large Integers" by Jason Papadopoulos.
5
+
6
+ Usage
7
+ -----
8
+
9
+ It's entirely simple right now, and there is probably a lot to be desired. In any case, use it as follows:
10
+
11
+ <pre><code>$irb -r lib/msieve --simple-prompt
12
+ >> m = Msieve.new("1234567890")
13
+ => #&lt;Msieve:0x14418e0&gt;
14
+ >> m.factor!
15
+ => [2, 3, 3, 5, 3607, 3803]
16
+ >> n = Msieve.new("235711131719")
17
+ => #&lt;Msieve:0x14f28c0&gt;
18
+ >> n.factor!
19
+ => [7, 4363, 7717859]
20
+ >> p = Msieve.new("149162536496481")
21
+ => #&lt;Msieve:0x15b3140&gt;
22
+ >> p.factor!
23
+ => [3, 7549, 48437, 135979]</code></pre>
24
+
25
+ You can also include elementary functions as listed in msieve's readme. I quote:
26
+
27
+ > Starting with v1.08, the inputs to msieve can be integer arithmetic
28
+ > expressions using any of the following operators:
29
+ >
30
+ > * \+ - plus, minus (lowest priority)
31
+ > * % integer remainder
32
+ > * \* / multiply, integer divide
33
+ > * ^ power
34
+ > * ( ) grouping (highest priority)
35
+
36
+ Examples:
37
+
38
+ <pre><code>$irb -r lib\msieve --simple-prompt
39
+ >> m = Msieve.new("(10^17-1)/9")
40
+ => #&lt;Msieve:0x13ea4a0&gt;
41
+ >> m.factor!
42
+ => [2071723, 5363222357]
43
+ >> m = Msieve.new("(10^19-1)/9")
44
+ => #&lt;Msieve:0x1467b80&gt;
45
+ >> m.factor!
46
+ => [1111111111111111111]</code></pre>
47
+
48
+ Caveat
49
+ ------
50
+
51
+ msieve has two headers that have the line
52
+
53
+ <pre><code>#include &lt;util.h&gt;</code></pre>
54
+
55
+ This is no good here, because mkmf always puts Ruby's include paths before the
56
+ ones you request. So it ends up including ruby/util.h. No good! I had to hack
57
+ my copy of msieve, the msieve.h and mp.h files, to change that line to
58
+
59
+ <pre><code>#include "util.h"</code></pre>
60
+
61
+ and boom! Everything works. No word on how to... autotically do this in the
62
+ gem? I am wholly against toying with the global vars that mkmf sets up, in
63
+ order to reorganize the include paths. Don't even suggest that. Yuck.
64
+
65
+
66
+ Bugs
67
+ ----
68
+
69
+ It has some bugs:
70
+
71
+ <pre><code>$irb -r lib\msieve --simple-prompt
72
+
73
+ >> m = Msieve.new(99999999)
74
+ => #&lt;Msieve:0x14e26c0&gt;
75
+ >> m.input
76
+ => "99999999"
77
+ >> m.factor!
78
+ => [3, 3, 11, 73, 101, 137]
79
+ >> m.factor!
80
+ => [3, 3, 11, 73, 101, 137, 3, 3, 11, 73, 101, 137]</code></pre>
81
+
82
+ Todo
83
+ ----
84
+
85
+ * Fix weird crashing bug that occurs sporadically
86
+ * Get all options working that msieve_obj_new() accepts
87
+ * Internal logging???
88
+ * Stop, Restart
89
+ * Integrate with Ruby gmp gem if available (passing in GMP::Z, factors coming
90
+ out as GMP::Z, adding a GMP::Z.factor! method
91
+ * Make Ruby bindings for GMP-ECM, then integrate those, haha.
92
+ * Oh, verify that anything works on !windows.
93
+ * Documentation
94
+ * CHANGELOG, gemify, etc.
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'mkmf'
4
+
5
+ dir_config('gmp')
6
+ dir_config('msieve')
7
+
8
+ ok = true
9
+ unless have_header('gmp.h')
10
+ $stderr.puts "can't find gmp.h, try --with-gmp-include=<path>"
11
+ ok = false
12
+ end
13
+
14
+ unless have_library('gmp', '__gmpz_init')
15
+ $stderr.puts "can't find -lgmp, try --with-gmp-lib=<path>"
16
+ ok = false
17
+ end
18
+
19
+ unless have_library('msieve', 'msieve_obj_new')
20
+ $stderr.puts "can't find -lmsieve, try --with-msieve-lib=<path>"
21
+ ok = false
22
+ end
23
+
24
+ unless have_header('msieve.h')
25
+ $stderr.puts "can't find msieve.h, try --with-msieve-include=<path>"
26
+ ok = false
27
+ end
28
+
29
+ $CFLAGS += ' -Wall -W -O6 -g'
30
+ if ok
31
+ create_makefile('msieve')
32
+ else
33
+ raise "Unable to build, correct above errors and rerun"
34
+ end
Binary file
Binary file
@@ -0,0 +1,327 @@
1
+ #include <msieve.h>
2
+ #include <ruby.h>
3
+
4
+ #if !defined(RSTRING_LEN)
5
+ # define RSTRING_LEN(x) (RSTRING(x)->len)
6
+ # define RSTRING_PTR(x) (RSTRING(x)->ptr)
7
+ #endif
8
+
9
+ #define msieve_get_struct(ruby_var,c_var) { Data_Get_Struct(ruby_var, msieve_obj, c_var); }
10
+ #define msieve_make_struct(ruby_var,c_var) { ruby_var = Data_Make_Struct(cMsieve, msieve_obj, 0, 0, c_var); }
11
+ #define BIGNUM_P(value) (TYPE(value) == T_BIGNUM)
12
+ #define HASH_P(value) (TYPE(value) == T_HASH)
13
+ #define NUMERIC_P(value) (FIXNUM_P(value) || BIGNUM_P(value))
14
+ #define STRING_P(value) (TYPE(value) == T_STRING)
15
+ #define MSIEVE_P(value) (rb_obj_is_instance_of(value, cMsieve) == Qtrue)
16
+ #define rb_symbol(value) (rb_funcall(rb_str_new2(value), rb_intern("to_sym"), 0))
17
+
18
+ #define DEFUN_0ARG_UINT32(fname) \
19
+ static VALUE r_msieve_##fname(VALUE self) \
20
+ { \
21
+ msieve_obj *self_val; \
22
+ msieve_get_struct (self, self_val); \
23
+ \
24
+ uint32 attr_val = self_val->fname; \
25
+ return INT2FIX(attr_val); \
26
+ }
27
+
28
+ #define DEFUN_0ARG_UINT64(fname) \
29
+ static VALUE r_msieve_##fname(VALUE self) \
30
+ { \
31
+ msieve_obj *self_val; \
32
+ msieve_get_struct (self, self_val); \
33
+ \
34
+ uint64 attr_val = self_val->fname; \
35
+ return INT2FIX(attr_val); \
36
+ }
37
+
38
+ #define DEFUN_0ARG_CHARSTAR(fname) \
39
+ static VALUE r_msieve_##fname(VALUE self) \
40
+ { \
41
+ msieve_obj *self_val; \
42
+ msieve_get_struct (self, self_val); \
43
+ \
44
+ char *attr_val = self_val->fname; \
45
+ return rb_str_new2(attr_val); \
46
+ }
47
+
48
+ VALUE cMsieve;
49
+ VALUE cMsieve_Factor;
50
+
51
+ void msieve_set_factors(VALUE obj);
52
+
53
+ /*
54
+ * Swiped from msieve's demo for now. Will push to Ruby (and maybe GMP) later.
55
+ */
56
+ void get_random_seeds(uint32 *seed1, uint32 *seed2) {
57
+
58
+ uint32 tmp_seed1, tmp_seed2;
59
+
60
+ /* In a multithreaded program, every msieve object
61
+ should have two unique, non-correlated seeds
62
+ chosen for it */
63
+
64
+ #if !defined(WIN32) && !defined(_WIN64)
65
+
66
+ FILE *rand_device = fopen("/dev/urandom", "r");
67
+
68
+ if (rand_device != NULL) {
69
+
70
+ /* Yay! Cryptographic-quality nondeterministic randomness! */
71
+
72
+ fread(&tmp_seed1, sizeof(uint32), (size_t)1, rand_device);
73
+ fread(&tmp_seed2, sizeof(uint32), (size_t)1, rand_device);
74
+ fclose(rand_device);
75
+ }
76
+ else
77
+
78
+ #endif
79
+ {
80
+ /* <Shrug> For everyone else, sample the current time,
81
+ the high-res timer (hopefully not correlated to the
82
+ current time), and the process ID. Multithreaded
83
+ applications should fold in the thread ID too */
84
+
85
+ uint64 high_res_time = read_clock();
86
+ tmp_seed1 = ((uint32)(high_res_time >> 32) ^
87
+ (uint32)time(NULL)) *
88
+ (uint32)getpid();
89
+ tmp_seed2 = (uint32)high_res_time;
90
+ }
91
+
92
+ /* The final seeds are the result of a multiplicative
93
+ hash of the initial seeds */
94
+
95
+ (*seed1) = tmp_seed1 * ((uint32)40499 * 65543);
96
+ (*seed2) = tmp_seed2 * ((uint32)40499 * 65543);
97
+ }
98
+
99
+ void msieve_free(void *p) {
100
+ msieve_obj_free(p);
101
+ }
102
+
103
+ VALUE msieve_alloc(VALUE klass) {
104
+ msieve_obj *msieve_val;
105
+ VALUE obj;
106
+
107
+ char *integer_val = "0";
108
+ uint32 default_flags = MSIEVE_FLAG_USE_LOGFILE;
109
+ char *savefile_name = NULL;
110
+ char *logfile_name = NULL;
111
+ char *nfs_fbfile_name = NULL;
112
+ uint32 seed1, seed2;
113
+ get_random_seeds(&seed1, &seed2);
114
+ uint32 max_relations = 0;
115
+ uint64 nfs_lower = 0;
116
+ uint64 nfs_upper = 0;
117
+ enum cpu_type cpu = get_cpu_type();
118
+ uint32 cache_size1;
119
+ uint32 cache_size2;
120
+ get_cache_sizes(&cache_size1, &cache_size2);
121
+ uint32 num_threads = 0;
122
+ uint32 mem_mb = 0;
123
+ uint32 which_gpu = 0;
124
+
125
+ msieve_val = msieve_obj_new(integer_val, default_flags,
126
+ savefile_name, logfile_name, nfs_fbfile_name,
127
+ seed1, seed2, max_relations,
128
+ nfs_lower, nfs_upper, cpu,
129
+ cache_size1, cache_size2,
130
+ num_threads, mem_mb, which_gpu);
131
+ obj = Data_Wrap_Struct(klass, 0, msieve_free, msieve_val);
132
+ return obj;
133
+ }
134
+
135
+ // /*
136
+ // * call-seq:
137
+ // * Msieve.new(hash)
138
+ // *
139
+ // * Creates a new Msieve object (state), with certain arguments and variables
140
+ // * set with <i>hash</i>.
141
+ // */
142
+ // VALUE r_msievesg_new(int argc, VALUE *argv, VALUE klass)
143
+ // {
144
+ // msieve_obj *res_val;
145
+ // VALUE res;
146
+ // (void)klass;
147
+
148
+ // if (argc > 2)
149
+ // rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1, or 2)", argc);
150
+
151
+ // msieve_make_struct (res, res_val);
152
+ // rb_obj_call_init (res, argc, argv);
153
+
154
+ // return res;
155
+ // }
156
+
157
+ VALUE r_msieve_initialize(int argc, VALUE *argv, VALUE self)
158
+ {
159
+ msieve_obj *self_val;
160
+ VALUE integer, hash, hash_value, str;
161
+ char *integer_val;
162
+
163
+ msieve_get_struct (self, self_val);
164
+ rb_scan_args (argc, argv, "11", &integer, &hash);
165
+ if (NUMERIC_P(integer)) {
166
+ VALUE integer_s = rb_funcall (integer, rb_intern("to_s"), 0);
167
+ str = StringValue (integer_s);
168
+ }
169
+ else if (STRING_P(integer)) {
170
+ str = StringValue (integer);
171
+ }
172
+ else {
173
+ rb_raise (rb_eArgError, "integer must be Numeric or String");
174
+ }
175
+ integer_val = RSTRING_PTR(str);
176
+ self_val->input = integer_val;
177
+
178
+ if (NIL_P(hash)) { hash = rb_hash_new (); }
179
+ if (! HASH_P(hash)) {
180
+ rb_raise (rb_eArgError, "options must be a Hash");
181
+ }
182
+
183
+ hash_value = rb_hash_aref(hash, rb_symbol("quiet"));
184
+ if (hash_value != Qnil) {
185
+ self_val->flags &= ~(MSIEVE_FLAG_USE_LOGFILE | MSIEVE_FLAG_LOG_TO_STDOUT);
186
+ }
187
+
188
+ hash_value = rb_hash_aref(hash, rb_symbol("max_relations"));
189
+ if (hash_value != Qnil) {
190
+ self_val->max_relations = FIX2INT(hash_value);
191
+ }
192
+
193
+ hash_value = rb_hash_aref(hash, rb_symbol("num_threads"));
194
+ if (hash_value != Qnil) {
195
+ self_val->num_threads = FIX2INT(hash_value);
196
+ }
197
+
198
+ hash_value = rb_hash_aref(hash, rb_symbol("mem_mb"));
199
+ if (hash_value != Qnil) {
200
+ self_val->mem_mb = FIX2INT(hash_value);
201
+ }
202
+
203
+ return Qnil;
204
+ }
205
+
206
+ VALUE r_msieve_factor_bang(VALUE self)
207
+ {
208
+ msieve_obj *self_val;
209
+ msieve_get_struct (self, self_val);
210
+
211
+ msieve_run(self_val);
212
+
213
+ if (!(self_val->flags & MSIEVE_FLAG_FACTORIZATION_DONE)) {
214
+ rb_raise (rb_eRuntimeError, "current factorization was interrupted");
215
+ }
216
+
217
+ msieve_set_factors(self);
218
+
219
+ return rb_iv_get (self, "@factors");
220
+ }
221
+
222
+ void msieve_set_factors(VALUE obj) {
223
+ msieve_obj *obj_val;
224
+ msieve_get_struct (obj, obj_val);
225
+ VALUE factors_array = rb_ary_new ();
226
+
227
+ //rb_iv_set (obj, "@factors", rb_ary_new);
228
+
229
+ msieve_factor *factor = obj_val->factors;
230
+ while (factor != NULL) {
231
+ VALUE factor_type;
232
+
233
+ if (factor->factor_type == MSIEVE_PRIME)
234
+ factor_type = rb_symbol("prime");
235
+ else if (factor->factor_type == MSIEVE_COMPOSITE)
236
+ factor_type = rb_symbol("composite");
237
+ else
238
+ factor_type = rb_symbol("probably_prime");
239
+
240
+ VALUE factor_obj = rb_funcall (cMsieve_Factor,
241
+ rb_intern("new"),
242
+ 3,
243
+ factor_type,
244
+ rb_str_new2(factor->number),
245
+ INT2FIX((int32)strlen(factor->number)));
246
+ rb_ary_push(factors_array, factor_obj);
247
+
248
+ factor = factor->next;
249
+ }
250
+ rb_iv_set (obj, "@factors", factors_array);
251
+ }
252
+
253
+ VALUE r_msieve_seed1(VALUE self)
254
+ {
255
+ msieve_obj *self_val;
256
+ msieve_get_struct (self, self_val);
257
+
258
+ long seed1_val = self_val->seed1;
259
+ VALUE seed1 = LONG2FIX(seed1_val);
260
+
261
+ return seed1;
262
+ }
263
+
264
+ DEFUN_0ARG_CHARSTAR(input)
265
+ DEFUN_0ARG_UINT32(seed2)
266
+ DEFUN_0ARG_UINT32(max_relations)
267
+ DEFUN_0ARG_UINT64(nfs_lower)
268
+ DEFUN_0ARG_UINT64(nfs_upper)
269
+ DEFUN_0ARG_UINT32(cache_size1)
270
+ DEFUN_0ARG_UINT32(cache_size2)
271
+ DEFUN_0ARG_UINT32(num_threads)
272
+ DEFUN_0ARG_UINT32(mem_mb)
273
+
274
+ VALUE r_msieve_factor_initialize(int argc, VALUE *argv, VALUE self) {
275
+ VALUE factor_type, number, digits;
276
+
277
+ rb_scan_args (argc, argv, "3", &factor_type, &number, &digits);
278
+ rb_iv_set (self, "@factor_type", factor_type);
279
+ rb_iv_set (self, "@number", number);
280
+ rb_iv_set (self, "@digits", digits);
281
+
282
+ return Qnil;
283
+ }
284
+
285
+ VALUE r_msieve_factor_inspect(VALUE self) {
286
+ return rb_iv_get (self, "@number");
287
+ }
288
+
289
+ VALUE r_msieve_factor_to_i(VALUE self) {
290
+ return rb_funcall(rb_iv_get (self, "@number"), rb_intern("to_i"), 0);
291
+ }
292
+
293
+ VALUE r_msieve_factor_to_s(VALUE self) {
294
+ return rb_iv_get (self, "@number");
295
+ }
296
+
297
+ void Init_msieve() {
298
+ cMsieve = rb_define_class ("Msieve", rb_cObject);
299
+ char msieve_version_string[5];
300
+ sprintf (msieve_version_string, "%d.%02d", MSIEVE_MAJOR_VERSION, MSIEVE_MINOR_VERSION);
301
+ rb_define_const (cMsieve, "MSIEVE_VERSION", rb_str_new2 (msieve_version_string));
302
+ rb_define_const (cMsieve, "VERSION", rb_str_new2 ("0.1.0"));
303
+
304
+ rb_define_alloc_func (cMsieve, msieve_alloc);
305
+ rb_define_method (cMsieve, "initialize", r_msieve_initialize, -1);
306
+ rb_define_method (cMsieve, "factor!", r_msieve_factor_bang, 0);
307
+ rb_define_method (cMsieve, "input", r_msieve_input, 0);
308
+ rb_define_method (cMsieve, "seed1", r_msieve_seed1, 0);
309
+ rb_define_method (cMsieve, "seed2", r_msieve_seed2, 0);
310
+ rb_define_method (cMsieve, "max_relations", r_msieve_max_relations, 0);
311
+ rb_define_method (cMsieve, "nfs_lower", r_msieve_nfs_lower, 0);
312
+ rb_define_method (cMsieve, "nfs_upper", r_msieve_nfs_upper, 0);
313
+ rb_define_method (cMsieve, "cache_size1", r_msieve_cache_size1, 0);
314
+ rb_define_method (cMsieve, "cache_size2", r_msieve_cache_size2, 0);
315
+ rb_define_method (cMsieve, "num_threads", r_msieve_num_threads, 0);
316
+ rb_define_method (cMsieve, "mem_mb", r_msieve_mem_mb, 0);
317
+ rb_define_attr (cMsieve, "factors", 1, 0);
318
+
319
+ cMsieve_Factor = rb_define_class_under (cMsieve, "Factor", rb_cObject);
320
+ rb_define_method (cMsieve_Factor, "initialize", r_msieve_factor_initialize, -1);
321
+ rb_define_method (cMsieve_Factor, "inspect", r_msieve_factor_inspect, 0);
322
+ rb_define_method (cMsieve_Factor, "to_i", r_msieve_factor_to_i, 0);
323
+ rb_define_method (cMsieve_Factor, "to_s", r_msieve_factor_to_s, 0);
324
+ rb_define_attr (cMsieve_Factor, "factor_type", 1, 0);
325
+ rb_define_attr (cMsieve_Factor, "number", 1, 0);
326
+ rb_define_attr (cMsieve_Factor, "digits", 1, 0);
327
+ }
Binary file
@@ -0,0 +1,18 @@
1
+ # Thank you, Nokogiri
2
+
3
+ require 'rbconfig'
4
+
5
+ ENV['PATH'] = [File.expand_path(
6
+ File.join(File.dirname(__FILE__), "..", "ext")
7
+ ), ENV['PATH']].compact.join(';') if RbConfig::CONFIG['host_os'] =~ /(mswin|mingw|mingw32)/i
8
+
9
+ require File.dirname(__FILE__) + '/../ext/msieve'
10
+
11
+ class Msieve
12
+ def self.clear_log(log_name = "msieve.log")
13
+ if File.exist? log_name
14
+ File.delete log_name
15
+ end
16
+ puts "Cleared! (but not really)."
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ class TC_Initiate < Test::Unit::TestCase
4
+ def setup
5
+ @sample_fixnums = [ 1, 2, 3, 4, 5, 8, 9, 15, 16, 17, 31, 32, 33,
6
+ 2**10-1, 2**10, 2*3*4*5*6*7, 10**6, 2**20]
7
+ @sample_strings = [ "1", "2", "3", "4", "5", "8", "9", "15",
8
+ "16", "17", "31", "32", "33", "2**10-1",
9
+ "2**10", "2*3*4*5*6*7", "10**6", "2**20"]
10
+ end
11
+
12
+ def test_initiate
13
+ (@sample_fixnums + @sample_strings).each do |i|
14
+ m = Msieve.new(i)
15
+ assert_equal(i.to_s, m.input, "Msieve.new(#{i.inspect}) should initiate ok.")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ require 'test_helper'
2
+
3
+ class TC_Version < Test::Unit::TestCase
4
+ def setup
5
+
6
+ end
7
+
8
+ def test_version
9
+ assert_equal("0.1.0", Msieve::VERSION, "msieve gem version should be correct")
10
+ assert_equal("1.44", Msieve::MSIEVE_VERSION, "msieve version should be correct")
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ require 'rbconfig'
3
+
4
+ ENV['PATH'] = [File.expand_path(
5
+ File.join(File.dirname(__FILE__), "..", "ext")
6
+ ), ENV['PATH']].compact.join(';') if RbConfig::CONFIG['host_os'] =~ /(mswin|mingw|mingw32)/i
7
+
8
+ require File.dirname(__FILE__) + '/../ext/msieve'
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test_helper'
4
+
5
+ require 'tc_version'
6
+ require 'tc_initiate'
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: msieve
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: x86-mingw32
6
+ authors:
7
+ - Sam Rawlins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-05-04 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: msieve - providing Ruby bindings to the msieve library.
17
+ email:
18
+ - sam.rawlins@gmail.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - ext/msieve.c
27
+ - ext/extconf.rb
28
+ - lib/msieve.rb
29
+ - ext/libgmp-10.dll
30
+ - ext/libmsieve.a
31
+ - ext/msieve.so
32
+ - test/tc_initiate.rb
33
+ - test/tc_version.rb
34
+ - test/test_helper.rb
35
+ - test/unit_tests.rb
36
+ - README.markdown
37
+ has_rdoc: true
38
+ homepage: http://github.com/srawlins/msieve
39
+ licenses: []
40
+
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.8.6
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements:
59
+ - msieve compiled and working properly.
60
+ rubyforge_project:
61
+ rubygems_version: 1.3.5
62
+ signing_key:
63
+ specification_version: 3
64
+ summary: Provides Ruby bindings to the msieve library.
65
+ test_files: []
66
+