Files
gds-render/plugins/python-renderer/src/plugin-main.c

174 lines
4.1 KiB
C

/*
* GDSII-Converter Python Plugin
* Copyright (C) 2019 Mario Hüttel <mario.huettel@gmx.net>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* @file python-renderer/plugin-main.c
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @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 <stdio.h>
#include <libgen.h>
#include <glib.h>
#include <unistd.h>
#include <Python.h>
#include <gds-render/gds-utils/gds-types.h>
#include <gds-render/output-renderers/external-renderer-interfaces.h>
#include <python-renderer/gds-render-module.h>
/**
* @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;
}
/** @} */