python: Port more tests.
[gpgme.git] / lang / python / gpgme.i
1 /*
2 # $Id$
3 # Copyright (C) 2004,2008 Igor Belyi <belyi@users.sourceforge.net>
4 # Copyright (C) 2002 John Goerzen <jgoerzen@complete.org>
5 #
6 #    This library is free software; you can redistribute it and/or
7 #    modify it under the terms of the GNU Lesser General Public
8 #    License as published by the Free Software Foundation; either
9 #    version 2.1 of the License, or (at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19 */
20 %module pygpgme
21 %include "cpointer.i"
22 %include "cstring.i"
23
24 // Generate doc strings for all methods.
25 %feature("autodoc", "0");
26
27 /* Allow use of Unicode objects, bytes, and None for strings.  */
28
29 %typemap(in) const char * {
30   if ($input == Py_None)
31     $1 = NULL;
32   else if (PyUnicode_Check($input))
33     $1 = PyUnicode_AsUTF8($input);
34   else if (PyBytes_Check($input))
35     $1 = PyBytes_AsString($input);
36   else {
37     PyErr_Format(PyExc_TypeError,
38                  "arg %d: expected str, bytes, or None, got %s",
39                  $argnum, $input->ob_type->tp_name);
40     return NULL;
41   }
42 }
43 %typemap(freearg) const char * "";
44
45 /* Likewise for a list of strings.  */
46 %typemap(in) const char *[] {
47   /* Check if is a list */
48   if (PyList_Check($input)) {
49     size_t i, size = PyList_Size($input);
50     $1 = (char **) malloc((size+1) * sizeof(char *));
51
52     for (i = 0; i < size; i++) {
53       PyObject *o = PyList_GetItem($input,i);
54       if (PyUnicode_Check(o))
55         $1[i] = PyUnicode_AsUTF8(o);
56       else if (PyString_Check(o))
57         $1[i] = PyString_AsString(o);
58       else {
59         PyErr_Format(PyExc_TypeError,
60                      "arg %d: list must contain only str or bytes, got %s "
61                      "at position %d",
62                      $argnum, o->ob_type->tp_name, i);
63         free($1);
64         return NULL;
65       }
66     }
67     $1[i] = NULL;
68   } else {
69     PyErr_Format(PyExc_TypeError,
70                  "arg %d: expected a list of str or bytes, got %s",
71                  $argnum, $input->ob_type->tp_name);
72     return NULL;
73   }
74 }
75 %typemap(freearg) const char *[] {
76   free((char *) $1);
77 }
78
79 // Release returned buffers as necessary.
80 %typemap(newfree) char * "free($1);";
81 %newobject gpgme_data_release_and_get_mem;
82
83 %{
84 /* Convert object to a pointer to gpgme type */
85 PyObject* object_to_gpgme_t(PyObject* input, const char* objtype, int argnum) {
86   PyObject *pyname = NULL, *pypointer = NULL;
87   pyname = PyObject_CallMethod(input, "_getctype", NULL);
88   if (pyname && PyUnicode_Check(pyname))
89     {
90       if (strcmp(PyUnicode_AsUTF8(pyname), objtype) != 0)
91         {
92           PyErr_Format(PyExc_TypeError,
93                        "arg %d: Expected value of type %s, but got %s",
94                        argnum, objtype, PyUnicode_AsUTF8(pyname));
95           Py_DECREF(pyname);
96           return NULL;
97         }
98     }
99   else
100     {
101       PyErr_Format(PyExc_TypeError,
102                    "Protocol violation: Expected an instance of type str "
103                    "from _getctype, but got %s",
104                    pyname == NULL ? "NULL"
105                    : (pyname == Py_None ? "None" : pyname->ob_type->tp_name));
106       return NULL;
107     }
108
109   Py_DECREF(pyname);
110   pypointer = PyObject_GetAttrString(input, "wrapped");
111   if (pypointer == NULL) {
112     PyErr_Format(PyExc_TypeError,
113                  "arg %d: Use of uninitialized Python object %s",
114                  argnum, objtype);
115     return NULL;
116   }
117   return pypointer;
118 }
119 %}
120
121 %typemap(arginit) gpgme_key_t [] {
122   $1 = NULL;
123 }
124
125 %typemap(in) gpgme_key_t [] {
126   int i, numb = 0;
127   if (!PySequence_Check($input)) {
128     PyErr_Format(PyExc_ValueError, "arg %d: Expected a list of gpgme_key_t",
129                  $argnum);
130     return NULL;
131   }
132   if((numb = PySequence_Length($input)) != 0) {
133     $1 = (gpgme_key_t*)malloc((numb+1)*sizeof(gpgme_key_t));
134     for(i=0; i<numb; i++) {
135       PyObject *pypointer = PySequence_GetItem($input, i);
136
137       /* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
138       /* &1_descriptor = $&1_descriptor *1_descriptor = $*1_descriptor */
139
140       // Following code is from swig's python.swg
141       if ((SWIG_ConvertPtr(pypointer,(void **) &$1[i], $*1_descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) {
142         Py_DECREF(pypointer);
143         return NULL;
144       }
145       Py_DECREF(pypointer);
146     }
147     $1[numb] = NULL;
148   }
149 }
150 %typemap(freearg) gpgme_key_t [] {
151   if ($1) free($1);
152 }
153
154 // Special handling for references to our objects.
155 %typemap(in) gpgme_data_t DATAIN {
156   if ($input == Py_None)
157     $1 = NULL;
158   else {
159     PyObject *pypointer = NULL;
160
161     if((pypointer=object_to_gpgme_t($input, "$1_ltype", $argnum)) == NULL)
162       return NULL;
163
164     /* input = $input, 1 = $1, 1_descriptor = $1_descriptor */
165
166     // Following code is from swig's python.swg
167
168     if ((SWIG_ConvertPtr(pypointer,(void **) &$1, $1_descriptor,
169          SWIG_POINTER_EXCEPTION | $disown )) == -1) {
170       Py_DECREF(pypointer);
171       return NULL;
172     }
173     Py_DECREF(pypointer);
174   }
175 }
176
177 %apply gpgme_data_t DATAIN {gpgme_data_t plain, gpgme_data_t cipher,
178                         gpgme_data_t sig, gpgme_data_t signed_text,
179                         gpgme_data_t plaintext, gpgme_data_t keydata,
180                         gpgme_data_t pubkey, gpgme_data_t seckey,
181                         gpgme_data_t out};
182
183 /* SWIG has problems interpreting ssize_t, off_t or gpgme_error_t in
184    gpgme.h.  */
185 /* XXX: This is wrong at least for off_t if compiled with LFS.  */
186 %typemap(out) ssize_t, off_t, gpgme_error_t, gpgme_err_code_t, gpgme_err_source_t, gpg_error_t {
187   $result = PyLong_FromLong($1);
188 }
189 /* XXX: This is wrong at least for off_t if compiled with LFS.  */
190 %typemap(in) ssize_t, off_t, gpgme_error_t, gpgme_err_code_t, gpgme_err_source_t, gpg_error_t {
191   $1 = PyLong_AsLong($input);
192 }
193
194 // Those are for gpgme_data_read() and gpgme_strerror_r()
195 %typemap(in) (void *buffer, size_t size), (char *buf, size_t buflen) {
196    $2 = PyLong_AsLong($input);
197    if ($2 < 0) {
198      PyErr_SetString(PyExc_ValueError, "Positive integer expected");
199      return NULL;
200    }
201    $1 = ($1_ltype) malloc($2+1);
202 }
203 %typemap(argout) (void *buffer, size_t size), (char *buf, size_t buflen) {
204   Py_XDECREF($result);   /* Blow away any previous result */
205   if (result < 0) {      /* Check for I/O error */
206     free($1);
207     return PyErr_SetFromErrno(PyExc_RuntimeError);
208   }
209   $result = PyBytes_FromStringAndSize($1,result);
210   free($1);
211 }
212
213 /* For gpgme_data_write, but should be universal.  */
214 %typemap(in) (const void *buffer, size_t size) {
215   if ($input == Py_None)
216     $1 = NULL, $2 = 0;
217   else if (PyUnicode_Check($input))
218     $1 = PyUnicode_AsUTF8AndSize($input, (size_t *) &$2);
219   else if (PyBytes_Check($input))
220     PyBytes_AsStringAndSize($input, (char **) &$1, (size_t *) &$2);
221   else {
222     PyErr_Format(PyExc_TypeError,
223                  "arg %d: expected str, bytes, or None, got %s",
224                  $argnum, $input->ob_type->tp_name);
225     return NULL;
226   }
227 }
228 %typemap(freearg) (const void *buffer, size_t size) "";
229
230 // Make types containing 'next' field to be lists
231 %ignore next;
232 %typemap(out) gpgme_sig_notation_t, gpgme_engine_info_t, gpgme_subkey_t, gpgme_key_sig_t,
233         gpgme_user_id_t, gpgme_invalid_key_t, gpgme_recipient_t, gpgme_new_signature_t,
234         gpgme_signature_t, gpgme_import_status_t, gpgme_conf_arg_t, gpgme_conf_opt_t,
235         gpgme_conf_comp_t {
236   int i;
237   int size = 0;
238   $1_ltype curr;
239   for (curr = $1; curr != NULL; curr = curr->next) {
240     size++;
241   }
242   $result = PyList_New(size);
243   for (i=0,curr=$1; i<size; i++,curr=curr->next) {
244     PyObject *o = SWIG_NewPointerObj(SWIG_as_voidptr(curr), $1_descriptor, %newpointer_flags);
245     PyList_SetItem($result, i, o);
246   }
247 }
248
249 // Include mapper for edit callbacks
250 %typemap(in) (gpgme_edit_cb_t fnc, void *fnc_value) {
251   $1 = (gpgme_edit_cb_t) pyEditCb;
252   if ($input == Py_None)
253     $2 = NULL;
254   else
255     $2 = $input;
256 }
257
258 /* Include the unmodified <gpgme.h> for cc, and the cleaned-up local
259    version for SWIG.  We do, however, want to hide certain fields on
260    some structs, which we provide prior to including the version for
261    SWIG.  */
262  %{ #include <gpgme.h> %}
263
264 /* This is for notations, where we want to hide the length fields, and
265    the unused bit field block.  */
266 struct _gpgme_sig_notation
267 {
268   struct _gpgme_sig_notation *next;
269
270   /* If NAME is a null pointer, then VALUE contains a policy URL
271      rather than a notation.  */
272   char *name;
273
274   /* The value of the notation data.  */
275   char *value;
276
277   /* The accumulated flags.  */
278   gpgme_sig_notation_flags_t flags;
279
280   /* Notation data is human-readable.  */
281   unsigned int human_readable : 1;
282
283   /* Notation data is critical.  */
284   unsigned int critical : 1;
285 };
286
287 /* Now include our local modified version.  Any structs defined above
288    are ignored.  */
289 %include "gpgme.h"
290
291 %include "errors.i"
292
293 // Generating and handling pointers-to-pointers.
294
295 %pointer_functions(gpgme_ctx_t, gpgme_ctx_t_p);
296 %pointer_functions(gpgme_data_t, gpgme_data_t_p);
297 %pointer_functions(gpgme_key_t, gpgme_key_t_p);
298 %pointer_functions(gpgme_error_t, gpgme_error_t_p);
299 %pointer_functions(gpgme_trust_item_t, gpgme_trust_item_t_p);
300 %pointer_functions(gpgme_engine_info_t, gpgme_engine_info_t_p);
301 %pointer_functions(PyObject *, PyObject_p_p);
302 %pointer_functions(void *, void_p_p);
303
304 // Helper functions.
305
306 %{
307 #include <stdio.h>
308 %}
309 FILE *fdopen(int fildes, const char *mode);
310
311 %{
312 #include "helpers.h"
313 %}
314 %include "helpers.h"