svg_converted: fix build (zlib2 split)
[mldonkey.git] / src / utils / lib / magiclib_stub.c
bloba01e0eb55fb29b9ca0ca51af530de6cde27b9411
1 /* File: magic.ml
3 Copyright (C) 2005
5 Christophe Troestler
6 email: Christophe.Troestler@umh.ac.be
7 WWW: http://www.umh.ac.be/math/an/software/
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public License
11 version 2.1 as published by the Free Software Foundation, with the
12 special exception on linking described in file LICENSE.
14 This library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
17 LICENSE for more details.
19 /* $Id$ */
21 #include "../../../config/config.h"
22 #include <caml/mlvalues.h>
23 #include <caml/memory.h>
24 #include <caml/alloc.h>
25 #include <caml/custom.h>
26 #include <caml/fail.h>
27 #include <caml/callback.h>
29 #include <magic.h>
30 #include <errno.h>
31 #define _XOPEN_SOURCE 600
32 #include <string.h>
33 #include <stdio.h>
35 /* Outputs an error message and terminates the program. */
36 #define DEBUG(...) \
37 fprintf(stderr, "DEBUG magic_stub: " __VA_ARGS__); \
38 printf("\n")
40 #define CAML_MAGIC_VERSION "0.2"
43 * Failure
46 static void raise_magic_failure(const char * msg)
48 static value * exn = NULL;
49 if (exn == NULL) exn = caml_named_value("Magiclib.Failure");
50 raise_with_string(*exn, (char *) msg);
53 /* [fname] is the function name. */
54 static void raise_on_error(const char* fname, magic_t cookie)
56 const char *err_magic;
57 char *errmsg; /* For thread safety of error messages */
58 int flen;
60 flen = strlen(fname);
61 if ((err_magic = magic_error(cookie)) != NULL) {
62 if ((errmsg = malloc(flen + strlen(err_magic) + 1)) == NULL)
63 raise_out_of_memory();
64 strcpy(errmsg, fname);
65 strcpy(errmsg + flen, err_magic);
66 raise_magic_failure(errmsg);
68 else {
69 int len = 80; /* Initial buffer length */
70 int err;
72 /* Allocate buffer [errmsg] until there is enough space for the
73 * error message. */
74 err = magic_errno(cookie);
75 if ((errmsg = malloc(len)) == NULL) raise_out_of_memory();
76 strcpy(errmsg, fname);
77 #ifdef HAVE_STRERROR_R
78 while (strerror_r(err, errmsg + flen, len - flen) < 0) {
79 len *= 2;
80 errmsg = realloc(errmsg, len);
81 if (errmsg == NULL) raise_out_of_memory();
83 #else
84 strcat (errmsg, strerror(err));
85 #endif
86 raise_sys_error(copy_string(errmsg));
92 * magic_t
95 /* magic_t is a pointer on 'struct magic_set' so one can set it to NULL */
96 #define COOKIE_VAL(v) (* ((magic_t *) Data_custom_val(v)))
98 /* If the cookie has not been forcibly closed with [magic_close], free it. */
99 static void free_cookie(value c)
101 magic_t cookie = COOKIE_VAL(c);
102 if (cookie != NULL) {
103 magic_close(cookie);
104 COOKIE_VAL(c) = NULL;
108 /* compare magic_t pointers (=> total order) */
109 static int compare_cookie(value c1, value c2)
111 magic_t cookie1 = COOKIE_VAL(c1), cookie2 = COOKIE_VAL(c2);
113 if (cookie1 == cookie2) return 0;
114 else if (cookie1 < cookie2) return -1;
115 else return 1;
118 static struct custom_operations cookie_ops = {
119 /* identifier */ "be.ac.umh.math/magic.cookie." CAML_MAGIC_VERSION,
120 /* finalize */ free_cookie,
121 /* compare */ compare_cookie,
122 /* hash */ custom_hash_default,
123 /* serialize */ custom_serialize_default,
124 /* deserialize */ custom_deserialize_default
127 #define ALLOC_COOKIE alloc_custom(&cookie_ops, sizeof(magic_t), \
128 sizeof(magic_t), 40 * sizeof(magic_t))
131 * Stubs
134 CAMLprim value ocaml_magic_open(value flags)
136 CAMLparam1(flags);
137 CAMLlocal1(c);
138 char *errmsg;
139 int len = 80;
141 c = ALLOC_COOKIE;
142 if ((COOKIE_VAL(c) = magic_open(Int_val(flags) | MAGIC_ERROR)) == NULL) {
143 if (errno == EINVAL)
144 /* An unsupported value for flags was given */
145 raise_magic_failure("Magiclib.create: Preserve_atime not supported");
146 else {
147 /* No cookie yet, so one cannot use the above generic err fun */
148 if ((errmsg = malloc(len)) == NULL) raise_out_of_memory();
149 strcpy(errmsg, "Magiclib.create: "); /* 14 chars */
150 #ifdef HAVE_STRERROR_R
151 while (strerror_r(errno, errmsg + 14, len - 14) < 0) {
152 len *= 2;
153 if ((errmsg = realloc(errmsg, len)) == NULL) raise_out_of_memory();
155 #else
156 strcat (errmsg, strerror(errno));
157 #endif
158 raise_sys_error(copy_string(errmsg));
161 CAMLreturn(c);
164 CAMLprim value ocaml_magic_close(value c)
166 CAMLparam1(c);
167 magic_t cookie = COOKIE_VAL(c);
168 if (cookie != NULL) /* if first time it is called */
169 magic_close(cookie);
170 COOKIE_VAL(c) = NULL; /* For the finalization function & multiple calls */
171 CAMLreturn(Val_unit);
175 CAMLprim value ocaml_magic_file(value c, value fname)
177 CAMLparam2(c, fname);
178 const char * ans;
179 magic_t cookie = COOKIE_VAL(c);
181 if (cookie == NULL) invalid_argument("Magiclib.file");
182 if ((ans = magic_file(cookie, String_val(fname))) == NULL) {
183 raise_on_error("Magiclib.file: ", cookie);
185 CAMLreturn(copy_string(ans));
188 CAMLprim value ocaml_magic_buffer(value c, value buf, value len)
190 CAMLparam3(c, buf, len);
191 const char * ans;
192 magic_t cookie = COOKIE_VAL(c);
194 if (cookie == NULL) caml_invalid_argument("Magiclib.buffer");
195 if ((ans = magic_buffer(cookie, String_val(buf), Int_val(len)))
196 == NULL)
197 raise_on_error("Magiclib.buffer: ", cookie);
198 CAMLreturn(copy_string(ans));
202 CAMLprim value ocaml_magic_setflags(value c, value flags)
204 CAMLparam2(c, flags);
205 magic_t cookie = COOKIE_VAL(c);
207 if (cookie == NULL) caml_invalid_argument("Magiclib.setflags");
208 if (magic_setflags(cookie, Int_val(flags)) < 0)
209 raise_magic_failure("Magiclib.setflags: Preserve_atime not supported");
210 CAMLreturn(Val_unit);
215 #define CHECK(fname) \
216 magic_t cookie = COOKIE_VAL(c); \
218 if (cookie == NULL) caml_invalid_argument("Magiclib.check"); \
219 if (magic_check(cookie, fname) < 0) \
220 CAMLreturn(Val_false); \
221 else \
222 CAMLreturn(Val_true)
224 CAMLprim value ocaml_magic_check_default(value c)
226 CAMLparam1(c);
227 CHECK(NULL);
229 CAMLprim value ocaml_magic_check(value c, value filenames)
231 CAMLparam2(c, filenames);
232 CHECK(String_val(filenames));
237 #define COMPILE(fname) \
238 magic_t cookie = COOKIE_VAL(c); \
240 if (cookie == NULL) caml_invalid_argument("Magiclib.compile"); \
241 if (magic_compile(cookie, fname) < 0) \
242 raise_on_error("Magiclib.compile: ", cookie); \
243 CAMLreturn(Val_unit)
245 CAMLprim value ocaml_magic_compile_default(value c)
247 CAMLparam1(c);
248 COMPILE(NULL);
251 CAMLprim value ocaml_magic_compile(value c, value filenames)
253 CAMLparam2(c, filenames);
254 COMPILE(String_val(filenames));
259 #define LOAD(fname) \
260 magic_t cookie = COOKIE_VAL(c); \
262 if (cookie == NULL) caml_invalid_argument("Magiclib.load"); \
263 if (magic_load(cookie, fname) < 0) \
264 raise_on_error("Magiclib.load: ", cookie); \
265 CAMLreturn(Val_unit)
267 CAMLprim
268 value ocaml_magic_load_default(value c)
270 CAMLparam1(c);
271 LOAD(NULL);
274 CAMLprim
275 value ocaml_magic_load(value c, value filenames)
277 CAMLparam2(c, filenames);
278 LOAD(String_val(filenames));