]> sigrok.org Git - libsigrokdecode.git/blob - decode.c
I2C decoder format draft (unfinished).
[libsigrokdecode.git] / decode.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
19  */
20
21 #include <sigrokdecode.h> /* First, so we avoid a _POSIX_C_SOURCE warning. */
22 #include <stdio.h>
23 #include <string.h>
24
25 /**
26  * Initialize libsigrokdecode.
27  *
28  * @return 0 upon success, non-zero otherwise.
29  */
30 int sigrokdecode_init(void)
31 {
32         /* Py_Initialize() returns void and usually cannot fail. */
33         Py_Initialize();
34
35         /* Add some more search directories for convenience. */
36         /* FIXME: Check error code. */
37         PyRun_SimpleString(
38                 "import sys;"
39                 "sys.path.append('libsigrokdecode/scripts');"
40                 "sys.path.append('../libsigrokdecode/scripts');"
41                 "sys.path.append('/usr/local/share/sigrok');"
42                 );
43
44         return 0;
45 }
46
47 /**
48  * Helper function to handle Python strings.
49  *
50  * TODO: @param entries.
51  *
52  * @return 0 upon success, non-zero otherwise. The 'outstr' argument will
53  *         point to a malloc()ed string upon success.
54  */
55 static int h_str(PyObject *py_res, PyObject *py_func, PyObject *py_mod,
56                  const char *key, char **outstr)
57 {
58         PyObject *py_str;
59         char *str;
60
61         py_str = PyMapping_GetItemString(py_res, (char *)key);
62         if (!py_str || !PyString_Check(py_str)) {
63                 if (PyErr_Occurred())
64                         PyErr_Print();
65                 Py_DECREF(py_func);
66                 Py_DECREF(py_mod);
67                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
68         }
69
70         if (!(str = PyString_AsString(py_str))) {
71                 if (PyErr_Occurred())
72                         PyErr_Print();
73                 Py_DECREF(py_str);
74                 Py_DECREF(py_func);
75                 Py_DECREF(py_mod);
76                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
77         }
78
79         if (!(*outstr = strdup(str))) {
80                 if (PyErr_Occurred())
81                         PyErr_Print();
82                 Py_DECREF(py_str);
83                 Py_DECREF(py_func);
84                 Py_DECREF(py_mod);
85                 return SIGROKDECODE_ERR_MALLOC;
86         }
87
88         Py_DECREF(py_str);
89
90         return 0;
91 }
92
93 /**
94  * TODO
95  *
96  * @param name TODO
97  * @return 0 upon success, non-zero otherwise.
98  */
99 int sigrokdecode_load_decoder(const char *name,
100                               struct sigrokdecode_decoder **dec)
101 {
102         struct sigrokdecode_decoder *d;
103         PyObject *py_name, *py_mod, *py_func, *py_res /* , *py_tuple */;
104         int r;
105
106         /* Get the name of the decoder module as Python string. */
107         if (!(py_name = PyString_FromString(name))) {
108                 PyErr_Print();
109                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
110         }
111
112         /* "Import" the Python module. */
113         if (!(py_mod = PyImport_Import(py_name))) {
114                 PyErr_Print();
115                 Py_DECREF(py_name);
116                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
117         }
118         Py_DECREF(py_name);
119
120         /* Get the 'register' function name as Python callable object. */
121         py_func = PyObject_GetAttrString(py_mod, "register");
122         if (!py_func || !PyCallable_Check(py_func)) {
123                 if (PyErr_Occurred())
124                         PyErr_Print();
125                 Py_DECREF(py_mod);
126                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
127         }
128
129         /* Call the 'register' function without arguments, get the result. */
130         if (!(py_res = PyObject_CallFunction(py_func, NULL))) {
131                 PyErr_Print();
132                 Py_DECREF(py_func);
133                 Py_DECREF(py_mod);
134                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
135         }
136
137         if (!(d = malloc(sizeof(struct sigrokdecode_decoder))))
138                 return SIGROKDECODE_ERR_MALLOC;
139
140         if ((r = h_str(py_res, py_func, py_mod, "id", &(d->id))) < 0)
141                 return r;
142
143         if ((r = h_str(py_res, py_func, py_mod, "name", &(d->name))) < 0)
144                 return r;
145
146         if ((r = h_str(py_res, py_func, py_mod, "desc", &(d->desc))) < 0)
147                 return r;
148
149         d->py_mod = py_mod;
150
151         Py_DECREF(py_res);
152         Py_DECREF(py_func);
153
154         /* Get the 'decode' function name as Python callable object. */
155         py_func = PyObject_GetAttrString(py_mod, "decode");
156         if (!py_func || !PyCallable_Check(py_func)) {
157                 if (PyErr_Occurred())
158                         PyErr_Print();
159                 Py_DECREF(py_mod);
160                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
161         }
162
163         d->py_func = py_func;
164
165         /* TODO: Handle inputformats, outputformats. */
166
167         *dec = d;
168
169         return 0;
170 }
171
172 /**
173  * Run the specified decoder function.
174  *
175  * @param dec TODO
176  * @param inbuf TODO
177  * @param inbuflen TODO
178  * @param outbuf TODO
179  * @param outbuflen TODO
180  * @return 0 upon success, non-zero otherwise.
181  */
182 int sigrokdecode_run_decoder(struct sigrokdecode_decoder *dec,
183                              uint8_t *inbuf, uint64_t inbuflen,
184                              uint8_t **outbuf, uint64_t *outbuflen)
185 {
186         PyObject *py_mod, *py_func, *py_args, *py_value, *py_res;
187         int ret;
188
189         /* TODO: Use #defines for the return codes. */
190
191         /* Return an error upon unusable input. */
192         if (dec == NULL)
193                 return SIGROKDECODE_ERR_ARGS; /* TODO: More specific error? */
194         if (inbuf == NULL)
195                 return SIGROKDECODE_ERR_ARGS; /* TODO: More specific error? */
196         if (inbuflen == 0) /* No point in working on empty buffers. */
197                 return SIGROKDECODE_ERR_ARGS; /* TODO: More specific error? */
198         if (outbuf == NULL)
199                 return SIGROKDECODE_ERR_ARGS; /* TODO: More specific error? */
200         if (outbuflen == NULL)
201                 return SIGROKDECODE_ERR_ARGS; /* TODO: More specific error? */
202
203         /* TODO: Error handling. */
204         py_mod = dec->py_mod;
205         py_func = dec->py_func;
206
207         /* TODO: Really run Py_DECREF on py_mod/py_func? */
208
209         /* Create a Python tuple of size 1. */
210         if (!(py_args = PyTuple_New(1))) {
211                 PyErr_Print();
212                 Py_DECREF(py_func);
213                 Py_DECREF(py_mod);
214                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
215         }
216
217         /* Get the input buffer as Python "string" (byte array). */
218         /* TODO: int vs. uint64_t for 'inbuflen'? */
219         if (!(py_value = Py_BuildValue("s#", inbuf, inbuflen))) {
220                 PyErr_Print();
221                 Py_DECREF(py_args);
222                 Py_DECREF(py_func);
223                 Py_DECREF(py_mod);
224                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
225         }
226
227         if (PyTuple_SetItem(py_args, 0, py_value) != 0) {
228                 PyErr_Print();
229                 Py_DECREF(py_value);
230                 Py_DECREF(py_args);
231                 Py_DECREF(py_func);
232                 Py_DECREF(py_mod);
233                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
234         }
235
236         if (!(py_res = PyObject_CallObject(py_func, py_args))) {
237                 PyErr_Print();
238                 Py_DECREF(py_value);
239                 Py_DECREF(py_args);
240                 Py_DECREF(py_func);
241                 Py_DECREF(py_mod);
242                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
243         }
244
245         if ((ret = PyObject_AsCharBuffer(py_res, (const char **)outbuf,
246                                          (Py_ssize_t *)outbuflen))) {
247                 PyErr_Print();
248                 Py_DECREF(py_res);
249                 Py_DECREF(py_value);
250                 Py_DECREF(py_args);
251                 Py_DECREF(py_func);
252                 Py_DECREF(py_mod);
253                 return SIGROKDECODE_ERR_PYTHON; /* TODO: More specific error? */
254         }
255
256         Py_DECREF(py_res);
257         // Py_DECREF(py_value);
258         Py_DECREF(py_args);
259         Py_DECREF(py_func);
260         Py_DECREF(py_mod);
261
262         return 0;
263 }
264
265 /**
266  * Shutdown libsigrokdecode.
267  *
268  * @return 0 upon success, non-zero otherwise.
269  */
270 int sigrokdecode_shutdown(void)
271 {
272         /* Py_Finalize() returns void, any finalization errors are ignored. */
273         Py_Finalize();
274
275         return 0;
276 }