Use CAMLreturn0 to avoid a warning.
[ocaml-libvirt.git] / libvirt / libvirt_c_epilogue.c
1 /* OCaml bindings for libvirt.
2  * (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
3  * http://libvirt.org/
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version,
9  * with the OCaml linking exception described in ../COPYING.LIB.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19  */
20
21 /* Please read libvirt/README file. */
22
23 static char *
24 Optstring_val (value strv)
25 {
26   if (strv == Val_int (0))      /* None */
27     return NULL;
28   else                          /* Some string */
29     return String_val (Field (strv, 0));
30 }
31
32 static value
33 Val_opt (void *ptr, Val_ptr_t Val_ptr)
34 {
35   CAMLparam0 ();
36   CAMLlocal2 (optv, ptrv);
37
38   if (ptr) {                    /* Some ptr */
39     optv = caml_alloc (1, 0);
40     ptrv = Val_ptr (ptr);
41     Store_field (optv, 0, ptrv);
42   } else                        /* None */
43     optv = Val_int (0);
44
45   CAMLreturn (optv);
46 }
47
48 #if 0
49 static value
50 option_default (value option, value deflt)
51 {
52   if (option == Val_int (0))    /* "None" */
53     return deflt;
54   else                          /* "Some 'a" */
55     return Field (option, 0);
56 }
57 #endif
58
59 static void
60 _raise_virterror (virConnectPtr conn, const char *fn)
61 {
62   CAMLparam0 ();
63   CAMLlocal1 (rv);
64   virErrorPtr errp;
65   struct _virError err;
66
67   errp = conn ? virConnGetLastError (conn) : virGetLastError ();
68
69   if (!errp) {
70     /* Fake a _virError structure. */
71     memset (&err, 0, sizeof err);
72     err.code = VIR_ERR_INTERNAL_ERROR;
73     err.domain = VIR_FROM_NONE;
74     err.level = VIR_ERR_ERROR;
75     err.message = (char *) fn;
76     errp = &err;
77   }
78
79   rv = Val_virterror (errp);
80   caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_virterror"), rv);
81
82   /*NOTREACHED*/
83   CAMLreturn0;
84 }
85
86 /* Raise an error if a function is not supported. */
87 static void
88 not_supported (const char *fn)
89 {
90   CAMLparam0 ();
91   CAMLlocal1 (fnv);
92
93   fnv = caml_copy_string (fn);
94   caml_raise_with_arg (*caml_named_value ("ocaml_libvirt_not_supported"), fnv);
95
96   /*NOTREACHED*/
97   CAMLreturn0;
98 }
99
100 /* Convert the virErrorNumber, virErrorDomain and virErrorLevel enums
101  * into values (longs because they are variants in OCaml).
102  *
103  * The enum values are part of the libvirt ABI so they cannot change,
104  * which means that we can convert these numbers directly into
105  * OCaml variants (which use the same ordering) very fast.
106  *
107  * The tricky part here is when we are linked to a newer version of
108  * libvirt than the one we were compiled against.  If the newer libvirt
109  * generates an error code which we don't know about then we need
110  * to convert it into VIR_*_UNKNOWN (code).
111  */
112
113 #define MAX_VIR_CODE 50 /* VIR_ERR_NO_STORAGE_VOL */
114 #define MAX_VIR_DOMAIN 17 /* VIR_FROM_STORAGE */
115 #define MAX_VIR_LEVEL VIR_ERR_ERROR
116
117 static inline value
118 Val_err_number (virErrorNumber code)
119 {
120   CAMLparam0 ();
121   CAMLlocal1 (rv);
122
123   if (0 <= code && code <= MAX_VIR_CODE)
124     rv = Val_int (code);
125   else {
126     rv = caml_alloc (1, 0);     /* VIR_ERR_UNKNOWN (code) */
127     Store_field (rv, 0, Val_int (code));
128   }
129
130   CAMLreturn (rv);
131 }
132
133 static inline value
134 Val_err_domain (virErrorDomain code)
135 {
136   CAMLparam0 ();
137   CAMLlocal1 (rv);
138
139   if (0 <= code && code <= MAX_VIR_DOMAIN)
140     rv = Val_int (code);
141   else {
142     rv = caml_alloc (1, 0);     /* VIR_FROM_UNKNOWN (code) */
143     Store_field (rv, 0, Val_int (code));
144   }
145
146   CAMLreturn (rv);
147 }
148
149 static inline value
150 Val_err_level (virErrorLevel code)
151 {
152   CAMLparam0 ();
153   CAMLlocal1 (rv);
154
155   if (0 <= code && code <= MAX_VIR_LEVEL)
156     rv = Val_int (code);
157   else {
158     rv = caml_alloc (1, 0);     /* VIR_ERR_UNKNOWN_LEVEL (code) */
159     Store_field (rv, 0, Val_int (code));
160   }
161
162   CAMLreturn (rv);
163 }
164
165 /* Convert a virterror to a value. */
166 static value
167 Val_virterror (virErrorPtr err)
168 {
169   CAMLparam0 ();
170   CAMLlocal3 (rv, connv, optv);
171
172   rv = caml_alloc (9, 0);
173   Store_field (rv, 0, Val_err_number (err->code));
174   Store_field (rv, 1, Val_err_domain (err->domain));
175   Store_field (rv, 2,
176                Val_opt (err->message, (Val_ptr_t) caml_copy_string));
177   Store_field (rv, 3, Val_err_level (err->level));
178
179   Store_field (rv, 4,
180                Val_opt (err->str1, (Val_ptr_t) caml_copy_string));
181   Store_field (rv, 5,
182                Val_opt (err->str2, (Val_ptr_t) caml_copy_string));
183   Store_field (rv, 6,
184                Val_opt (err->str3, (Val_ptr_t) caml_copy_string));
185   Store_field (rv, 7, caml_copy_int32 (err->int1));
186   Store_field (rv, 8, caml_copy_int32 (err->int2));
187
188   CAMLreturn (rv);
189 }
190
191 static void conn_finalize (value);
192 static void dom_finalize (value);
193 static void net_finalize (value);
194 #ifdef HAVE_VIRSTORAGEPOOLPTR
195 static void pol_finalize (value);
196 #endif
197 #ifdef HAVE_VIRSTORAGEVOLPTR
198 static void vol_finalize (value);
199 #endif
200 #ifdef HAVE_VIRJOBPTR
201 static void jb_finalize (value);
202 #endif
203
204 static struct custom_operations conn_custom_operations = {
205   "conn_custom_operations",
206   conn_finalize,
207   custom_compare_default,
208   custom_hash_default,
209   custom_serialize_default,
210   custom_deserialize_default
211 };
212
213 static struct custom_operations dom_custom_operations = {
214   "dom_custom_operations",
215   dom_finalize,
216   custom_compare_default,
217   custom_hash_default,
218   custom_serialize_default,
219   custom_deserialize_default
220
221 };
222
223 static struct custom_operations net_custom_operations = {
224   "net_custom_operations",
225   net_finalize,
226   custom_compare_default,
227   custom_hash_default,
228   custom_serialize_default,
229   custom_deserialize_default
230 };
231
232 #ifdef HAVE_VIRSTORAGEPOOLPTR
233 static struct custom_operations pol_custom_operations = {
234   "pol_custom_operations",
235   pol_finalize,
236   custom_compare_default,
237   custom_hash_default,
238   custom_serialize_default,
239   custom_deserialize_default
240 };
241 #endif
242
243 #ifdef HAVE_VIRSTORAGEVOLPTR
244 static struct custom_operations vol_custom_operations = {
245   "vol_custom_operations",
246   vol_finalize,
247   custom_compare_default,
248   custom_hash_default,
249   custom_serialize_default,
250   custom_deserialize_default
251 };
252 #endif
253
254 #ifdef HAVE_VIRJOBPTR
255 static struct custom_operations jb_custom_operations = {
256   "jb_custom_operations",
257   jb_finalize,
258   custom_compare_default,
259   custom_hash_default,
260   custom_serialize_default,
261   custom_deserialize_default
262 };
263 #endif
264
265 static value
266 Val_connect (virConnectPtr conn)
267 {
268   CAMLparam0 ();
269   CAMLlocal1 (rv);
270   rv = caml_alloc_custom (&conn_custom_operations,
271                           sizeof (virConnectPtr), 0, 1);
272   Connect_val (rv) = conn;
273   CAMLreturn (rv);
274 }
275
276 static value
277 Val_dom (virDomainPtr dom)
278 {
279   CAMLparam0 ();
280   CAMLlocal1 (rv);
281   rv = caml_alloc_custom (&dom_custom_operations,
282                           sizeof (virDomainPtr), 0, 1);
283   Dom_val (rv) = dom;
284   CAMLreturn (rv);
285 }
286
287 static value
288 Val_net (virNetworkPtr net)
289 {
290   CAMLparam0 ();
291   CAMLlocal1 (rv);
292   rv = caml_alloc_custom (&net_custom_operations,
293                           sizeof (virNetworkPtr), 0, 1);
294   Net_val (rv) = net;
295   CAMLreturn (rv);
296 }
297
298 #ifdef HAVE_VIRSTORAGEPOOLPTR
299 static value
300 Val_pol (virStoragePoolPtr pol)
301 {
302   CAMLparam0 ();
303   CAMLlocal1 (rv);
304   rv = caml_alloc_custom (&pol_custom_operations,
305                           sizeof (virStoragePoolPtr), 0, 1);
306   Pol_val (rv) = pol;
307   CAMLreturn (rv);
308 }
309 #endif
310
311 #ifdef HAVE_VIRSTORAGEVOLPTR
312 static value
313 Val_vol (virStorageVolPtr vol)
314 {
315   CAMLparam0 ();
316   CAMLlocal1 (rv);
317   rv = caml_alloc_custom (&vol_custom_operations,
318                           sizeof (virStorageVolPtr), 0, 1);
319   Vol_val (rv) = vol;
320   CAMLreturn (rv);
321 }
322 #endif
323
324 #ifdef HAVE_VIRJOBPTR
325 static value
326 Val_jb (virJobPtr jb)
327 {
328   CAMLparam0 ();
329   CAMLlocal1 (rv);
330   rv = caml_alloc_custom (&jb_custom_operations,
331                           sizeof (virJobPtr), 0, 1);
332   Jb_val (rv) = jb;
333   CAMLreturn (rv);
334 }
335 #endif
336
337 /* This wraps up the (dom, conn) pair (Domain.t). */
338 static value
339 Val_domain (virDomainPtr dom, value connv)
340 {
341   CAMLparam1 (connv);
342   CAMLlocal2 (rv, v);
343
344   rv = caml_alloc_tuple (2);
345   v = Val_dom (dom);
346   Store_field (rv, 0, v);
347   Store_field (rv, 1, connv);
348   CAMLreturn (rv);
349 }
350
351 /* This wraps up the (net, conn) pair (Network.t). */
352 static value
353 Val_network (virNetworkPtr net, value connv)
354 {
355   CAMLparam1 (connv);
356   CAMLlocal2 (rv, v);
357
358   rv = caml_alloc_tuple (2);
359   v = Val_net (net);
360   Store_field (rv, 0, v);
361   Store_field (rv, 1, connv);
362   CAMLreturn (rv);
363 }
364
365 #ifdef HAVE_VIRSTORAGEPOOLPTR
366 /* This wraps up the (pol, conn) pair (Pool.t). */
367 static value
368 Val_pool (virStoragePoolPtr pol, value connv)
369 {
370   CAMLparam1 (connv);
371   CAMLlocal2 (rv, v);
372
373   rv = caml_alloc_tuple (2);
374   v = Val_pol (pol);
375   Store_field (rv, 0, v);
376   Store_field (rv, 1, connv);
377   CAMLreturn (rv);
378 }
379 #endif
380
381 #ifdef HAVE_VIRSTORAGEVOLPTR
382 /* This wraps up the (vol, conn) pair (Volume.t). */
383 static value
384 Val_volume (virStorageVolPtr vol, value connv)
385 {
386   CAMLparam1 (connv);
387   CAMLlocal2 (rv, v);
388
389   rv = caml_alloc_tuple (2);
390   v = Val_vol (vol);
391   Store_field (rv, 0, v);
392   Store_field (rv, 1, connv);
393   CAMLreturn (rv);
394 }
395 #endif
396
397 #ifdef HAVE_VIRJOBPTR
398 /* This wraps up the (jb, conn) pair (Job.t). */
399 static value
400 Val_job (virJobPtr jb, value connv)
401 {
402   CAMLparam1 (connv);
403   CAMLlocal2 (rv, v);
404
405   rv = caml_alloc_tuple (2);
406   v = Val_jb (jb);
407   Store_field (rv, 0, v);
408   Store_field (rv, 1, connv);
409   CAMLreturn (rv);
410 }
411 #endif
412
413 static void
414 conn_finalize (value connv)
415 {
416   virConnectPtr conn = Connect_val (connv);
417   if (conn) (void) virConnectClose (conn);
418 }
419
420 static void
421 dom_finalize (value domv)
422 {
423   virDomainPtr dom = Dom_val (domv);
424   if (dom) (void) virDomainFree (dom);
425 }
426
427 static void
428 net_finalize (value netv)
429 {
430   virNetworkPtr net = Net_val (netv);
431   if (net) (void) virNetworkFree (net);
432 }
433
434 #ifdef HAVE_VIRSTORAGEPOOLPTR
435 static void
436 pol_finalize (value polv)
437 {
438   virStoragePoolPtr pol = Pol_val (polv);
439   if (pol) (void) virStoragePoolFree (pol);
440 }
441 #endif
442
443 #ifdef HAVE_VIRSTORAGEVOLPTR
444 static void
445 vol_finalize (value volv)
446 {
447   virStorageVolPtr vol = Vol_val (volv);
448   if (vol) (void) virStorageVolFree (vol);
449 }
450 #endif
451
452 #ifdef HAVE_VIRJOBPTR
453 static void
454 jb_finalize (value jbv)
455 {
456   virJobPtr jb = Jb_val (jbv);
457   if (jb) (void) virJobFree (jb);
458 }
459 #endif