]> sigrok.org Git - libsigrokdecode.git/blob - decoder.c
srd: Add/use SRD_API/SRD_PRIV macros.
[libsigrokdecode.git] / decoder.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5  * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "config.h"
22 #include "sigrokdecode.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
23 #include "sigrokdecode-internal.h"
24 #include <glib.h>
25
26 /* The list of protocol decoders. */
27 SRD_PRIV GSList *pd_list = NULL;
28
29 /* module_sigrokdecode.c */
30 extern SRD_PRIV PyObject *mod_sigrokdecode;
31
32 /**
33  * Returns the list of supported/loaded protocol decoders.
34  *
35  * This is a GSList containing the names of the decoders as strings.
36  *
37  * @return List of decoders, NULL if none are supported or loaded.
38  */
39 SRD_API GSList *srd_list_decoders(void)
40 {
41         return pd_list;
42 }
43
44 /**
45  * Get the decoder with the specified ID.
46  *
47  * @param id The ID string of the decoder to return.
48  * @return The decoder with the specified ID, or NULL if not found.
49  */
50 SRD_API struct srd_decoder *srd_get_decoder_by_id(const char *id)
51 {
52         GSList *l;
53         struct srd_decoder *dec;
54
55         for (l = srd_list_decoders(); l; l = l->next) {
56                 dec = l->data;
57                 if (!strcmp(dec->id, id))
58                         return dec;
59         }
60
61         return NULL;
62 }
63
64 static int get_probes(struct srd_decoder *d, char *attr, GSList **pl)
65 {
66         PyObject *py_probelist, *py_entry;
67         struct srd_probe *p;
68         int ret, num_probes, i;
69
70         if (!PyObject_HasAttrString(d->py_dec, attr))
71                 /* No probes of this type specified. */
72                 return SRD_OK;
73
74         ret = SRD_ERR_PYTHON;
75         py_probelist = py_entry = NULL;
76
77         py_probelist = PyObject_GetAttrString(d->py_dec, attr);
78         if (!PyList_Check(py_probelist)) {
79                 srd_err("Protocol decoder %s %s attribute is not "
80                         "a list.", d->name, attr);
81                 goto err_out;
82         }
83
84         num_probes = PyList_Size(py_probelist);
85         if (num_probes == 0)
86                 /* Empty probelist. */
87                 return SRD_OK;
88
89         for (i = 0; i < num_probes; i++) {
90                 py_entry = PyList_GetItem(py_probelist, i);
91                 if (!PyDict_Check(py_entry)) {
92                         srd_err("Protocol decoder %s %s attribute is not "
93                                 "a list with dict elements.", d->name, attr);
94                         goto err_out;
95                 }
96
97                 if (!(p = g_try_malloc(sizeof(struct srd_probe)))) {
98                         ret = SRD_ERR_MALLOC;
99                         goto err_out;
100                 }
101
102                 if ((py_dictitem_as_str(py_entry, "id", &p->id)) != SRD_OK)
103                         goto err_out;
104                 if ((py_dictitem_as_str(py_entry, "name", &p->name)) != SRD_OK)
105                         goto err_out;
106                 if ((py_dictitem_as_str(py_entry, "desc", &p->desc)) != SRD_OK)
107                         goto err_out;
108                 p->order = i;
109
110                 *pl = g_slist_append(*pl, p);
111         }
112         ret = SRD_OK;
113
114 err_out:
115         Py_DecRef(py_entry);
116         Py_DecRef(py_probelist);
117
118         return ret;
119 }
120
121 /**
122  * Load a protocol decoder module into the embedded Python interpreter.
123  *
124  * @param name The module name to be loaded.
125  * @param dec Pointer to the struct srd_decoder filled with the loaded module.
126  *
127  * @return SRD_OK upon success, a (negative) error code otherwise.
128  */
129 SRD_API int srd_load_decoder(const char *name, struct srd_decoder **dec)
130 {
131         PyObject *py_basedec, *py_method, *py_attr, *py_annlist, *py_ann;
132         struct srd_decoder *d;
133         int alen, ret, i;
134         char **ann;
135
136         srd_dbg("Loading module '%s'.", name);
137
138         py_basedec = py_method = py_attr = NULL;
139
140         if (!(d = g_try_malloc0(sizeof(struct srd_decoder)))) {
141                 srd_dbg("Failed to malloc struct srd_decoder.");
142                 ret = SRD_ERR_MALLOC;
143                 goto err_out;
144         }
145
146         ret = SRD_ERR_PYTHON;
147
148         /* Import the Python module. */
149         if (!(d->py_mod = PyImport_ImportModule(name))) {
150                 catch_exception("import of '%s' failed.", name);
151                 goto err_out;
152         }
153
154         /* Get the 'Decoder' class as Python object. */
155         if (!(d->py_dec = PyObject_GetAttrString(d->py_mod, "Decoder"))) {
156                 /* This generated an AttributeError exception. */
157                 PyErr_Clear();
158                 srd_err("Decoder class not found in protocol decoder %s.", name);
159                 goto err_out;
160         }
161
162         if (!(py_basedec = PyObject_GetAttrString(mod_sigrokdecode, "Decoder"))) {
163                 srd_dbg("sigrokdecode module not loaded.");
164                 goto err_out;
165         }
166
167         if (!PyObject_IsSubclass(d->py_dec, py_basedec)) {
168                 srd_err("Decoder class in protocol decoder module %s is not "
169                         "a subclass of sigrokdecode.Decoder.", name);
170                 goto err_out;
171         }
172         Py_CLEAR(py_basedec);
173
174         /* Check for a proper start() method. */
175         if (!PyObject_HasAttrString(d->py_dec, "start")) {
176                 srd_err("Protocol decoder %s has no start() method Decoder "
177                         "class.", name);
178                 goto err_out;
179         }
180         py_method = PyObject_GetAttrString(d->py_dec, "start");
181         if (!PyFunction_Check(py_method)) {
182                 srd_err("Protocol decoder %s Decoder class attribute 'start' "
183                         "is not a method.", name);
184                 goto err_out;
185         }
186         Py_CLEAR(py_method);
187
188         /* Check for a proper decode() method. */
189         if (!PyObject_HasAttrString(d->py_dec, "decode")) {
190                 srd_err("Protocol decoder %s has no decode() method Decoder "
191                         "class.", name);
192                 goto err_out;
193         }
194         py_method = PyObject_GetAttrString(d->py_dec, "decode");
195         if (!PyFunction_Check(py_method)) {
196                 srd_err("Protocol decoder %s Decoder class attribute 'decode' "
197                         "is not a method.", name);
198                 goto err_out;
199         }
200         Py_CLEAR(py_method);
201
202         /* If present, options must be a dictionary. */
203         if (PyObject_HasAttrString(d->py_dec, "options")) {
204                 py_attr = PyObject_GetAttrString(d->py_dec, "options");
205                 if (!PyDict_Check(py_attr)) {
206                         srd_err("Protocol decoder %s options attribute is not "
207                                 "a dictionary.", d->name);
208                         Py_DecRef(py_attr);
209                         goto err_out;
210                 }
211                 Py_DecRef(py_attr);
212         }
213
214         /* Check and import required probes. */
215         if (get_probes(d, "probes", &d->probes) != SRD_OK)
216                 goto err_out;
217
218         /* Check and import optional probes. */
219         if (get_probes(d, "optional_probes", &d->opt_probes) != SRD_OK)
220                 goto err_out;
221
222         /* Store required fields in newly allocated strings. */
223         if (py_attr_as_str(d->py_dec, "id", &(d->id)) != SRD_OK)
224                 goto err_out;
225
226         if (py_attr_as_str(d->py_dec, "name", &(d->name)) != SRD_OK)
227                 goto err_out;
228
229         if (py_attr_as_str(d->py_dec, "longname", &(d->longname)) != SRD_OK)
230                 goto err_out;
231
232         if (py_attr_as_str(d->py_dec, "desc", &(d->desc)) != SRD_OK)
233                 goto err_out;
234
235         if (py_attr_as_str(d->py_dec, "license", &(d->license)) != SRD_OK)
236                 goto err_out;
237
238         /* TODO: Handle inputformats, outputformats. */
239         d->inputformats = NULL;
240         d->outputformats = NULL;
241
242         /* Convert class annotation attribute to GSList of **char */
243         d->annotations = NULL;
244         if (PyObject_HasAttrString(d->py_dec, "annotations")) {
245                 py_annlist = PyObject_GetAttrString(d->py_dec, "annotations");
246                 if (!PyList_Check(py_annlist)) {
247                         srd_err("Protocol decoder module %s annotations "
248                                 "should be a list.", name);
249                         goto err_out;
250                 }
251                 alen = PyList_Size(py_annlist);
252                 for (i = 0; i < alen; i++) {
253                         py_ann = PyList_GetItem(py_annlist, i);
254                         if (!PyList_Check(py_ann) || PyList_Size(py_ann) != 2) {
255                                 srd_err("Protocol decoder module %s "
256                                         "annotation %d should be a list with "
257                                         "two elements.", name, i + 1);
258                                 goto err_out;
259                         }
260
261                         if (py_strlist_to_char(py_ann, &ann) != SRD_OK) {
262                                 goto err_out;
263                         }
264                         d->annotations = g_slist_append(d->annotations, ann);
265                 }
266         }
267
268         *dec = d;
269         ret = SRD_OK;
270
271 err_out:
272         if (ret != SRD_OK) {
273                 Py_XDECREF(py_method);
274                 Py_XDECREF(py_basedec);
275                 Py_XDECREF(d->py_dec);
276                 Py_XDECREF(d->py_mod);
277                 g_free(d);
278         }
279
280         return ret;
281 }
282
283 SRD_API char *srd_decoder_doc(struct srd_decoder *dec)
284 {
285         PyObject *py_str;
286         char *doc;
287
288         if (!PyObject_HasAttrString(dec->py_mod, "__doc__"))
289                 return NULL;
290
291         if (!(py_str = PyObject_GetAttrString(dec->py_mod, "__doc__"))) {
292                 catch_exception("");
293                 return NULL;
294         }
295
296         doc = NULL;
297         if (py_str != Py_None)
298                 py_str_as_str(py_str, &doc);
299         Py_DecRef(py_str);
300
301         return doc;
302 }
303
304 static void free_probes(GSList *probelist)
305 {
306         GSList *l;
307         struct srd_probe *p;
308
309         if (probelist == NULL)
310                 return;
311
312         for (l = probelist; l; l = l->next) {
313                 p = l->data;
314                 g_free(p->id);
315                 g_free(p->name);
316                 g_free(p->desc);
317                 g_free(p);
318         }
319         g_slist_free(probelist);
320
321 }
322
323 /**
324  * Unload decoder module.
325  *
326  * @param dec The struct srd_decoder to be unloaded.
327  *
328  * @return SRD_OK upon success, a (negative) error code otherwise.
329  */
330 SRD_API int srd_unload_decoder(struct srd_decoder *dec)
331 {
332         srd_dbg("unloading decoder %s", dec->name);
333
334         /* Since any instances of this decoder need to be released as well,
335          * but they could be anywhere in the stack, just free the entire
336          * stack. A frontend reloading a decoder thus has to restart all
337          * instances, and rebuild the stack. */
338         srd_instance_free_all(NULL);
339
340         free_probes(dec->probes);
341         free_probes(dec->opt_probes);
342         g_free(dec->id);
343         g_free(dec->name);
344         g_free(dec->longname);
345         g_free(dec->desc);
346         g_free(dec->license);
347
348         /* TODO: Free everything in inputformats and outputformats. */
349         if (dec->inputformats != NULL)
350                 g_slist_free(dec->inputformats);
351         if (dec->outputformats != NULL)
352                 g_slist_free(dec->outputformats);
353
354         /* The module's Decoder class. */
355         Py_XDECREF(dec->py_dec);
356         /* The module itself. */
357         Py_XDECREF(dec->py_mod);
358
359         /* TODO: (g_)free dec itself? */
360
361         return SRD_OK;
362 }
363
364 SRD_API int srd_load_all_decoders(void)
365 {
366         GDir *dir;
367         GError *error;
368         struct srd_decoder *dec;
369         int ret;
370         const gchar *direntry;
371         char *decodername;
372
373         if (!(dir = g_dir_open(DECODERS_DIR, 0, &error))) {
374                 return SRD_ERR_DECODERS_DIR;
375         }
376
377         while ((direntry = g_dir_read_name(dir)) != NULL) {
378                 /* The decoder name is the PD directory name (e.g. "i2c"). */
379                 decodername = g_strdup(direntry);
380
381                 if ((ret = srd_load_decoder(decodername, &dec)) == SRD_OK) {
382                         /* Append it to the list of supported/loaded decoders. */
383                         pd_list = g_slist_append(pd_list, dec);
384                 }
385         }
386         g_dir_close(dir);
387
388         return SRD_OK;
389 }
390
391 /**
392  * TODO
393  */
394 SRD_API int srd_unload_all_decoders(void)
395 {
396         GSList *l;
397         struct srd_decoder *dec;
398
399         for (l = srd_list_decoders(); l; l = l->next) {
400                 dec = l->data;
401                 srd_unload_decoder(dec);
402         }
403
404         return SRD_OK;
405 }