tests: Rename extratests -> tests/extra.
[libguestfs.git] / generator / generator_python.ml
1 (* libguestfs
2  * Copyright (C) 2009-2011 Red Hat Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *)
18
19 (* Please read generator/README first. *)
20
21 open Printf
22
23 open Generator_types
24 open Generator_utils
25 open Generator_pr
26 open Generator_docstrings
27 open Generator_optgroups
28 open Generator_actions
29 open Generator_structs
30 open Generator_c
31 open Generator_events
32
33 (* Generate Python C module. *)
34 let rec generate_python_c () =
35   generate_header CStyle LGPLv2plus;
36
37   pr "\
38 #include <config.h>
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <assert.h>
43
44 #include \"guestfs-py.h\"
45
46 /* This list should be freed (but not the strings) after use. */
47 static char **
48 get_string_list (PyObject *obj)
49 {
50   size_t i, len;
51   char **r;
52 #ifndef HAVE_PYSTRING_ASSTRING
53   PyObject *bytes;
54 #endif
55
56   assert (obj);
57
58   if (!PyList_Check (obj)) {
59     PyErr_SetString (PyExc_RuntimeError, \"expecting a list parameter\");
60     return NULL;
61   }
62
63   Py_ssize_t slen = PyList_Size (obj);
64   if (slen == -1) {
65     PyErr_SetString (PyExc_RuntimeError, \"get_string_list: PyList_Size failure\");
66     return NULL;
67   }
68   len = (size_t) slen;
69   r = malloc (sizeof (char *) * (len+1));
70   if (r == NULL) {
71     PyErr_SetString (PyExc_RuntimeError, \"get_string_list: out of memory\");
72     return NULL;
73   }
74
75   for (i = 0; i < len; ++i) {
76 #ifdef HAVE_PYSTRING_ASSTRING
77     r[i] = PyString_AsString (PyList_GetItem (obj, i));
78 #else
79     bytes = PyUnicode_AsUTF8String (PyList_GetItem (obj, i));
80     r[i] = PyBytes_AS_STRING (bytes);
81 #endif
82   }
83   r[len] = NULL;
84
85   return r;
86 }
87
88 static PyObject *
89 put_string_list (char * const * const argv)
90 {
91   PyObject *list;
92   int argc, i;
93
94   for (argc = 0; argv[argc] != NULL; ++argc)
95     ;
96
97   list = PyList_New (argc);
98   for (i = 0; i < argc; ++i) {
99 #ifdef HAVE_PYSTRING_ASSTRING
100     PyList_SetItem (list, i, PyString_FromString (argv[i]));
101 #else
102     PyList_SetItem (list, i, PyUnicode_FromString (argv[i]));
103 #endif
104   }
105
106   return list;
107 }
108
109 static PyObject *
110 put_table (char * const * const argv)
111 {
112   PyObject *list, *item;
113   int argc, i;
114
115   for (argc = 0; argv[argc] != NULL; ++argc)
116     ;
117
118   list = PyList_New (argc >> 1);
119   for (i = 0; i < argc; i += 2) {
120     item = PyTuple_New (2);
121 #ifdef HAVE_PYSTRING_ASSTRING
122     PyTuple_SetItem (item, 0, PyString_FromString (argv[i]));
123     PyTuple_SetItem (item, 1, PyString_FromString (argv[i+1]));
124 #else
125     PyTuple_SetItem (item, 0, PyUnicode_FromString (argv[i]));
126     PyTuple_SetItem (item, 1, PyUnicode_FromString (argv[i+1]));
127 #endif
128     PyList_SetItem (list, i >> 1, item);
129   }
130
131   return list;
132 }
133
134 static void
135 free_strings (char **argv)
136 {
137   int argc;
138
139   for (argc = 0; argv[argc] != NULL; ++argc)
140     free (argv[argc]);
141   free (argv);
142 }
143
144 ";
145
146   let emit_put_list_function typ =
147     pr "static PyObject *\n";
148     pr "put_%s_list (struct guestfs_%s_list *%ss)\n" typ typ typ;
149     pr "{\n";
150     pr "  PyObject *list;\n";
151     pr "  size_t i;\n";
152     pr "\n";
153     pr "  list = PyList_New (%ss->len);\n" typ;
154     pr "  for (i = 0; i < %ss->len; ++i)\n" typ;
155     pr "    PyList_SetItem (list, i, put_%s (&%ss->val[i]));\n" typ typ;
156     pr "  return list;\n";
157     pr "};\n";
158     pr "\n"
159   in
160
161   (* Structures, turned into Python dictionaries. *)
162   List.iter (
163     fun (typ, cols) ->
164       pr "static PyObject *\n";
165       pr "put_%s (struct guestfs_%s *%s)\n" typ typ typ;
166       pr "{\n";
167       pr "  PyObject *dict;\n";
168       pr "\n";
169       pr "  dict = PyDict_New ();\n";
170       List.iter (
171         function
172         | name, FString ->
173             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
174             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
175             pr "                        PyString_FromString (%s->%s));\n"
176               typ name;
177             pr "#else\n";
178             pr "                        PyUnicode_FromString (%s->%s));\n"
179               typ name;
180             pr "#endif\n"
181         | name, FBuffer ->
182             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
183             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
184             pr "                        PyString_FromStringAndSize (%s->%s, %s->%s_len));\n"
185               typ name typ name;
186             pr "#else\n";
187             pr "                        PyBytes_FromStringAndSize (%s->%s, %s->%s_len));\n"
188               typ name typ name;
189             pr "#endif\n"
190         | name, FUUID ->
191             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
192             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
193             pr "                        PyString_FromStringAndSize (%s->%s, 32));\n"
194               typ name;
195             pr "#else\n";
196             pr "                        PyBytes_FromStringAndSize (%s->%s, 32));\n"
197               typ name;
198             pr "#endif\n"
199         | name, (FBytes|FUInt64) ->
200             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
201             pr "                        PyLong_FromUnsignedLongLong (%s->%s));\n"
202               typ name
203         | name, FInt64 ->
204             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
205             pr "                        PyLong_FromLongLong (%s->%s));\n"
206               typ name
207         | name, FUInt32 ->
208             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
209             pr "                        PyLong_FromUnsignedLong (%s->%s));\n"
210               typ name
211         | name, FInt32 ->
212             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
213             pr "                        PyLong_FromLong (%s->%s));\n"
214               typ name
215         | name, FOptPercent ->
216             pr "  if (%s->%s >= 0)\n" typ name;
217             pr "    PyDict_SetItemString (dict, \"%s\",\n" name;
218             pr "                          PyFloat_FromDouble ((double) %s->%s));\n"
219               typ name;
220             pr "  else {\n";
221             pr "    Py_INCREF (Py_None);\n";
222             pr "    PyDict_SetItemString (dict, \"%s\", Py_None);\n" name;
223             pr "  }\n"
224         | name, FChar ->
225             pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
226             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
227             pr "                        PyString_FromStringAndSize (&dirent->%s, 1));\n" name;
228             pr "#else\n";
229             pr "  PyDict_SetItemString (dict, \"%s\",\n" name;
230             pr "                        PyUnicode_FromStringAndSize (&dirent->%s, 1));\n" name;
231             pr "#endif\n"
232       ) cols;
233       pr "  return dict;\n";
234       pr "};\n";
235       pr "\n";
236
237   ) structs;
238
239   (* Emit a put_TYPE_list function definition only if that function is used. *)
240   List.iter (
241     function
242     | typ, (RStructListOnly | RStructAndList) ->
243         (* generate the function for typ *)
244         emit_put_list_function typ
245     | typ, _ -> () (* empty *)
246   ) (rstructs_used_by all_functions);
247
248   (* Python wrapper functions. *)
249   List.iter (
250     fun (name, (ret, args, optargs as style), _, _, _, _, _) ->
251       pr "static PyObject *\n";
252       pr "py_guestfs_%s (PyObject *self, PyObject *args)\n" name;
253       pr "{\n";
254
255       pr "  PyThreadState *py_save = NULL;\n";
256       pr "  PyObject *py_g;\n";
257       pr "  guestfs_h *g;\n";
258       pr "  PyObject *py_r;\n";
259
260       if optargs <> [] then (
261         pr "  struct guestfs_%s_argv optargs_s;\n" name;
262         pr "  struct guestfs_%s_argv *optargs = &optargs_s;\n" name;
263       );
264
265       (match ret with
266        | RErr | RInt _ | RBool _ -> pr "  int r;\n"
267        | RInt64 _ -> pr "  int64_t r;\n"
268        | RConstString _ | RConstOptString _ ->
269            pr "  const char *r;\n"
270        | RString _ -> pr "  char *r;\n"
271        | RStringList _ | RHashtable _ -> pr "  char **r;\n"
272        | RStruct (_, typ) -> pr "  struct guestfs_%s *r;\n" typ
273        | RStructList (_, typ) ->
274            pr "  struct guestfs_%s_list *r;\n" typ
275        | RBufferOut _ ->
276            pr "  char *r;\n";
277            pr "  size_t size;\n"
278       );
279
280       List.iter (
281         function
282         | Pathname n | Device n | Dev_or_Path n | String n | Key n
283         | FileIn n | FileOut n ->
284             pr "  const char *%s;\n" n
285         | OptString n -> pr "  const char *%s;\n" n
286         | BufferIn n ->
287             pr "  const char *%s;\n" n;
288             pr "  Py_ssize_t %s_size;\n" n
289         | StringList n | DeviceList n ->
290             pr "  PyObject *py_%s;\n" n;
291             pr "  char **%s;\n" n
292         | Bool n -> pr "  int %s;\n" n
293         | Int n -> pr "  int %s;\n" n
294         | Int64 n -> pr "  long long %s;\n" n
295         | Pointer (t, n) ->
296             pr "  long long %s_int64;\n" n;
297             pr "  %s %s;\n" t n
298       ) args;
299
300       if optargs <> [] then (
301         (* XXX This is horrible.  We have to use sentinel values on the
302          * Python side to denote values not set.
303          *)
304         (* Since we don't know if Python types will exactly match
305          * structure types, declare some local variables here.
306          *)
307         List.iter (
308           function
309           | Bool n
310           | Int n -> pr "  int optargs_t_%s = -1;\n" n
311           | Int64 n -> pr "  long long optargs_t_%s = -1;\n" n
312           | String n -> pr "  const char *optargs_t_%s = NULL;\n" n
313           | _ -> assert false
314         ) optargs
315       );
316
317       pr "\n";
318
319       if optargs <> [] then (
320         pr "  optargs_s.bitmask = 0;\n";
321         pr "\n"
322       );
323
324       (* Convert the required parameters. *)
325       pr "  if (!PyArg_ParseTuple (args, (char *) \"O";
326       List.iter (
327         function
328         | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _
329         | FileIn _ | FileOut _ -> pr "s"
330         | OptString _ -> pr "z"
331         | StringList _ | DeviceList _ -> pr "O"
332         | Bool _ -> pr "i" (* XXX Python has booleans? *)
333         | Int _ -> pr "i"
334         | Int64 _ | Pointer _ ->
335             (* XXX Whoever thought it was a good idea to
336              * emulate C's int/long/long long in Python?
337              *)
338             pr "L"
339         | BufferIn _ -> pr "s#"
340       ) args;
341
342       (* Optional parameters. *)
343       if optargs <> [] then (
344         List.iter (
345           function
346           | Bool _ | Int _ -> pr "i"
347           | Int64 _ -> pr "L"
348           | String _ -> pr "z" (* because we use None to mean not set *)
349           | _ -> assert false
350         ) optargs;
351       );
352
353       pr ":guestfs_%s\",\n" name;
354       pr "                         &py_g";
355       List.iter (
356         function
357         | Pathname n | Device n | Dev_or_Path n | String n | Key n
358         | FileIn n | FileOut n -> pr ", &%s" n
359         | OptString n -> pr ", &%s" n
360         | StringList n | DeviceList n -> pr ", &py_%s" n
361         | Bool n -> pr ", &%s" n
362         | Int n -> pr ", &%s" n
363         | Int64 n -> pr ", &%s" n
364         | Pointer (_, n) -> pr ", &%s_int64" n
365         | BufferIn n -> pr ", &%s, &%s_size" n n
366       ) args;
367
368       List.iter (
369         function
370         | Bool n | Int n | Int64 n | String n -> pr ", &optargs_t_%s" n
371         | _ -> assert false
372       ) optargs;
373
374       pr "))\n";
375       pr "    return NULL;\n";
376
377       pr "  g = get_handle (py_g);\n";
378       List.iter (
379         function
380         | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _
381         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
382         | BufferIn _ -> ()
383         | StringList n | DeviceList n ->
384             pr "  %s = get_string_list (py_%s);\n" n n;
385             pr "  if (!%s) return NULL;\n" n
386         | Pointer (t, n) ->
387             pr "  %s = (%s) (intptr_t) %s_int64;\n" n t n
388       ) args;
389
390       pr "\n";
391
392       if optargs <> [] then (
393         let uc_name = String.uppercase name in
394         List.iter (
395           fun argt ->
396             let n = name_of_argt argt in
397             let uc_n = String.uppercase n in
398             pr "  if (optargs_t_%s != " n;
399             (match argt with
400              | Bool _ | Int _ | Int64 _ -> pr "-1"
401              | String _ -> pr "NULL"
402              | _ -> assert false
403             );
404             pr ") {\n";
405             pr "    optargs_s.%s = optargs_t_%s;\n" n n;
406             pr "    optargs_s.bitmask |= GUESTFS_%s_%s_BITMASK;\n" uc_name uc_n;
407             pr "  }\n"
408         ) optargs;
409         pr "\n"
410       );
411
412       (* Release Python GIL while running.  This code is from
413        * libvirt/python/typewrappers.h.  Thanks to Dan Berrange for
414        * showing us how to do this properly.
415        *)
416       pr "  if (PyEval_ThreadsInitialized ())\n";
417       pr "    py_save = PyEval_SaveThread ();\n";
418       pr "\n";
419
420       if optargs = [] then
421         pr "  r = guestfs_%s " name
422       else
423         pr "  r = guestfs_%s_argv " name;
424       generate_c_call_args ~handle:"g" style;
425       pr ";\n";
426
427       pr "\n";
428       pr "  if (PyEval_ThreadsInitialized ())\n";
429       pr "    PyEval_RestoreThread (py_save);\n";
430       pr "\n";
431
432       List.iter (
433         function
434         | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _
435         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
436         | BufferIn _ | Pointer _ -> ()
437         | StringList n | DeviceList n ->
438             pr "  free (%s);\n" n
439       ) args;
440
441       (match errcode_of_ret ret with
442        | `CannotReturnError -> ()
443        | `ErrorIsMinusOne ->
444            pr "  if (r == -1) {\n";
445            pr "    PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
446            pr "    return NULL;\n";
447            pr "  }\n"
448        | `ErrorIsNULL ->
449            pr "  if (r == NULL) {\n";
450            pr "    PyErr_SetString (PyExc_RuntimeError, guestfs_last_error (g));\n";
451            pr "    return NULL;\n";
452            pr "  }\n"
453       );
454       pr "\n";
455
456       (match ret with
457        | RErr ->
458            pr "  Py_INCREF (Py_None);\n";
459            pr "  py_r = Py_None;\n"
460        | RInt _
461        | RBool _ -> pr "  py_r = PyLong_FromLong ((long) r);\n"
462        | RInt64 _ -> pr "  py_r = PyLong_FromLongLong (r);\n"
463        | RConstString _ ->
464            pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
465            pr "  py_r = PyString_FromString (r);\n";
466            pr "#else\n";
467            pr "  py_r = PyUnicode_FromString (r);\n";
468            pr "#endif\n"
469        | RConstOptString _ ->
470            pr "  if (r) {\n";
471            pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
472            pr "    py_r = PyString_FromString (r);\n";
473            pr "#else\n";
474            pr "    py_r = PyUnicode_FromString (r);\n";
475            pr "#endif\n";
476            pr "  } else {\n";
477            pr "    Py_INCREF (Py_None);\n";
478            pr "    py_r = Py_None;\n";
479            pr "  }\n"
480        | RString _ ->
481            pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
482            pr "  py_r = PyString_FromString (r);\n";
483            pr "#else\n";
484            pr "  py_r = PyUnicode_FromString (r);\n";
485            pr "#endif\n";
486            pr "  free (r);\n"
487        | RStringList _ ->
488            pr "  py_r = put_string_list (r);\n";
489            pr "  free_strings (r);\n"
490        | RStruct (_, typ) ->
491            pr "  py_r = put_%s (r);\n" typ;
492            pr "  guestfs_free_%s (r);\n" typ
493        | RStructList (_, typ) ->
494            pr "  py_r = put_%s_list (r);\n" typ;
495            pr "  guestfs_free_%s_list (r);\n" typ
496        | RHashtable n ->
497            pr "  py_r = put_table (r);\n";
498            pr "  free_strings (r);\n"
499        | RBufferOut _ ->
500            pr "#ifdef HAVE_PYSTRING_ASSTRING\n";
501            pr "  py_r = PyString_FromStringAndSize (r, size);\n";
502            pr "#else\n";
503            pr "  py_r = PyBytes_FromStringAndSize (r, size);\n";
504            pr "#endif\n";
505            pr "  free (r);\n"
506       );
507
508       pr "  return py_r;\n";
509       pr "}\n";
510       pr "\n"
511   ) all_functions;
512
513   (* Table of functions. *)
514   pr "static PyMethodDef methods[] = {\n";
515   pr "  { (char *) \"create\", py_guestfs_create, METH_VARARGS, NULL },\n";
516   pr "  { (char *) \"close\", py_guestfs_close, METH_VARARGS, NULL },\n";
517   pr "  { (char *) \"set_event_callback\",\n";
518   pr "    py_guestfs_set_event_callback, METH_VARARGS, NULL },\n";
519   pr "  { (char *) \"delete_event_callback\",\n";
520   pr "    py_guestfs_delete_event_callback, METH_VARARGS, NULL },\n";
521   List.iter (
522     fun (name, _, _, _, _, _, _) ->
523       pr "  { (char *) \"%s\", py_guestfs_%s, METH_VARARGS, NULL },\n"
524         name name
525   ) all_functions;
526   pr "  { NULL, NULL, 0, NULL }\n";
527   pr "};\n";
528   pr "\n";
529
530   (* Init function. *)
531   pr "\
532 #if PY_MAJOR_VERSION >= 3
533 static struct PyModuleDef moduledef = {
534   PyModuleDef_HEAD_INIT,
535   \"libguestfsmod\",     /* m_name */
536   \"libguestfs module\",   /* m_doc */
537   -1,                    /* m_size */
538   methods,               /* m_methods */
539   NULL,                  /* m_reload */
540   NULL,                  /* m_traverse */
541   NULL,                  /* m_clear */
542   NULL,                  /* m_free */
543 };
544 #endif
545
546 static PyObject *
547 moduleinit (void)
548 {
549   PyObject *m;
550
551 #if PY_MAJOR_VERSION >= 3
552   m = PyModule_Create (&moduledef);
553 #else
554   m = Py_InitModule ((char *) \"libguestfsmod\", methods);
555 #endif
556
557   return m; /* m might be NULL if module init failed */
558 }
559
560 #if PY_MAJOR_VERSION >= 3
561 PyMODINIT_FUNC
562 PyInit_libguestfsmod (void)
563 {
564   return moduleinit ();
565 }
566 #else
567 void
568 initlibguestfsmod (void)
569 {
570   (void) moduleinit ();
571 }
572 #endif
573 "
574
575 (* Generate Python module. *)
576 and generate_python_py () =
577   generate_header HashStyle LGPLv2plus;
578
579   pr "\
580 \"\"\"Python bindings for libguestfs
581
582 import guestfs
583 g = guestfs.GuestFS ()
584 g.add_drive_opts (\"guest.img\", format=\"raw\")
585 g.launch ()
586 parts = g.list_partitions ()
587
588 The guestfs module provides a Python binding to the libguestfs API
589 for examining and modifying virtual machine disk images.
590
591 Amongst the things this is good for: making batch configuration
592 changes to guests, getting disk used/free statistics (see also:
593 virt-df), migrating between virtualization systems (see also:
594 virt-p2v), performing partial backups, performing partial guest
595 clones, cloning guests and changing registry/UUID/hostname info, and
596 much else besides.
597
598 Libguestfs uses Linux kernel and qemu code, and can access any type of
599 guest filesystem that Linux and qemu can, including but not limited
600 to: ext2/3/4, btrfs, FAT and NTFS, LVM, many different disk partition
601 schemes, qcow, qcow2, vmdk.
602
603 Libguestfs provides ways to enumerate guest storage (eg. partitions,
604 LVs, what filesystem is in each LV, etc.).  It can also run commands
605 in the context of the guest.  Also you can access filesystems over
606 FUSE.
607
608 Errors which happen while using the API are turned into Python
609 RuntimeError exceptions.
610
611 To create a guestfs handle you usually have to perform the following
612 sequence of calls:
613
614 # Create the handle, call add_drive* at least once, and possibly
615 # several times if the guest has multiple block devices:
616 g = guestfs.GuestFS ()
617 g.add_drive_opts (\"guest.img\", format=\"raw\")
618
619 # Launch the qemu subprocess and wait for it to become ready:
620 g.launch ()
621
622 # Now you can issue commands, for example:
623 logvols = g.lvs ()
624
625 \"\"\"
626
627 import libguestfsmod
628
629 ";
630
631   List.iter (
632     fun (name, bitmask) ->
633       pr "EVENT_%s = 0x%x\n" (String.uppercase name) bitmask
634   ) events;
635   pr "\n";
636
637   pr "\
638 class ClosedHandle(ValueError):
639     pass
640
641 class GuestFS:
642     \"\"\"Instances of this class are libguestfs API handles.\"\"\"
643
644     def __init__ (self):
645         \"\"\"Create a new libguestfs handle.\"\"\"
646         self._o = libguestfsmod.create ()
647
648     def __del__ (self):
649         if self._o:
650             libguestfsmod.close (self._o)
651
652     def _check_not_closed (self):
653         if not self._o:
654             raise ClosedHandle (\"GuestFS: method called on closed handle\")
655
656     def close (self):
657         \"\"\"Explicitly close the guestfs handle.
658
659         The handle is closed implicitly when its reference count goes
660         to zero (eg. when it goes out of scope or the program ends).
661
662         This call is only needed if you want to force the handle to
663         close now.  After calling this, the program must not call
664         any method on the handle (except the implicit call to
665         __del__ which happens when the final reference is cleaned up).
666         \"\"\"
667         self._check_not_closed ()
668         libguestfsmod.close (self._o)
669         self._o = None
670
671     def set_event_callback (self, cb, event_bitmask):
672         \"\"\"Register an event callback.
673
674         Register \"cb\" as a callback function for all of the
675         events in \"event_bitmask\".  \"event_bitmask\" should be
676         one or more \"guestfs.EVENT_*\" flags logically or'd together.
677
678         This function returns an event handle which can be used
679         to delete the callback (see \"delete_event_callback\").
680
681         The callback function receives 4 parameters:
682
683         cb (event, event_handle, buf, array)
684
685         \"event\" is one of the \"EVENT_*\" flags.  \"buf\" is a
686         message buffer (only for some types of events).  \"array\"
687         is an array of integers (only for some types of events).
688
689         You should read the documentation for
690         \"guestfs_set_event_callback\" in guestfs(3) before using
691         this function.
692         \"\"\"
693         self._check_not_closed ()
694         return libguestfsmod.set_event_callback (self._o, cb, event_bitmask)
695
696     def delete_event_callback (self, event_handle):
697         \"\"\"Delete an event callback.\"\"\"
698         self._check_not_closed ()
699         libguestfsmod.delete_event_callback (self._o, event_handle)
700
701 ";
702
703   List.iter (
704     fun (name, (ret, args, optargs), _, flags, _, _, longdesc) ->
705       pr "    def %s (self" name;
706       List.iter (fun arg -> pr ", %s" (name_of_argt arg)) args;
707       List.iter (
708         function
709         | Bool n | Int n | Int64 n -> pr ", %s=-1" n
710         | String n -> pr ", %s=None" n
711         | _ -> assert false
712       ) optargs;
713       pr "):\n";
714
715       if not (List.mem NotInDocs flags) then (
716         let doc = replace_str longdesc "C<guestfs_" "C<g." in
717         let doc =
718           match ret with
719           | RErr | RInt _ | RInt64 _ | RBool _
720           | RConstOptString _ | RConstString _
721           | RString _ | RBufferOut _ -> doc
722           | RStringList _ ->
723               doc ^ "\n\nThis function returns a list of strings."
724           | RStruct (_, typ) ->
725               doc ^ sprintf "\n\nThis function returns a dictionary, with keys matching the various fields in the guestfs_%s structure." typ
726           | RStructList (_, typ) ->
727               doc ^ sprintf "\n\nThis function returns a list of %ss.  Each %s is represented as a dictionary." typ typ
728           | RHashtable _ ->
729               doc ^ "\n\nThis function returns a dictionary." in
730         let doc =
731           if List.mem ProtocolLimitWarning flags then
732             doc ^ "\n\n" ^ protocol_limit_warning
733           else doc in
734         let doc =
735           match deprecation_notice flags with
736           | None -> doc
737           | Some txt -> doc ^ "\n\n" ^ txt in
738         let doc = pod2text ~width:60 name doc in
739         let doc = List.map (fun line -> replace_str line "\\" "\\\\") doc in
740         let doc = String.concat "\n        " doc in
741         pr "        \"\"\"%s\"\"\"\n" doc;
742       );
743       (* Callers might pass in iterables instead of plain lists;
744        * convert those to plain lists because the C side of things
745        * cannot deal with iterables.  (RHBZ#693306).
746        *)
747       List.iter (
748         function
749         | Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _
750         | FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
751         | BufferIn _ | Pointer _ -> ()
752         | StringList n | DeviceList n ->
753             pr "        %s = list (%s)\n" n n
754       ) args;
755       pr "        self._check_not_closed ()\n";
756       pr "        return libguestfsmod.%s (self._o" name;
757       List.iter (fun arg -> pr ", %s" (name_of_argt arg)) (args@optargs);
758       pr ")\n\n";
759   ) all_functions