blob: c1b90404cbd43fd513363de5de34599ed7453387 [file] [log] [blame]
Bert Vermeulenb2c19612011-12-04 10:33:02 +01001/*
Uwe Hermann50bd5d22013-04-23 22:27:20 +02002 * This file is part of the libsigrokdecode project.
Bert Vermeulenb2c19612011-12-04 10:33:02 +01003 *
4 * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
Bert Vermeulen4fadb122012-01-22 03:29:22 +01005 * Copyright (C) 2012 Bert Vermeulen <bert@biot.com>
Bert Vermeulenb2c19612011-12-04 10:33:02 +01006 *
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
Marcus Comstedtf6c7ead2014-07-01 00:07:40 +020021#include "libsigrokdecode-internal.h" /* First, so we avoid a _POSIX_C_SOURCE warning. */
22#include "libsigrokdecode.h"
Bert Vermeulen15969942012-01-07 02:50:14 +010023#include "config.h"
Bert Vermeulenb2c19612011-12-04 10:33:02 +010024
Bert Vermeulenb2c19612011-12-04 10:33:02 +010025/**
Uwe Hermann511e2122012-02-10 09:29:38 +010026 * Get the value of a Python object's attribute, returned as a newly
Bert Vermeulen451680f2012-01-15 03:58:27 +010027 * allocated char *.
Bert Vermeulenb2c19612011-12-04 10:33:02 +010028 *
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +010029 * @param py_obj The object to probe.
Bert Vermeulen451680f2012-01-15 03:58:27 +010030 * @param attr Name of the attribute to retrieve.
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +010031 * @param outstr ptr to char * storage to be filled in.
Bert Vermeulenb2c19612011-12-04 10:33:02 +010032 *
33 * @return SRD_OK upon success, a (negative) error code otherwise.
34 * The 'outstr' argument points to a malloc()ed string upon success.
Uwe Hermann57790bc2013-02-09 21:44:11 +010035 *
36 * @private
Bert Vermeulenb2c19612011-12-04 10:33:02 +010037 */
Uwe Hermannabeeed82012-03-16 15:12:54 +010038SRD_PRIV int py_attr_as_str(const PyObject *py_obj, const char *attr,
39 char **outstr)
Bert Vermeulenb2c19612011-12-04 10:33:02 +010040{
Bert Vermeulen451680f2012-01-15 03:58:27 +010041 PyObject *py_str;
Bert Vermeulenb2c19612011-12-04 10:33:02 +010042 int ret;
43
Uwe Hermannabeeed82012-03-16 15:12:54 +010044 if (!PyObject_HasAttrString((PyObject *)py_obj, attr)) {
Uwe Hermann7a1712c2012-01-26 01:15:10 +010045 srd_dbg("%s object has no attribute '%s'.",
46 Py_TYPE(py_obj)->tp_name, attr);
Bert Vermeulen451680f2012-01-15 03:58:27 +010047 return SRD_ERR_PYTHON;
48 }
49
Uwe Hermannabeeed82012-03-16 15:12:54 +010050 if (!(py_str = PyObject_GetAttrString((PyObject *)py_obj, attr))) {
Uwe Hermannaafeeae2012-03-25 15:08:16 +020051 srd_exception_catch("");
Bert Vermeulen451680f2012-01-15 03:58:27 +010052 return SRD_ERR_PYTHON;
53 }
54
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010055 if (!PyUnicode_Check(py_str)) {
Uwe Hermann7a1712c2012-01-26 01:15:10 +010056 srd_dbg("%s attribute should be a string, but is a %s.",
57 attr, Py_TYPE(py_str)->tp_name);
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010058 Py_DecRef(py_str);
59 return SRD_ERR_PYTHON;
60 }
61
Bert Vermeulen451680f2012-01-15 03:58:27 +010062 ret = py_str_as_str(py_str, outstr);
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010063 Py_DecRef(py_str);
Bert Vermeulen451680f2012-01-15 03:58:27 +010064
65 return ret;
66}
67
Bert Vermeulen451680f2012-01-15 03:58:27 +010068/**
Uwe Hermann511e2122012-02-10 09:29:38 +010069 * Get the value of a Python dictionary item, returned as a newly
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010070 * allocated char *.
71 *
72 * @param py_obj The dictionary to probe.
Uwe Hermann29590b12012-05-09 01:06:01 +020073 * @param key Key of the item to retrieve.
74 * @param outstr Pointer to char * storage to be filled in.
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010075 *
76 * @return SRD_OK upon success, a (negative) error code otherwise.
77 * The 'outstr' argument points to a malloc()ed string upon success.
Uwe Hermann57790bc2013-02-09 21:44:11 +010078 *
79 * @private
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010080 */
Uwe Hermannabeeed82012-03-16 15:12:54 +010081SRD_PRIV int py_dictitem_as_str(const PyObject *py_obj, const char *key,
Uwe Hermann55c3c5f2012-02-09 19:11:53 +010082 char **outstr)
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010083{
84 PyObject *py_value;
85 int ret;
86
Uwe Hermannabeeed82012-03-16 15:12:54 +010087 if (!PyDict_Check((PyObject *)py_obj)) {
Uwe Hermannc9bfccc2012-02-08 22:39:30 +010088 srd_dbg("Object is a %s, not a dictionary.",
Uwe Hermannabeeed82012-03-16 15:12:54 +010089 Py_TYPE((PyObject *)py_obj)->tp_name);
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010090 return SRD_ERR_PYTHON;
91 }
92
Uwe Hermannabeeed82012-03-16 15:12:54 +010093 if (!(py_value = PyDict_GetItemString((PyObject *)py_obj, key))) {
Uwe Hermann7a1712c2012-01-26 01:15:10 +010094 srd_dbg("Dictionary has no attribute '%s'.", key);
Bert Vermeulend42fc6e2012-01-20 22:08:22 +010095 return SRD_ERR_PYTHON;
96 }
97
98 if (!PyUnicode_Check(py_value)) {
Uwe Hermannc9bfccc2012-02-08 22:39:30 +010099 srd_dbg("Dictionary value for %s should be a string, but is "
100 "a %s.", key, Py_TYPE(py_value)->tp_name);
Bert Vermeulend42fc6e2012-01-20 22:08:22 +0100101 return SRD_ERR_PYTHON;
102 }
103
104 ret = py_str_as_str(py_value, outstr);
105
Bert Vermeulen708b3b82012-02-28 01:16:29 +0100106 return ret;
Bert Vermeulend42fc6e2012-01-20 22:08:22 +0100107}
108
Bert Vermeulend42fc6e2012-01-20 22:08:22 +0100109/**
Uwe Hermann511e2122012-02-10 09:29:38 +0100110 * Get the value of a Python unicode string object, returned as a newly
Bert Vermeulen451680f2012-01-15 03:58:27 +0100111 * allocated char *.
112 *
113 * @param py_str The unicode string object.
114 * @param outstr ptr to char * storage to be filled in.
115 *
116 * @return SRD_OK upon success, a (negative) error code otherwise.
117 * The 'outstr' argument points to a malloc()ed string upon success.
Uwe Hermann57790bc2013-02-09 21:44:11 +0100118 *
119 * @private
Bert Vermeulen451680f2012-01-15 03:58:27 +0100120 */
Uwe Hermannabeeed82012-03-16 15:12:54 +0100121SRD_PRIV int py_str_as_str(const PyObject *py_str, char **outstr)
Bert Vermeulen451680f2012-01-15 03:58:27 +0100122{
123 PyObject *py_encstr;
124 int ret;
125 char *str;
126
127 py_encstr = NULL;
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +0100128 str = NULL;
129 ret = SRD_OK;
130
Uwe Hermannabeeed82012-03-16 15:12:54 +0100131 if (!PyUnicode_Check((PyObject *)py_str)) {
Uwe Hermannc9bfccc2012-02-08 22:39:30 +0100132 srd_dbg("Object is a %s, not a string object.",
Uwe Hermannabeeed82012-03-16 15:12:54 +0100133 Py_TYPE((PyObject *)py_str)->tp_name);
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +0100134 ret = SRD_ERR_PYTHON;
135 goto err_out;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100136 }
137
Uwe Hermannabeeed82012-03-16 15:12:54 +0100138 if (!(py_encstr = PyUnicode_AsEncodedString((PyObject *)py_str,
139 "utf-8", NULL))) {
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +0100140 ret = SRD_ERR_PYTHON;
141 goto err_out;
Bert Vermeulen5f802ec2011-12-27 22:15:53 +0100142 }
143 if (!(str = PyBytes_AS_STRING(py_encstr))) {
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +0100144 ret = SRD_ERR_PYTHON;
145 goto err_out;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100146 }
147
148 if (!(*outstr = g_strdup(str))) {
Uwe Hermanna61ece22012-02-10 00:06:58 +0100149 srd_dbg("Failed to g_malloc() outstr.");
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100150 ret = SRD_ERR_MALLOC;
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +0100151 goto err_out;
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100152 }
153
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +0100154err_out:
Bert Vermeulen8b4bbd22011-12-28 13:40:23 +0100155 if (py_encstr)
156 Py_XDECREF(py_encstr);
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100157
Bert Vermeulen451680f2012-01-15 03:58:27 +0100158 if (PyErr_Occurred()) {
Uwe Hermannaafeeae2012-03-25 15:08:16 +0200159 srd_exception_catch("string conversion failed");
Bert Vermeulen451680f2012-01-15 03:58:27 +0100160 }
Bert Vermeulenb2c19612011-12-04 10:33:02 +0100161
162 return ret;
163}
164
Bert Vermeulen15969942012-01-07 02:50:14 +0100165/**
Uwe Hermann511e2122012-02-10 09:29:38 +0100166 * Convert a Python list of unicode strings to a NULL-terminated UTF8-encoded
Uwe Hermann56bf4c22012-02-11 20:06:46 +0100167 * char * array. The caller must g_free() each string when finished.
Bert Vermeulen451680f2012-01-15 03:58:27 +0100168 *
169 * @param py_strlist The list object.
170 * @param outstr ptr to char ** storage to be filled in.
171 *
172 * @return SRD_OK upon success, a (negative) error code otherwise.
Uwe Hermanna61ece22012-02-10 00:06:58 +0100173 * The 'outstr' argument points to a g_malloc()ed char** upon success.
Uwe Hermann57790bc2013-02-09 21:44:11 +0100174 *
175 * @private
Bert Vermeulen15969942012-01-07 02:50:14 +0100176 */
Bert Vermeulen62a2b152013-12-11 23:41:02 +0100177SRD_PRIV int py_strseq_to_char(const PyObject *py_strseq, char ***outstr)
Bert Vermeulen15969942012-01-07 02:50:14 +0100178{
179 PyObject *py_str;
180 int list_len, i;
181 char **out, *str;
182
Bert Vermeulen62a2b152013-12-11 23:41:02 +0100183 list_len = PySequence_Size((PyObject *)py_strseq);
Uwe Hermanna61ece22012-02-10 00:06:58 +0100184 if (!(out = g_try_malloc(sizeof(char *) * (list_len + 1)))) {
185 srd_err("Failed to g_malloc() 'out'.");
Bert Vermeulen15969942012-01-07 02:50:14 +0100186 return SRD_ERR_MALLOC;
Uwe Hermanna61ece22012-02-10 00:06:58 +0100187 }
Bert Vermeulen15969942012-01-07 02:50:14 +0100188 for (i = 0; i < list_len; i++) {
Bert Vermeulen451680f2012-01-15 03:58:27 +0100189 if (!(py_str = PyUnicode_AsEncodedString(
Bert Vermeulen62a2b152013-12-11 23:41:02 +0100190 PySequence_GetItem((PyObject *)py_strseq, i), "utf-8", NULL)))
Bert Vermeulen15969942012-01-07 02:50:14 +0100191 return SRD_ERR_PYTHON;
192 if (!(str = PyBytes_AS_STRING(py_str)))
193 return SRD_ERR_PYTHON;
194 out[i] = g_strdup(str);
195 }
196 out[i] = NULL;
197 *outstr = out;
198
199 return SRD_OK;
200}