KiCad PCB EDA Suite
pcbnew_scripting.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <[email protected]>
5 * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
30#include <python_scripting.h>
31
32#include <cstdlib>
33#include <cstring>
34#include <Python.h>
35#include <sstream>
36
37#include <eda_base_frame.h>
38#include <gal/color4d.h>
39#include <trace_helpers.h>
40#include <string_utils.h>
41#include <macros.h>
42#include <paths.h>
44
46
47#include <wx/app.h>
48
49#include <config.h>
50
51
58static void pcbnewRunPythonMethodWithReturnedString( const char* aMethodName, wxString& aNames )
59{
60 aNames.Clear();
61
62 PyLOCK lock;
63 PyErr_Clear();
64
65 PyObject* builtins = PyImport_ImportModule( "pcbnew" );
66 wxASSERT( builtins );
67
68 if( !builtins ) // Something is wrong in pcbnew.py module (incorrect version?)
69 return;
70
71 PyObject* globals = PyDict_New();
72 PyDict_SetItemString( globals, "pcbnew", builtins );
73 Py_DECREF( builtins );
74
75 // Build the python code
76 char cmd[1024];
77 snprintf( cmd, sizeof(cmd), "result = %s()", aMethodName );
78
79 // Execute the python code and get the returned data
80 PyObject* localDict = PyDict_New();
81 PyObject* pobj = PyRun_String( cmd, Py_file_input, globals, localDict);
82 Py_DECREF( globals );
83
84 if( pobj )
85 {
86 PyObject* str = PyDict_GetItemString(localDict, "result" );
87 const char* str_res = nullptr;
88
89 if(str)
90 {
91 PyObject* temp_bytes = PyUnicode_AsEncodedString( str, "UTF-8", "strict" );
92
93 if( temp_bytes != nullptr )
94 {
95 str_res = PyBytes_AS_STRING( temp_bytes );
96 aNames = FROM_UTF8( str_res );
97 Py_DECREF( temp_bytes );
98 }
99 else
100 {
101 wxLogMessage( "cannot encode Unicode python string" );
102 }
103 }
104 else
105 {
106 aNames = wxString();
107 }
108
109 Py_DECREF( pobj );
110 }
111
112 Py_DECREF( localDict );
113
114 if( PyErr_Occurred() )
115 {
116 if( strcmp( aMethodName, "pcbnew.GetWizardsBackTrace" ) == 0 )
117 aNames = PyErrStringWithTraceback();
118 else
119 wxLogMessage( PyErrStringWithTraceback() );
120 }
121}
122
123
124void pcbnewGetUnloadableScriptNames( wxString& aNames )
125{
126 pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetUnLoadableWizards", aNames );
127}
128
129
130void pcbnewGetScriptsSearchPaths( wxString& aNames )
131{
132 pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsSearchPaths", aNames );
133}
134
135
136void pcbnewGetWizardsBackTrace( wxString& aTrace )
137{
138 pcbnewRunPythonMethodWithReturnedString( "pcbnew.GetWizardsBackTrace", aTrace );
139
140 // Filter message before displaying them
141 // a trace starts by "Traceback" and is followed by 2 useless lines
142 // for our purpose
143 wxArrayString traces;
144 wxStringSplit( aTrace, traces, '\n' );
145
146 // Build the filtered message (remove useless lines)
147 aTrace.Clear();
148
149 for( unsigned ii = 0; ii < traces.Count(); ++ii )
150 {
151 if( traces[ii].Contains( wxT( "Traceback" ) ) )
152 {
153 ii += 2; // Skip this line and next lines which are related to pcbnew.py module
154
155 if( !aTrace.IsEmpty() ) // Add separator for the next trace block
156 aTrace << wxT( "\n**********************************\n" );
157 }
158 else
159 {
160 aTrace += traces[ii] + wxT( "\n" );
161 }
162 }
163}
Base window classes and related definitions.
This file contains miscellaneous commonly used macros and functions.
static wxString FROM_UTF8(const char *cstring)
Convert a UTF8 encoded C string to a wxString for all wxWidgets build modes.
Definition: macros.h:110
void pcbnewGetUnloadableScriptNames(wxString &aNames)
Collect the list of python scripts which could not be loaded.
void pcbnewGetScriptsSearchPaths(wxString &aNames)
Collect the list of paths where python scripts are searched.
static void pcbnewRunPythonMethodWithReturnedString(const char *aMethodName, wxString &aNames)
Run a python method from the pcbnew module.
void pcbnewGetWizardsBackTrace(wxString &aTrace)
Return the backtrace of errors (if any) when wizard python scripts are loaded.
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
wxLogTrace helper definitions.