/* * GDSII-Converter Python Plugin * Copyright (C) 2019 Mario Hüttel * * This file is part of GDSII-Converter. * * GDSII-Converter is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * GDSII-Converter 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 GDSII-Converter. If not, see . */ /** * @file python-renderer/plugin-main.c * @author Mario Hüttel */ /** * @defgroup python-plugin Python Plugin for External Renderer * @ingroup plugins * This is a plugin for calling an external python script as renderer * @addtogroup python-plugin * @{ */ #include #include #include #include #include #include #include #include /** * @brief Global variable for loaded module. This is not very nice. * @warning This has to be changed, if this api wants to be re-entrant. */ static PyObject *p_module = NULL; int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_RENDER_FUNCTION)(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale) { int ret = 0; PyObject *p_render_func; PyObject *p_return_value; if (!toplevel) return -1000; if (!p_module) return -2000; printf("Rendering %s\n", toplevel->name); p_render_func = PyObject_GetAttrString(p_module, "test_func"); if (!p_render_func && !PyCallable_Check(p_render_func)) { if (PyErr_Occurred()) PyErr_Print(); else fprintf(stderr, "Function not found in python module\n"); ret = -1; goto return_value; } p_return_value = PyObject_CallObject(p_render_func, NULL); if (p_return_value) { printf("Result of call: %ld\n", PyLong_AsLong(p_return_value)); Py_DECREF(p_return_value); } Py_XDECREF(p_render_func); return_value: return ret; } int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_INIT_FUNCTION)(const char *params, const char *version) { int ret = 0; PyObject *p_name; PyObject *p_sys_path; PyObject *p_mod_dir_string; PyObject *gds_render_module; char file_path[PATH_MAX]; char *file_path_for_dir; char *file_path_for_base; char *dir_name; char *base_name; if (!params || !version) return -1000; printf("Init with params: %s\ngds-render version: %s\n", params, version); ret = PyImport_AppendInittab("gds_render", &init_gds_render_module); if (ret) { ret = -1; fprintf(stderr, "Registration of gds_render python module failed\n"); goto return_value; } Py_Initialize(); if (!realpath(params, file_path)) { ret = -2; fprintf(stderr, "Invalid file name.\n"); goto return_value; } file_path_for_dir = strdup(file_path); if (!file_path_for_dir) { ret = -3; goto return_value; } file_path_for_base = strdup(file_path); if (!file_path_for_base) { ret = -3; free (file_path_for_dir); goto return_value; } dir_name = dirname(file_path_for_dir); base_name = basename(file_path_for_base); printf("Dir name : %s\n BAse name: %s\n", dir_name, base_name); p_sys_path = PySys_GetObject("path"); p_mod_dir_string = PyUnicode_FromString(dir_name); PyList_Append(p_sys_path, p_mod_dir_string); Py_DECREF(p_mod_dir_string); p_name = PyUnicode_DecodeFSDefault(strtok(base_name, ".")); p_module = PyImport_Import(p_name); Py_DECREF(p_name); if (!p_module) { PyErr_Print(); fprintf(stderr, "Failed to load %s\n", params); ret = -1; goto return_value; } free(file_path_for_dir); free(file_path_for_base); return_value: return ret; } int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_FINALIZE_FUNCTION)(void) { int ret; printf("Finalizing\n"); if (p_module) Py_DECREF(p_module); ret = Py_FinalizeEx(); return ret; } /** @} */