174 lines
4.1 KiB
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;
|
|
}
|
|
|
|
/** @} */
|