ruby-filemagic 0.6.2-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,99 @@
1
+ require 'filemagic'
2
+
3
+ module FileMagic::Ext
4
+
5
+ def self.included(base)
6
+ base.class_eval {
7
+ extend ClassMethods
8
+ include InstanceMethods
9
+ }
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ def file_type(file, *flags)
15
+ raise NotImplementedError, 'must be implemented by including class'
16
+ end
17
+
18
+ def file(file, *flags)
19
+ file_type(file, *flags)
20
+ end
21
+
22
+ def mime_type(file, *flags)
23
+ file_type(file, *flags.unshift(:mime))
24
+ end
25
+
26
+ alias_method :mime, :mime_type
27
+
28
+ def content_type(file, *flags)
29
+ mime_type(file, *flags << { simplified: true })
30
+ end
31
+
32
+ end
33
+
34
+ module InstanceMethods
35
+
36
+ def file_type(*flags)
37
+ self.class.file_type(self, *flags)
38
+ end
39
+
40
+ alias_method :file, :file_type
41
+
42
+ def mime_type(*flags)
43
+ self.class.mime_type(self, *flags)
44
+ end
45
+
46
+ alias_method :mime, :mime_type
47
+
48
+ def content_type(*flags)
49
+ self.class.content_type(self, *flags)
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
56
+ class File
57
+
58
+ include FileMagic::Ext
59
+
60
+ def self.file_type(file, *flags)
61
+ FileMagic.fm(*flags).file(file.respond_to?(:path) ? file.path : file)
62
+ rescue FileMagic::FileMagicError
63
+ end
64
+
65
+ end
66
+
67
+ class String
68
+
69
+ include FileMagic::Ext
70
+
71
+ def self.file_type(string, *flags)
72
+ FileMagic.fm(*flags).buffer(string)
73
+ rescue FileMagic::FileMagicError
74
+ end
75
+
76
+ end
77
+
78
+ if $0 == __FILE__
79
+ f = __FILE__
80
+ p f
81
+
82
+ p File.file_type(f)
83
+ p File.mime_type(f)
84
+ p File.content_type(f)
85
+
86
+ f = File.new(f)
87
+ p f
88
+
89
+ p f.file_type
90
+ p f.mime_type
91
+ p f.content_type
92
+
93
+ s = '#! /usr/bin/ruby'
94
+ p s
95
+
96
+ p s.file_type
97
+ p s.mime_type
98
+ p s.content_type
99
+ end
Binary file
@@ -0,0 +1,27 @@
1
+ class FileMagic
2
+
3
+ module Version
4
+
5
+ MAJOR = 0
6
+ MINOR = 6
7
+ TINY = 2
8
+
9
+ class << self
10
+
11
+ # Returns array representation.
12
+ def to_a
13
+ [MAJOR, MINOR, TINY]
14
+ end
15
+
16
+ # Short-cut for version string.
17
+ def to_s
18
+ to_a.join('.')
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+
25
+ VERSION = Version.to_s
26
+
27
+ end
data/lib/filemagic.rb ADDED
@@ -0,0 +1,142 @@
1
+ begin
2
+ require "filemagic/#{RUBY_VERSION[/\d+.\d+/]}/ruby_filemagic"
3
+ rescue LoadError => err
4
+ raise if err.respond_to?(:path) && !err.path
5
+ require 'filemagic/ruby_filemagic'
6
+ end
7
+
8
+ require 'filemagic/version'
9
+
10
+ class FileMagic
11
+
12
+ DEFAULT_MAGIC = __FILE__.sub(/\.rb\z/, '/magic.mgc')
13
+
14
+ ENV['MAGIC'] ||= DEFAULT_MAGIC unless path
15
+
16
+ # Map flag names to their values (:name => Integer).
17
+ FLAGS_BY_SYM = [
18
+ :none, # No flags
19
+ :debug, # Turn on debugging
20
+ :symlink, # Follow symlinks
21
+ :compress, # Check inside compressed files
22
+ :devices, # Look at the contents of devices
23
+ :mime_type, # Return only the MIME type
24
+ :continue, # Return all matches
25
+ :check, # Print warnings to stderr
26
+ :preserve_atime, # Restore access time on exit
27
+ :raw, # Don't translate unprint chars
28
+ :error, # Handle ENOENT etc as real errors
29
+ :mime_encoding, # Return only the MIME encoding
30
+ :mime, # MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING
31
+ :apple, # Return the Apple creator and type
32
+ :no_check_compress, # Don't check for compressed files
33
+ :no_check_tar, # Don't check for tar files
34
+ :no_check_soft, # Don't check magic entries
35
+ :no_check_apptype, # Don't check application type
36
+ :no_check_elf, # Don't check for elf details
37
+ :no_check_text, # Don't check for text files
38
+ :no_check_cdf, # Don't check for cdf files
39
+ :no_check_tokens, # Don't check ascii/tokens
40
+ :no_check_encoding, # Don't check text encodings
41
+ :no_check_builtin, # No built-in tests; only consult the magic file
42
+
43
+ # Defined for backwards compatibility (renamed)
44
+ :no_check_ascii, # MAGIC_NO_CHECK_TEXT
45
+
46
+ # Defined for backwards compatibility; do nothing
47
+ :no_check_fortran, # Don't check ascii/fortran
48
+ :no_check_troff # Don't check ascii/troff
49
+ ].inject({}) { |flags, flag|
50
+ const = "MAGIC_#{flag.to_s.upcase}"
51
+ flags.update(flag => const_defined?(const) && const_get(const))
52
+ }
53
+
54
+ # Map flag values to their names (Integer => :name).
55
+ FLAGS_BY_INT = FLAGS_BY_SYM.invert.update(0 => :none)
56
+
57
+ # Extract "simple" MIME type.
58
+ SIMPLE_RE = %r{([.\w\/-]+)}
59
+
60
+ @fm = {}
61
+
62
+ class << self
63
+
64
+ # Provide a "magic singleton".
65
+ def fm(*flags)
66
+ options = flags.last.is_a?(Hash) ? flags.pop : {}
67
+
68
+ if fm = @fm[key = [flags = flags(flags), options]]
69
+ return fm unless fm.closed?
70
+ end
71
+
72
+ @fm[key] = new(flags, options)
73
+ end
74
+
75
+ # Clear our instance cache.
76
+ def clear!
77
+ @fm.each_value(&:close).clear
78
+ end
79
+
80
+ # Just like #new, but takes an optional block, in which case #close
81
+ # is called at the end and the value of the block is returned.
82
+ def open(*flags)
83
+ fm = new(*flags)
84
+
85
+ if block_given?
86
+ begin
87
+ yield fm
88
+ ensure
89
+ fm.close
90
+ end
91
+ else
92
+ fm
93
+ end
94
+ end
95
+
96
+ # Just a short-cut to #open with the +mime+ flag set.
97
+ def mime(*flags, &block)
98
+ open(:mime, *flags, &block)
99
+ end
100
+
101
+ def magic_version(default = MAGIC_VERSION)
102
+ default != '0' ? default :
103
+ user_magic_version ||
104
+ auto_magic_version ||
105
+ [default, 'unknown']
106
+ end
107
+
108
+ private
109
+
110
+ def user_magic_version(key = 'MAGIC_VERSION')
111
+ [ENV[key], 'user-specified'] if ENV[key]
112
+ end
113
+
114
+ def auto_magic_version
115
+ require 'nuggets/file/which'
116
+
117
+ if cmd = File.which_command([
118
+ 'dpkg-query -f \'${Version}\' -W libmagic-dev',
119
+ 'file -v'
120
+ ])
121
+ [%x{#{cmd}}[/\d+\.\d+/], 'auto-detected']
122
+ end
123
+ rescue LoadError
124
+ end
125
+
126
+ end
127
+
128
+ attr_writer :simplified
129
+
130
+ def simplified?
131
+ @simplified
132
+ end
133
+
134
+ def io(io, length = 8)
135
+ buffer(io.read(length))
136
+ end
137
+
138
+ def inspect
139
+ super.insert(-2, closed? ? ' (closed)' : '')
140
+ end
141
+
142
+ end
@@ -0,0 +1 @@
1
+ require 'filemagic'
Binary file
@@ -0,0 +1,227 @@
1
+ require 'test/unit'
2
+ require 'filemagic'
3
+
4
+ class TestFileMagic < Test::Unit::TestCase
5
+
6
+ magic_version, origin = FileMagic.magic_version
7
+ MAGIC_VERSION = magic_version.to_f
8
+
9
+ warn <<-EOT
10
+
11
+ libmagic version: #{MAGIC_VERSION}#{" (#{origin})" if origin}
12
+ magic file from #{FileMagic.path}
13
+
14
+ EOT
15
+
16
+ def test_file
17
+ fm = FileMagic.new(FileMagic::MAGIC_NONE)
18
+
19
+ python_script = match_version(
20
+ 0 => 'a python script, ASCII text executable',
21
+ 5.11 => 'Python script, ASCII text executable'
22
+ )
23
+
24
+ res = fm.file(path_to('pyfile'))
25
+ assert_equal(python_script, res)
26
+
27
+ if File.symlink?(path_to('pylink'))
28
+ res = fm.file(path_to('pylink'))
29
+ assert_equal("symbolic link to `pyfile'", res.strip)
30
+ end
31
+
32
+ fm.close
33
+ fm = FileMagic.new(FileMagic::MAGIC_SYMLINK)
34
+
35
+ res = fm.file(path_to('pylink'))
36
+ assert_equal(python_script, res)
37
+
38
+ fm.close
39
+ fm = FileMagic.new(FileMagic::MAGIC_SYMLINK | FileMagic::MAGIC_MIME)
40
+
41
+ res = fm.file(path_to('pylink'))
42
+ assert_equal('text/plain; charset=us-ascii', res)
43
+
44
+ fm.close
45
+ fm = FileMagic.new(FileMagic::MAGIC_COMPRESS)
46
+
47
+ res = fm.file(path_to('pyfile-compressed.gz'))
48
+ gzip_compressed = 'gzip compressed data, was "pyfile-compressed"'
49
+ assert_match(Gem.win_platform? ? /^#{gzip_compressed}/ :
50
+ /^#{python_script} \(#{gzip_compressed}/, res)
51
+
52
+ fm.close
53
+ end
54
+
55
+ def test_buffer
56
+ fm = FileMagic.new(FileMagic::MAGIC_NONE)
57
+ res = fm.buffer("#!/bin/sh\n")
58
+ fm.close
59
+ assert_equal('POSIX shell script, ASCII text executable', res)
60
+ end
61
+
62
+ def test_check
63
+ return if Gem.win_platform?
64
+ fm = FileMagic.new(FileMagic::MAGIC_NONE)
65
+ res = silence_stderr { fm.check(path_to('perl')) }
66
+ fm.close
67
+ assert(res)
68
+ end
69
+
70
+ def test_check_compiled
71
+ return if MAGIC_VERSION <= 5.09
72
+ fm = FileMagic.new(FileMagic::MAGIC_NONE)
73
+ res = silence_stderr { fm.check(path_to('perl.mgc')) }
74
+ fm.close
75
+ assert(res)
76
+ end
77
+
78
+ def test_compile
79
+ assert(File.writable?('.'), "can't write to current directory")
80
+ fm = FileMagic.new(FileMagic::MAGIC_NONE)
81
+ res = fm.compile(path_to('perl'))
82
+ fm.close
83
+ assert(res)
84
+ File.unlink(path_to('perl.mgc', '.'))
85
+ end
86
+
87
+ def test_block
88
+ block_fm = nil
89
+ res = FileMagic.open(FileMagic::MAGIC_NONE) { |fm|
90
+ block_fm = fm
91
+ fm.file(path_to('pyfile'))
92
+ }
93
+ assert_equal(match_version(
94
+ 0 => 'a python script, ASCII text executable',
95
+ 5.11 => 'Python script, ASCII text executable'
96
+ ), res)
97
+ assert block_fm.closed?
98
+ end
99
+
100
+ def test_flags_to_int
101
+ assert_raise(TypeError) { FileMagic.flags(0) }
102
+ assert_equal(0, FileMagic.flags([FileMagic::MAGIC_NONE]))
103
+ assert_equal(0, FileMagic.flags([:none]))
104
+ assert_equal(0, FileMagic.flags([]))
105
+ assert_equal(1072, FileMagic.flags([:mime, :continue]))
106
+ end
107
+
108
+ def test_setflags
109
+ fm = FileMagic.new(FileMagic::MAGIC_NONE)
110
+ assert_equal([], fm.flags)
111
+ fm.flags = FileMagic::MAGIC_SYMLINK
112
+ assert_equal([:symlink], fm.flags)
113
+ fm.close
114
+ end
115
+
116
+ def test_abbr
117
+ fm = FileMagic.new(:mime, :continue)
118
+ assert_equal([:mime_type, :continue, :mime_encoding], fm.flags)
119
+ fm.flags = :symlink
120
+ assert_equal([:symlink], fm.flags)
121
+ fm.close
122
+ end
123
+
124
+ def test_close
125
+ fm = FileMagic.new
126
+ fm.close
127
+ assert fm.closed?
128
+ fm.close
129
+ assert fm.closed?
130
+ end
131
+
132
+ # tests adapted from mahoro:
133
+
134
+ def test_mahoro_file
135
+ fm = FileMagic.new
136
+ fm.flags = FileMagic::MAGIC_NONE
137
+ assert_equal(match_version(
138
+ 0 => 'ASCII C program text',
139
+ 5.11 => 'C source, ASCII text'
140
+ ), fm.file(path_to('mahoro.c')))
141
+ end
142
+
143
+ def test_mahoro_mime_file
144
+ fm = FileMagic.new
145
+ fm.flags = FileMagic::MAGIC_MIME
146
+ assert_equal('text/x-c; charset=us-ascii', fm.file(path_to('mahoro.c')))
147
+ end
148
+
149
+ def test_mahoro_buffer
150
+ fm = FileMagic.new
151
+ fm.flags = FileMagic::MAGIC_NONE
152
+ assert_equal(match_version(
153
+ 0 => 'ASCII C program text',
154
+ 5.11 => 'C source, ASCII text'
155
+ ), fm.buffer(File.read(path_to('mahoro.c'))))
156
+ end
157
+
158
+ def test_mahoro_mime_buffer
159
+ fm = FileMagic.new
160
+ fm.flags = FileMagic::MAGIC_MIME
161
+ assert_equal('text/x-c; charset=us-ascii', fm.buffer(File.read(path_to('mahoro.c'))))
162
+ end
163
+
164
+ def test_mahoro_valid
165
+ fm = FileMagic.new
166
+ assert(silence_stderr { fm.valid? }, 'Default database was not valid.')
167
+ end
168
+
169
+ # test abbreviating mime types
170
+
171
+ def test_abbrev_mime_type
172
+ fm = FileMagic.mime
173
+
174
+ refute fm.simplified?
175
+ assert_equal('text/plain; charset=us-ascii', fm.file(path_to('perl')))
176
+
177
+ fm.simplified = true
178
+ assert fm.simplified?
179
+ assert_equal('text/plain', fm.file(path_to('perl')))
180
+ assert_equal(match_version(
181
+ 0 => 'application/vnd.ms-office',
182
+ 5.11 => 'application/msword',
183
+ 5.14 => 'application/vnd.ms-office'
184
+ ), fm.file(path_to('excel-example.xls')))
185
+ end
186
+
187
+ def test_singleton
188
+ fm1 = FileMagic.fm
189
+ assert_equal(fm1, FileMagic.fm)
190
+
191
+ refute fm1.simplified?
192
+ assert_equal('ASCII text', fm1.file(path_to('perl')))
193
+
194
+ fm2 = FileMagic.fm(:mime)
195
+ assert_equal(fm2, FileMagic.fm(:mime))
196
+ refute_equal(fm2, fm1)
197
+
198
+ refute fm2.simplified?
199
+ assert_equal('text/plain; charset=us-ascii', fm2.file(path_to('perl')))
200
+
201
+ fm3 = FileMagic.fm(:mime, simplified: true)
202
+ assert_equal(fm3, FileMagic.fm(:mime, simplified: true))
203
+ refute_equal(fm3, fm2)
204
+ refute_equal(fm3, fm1)
205
+
206
+ assert fm3.simplified?
207
+ assert_equal('text/plain', fm3.file(path_to('perl')))
208
+ end
209
+
210
+ # utility methods:
211
+
212
+ def path_to(file, dir = File.dirname(__FILE__))
213
+ File.join(dir, file)
214
+ end
215
+
216
+ def silence_stderr
217
+ require 'nuggets/io/redirect'
218
+ $stderr.redirect { yield }
219
+ rescue LoadError
220
+ yield
221
+ end
222
+
223
+ def match_version(versions)
224
+ versions.sort_by { |k,| -k }.find { |k,| k <= MAGIC_VERSION }.last
225
+ end
226
+
227
+ end
data/test/leaktest.rb ADDED
@@ -0,0 +1,16 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ require 'filemagic'
3
+
4
+ warn "watch -n 1 'ps aux | grep [l]eaktest'"
5
+
6
+ def do_file(filename)
7
+ fm = FileMagic.new(0)
8
+ file = fm.file(filename)
9
+ fm.close
10
+ return file
11
+ end
12
+
13
+ loop do
14
+ puts do_file($0)
15
+ sleep 1
16
+ end
data/test/mahoro.c ADDED
@@ -0,0 +1,187 @@
1
+ /*
2
+ * This file is Public Domain.
3
+ */
4
+
5
+ #include <ruby.h>
6
+ #include <magic.h>
7
+
8
+ struct MagicCookie
9
+ {
10
+ magic_t cookie;
11
+ };
12
+
13
+ static VALUE cMahoro;
14
+ static VALUE eMahoroError;
15
+
16
+ static void
17
+ mahoro_free(ptr)
18
+ struct MagicCookie *ptr;
19
+ {
20
+ magic_close(ptr->cookie);
21
+ free(ptr);
22
+ }
23
+
24
+ static VALUE
25
+ mahoro_allocate(klass)
26
+ VALUE klass;
27
+ {
28
+ return Data_Wrap_Struct(klass, 0, mahoro_free, 0);
29
+ }
30
+
31
+ static VALUE
32
+ mahoro_initialize(argc, argv, self)
33
+ int argc;
34
+ VALUE *argv, self;
35
+ {
36
+ int flags = MAGIC_NONE;
37
+ char *path = 0;
38
+ struct MagicCookie *ptr;
39
+ magic_t cookie;
40
+ VALUE vpath, vflags;
41
+
42
+ switch(rb_scan_args(argc, argv, "02", &vflags, &vpath)) {
43
+ case 2:
44
+ if(!NIL_P(vpath)) {
45
+ path = StringValuePtr(vpath);
46
+ }
47
+ /* fallthrough */
48
+ case 1:
49
+ flags = FIX2INT(vflags);
50
+ break;
51
+ }
52
+
53
+ if(!(cookie = magic_open(flags))) {
54
+ rb_raise(eMahoroError, "failed to initialize magic cookie");
55
+ }
56
+
57
+ if(magic_load(cookie, path)) {
58
+ rb_raise(eMahoroError, "failed to load database: %s",
59
+ magic_error(cookie));
60
+ }
61
+
62
+ ptr = ALLOC(struct MagicCookie);
63
+ ptr->cookie = cookie;
64
+ DATA_PTR(self) = ptr;
65
+
66
+ return self;
67
+ }
68
+
69
+ static VALUE
70
+ mahoro_file(self, path)
71
+ VALUE self, path;
72
+ {
73
+ const char *msg;
74
+ magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
75
+
76
+ if(!(msg = magic_file(cookie, StringValuePtr(path)))) {
77
+ rb_raise(eMahoroError, "failed lookup: %s", magic_error(cookie));
78
+ }
79
+
80
+ return rb_str_new2(msg);
81
+ }
82
+
83
+ static VALUE
84
+ mahoro_buffer(self, input)
85
+ VALUE self, input;
86
+ {
87
+ const char *msg;
88
+ magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
89
+
90
+ if(!(msg = magic_buffer(cookie, StringValuePtr(input),
91
+ RSTRING(StringValue(input))->len))) {
92
+ rb_raise(eMahoroError, "failed lookup: %s", magic_error(cookie));
93
+ }
94
+
95
+ return rb_str_new2(msg);
96
+ }
97
+
98
+ static VALUE
99
+ mahoro_set_flags(self, flags)
100
+ VALUE self, flags;
101
+ {
102
+ magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
103
+
104
+ return INT2FIX(magic_setflags(cookie, FIX2INT(flags)));
105
+ }
106
+
107
+ static VALUE
108
+ mahoro_check(argc, argv, self)
109
+ int argc;
110
+ VALUE *argv, self;
111
+ {
112
+ char *path = 0;
113
+ VALUE vpath;
114
+ magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
115
+
116
+ switch(rb_scan_args(argc, argv, "01", &vpath)) {
117
+ case 1:
118
+ if(!NIL_P(vpath)) {
119
+ path = StringValuePtr(vpath);
120
+ }
121
+ break;
122
+ }
123
+
124
+ if(!magic_check(cookie, path)) {
125
+ return Qtrue;
126
+ } else {
127
+ return Qfalse;
128
+ }
129
+ }
130
+
131
+ static VALUE
132
+ mahoro_compile(klass, path)
133
+ VALUE klass, path;
134
+ {
135
+ magic_t cookie = magic_open(MAGIC_NONE);
136
+
137
+ if(magic_compile(cookie, StringValuePtr(path))) {
138
+ rb_raise(eMahoroError, "failed compile: %s", magic_error(cookie));
139
+ }
140
+
141
+ magic_close(cookie);
142
+
143
+ return Qtrue;
144
+ }
145
+
146
+ static VALUE
147
+ mahoro_load(self, path)
148
+ VALUE self, path;
149
+ {
150
+ magic_t cookie = ((struct MagicCookie *) DATA_PTR(self))->cookie;
151
+
152
+ if(magic_load(cookie, StringValuePtr(path))) {
153
+ rb_raise(eMahoroError, "failed load: %s", magic_error(cookie));
154
+ }
155
+
156
+ return self;
157
+ }
158
+
159
+ void Init_mahoro(void)
160
+ {
161
+ cMahoro = rb_define_class("Mahoro", rb_cObject);
162
+ eMahoroError = rb_define_class_under(cMahoro, "Error", rb_eStandardError);
163
+
164
+ rb_const_set(cMahoro, rb_intern("NONE"), INT2FIX(MAGIC_NONE));
165
+ rb_const_set(cMahoro, rb_intern("DEBUG"), INT2FIX(MAGIC_DEBUG));
166
+ rb_const_set(cMahoro, rb_intern("SYMLINK"), INT2FIX(MAGIC_SYMLINK));
167
+ rb_const_set(cMahoro, rb_intern("COMPRESS"), INT2FIX(MAGIC_COMPRESS));
168
+ rb_const_set(cMahoro, rb_intern("DEVICES"), INT2FIX(MAGIC_DEVICES));
169
+ rb_const_set(cMahoro, rb_intern("MIME"), INT2FIX(MAGIC_MIME));
170
+ rb_const_set(cMahoro, rb_intern("CONTINUE"), INT2FIX(MAGIC_CONTINUE));
171
+ rb_const_set(cMahoro, rb_intern("CHECK"), INT2FIX(MAGIC_CHECK));
172
+ rb_const_set(cMahoro, rb_intern("PRESERVE_ATIME"),
173
+ INT2FIX(MAGIC_PRESERVE_ATIME));
174
+ rb_const_set(cMahoro, rb_intern("RAW"), INT2FIX(MAGIC_RAW));
175
+ rb_const_set(cMahoro, rb_intern("ERROR"), INT2FIX(MAGIC_ERROR));
176
+
177
+ rb_define_alloc_func(cMahoro, mahoro_allocate);
178
+ rb_define_method(cMahoro, "initialize", mahoro_initialize, -1);
179
+ rb_define_method(cMahoro, "file", mahoro_file, 1);
180
+ rb_define_method(cMahoro, "buffer", mahoro_buffer, 1);
181
+ rb_define_method(cMahoro, "flags=", mahoro_set_flags, 1);
182
+ rb_define_method(cMahoro, "valid?", mahoro_check, -1);
183
+ rb_define_singleton_method(cMahoro, "compile", mahoro_compile, 1);
184
+ rb_define_method(cMahoro, "load", mahoro_load, 1);
185
+ }
186
+
187
+ /* arch-tag: mahoro */