From 43114165fb5e59c4267991f4922970c897fe2d88 Mon Sep 17 00:00:00 2001 From: manojgudi Date: Tue, 23 Jul 2013 07:54:12 +0530 Subject: initial commit --- sciconv_write.c | 604 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 604 insertions(+) create mode 100755 sciconv_write.c (limited to 'sciconv_write.c') diff --git a/sciconv_write.c b/sciconv_write.c new file mode 100755 index 0000000..45844ba --- /dev/null +++ b/sciconv_write.c @@ -0,0 +1,604 @@ +/* + This file is part of Sciscipy. + + Sciscipy is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Sciscipy is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Foobar. If not, see . + + Copyright (c) 2009, Vincent Guffens. +*/ + +#include "sciconv_write.h" +#include "util.h" +#include "Scierror.h" + +struct sciconv_write_struct *sciconv_write_list = NULL ; + +/** list of string + * + * WARNING: This will not work with Python 3.0 + */ +static int write_listofstring(char *name, PyObject *obj) +{ + int i, n ; + int tot_size = 0; + PyObject *item ; + char *str_item, *buff, *ptr ; + + if (!PyList_Check(obj)) + { + obj = create_list(obj) ; + } + + n = PyList_Size(obj) ; + + for (i = 0; i < n; ++i) + { + item = PyList_GetItem(obj, i) ; + str_item = PyString_AsString(item) ; + tot_size += strlen(str_item) ; + } + + buff = (char *) malloc((strlen(name) + tot_size + 3 * n + 3) * sizeof(char)) ; + ptr = buff ; + strcpy(ptr, name) ; + ptr += strlen(name) ; + + strcpy(ptr, "=[") ; + ptr += 2 ; + + for (i = 0; i < n; ++i) + { + item = PyList_GetItem(obj, i) ; + str_item = PyString_AsString(item) ; + strcpy(ptr, "'") ; + ptr++ ; + strcpy(ptr, str_item) ; + ptr += strlen(str_item) ; + strcpy(ptr, "'") ; + ptr++ ; + if (i != n - 1) + { + strcpy(ptr, ",") ; + ptr++ ; + } + } + + strcpy(ptr, "]") ; + SendScilabJob(buff); + + return 1 ; +} + +/** + */ +static int test_listofstring(PyObject *obj) +{ + PyObject *item ; + int n ; + + if (PyString_Check(obj)) + { + sci_debug("[sciconv_write] Match for list of string\n") ; + return 1 ; + } + + if (PyList_Check(obj)) + { + n = PyList_Size(obj) ; + if (n == 0) + { + return -1 ; + } + + item = PyList_GetItem(obj, 0) ; + + if (PyString_Check(item)) + { + sci_debug("[sciconv_write] Match for list of string\n") ; + return 1 ; + } + } + + return -1 ; +} + +/** + * @param name: the name of the scilab variable we want to create + * @return: negative on failure +*/ +static int write_listoflist(char *name, PyObject *obj) +{ + int i, j, m, n ; + double *new_vec ; + double *new_vec_img ; + PyObject *item, *element ; + int is_complex_found = 0 ; + SciErr sciErr; + + m = PyList_Size(obj) ; + item = PyList_GetItem(obj, 0) ; + n = PyList_Size(item) ; + + new_vec = (double*) calloc(sizeof(double) * m * n, 1) ; + if (!new_vec) + { + return -1 ; + } + + new_vec_img = (double*) calloc(sizeof(double) * m * n, 1) ; + if (!new_vec_img) + { + free(new_vec); + return -1 ; + } + + for (i = 0; i < m; i++) + { + item = PyList_GetItem(obj, i) ; + + for (j = 0; j < n; j++) + { + element = PyList_GetItem(item, j) ; + + if (PyComplex_Check(element)) + { + is_complex_found = 1 ; + new_vec[j * m + i] = PyComplex_RealAsDouble(element) ; + new_vec_img[j * m + i] = PyComplex_ImagAsDouble(element) ; + continue ; + } + + if (PyFloat_Check(element) || PyLong_Check(element) || PyInt_Check(element)) + { + new_vec[j * m + i] = PyFloat_AsDouble(element) ; + continue ; + } + + sci_debug("[write_listoflist] something found" \ + "that is not real or complex") ; + free(new_vec) ; + free(new_vec_img) ; + return -1 ; + } + } + + if (is_complex_found) + { + sciErr = createNamedComplexMatrixOfDouble(pvApiCtx, name, m, n, new_vec, new_vec_img); + free(new_vec_img); + free(new_vec); + if (sciErr.iErr) + { + printError(&sciErr, 0); + Scierror(999, "Cannot create complex variable '%s'.\n", name); + return 0; + } + + } + else + { + sciErr = createNamedMatrixOfDouble(pvApiCtx, name, m, n, new_vec); + free(new_vec) ; + free(new_vec_img) ; + if (sciErr.iErr) + { + PyErr_SetString(PyExc_TypeError, "Error in Writematrix"); + return 0; + } + } + return 1 ; +} + +static int test_listoflist(PyObject *obj) +{ + int n ; + PyObject *item, *el ; + + + if (!PyList_Check(obj)) + { + return -1 ; + } + n = PyList_Size(obj) ; + if (n == 0) + { + return -1 ; + } + + item = PyList_GetItem(obj, 0) ; + + if (!PyList_Check(item) || PyList_Size(item) == 0) + { + return -1 ; + } + + el = PyList_GetItem(item, 0) ; + + /* Only the first element is checked, the converter + will fail later on if all items are not real or + complex (This is for performance) + */ + if (PyFloat_Check(el) || PyLong_Check(el) || PyComplex_Check(el) || PyInt_Check(el)) + { + sci_debug("[sciconv_write] Match for list of list\n") ; + return 1 ; + } + else + { + return -1 ; + } +} + +static int write_listofdouble(char *name, PyObject *obj) +{ + int i, m ; + int n = 1 ; + double *new_vec ; + double *new_vec_img ; + PyObject *element ; + int is_complex_found = 0 ; + SciErr sciErr; + + if (!PyList_Check(obj)) + { + obj = create_list(obj) ; + } + + m = PyList_Size(obj) ; + + new_vec = (double*) calloc(sizeof(double) * m, 1) ; + + if (!new_vec) + { + return -1 ; + } + + new_vec_img = (double*) calloc(sizeof(double) * m, 1) ; + + if (!new_vec_img) + { + free(new_vec); + return -1 ; + } + + for (i = 0; i < m; i++) + { + element = PyList_GetItem(obj, i) ; + + if (PyComplex_Check(element)) + { + is_complex_found = 1 ; + new_vec[i] = PyComplex_RealAsDouble(element) ; + new_vec_img[i] = PyComplex_ImagAsDouble(element) ; + continue ; + } + + if (PyFloat_Check(element) || PyLong_Check(element) || PyInt_Check(element)) + { + new_vec[i] = PyFloat_AsDouble(element) ; + continue ; + } + + sci_debug("[write_listofdouble] something found" \ + "that is not real or complex") ; + free(new_vec) ; + free(new_vec_img) ; + return -1 ; + } + + + if (is_complex_found) + { + sciErr = createNamedComplexMatrixOfDouble(pvApiCtx, name, n, m, new_vec, new_vec_img); + free(new_vec); + free(new_vec_img); + if (sciErr.iErr) + { + printError(&sciErr, 0); + Scierror(999, "Cannot create complex variable '%s'.\n", name); + return 0; + } + } + else + { + sciErr = createNamedMatrixOfDouble(pvApiCtx, name, n, m, new_vec); + free(new_vec); + free(new_vec_img); + if (sciErr.iErr) + { + PyErr_SetString(PyExc_TypeError, "Error in Writematrix") ; + return 0; + } + } + + return 1 ; + +} + +static int test_listofdouble(PyObject *obj) +{ + PyObject *item ; + int n ; + + if (PyFloat_Check(obj) || PyLong_Check(obj) || PyComplex_Check(obj) || PyInt_Check(obj)) + { + sci_debug("[sciconv_write] Match for list of double\n") ; + return 1 ; + } + + if (PyList_Check(obj)) + { + n = PyList_Size(obj) ; + if (n == 0) + { + return -1 ; + } + + item = PyList_GetItem(obj, 0) ; + + if (PyFloat_Check(item) || PyLong_Check(item) || PyComplex_Check(item) || PyInt_Check(item)) + { + sci_debug("[sciconv_write] Match for list of double\n") ; + return 1 ; + } + } + + return -1 ; +} + +#if NUMPY == 1 +static int write_numpy(char *name, PyObject *obj) +{ + + PyArrayObject * array = (PyArrayObject *) obj ; + double * data ; + double * data_img ; + int i, j, m, n ; + complex * item ; + SciErr sciErr; + + // TODO: add support for 1D array + + if (array->nd != 1 && array->nd != 2) + { + sci_debug("[sciconv_write] Only 1D and 2D array are supported\n") ; + return -1 ; + } + + if (array->nd == 1) + { + m = array->dimensions[0] ; + n = 1 ; + } + else + { + m = array->dimensions[0] ; + n = array->dimensions[1] ; + } + + if ((array->descr->type_num == PyArray_DOUBLE) || \ + (array->descr->type_num == PyArray_INT) ) + { + + data = (double*) malloc(m * n * sizeof(double)) ; + + if (!data) + { + sci_error("[sciconv_write] out of memory\n") ; + return -1 ; + } + + for (i = 0; i < m ; i++) + for (j = 0; j < n ; j++) + data[j * m + i] = *(double*)(array->data + i * array->strides[0] + \ + j * array->strides[1]) ; + + sciErr = createNamedMatrixOfDouble(pvApiCtx, name, m, n, data); + free(data); + if (sciErr.iErr) + { + PyErr_SetString(PyExc_TypeError, "Error in Writematrix") ; + return 0; + } + + return 1 ; + } + + if (array->descr->type_num == PyArray_CDOUBLE) + { + data = (double*) malloc(m * n * sizeof(double)) ; + data_img = (double*) malloc(m * n * sizeof(double)) ; + + if (!data) + { + sci_error("[sciconv_write] out of memory\n") ; + free(data_img); + return -1 ; + } + + for (i = 0; i < m ; i++) + for (j = 0; j < n ; j++) + { + + item = (complex*)(array->data + i * array->strides[0] + \ + j * array->strides[1]) ; + data[j * m + i] = (*item)[0] ; + data_img[j * m + i] = (*item)[1] ; + } + + sciErr = createNamedComplexMatrixOfDouble(pvApiCtx, name, m, n, data, data_img); + if (sciErr.iErr) + { + printError(&sciErr, 0); + free(data); + free(data_img); + Scierror(999, "Cannot create complex variable '%s'.\n", name); + return 0; + } + + + free(data) ; + free(data_img) ; + return 1 ; + } + + sci_debug("[sciconv_write] Array type not supported\n") ; + return -1 ; +} + +static int test_numpy(PyObject *obj) +{ + if (PyArray_Check(obj)) + { + sci_debug("[sciconv_write] Match for numpy array\n") ; + return 1 ; + } + else + { + return -1 ; + } +} +#endif + +static int write_tlist(char *name, PyObject *obj) +{ + int nb_item ; + int *tlist_address ; + SciErr sciErr ; + nb_item = PyDict_Size(obj) - 1 ; + sciErr = createNamedTList(pvApiCtx, name, nb_item, &tlist_address) ; + PyObject *key, *value; + Py_ssize_t pos = 0; + PyObject *py_str_to_create = PyString_FromString("[") ; + PyObject *py_value_str = PyString_FromString("") ; + printf("Entering write 1\n") ; + if (sciErr.iErr) + { + PyErr_SetString(PyExc_TypeError, getErrorMessage(sciErr)) ; + return -1; + } + printf("Entering write 2\n") ; + + // py_str_tocreate = + // ['a_name', 'var1', ..., 'varN'] + while (PyDict_Next(obj, &pos, &key, &value)) + { + char *str_key = NULL ; + if (!PyString_Check(key)) + { + return -1 ; + } + + str_key = PyString_AsString(key) ; + + if (strcmp(str_key, TLIST_NAME) == 0) + { + if (!PyString_Check(value)) + { + return -1 ; + } + PyString_Concat(&py_str_to_create, PyString_FromString("\"")) ; + PyString_Concat(&py_str_to_create, value) ; + PyString_Concat(&py_str_to_create, PyString_FromString("\"")) ; + } + printf("Entering write i\n") ; + } + printf("Entering write 3\n") ; + pos = 0 ; + while (PyDict_Next(obj, &pos, &key, &value)) + { + char *str_key = NULL ; + if (!PyString_Check(key)) + { + return -1 ; + } + + str_key = PyString_AsString(key) ; + if (strcmp(str_key, TLIST_NAME) != 0) + { + char rnd_name[BUFSIZE] ; + PyString_Concat(&py_str_to_create, PyString_FromString(",\"")) ; + PyString_Concat(&py_str_to_create, key) ; + PyString_Concat(&py_str_to_create, PyString_FromString("\"")) ; + // TODO + // write(rnd_name, value) + snprintf(rnd_name, BUFSIZE - 1, ",rnd_var__%i", rand()) ; + PyString_Concat(&py_value_str, PyString_FromString(rnd_name)) ; + } + } + PyString_Concat(&py_str_to_create, PyString_FromString("]")) ; + printf("%s = tlist(%s%s)\n", name, PyString_AsString(py_str_to_create), PyString_AsString(py_value_str)) ; + // creates a string name = tlist(['a_name', 'var1', ..., 'varN'], var1,..., varN) + // eval the string + + return 1 ; +} + +static int test_dict_tlist(PyObject *obj) +{ + PyObject *py_list_name = PyString_FromString(TLIST_NAME) ; + if (PyDict_Check(obj) && PyDict_Contains(obj, py_list_name)) + { + sci_debug("[sciconv_write] Match for tlist\n") ; + Py_DECREF(py_list_name) ; + return 1 ; + } + else + { + Py_DECREF(py_list_name) ; + return -1 ; + } +} + + +/** + * Add a new converter to the list + * @param new_type: A scilab type number + * @param func: The converter function +*/ +static void sciconv_write_add(int (*test_func)(PyObject*), int(*func)(char*, PyObject *), WRITETYPE_t id) +{ + struct sciconv_write_struct *new_conv = \ + (struct sciconv_write_struct*) malloc(sizeof(struct sciconv_write_struct)) ; + + new_conv->test_func = test_func ; + new_conv->conv_func = func ; + new_conv->write_type = id ; + if (sciconv_write_list == NULL) + { + sciconv_write_list = new_conv ; + new_conv->next = NULL ; + return ; + } + + new_conv->next = sciconv_write_list->next ; + sciconv_write_list->next = new_conv ; +} + +/** + * Initialization + * Add all the known converter to the list +*/ +void sciconv_write_init(void) +{ + // The one added first is the one tested first + // so the order can be important +#if NUMPY == 1 + sciconv_write_add(test_numpy, write_numpy, NUMPY_ARRAY) ; +#endif + sciconv_write_add(test_listoflist, write_listoflist, LISTOFLIST) ; + sciconv_write_add(test_listofdouble, write_listofdouble, LISTOFDOUBLE) ; + sciconv_write_add(test_listofstring, write_listofstring, LISTOFSTRING) ; + sciconv_write_add(test_dict_tlist, write_tlist, TLIST) ; +} + -- cgit