ruby-magic 0.2.0 → 0.3.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.
- checksums.yaml +5 -5
- data/AUTHORS +1 -1
- data/CHANGELOG.md +60 -0
- data/COPYRIGHT +1 -1
- data/NOTICE +466 -0
- data/README.md +43 -0
- data/VERSION +1 -1
- data/ext/magic/common.h +80 -47
- data/ext/magic/extconf.rb +141 -82
- data/ext/magic/functions.c +251 -236
- data/ext/magic/functions.h +44 -88
- data/ext/magic/ruby-magic.c +1235 -627
- data/ext/magic/ruby-magic.h +222 -159
- data/kwilczynski-public.pem +25 -0
- data/lib/magic.rb +78 -89
- data/lib/magic/core/file.rb +9 -66
- data/lib/magic/core/string.rb +1 -43
- data/lib/magic/version.rb +14 -48
- metadata +24 -25
- data/CHANGES +0 -50
- data/CHANGES.rdoc +0 -50
- data/README +0 -1
- data/README.rdoc +0 -8
- data/Rakefile +0 -79
- data/TODO +0 -24
- data/bin/magic +0 -33
- data/ruby-magic.gemspec +0 -62
- data/test/helpers/magic_test_helper.rb +0 -35
- data/test/test_constants.rb +0 -96
- data/test/test_magic.rb +0 -461
data/ext/magic/ruby-magic.h
CHANGED
@@ -1,23 +1,3 @@
|
|
1
|
-
/* :enddoc: */
|
2
|
-
|
3
|
-
/*
|
4
|
-
* ruby-magic.h
|
5
|
-
*
|
6
|
-
* Copyright 2013-2015 Krzysztof Wilczynski
|
7
|
-
*
|
8
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
-
* you may not use this file except in compliance with the License.
|
10
|
-
* You may obtain a copy of the License at
|
11
|
-
*
|
12
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
13
|
-
*
|
14
|
-
* Unless required by applicable law or agreed to in writing, software
|
15
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
-
* See the License for the specific language governing permissions and
|
18
|
-
* limitations under the License.
|
19
|
-
*/
|
20
|
-
|
21
1
|
#if !defined(_RUBY_MAGIC_H)
|
22
2
|
#define _RUBY_MAGIC_H 1
|
23
3
|
|
@@ -28,204 +8,289 @@ extern "C" {
|
|
28
8
|
#include "common.h"
|
29
9
|
#include "functions.h"
|
30
10
|
|
31
|
-
#define
|
32
|
-
#define STRING_P(x) (TYPE(x) == T_STRING)
|
33
|
-
#define ARRAY_P(x) (TYPE(x) == T_ARRAY)
|
11
|
+
#define MAGIC_SYNCHRONIZED(f, d) magic_lock(object, (f), (d))
|
34
12
|
|
35
|
-
#
|
36
|
-
|
37
|
-
#endif
|
13
|
+
#define MAGIC_OBJECT(o) \
|
14
|
+
Data_Get_Struct(object, magic_object_t, (o))
|
38
15
|
|
39
|
-
#
|
40
|
-
|
41
|
-
#endif
|
16
|
+
#define MAGIC_COOKIE(o, c) \
|
17
|
+
((c) = MAGIC_OBJECT((o))->cookie)
|
42
18
|
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#endif
|
19
|
+
#define MAGIC_CLOSED_P(o) RTEST(rb_mgc_close_p((o)))
|
20
|
+
#define MAGIC_LOADED_P(o) RTEST(rb_mgc_load_p((o)))
|
46
21
|
|
47
|
-
#
|
48
|
-
|
49
|
-
|
22
|
+
#define MAGIC_WARNING(i, ...) \
|
23
|
+
do { \
|
24
|
+
if (!(i) || !(rb_mgc_warning & BIT(i))) { \
|
25
|
+
rb_mgc_warning |= BIT(i); \
|
26
|
+
rb_warn(__VA_ARGS__); \
|
27
|
+
} \
|
28
|
+
} while(0)
|
50
29
|
|
51
|
-
#
|
52
|
-
|
53
|
-
#endif
|
30
|
+
#define MAGIC_ARGUMENT_TYPE_ERROR(o, ...) \
|
31
|
+
rb_raise(rb_eTypeError, error(E_ARGUMENT_TYPE_INVALID), CLASS_NAME((o)), __VA_ARGS__)
|
54
32
|
|
55
|
-
#
|
56
|
-
|
57
|
-
#endif
|
33
|
+
#define MAGIC_GENERIC_ERROR(k, e, m) \
|
34
|
+
rb_exc_raise(magic_generic_error((k), (e), error(m)))
|
58
35
|
|
59
|
-
#define
|
60
|
-
|
61
|
-
#define RARRAY_FIRST(a) (RARRAY_EMPTY_P(a) ? Qnil : RARRAY_PTR(a)[0])
|
62
|
-
|
63
|
-
#define NOGVL_FUNCTION (VALUE (*)(void *))
|
64
|
-
|
65
|
-
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \
|
66
|
-
defined(HAVE_RUBY_THREAD_H) && HAVE_RUBY_THREAD_H
|
67
|
-
# include <ruby/thread.h>
|
68
|
-
# define NOGVL(f, d) \
|
69
|
-
rb_thread_call_without_gvl((f), (d), RUBY_UBF_IO, NULL)
|
70
|
-
#elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
71
|
-
# define NOGVL(f, d) \
|
72
|
-
rb_thread_blocking_region(NOGVL_FUNCTION(f), (d), RUBY_UBF_IO, NULL)
|
73
|
-
#else
|
74
|
-
# include <rubysig.h>
|
75
|
-
static inline VALUE
|
76
|
-
fake_blocking_region(VALUE (*f)(ANYARGS), void *data)
|
77
|
-
{
|
78
|
-
VALUE rv;
|
36
|
+
#define MAGIC_LIBRARY_ERROR(c) \
|
37
|
+
rb_exc_raise(magic_library_error(rb_mgc_eMagicError, (c)))
|
79
38
|
|
80
|
-
|
81
|
-
|
82
|
-
TRAP_END;
|
39
|
+
#define MAGIC_CHECK_INTEGER_TYPE(o) magic_check_type((o), T_FIXNUM)
|
40
|
+
#define MAGIC_CHECK_STRING_TYPE(o) magic_check_type((o), T_STRING)
|
83
41
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
42
|
+
#define MAGIC_CHECK_ARGUMENT_MISSING(t, o) \
|
43
|
+
do { \
|
44
|
+
if ((t) < (o)) \
|
45
|
+
rb_raise(rb_eArgError, error(E_ARGUMENT_MISSING), (t), (o)); \
|
46
|
+
} while(0)
|
88
47
|
|
89
|
-
#define
|
48
|
+
#define MAGIC_CHECK_ARRAY_EMPTY(o) \
|
49
|
+
do { \
|
50
|
+
if (RARRAY_EMPTY_P(o)) \
|
51
|
+
rb_raise(rb_eArgError, "%s", error(E_ARGUMENT_TYPE_ARRAY_EMPTY)); \
|
52
|
+
} while(0)
|
53
|
+
|
54
|
+
#define MAGIC_CHECK_ARRAY_OF_STRINGS(o) \
|
55
|
+
magic_check_type_array_of_strings((o))
|
90
56
|
|
91
|
-
#define
|
92
|
-
|
57
|
+
#define MAGIC_CHECK_OPEN(o) \
|
58
|
+
do { \
|
59
|
+
if (MAGIC_CLOSED_P(o)) \
|
60
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eLibraryError, EFAULT, \
|
61
|
+
E_MAGIC_LIBRARY_CLOSED); \
|
62
|
+
} while(0)
|
93
63
|
|
94
|
-
#define
|
64
|
+
#define MAGIC_CHECK_LOADED(o) \
|
65
|
+
do { \
|
66
|
+
if (!MAGIC_LOADED_P(o)) \
|
67
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eMagicError, EFAULT, \
|
68
|
+
E_MAGIC_LIBRARY_NOT_LOADED); \
|
69
|
+
} while(0)
|
95
70
|
|
96
|
-
#define
|
97
|
-
do { \
|
98
|
-
VALUE __e_##k = magic_generic_error((k), (e), (m)); \
|
99
|
-
rb_exc_raise(__e_##k); \
|
100
|
-
} while(0)
|
71
|
+
#define MAGIC_STRINGIFY(s) #s
|
101
72
|
|
102
|
-
#define
|
103
|
-
|
104
|
-
VALUE __e_library = magic_library_error(rb_mgc_eMagicError, (c)); \
|
105
|
-
rb_exc_raise(__e_library); \
|
106
|
-
} while(0)
|
73
|
+
#define MAGIC_DEFINE_FLAG(c) \
|
74
|
+
rb_define_const(rb_cMagic, MAGIC_STRINGIFY(c), INT2NUM(MAGIC_##c));
|
107
75
|
|
108
|
-
#define
|
109
|
-
|
110
|
-
if (MAGIC_CLOSED_P(o)) { \
|
111
|
-
MAGIC_GENERIC_ERROR(rb_mgc_eLibraryError, EFAULT, \
|
112
|
-
error(E_MAGIC_LIBRARY_CLOSED)); \
|
113
|
-
} \
|
114
|
-
} while(0) \
|
76
|
+
#define MAGIC_DEFINE_PARAMETER(c) \
|
77
|
+
rb_define_const(rb_cMagic, MAGIC_STRINGIFY(PARAM_##c), INT2NUM(MAGIC_PARAM_##c));
|
115
78
|
|
116
79
|
#define error(t) errors[(t)]
|
117
80
|
|
118
81
|
enum error {
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
82
|
+
E_UNKNOWN = 0,
|
83
|
+
E_NOT_ENOUGH_MEMORY,
|
84
|
+
E_ARGUMENT_MISSING,
|
85
|
+
E_ARGUMENT_TYPE_INVALID,
|
86
|
+
E_ARGUMENT_TYPE_ARRAY_EMPTY,
|
87
|
+
E_ARGUMENT_TYPE_ARRAY_STRINGS,
|
88
|
+
E_MAGIC_LIBRARY_INITIALIZE,
|
89
|
+
E_MAGIC_LIBRARY_CLOSED,
|
90
|
+
E_MAGIC_LIBRARY_NOT_LOADED,
|
91
|
+
E_PARAM_INVALID_TYPE,
|
92
|
+
E_PARAM_INVALID_VALUE,
|
93
|
+
E_FLAG_NOT_IMPLEMENTED,
|
94
|
+
E_FLAG_INVALID_TYPE
|
125
95
|
};
|
126
96
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
};
|
97
|
+
typedef struct parameter {
|
98
|
+
size_t value;
|
99
|
+
int tag;
|
100
|
+
} parameter_t;
|
101
|
+
|
102
|
+
typedef union file {
|
103
|
+
const char *path;
|
104
|
+
int fd;
|
105
|
+
} file_t;
|
106
|
+
|
107
|
+
typedef struct buffers {
|
108
|
+
size_t count;
|
109
|
+
size_t *sizes;
|
110
|
+
void **pointers;
|
111
|
+
} buffers_t;
|
112
|
+
|
113
|
+
typedef struct magic_object {
|
114
|
+
magic_t cookie;
|
115
|
+
VALUE mutex;
|
116
|
+
unsigned int database_loaded:1;
|
117
|
+
unsigned int stop_on_errors:1;
|
118
|
+
} magic_object_t;
|
119
|
+
|
120
|
+
typedef struct magic_arguments {
|
121
|
+
union {
|
122
|
+
file_t file;
|
123
|
+
parameter_t parameter;
|
124
|
+
buffers_t buffers;
|
125
|
+
} type;
|
126
|
+
magic_t cookie;
|
127
|
+
const char *result;
|
128
|
+
int flags;
|
129
|
+
int status;
|
130
|
+
unsigned int stop_on_errors:1;
|
131
|
+
} magic_arguments_t;
|
132
|
+
|
133
|
+
typedef struct magic_exception {
|
134
|
+
const char *magic_error;
|
135
|
+
VALUE klass;
|
136
|
+
int magic_errno;
|
137
|
+
} magic_exception_t;
|
131
138
|
|
132
|
-
|
133
|
-
|
134
|
-
|
139
|
+
static const char *errors[] = {
|
140
|
+
[E_UNKNOWN] = "an unknown error has occurred",
|
141
|
+
[E_NOT_ENOUGH_MEMORY] = "cannot allocate memory",
|
142
|
+
[E_ARGUMENT_MISSING] = "wrong number of arguments (given %d, expected %d)",
|
143
|
+
[E_ARGUMENT_TYPE_INVALID] = "wrong argument type %s (expected %s)",
|
144
|
+
[E_ARGUMENT_TYPE_ARRAY_EMPTY] = "arguments list cannot be empty (expected array of String)",
|
145
|
+
[E_ARGUMENT_TYPE_ARRAY_STRINGS] = "wrong argument type %s in arguments list (expected String)",
|
146
|
+
[E_MAGIC_LIBRARY_INITIALIZE] = "failed to initialize Magic library",
|
147
|
+
[E_MAGIC_LIBRARY_CLOSED] = "Magic library is not open",
|
148
|
+
[E_MAGIC_LIBRARY_NOT_LOADED] = "Magic library not loaded",
|
149
|
+
[E_PARAM_INVALID_TYPE] = "unknown or invalid parameter specified",
|
150
|
+
[E_PARAM_INVALID_VALUE] = "invalid parameter value specified",
|
151
|
+
[E_FLAG_NOT_IMPLEMENTED] = "flag is not implemented",
|
152
|
+
[E_FLAG_INVALID_TYPE] = "unknown or invalid flag specified",
|
153
|
+
NULL
|
135
154
|
};
|
136
155
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
file_t file;
|
145
|
-
buffer_t buffer;
|
146
|
-
} data;
|
147
|
-
};
|
156
|
+
static inline VALUE
|
157
|
+
magic_shift(VALUE v)
|
158
|
+
{
|
159
|
+
return ARRAY_P(v) ? \
|
160
|
+
rb_funcall(v, rb_intern("shift"), 0, Qundef) : \
|
161
|
+
Qnil;
|
162
|
+
}
|
148
163
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
164
|
+
static inline VALUE
|
165
|
+
magic_split(VALUE a, VALUE b)
|
166
|
+
{
|
167
|
+
return (STRING_P(a) && STRING_P(b)) ? \
|
168
|
+
rb_funcall(a, rb_intern("split"), 1, b) : \
|
169
|
+
Qnil;
|
170
|
+
}
|
154
171
|
|
155
|
-
|
156
|
-
|
172
|
+
static inline VALUE
|
173
|
+
magic_join(VALUE a, VALUE b)
|
174
|
+
{
|
175
|
+
return (ARRAY_P(a) && STRING_P(b)) ? \
|
176
|
+
rb_funcall(a, rb_intern("join"), 1, b) : \
|
177
|
+
Qnil;
|
178
|
+
}
|
157
179
|
|
158
|
-
static
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
NULL
|
166
|
-
};
|
180
|
+
static inline VALUE
|
181
|
+
magic_flatten(VALUE v)
|
182
|
+
{
|
183
|
+
return ARRAY_P(v) ? \
|
184
|
+
rb_funcall(v, rb_intern("flatten"), 0, Qundef) : \
|
185
|
+
Qnil;
|
186
|
+
}
|
167
187
|
|
168
|
-
|
169
|
-
|
188
|
+
static int
|
189
|
+
magic_fileno(VALUE object)
|
170
190
|
{
|
171
|
-
|
172
|
-
|
173
|
-
|
191
|
+
int fd;
|
192
|
+
rb_io_t *io;
|
193
|
+
|
194
|
+
if (rb_respond_to(object, rb_intern("fileno"))) {
|
195
|
+
object = rb_funcall(object, rb_intern("fileno"), 0, Qundef);
|
196
|
+
return NUM2INT(object);
|
197
|
+
}
|
198
|
+
|
199
|
+
if (!FILE_P(object))
|
200
|
+
object = rb_convert_type(object, T_FILE, "IO", "to_io");
|
174
201
|
|
175
|
-
|
202
|
+
GetOpenFile(object, io);
|
203
|
+
if ((fd = FPTR_TO_FD(io)) < 0)
|
204
|
+
rb_raise(rb_eIOError, "closed stream");
|
205
|
+
|
206
|
+
return fd;
|
176
207
|
}
|
177
208
|
|
178
|
-
inline
|
179
|
-
|
209
|
+
static inline VALUE
|
210
|
+
magic_path(VALUE object)
|
180
211
|
{
|
181
|
-
|
182
|
-
|
183
|
-
}
|
212
|
+
if (STRING_P(object))
|
213
|
+
return object;
|
184
214
|
|
185
|
-
|
215
|
+
if (rb_respond_to(object, rb_intern("to_path")))
|
216
|
+
return rb_funcall(object, rb_intern("to_path"), 0, Qundef);
|
217
|
+
|
218
|
+
if (rb_respond_to(object, rb_intern("path")))
|
219
|
+
return rb_funcall(object, rb_intern("path"), 0, Qundef);
|
220
|
+
|
221
|
+
if (rb_respond_to(object, rb_intern("to_s")))
|
222
|
+
return rb_funcall(object, rb_intern("to_s"), 0, Qundef);
|
223
|
+
|
224
|
+
return Qnil;
|
186
225
|
}
|
187
226
|
|
188
|
-
inline
|
189
|
-
|
227
|
+
static inline void
|
228
|
+
magic_check_type(VALUE object, int type)
|
190
229
|
{
|
191
|
-
|
192
|
-
return rb_funcall(a, rb_intern("split"), 1, b);
|
193
|
-
}
|
230
|
+
VALUE boolean = Qundef;
|
194
231
|
|
195
|
-
|
232
|
+
boolean = rb_obj_is_kind_of(object, T_INTEGER);
|
233
|
+
if (type == T_FIXNUM && !RVAL2CBOOL(boolean))
|
234
|
+
MAGIC_ARGUMENT_TYPE_ERROR(object, rb_class2name(T_INTEGER));
|
235
|
+
|
236
|
+
Check_Type(object, type);
|
196
237
|
}
|
197
238
|
|
198
|
-
inline
|
199
|
-
|
239
|
+
static inline void
|
240
|
+
magic_check_type_array_of_strings(VALUE object)
|
200
241
|
{
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
242
|
+
VALUE value = Qundef;
|
243
|
+
|
244
|
+
for (int i = 0; i < RARRAY_LEN(object); i++) {
|
245
|
+
value = RARRAY_AREF(object, (long)i);
|
246
|
+
if (NIL_P(value) || !STRING_P(value))
|
247
|
+
rb_raise(rb_eTypeError,
|
248
|
+
error(E_ARGUMENT_TYPE_ARRAY_STRINGS),
|
249
|
+
CLASS_NAME(value));
|
250
|
+
}
|
206
251
|
}
|
207
252
|
|
208
|
-
RUBY_EXTERN ID id_at_flags
|
253
|
+
RUBY_EXTERN ID id_at_flags;
|
254
|
+
RUBY_EXTERN ID id_at_paths;
|
209
255
|
|
210
256
|
RUBY_EXTERN VALUE rb_cMagic;
|
211
257
|
|
212
258
|
RUBY_EXTERN VALUE rb_mgc_eError;
|
213
259
|
RUBY_EXTERN VALUE rb_mgc_eMagicError;
|
214
260
|
RUBY_EXTERN VALUE rb_mgc_eLibraryError;
|
261
|
+
RUBY_EXTERN VALUE rb_mgc_eParameterError;
|
215
262
|
RUBY_EXTERN VALUE rb_mgc_eFlagsError;
|
216
263
|
RUBY_EXTERN VALUE rb_mgc_eNotImplementedError;
|
217
264
|
|
265
|
+
RUBY_EXTERN VALUE rb_mgc_get_do_not_auto_load_global(VALUE object);
|
266
|
+
RUBY_EXTERN VALUE rb_mgc_set_do_not_auto_load_global(VALUE object,
|
267
|
+
VALUE value);
|
268
|
+
|
269
|
+
RUBY_EXTERN VALUE rb_mgc_get_do_not_stop_on_error_global(VALUE object);
|
270
|
+
RUBY_EXTERN VALUE rb_mgc_set_do_not_stop_on_error_global(VALUE object,
|
271
|
+
VALUE value);
|
272
|
+
|
218
273
|
RUBY_EXTERN VALUE rb_mgc_initialize(VALUE object, VALUE arguments);
|
219
274
|
|
275
|
+
RUBY_EXTERN VALUE rb_mgc_get_do_not_stop_on_error(VALUE object);
|
276
|
+
RUBY_EXTERN VALUE rb_mgc_set_do_not_stop_on_error(VALUE object, VALUE value);
|
277
|
+
|
278
|
+
RUBY_EXTERN VALUE rb_mgc_open_p(VALUE object);
|
220
279
|
RUBY_EXTERN VALUE rb_mgc_close(VALUE object);
|
221
|
-
RUBY_EXTERN VALUE
|
280
|
+
RUBY_EXTERN VALUE rb_mgc_close_p(VALUE object);
|
222
281
|
|
223
|
-
RUBY_EXTERN VALUE
|
282
|
+
RUBY_EXTERN VALUE rb_mgc_get_paths(VALUE object);
|
283
|
+
|
284
|
+
RUBY_EXTERN VALUE rb_mgc_get_parameter(VALUE object, VALUE tag);
|
285
|
+
RUBY_EXTERN VALUE rb_mgc_set_parameter(VALUE object, VALUE tag, VALUE value);
|
224
286
|
|
225
287
|
RUBY_EXTERN VALUE rb_mgc_get_flags(VALUE object);
|
226
288
|
RUBY_EXTERN VALUE rb_mgc_set_flags(VALUE object, VALUE value);
|
227
289
|
|
228
290
|
RUBY_EXTERN VALUE rb_mgc_load(VALUE object, VALUE arguments);
|
291
|
+
RUBY_EXTERN VALUE rb_mgc_load_buffers(VALUE object, VALUE arguments);
|
292
|
+
RUBY_EXTERN VALUE rb_mgc_load_p(VALUE object);
|
293
|
+
|
229
294
|
RUBY_EXTERN VALUE rb_mgc_compile(VALUE object, VALUE arguments);
|
230
295
|
RUBY_EXTERN VALUE rb_mgc_check(VALUE object, VALUE arguments);
|
231
296
|
|
@@ -240,5 +305,3 @@ RUBY_EXTERN VALUE rb_mgc_version(VALUE object);
|
|
240
305
|
#endif
|
241
306
|
|
242
307
|
#endif /* _RUBY_MAGIC_H */
|
243
|
-
|
244
|
-
/* vim: set ts=8 sw=4 sts=2 et : */
|