py2yacs library can build a yacs schema out of a python script.
The schema contains a single python node which executes a function
from the python script.
Input and output ports are deducted from the parameters and the
returns of the chosen function. The type of ports are restricted
to 'double'.
# KERNEL
##
IF(SALOME_YACS_USE_KERNEL)
- SET(SUBDIRS_KERNEL runtime yacsloader evalyfx)
+ SET(SUBDIRS_KERNEL runtime yacsloader evalyfx py2yacs)
ENDIF(SALOME_YACS_USE_KERNEL)
##
pmml
yacsloader
yacsloader_swig
+ py2yacs
)
--- /dev/null
+# Copyright (C) 2012-2016 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+INCLUDE_DIRECTORIES(
+ ${PYTHON_INCLUDE_DIR}
+ ${SALOME_INCL_PATH}
+ ${PROJECT_SOURCE_DIR}/src/bases
+ ${PROJECT_SOURCE_DIR}/src/engine
+ ${PROJECT_SOURCE_DIR}/src/runtime
+ ${PROJECT_SOURCE_DIR}
+ )
+
+ADD_DEFINITIONS(
+ ${PYTHON_DEFINITIONS}
+ )
+
+IF(SALOME_BUILD_TESTS)
+ ADD_SUBDIRECTORY(Test)
+ENDIF(SALOME_BUILD_TESTS)
+
+SET(_link_LIBRARIES
+ ${PYTHON_LIBRARIES}
+ YACSRuntimeSALOME
+ )
+
+SET(_py2yacs_sources
+ py2yacs.cxx
+ )
+
+SET(_py2yacs_headers
+ py2yacs.hxx
+ )
+
+ADD_LIBRARY(py2yacslib ${_py2yacs_sources})
+TARGET_LINK_LIBRARIES(py2yacslib ${_link_LIBRARIES})
+
+INSTALL(TARGETS py2yacslib EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS})
+INSTALL(FILES ${_py2yacs_headers} DESTINATION ${SALOME_INSTALL_HEADERS})
+
+SET( _py_SCRIPTS
+ py2yacs.py
+ )
+
+SALOME_INSTALL_SCRIPTS("${_py_SCRIPTS}" ${SALOME_INSTALL_PYTHON})
--- /dev/null
+# Copyright (C) 2012-2016 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+INCLUDE_DIRECTORIES(
+ ${CPPUNIT_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+SET(_link_LIBRARIES
+ ${CPPUNIT_LIBRARIES}
+ py2yacslib
+)
+
+SET(Py2yacsTest_SOURCES
+ TestPy2yacs.cxx
+ Py2yacsTest.cxx
+ Py2yacsTest.hxx
+)
+
+ADD_EXECUTABLE(TestPy2yacs ${Py2yacsTest_SOURCES})
+TARGET_LINK_LIBRARIES(TestPy2yacs ${_link_LIBRARIES})
+
+ADD_EXECUTABLE(test_py2yacs test_py2yacs.cxx)
+TARGET_LINK_LIBRARIES(test_py2yacs py2yacslib)
+
+# For salome test
+IF(NOT WIN32)
+ ADD_TEST(TestPy2yacs TestPy2yacs)
+ SET_TESTS_PROPERTIES(TestPy2yacs PROPERTIES
+ ENVIRONMENT "PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR}:${CMAKE_CURRENT_SOURCE_DIR}/..:$ENV{PYTHONPATH}"
+ )
+
+ SET(LOCAL_TEST_DIR ${SALOME_YACS_INSTALL_TEST}/py2yacs)
+ SET(LOCAL_TEST_FILES
+ bad_parsers.py
+ err_py2yacs_invalid.py
+ )
+ INSTALL(FILES ${LOCAL_TEST_FILES}
+ DESTINATION ${LOCAL_TEST_DIR})
+ INSTALL(FILES CTestTestfileInstall.cmake
+ DESTINATION ${LOCAL_TEST_DIR}
+ RENAME CTestTestfile.cmake)
+ INSTALL(TARGETS TestPy2yacs test_py2yacs
+ DESTINATION ${LOCAL_TEST_DIR})
+
+ENDIF()
\ No newline at end of file
--- /dev/null
+# Copyright (C) 2012-2016 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+IF(NOT WIN32)
+ SET(TEST_NAME ${COMPONENT_NAME}_Py2YacsTest)
+ # No need of a salome session for this test
+ ADD_TEST(${TEST_NAME} TestPy2yacs)
+ SET_TESTS_PROPERTIES(${TEST_NAME} PROPERTIES
+ LABELS "${COMPONENT_NAME}"
+ )
+
+ENDIF()
--- /dev/null
+// Copyright (C) 2006-2016 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include <Python.h>
+#include <fstream>
+#include <string>
+#include <sstream>
+
+#include "Py2yacsTest.hxx"
+#include "py2yacs.hxx"
+#include "Proc.hxx"
+#include "Executor.hxx"
+
+#include "RuntimeSALOME.hxx"
+#include "PythonPorts.hxx"
+#include "InputPort.hxx"
+//#include "parsers.hxx"
+
+void Py2yacsTest::setUp()
+{
+ YACS::ENGINE::RuntimeSALOME::setRuntime();
+ //YACS::ENGINE::getRuntime()->init();
+}
+
+void Py2yacsTest::tearDown()
+{
+ //YACS::ENGINE::getRuntime()->fini();
+}
+
+static
+void verifyCorrectPycode(const char * code_py, const char * function_name,
+ int nbInputPorts, const char** input_ports,
+ int nbOutputPorts, const char** output_ports)
+{
+ std::cerr << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << code_py << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << "Function :" << function_name << std::endl;
+ Py2yacs parser;
+ try
+ {
+ parser.load(code_py);
+ }
+ catch(Py2yacsException& e)
+ {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch(...)
+ {
+ CPPUNIT_FAIL("Unknown exception");
+ }
+ YACS::ENGINE::Proc* p = parser.createProc(function_name);
+ CPPUNIT_ASSERT( p != NULL);
+ YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
+ CPPUNIT_ASSERT( n != NULL);
+ CPPUNIT_ASSERT( n->getNumberOfInputPorts() == nbInputPorts);
+ for(int i = 0; i < nbInputPorts; i++)
+ CPPUNIT_ASSERT( n->getInputPort(input_ports[i]) != NULL);
+ CPPUNIT_ASSERT( n->getNumberOfOutputPorts() == nbOutputPorts);
+ for(int i = 0; i < nbOutputPorts; i++)
+ CPPUNIT_ASSERT( n->getOutputPort(output_ports[i]) != NULL);
+ delete p;
+}
+
+static
+void verifyWrongPycode(const char* code_py, const char* function_name,
+ const char* error_message)
+{
+ Py2yacs parser;
+ try
+ {
+ parser.load(code_py);
+ YACS::ENGINE::Proc* p = parser.createProc(function_name);
+ CPPUNIT_FAIL("Exception expected and no exception occured.");
+ }
+ catch(Py2yacsException& e)
+ {
+ std::string what = e.what();
+ std::cerr << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << code_py << std::endl;
+ std::cerr << "-----------------------------------------------" << std::endl;
+ std::cerr << "Function :" << function_name << std::endl;
+ std::cerr << "==========EXCEPTION TEXT=======================" << std::endl;
+ std::cerr << what << std::endl;
+ std::cerr << "===============================================" << std::endl;
+ CPPUNIT_ASSERT(what.find(error_message) != std::string::npos);
+ }
+}
+
+static
+void verifyWrongParser(const char* parser_module, const char* parser_function,
+ const char* error_message)
+{
+ const char* code_py = "def f():\n"
+ " return\n";
+ Py2yacs parser(parser_module, parser_function);
+ try
+ {
+ parser.load(code_py);
+ CPPUNIT_FAIL("Exception expected and no exception occured.");
+ }
+ catch(Py2yacsException& e)
+ {
+ std::string what = e.what();
+ std::cerr << std::endl;
+ std::cerr << "==========EXCEPTION TEXT=======================" << std::endl;
+ std::cerr << what << std::endl;
+ std::cerr << "===============================================" << std::endl;
+ CPPUNIT_ASSERT(what.find(error_message) != std::string::npos);
+ }
+}
+
+void Py2yacsTest::t1()
+{
+ const char * code_py = "def f1(a, b, c):\n"
+ " y = a*b + c\n"
+ " return y\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char* output_ports[] = {"y"};
+ verifyCorrectPycode(code_py, "f1", 3, input_ports, 1, output_ports);
+}
+
+void Py2yacsTest::t2()
+{
+ const char * code_py = "def f1(a, b, c):\n"
+ " x = a + b + c\n"
+ " y = a*b + c\n"
+ " z = a*b*c\n"
+ " return x, y, z\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char* output_ports[] = {"x", "y", "z"};
+ verifyCorrectPycode(code_py, "f1", 3, input_ports, 3, output_ports);
+}
+
+void Py2yacsTest::t3()
+{
+ const char * code_py = "def f1(a, b, c):\n"
+ " print a\n"
+ " print b\n"
+ " print c\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char* output_ports[] = {};
+ verifyCorrectPycode(code_py, "f1", 3, input_ports, 0, output_ports);
+}
+
+void Py2yacsTest::t4()
+{
+ const char * code_py = "def f1():\n"
+ " print 'toto'\n"
+ " return\n";
+ const char* input_ports[] = {"a", "b", "c"};
+ const char* output_ports[] = {};
+ verifyCorrectPycode(code_py, "f1", 0, input_ports, 0, output_ports);
+}
+
+void Py2yacsTest::t5()
+{
+ const char * code_py = "def f1(a):\n"
+ " x = -a\n"
+ " if a > 0:\n"
+ " return a\n"
+ " else:\n"
+ " return x\n"
+ "class ignoremoi:\n"
+ " def ignoreF(t):\n"
+ " return t+1\n"
+ "def f2(v):\n"
+ " ret = f1(v)\n"
+ " return ret\n";
+ const char* input_ports[] = {"v"};
+ const char* output_ports[] = {"ret"};
+ verifyCorrectPycode(code_py, "f2", 1, input_ports, 1, output_ports);
+}
+
+void Py2yacsTest::no_multiple_returns()
+{
+ const char * code_py = "def f(a):\n"
+ " x = -a\n"
+ " if a > 0:\n"
+ " return a\n"
+ " else:\n"
+ " return x\n";
+ verifyWrongPycode(code_py, "f", "multiple returns.");
+}
+
+void Py2yacsTest::unaccepted_statement()
+{
+ const char * code_py = "def f(a):\n"
+ " return a\n"
+ "x=5\n";
+ verifyWrongPycode(code_py, "f", "not accepted statement");
+}
+
+void Py2yacsTest::unaccepted_statement2()
+{
+ const char * code_py = "def f(a):\n"
+ " return a\n"
+ "if __name__ == '__main__':"
+ " print 'toto'\n";
+ verifyWrongPycode(code_py, "f", "not accepted statement");
+}
+
+void Py2yacsTest::unaccepted_return()
+{
+ const char * code_py = "def f(a):\n"
+ " return 7\n";
+ verifyWrongPycode(code_py, "f", "invalid type returned");
+}
+
+void Py2yacsTest::unaccepted_return2()
+{
+ const char * code_py = "def f1(a):\n"
+ " return 7\n"
+ "def f2(x):\n"
+ " return f1(x)\n";
+ verifyWrongPycode(code_py, "f2", "invalid type returned");
+}
+
+void Py2yacsTest::syntaxError()
+{
+ const char * code_py = "bla bla bla\n"
+ " return f1(x)\n";
+ verifyWrongPycode(code_py, "f2", "SyntaxError");
+}
+
+void Py2yacsTest::badFunctionName()
+{
+ const char * code_py = "def f1(a):\n"
+ " x=7\n"
+ " return x\n"
+ "def f2(x):\n"
+ " y=8\n"
+ " return y\n";
+ verifyWrongPycode(code_py, "nonexistant", "Function not found:");
+}
+
+void Py2yacsTest::schemaExec()
+{
+ const char * code_py = "def f(a):\n"
+ " x = a\n"
+ " return x\n";
+ Py2yacs parser;
+ try
+ {
+ parser.load(code_py);
+ }
+ catch(Py2yacsException& e)
+ {
+ CPPUNIT_FAIL(e.what());
+ }
+ catch(...)
+ {
+ CPPUNIT_FAIL("Unknown exception");
+ }
+ YACS::ENGINE::Proc* p = parser.createProc("f");
+ CPPUNIT_ASSERT( p != NULL);
+ YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
+ CPPUNIT_ASSERT( n != NULL);
+ CPPUNIT_ASSERT( n->getInputPort("a") != NULL);
+ CPPUNIT_ASSERT( n->getOutputPort("x") != NULL);
+ // run the schema
+ n->getInputPort("a")->edInit(42.);
+ YACS::ENGINE::Executor executor;
+ executor.RunW(p, 0);
+ // verify the output port value
+ YACS::ENGINE::OutputPyPort* var = dynamic_cast<YACS::ENGINE::OutputPyPort*>(n->getOutputPort("x"));
+ CPPUNIT_ASSERT(var);
+ PyObject* pyVal = var->get();
+ CPPUNIT_ASSERT(pyVal);
+ CPPUNIT_ASSERT(PyFloat_Check(pyVal));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(42., PyFloat_AsDouble(pyVal), 1.E-12);
+}
+
+// Test the behaviour when there is an error in the python parser
+void Py2yacsTest::parserErrors()
+{
+ verifyWrongParser("bad_parsers", "p1", "argument");
+ verifyWrongParser("bad_parsers", "p2", "Attribute 'name' not found");
+ verifyWrongParser("bad_parsers", "p3", "should be a python list");
+ verifyWrongParser("bad_parsers", "p4", "Traceback");
+ verifyWrongParser("bad_parsers", "f", "Cannot find the parsing function");
+ verifyWrongParser("err_py2yacs_invalid", "get_properties", "invalid syntax");
+ verifyWrongParser("no_file", "f", "Failed to load");
+ verifyWrongParser("bad_parsers", "p5", " ");
+ verifyWrongParser("bad_parsers", "p6", " ");
+ verifyWrongParser("bad_parsers", "p7", " ");
+ verifyWrongParser("bad_parsers", "p8", "Attribute 'name' should be a string.");
+ verifyWrongParser("bad_parsers", "p9", " ");
+ verifyWrongParser("bad_parsers", "p10", " ");
+}
+
+void Py2yacsTest::globalVerification()
+{
+ std::ifstream file_stream("exemple_py2yacs.py");
+ if(!file_stream)
+ return;
+
+ std::stringstream buffer;
+ buffer << file_stream.rdbuf();
+ Py2yacs parser;
+ parser.load(buffer.str());
+ std::list<FunctionProperties>::const_iterator it_fp;
+ const std::list<FunctionProperties>& functions = parser.getFunctionProperties();
+ for(it_fp=functions.begin();it_fp!=functions.end();it_fp++)
+ {
+ std::cerr << "Function :" << it_fp->_name << std::endl;
+ std::list<std::string>::const_iterator it;
+ std::cerr << "Input ports :" ;
+ for(it=it_fp->_input_ports.begin();it!=it_fp->_input_ports.end();it++)
+ std::cerr << *it << ",";
+ std::cerr << std::endl;
+ std::cerr << "Output ports :" ;
+ for(it=it_fp->_output_ports.begin();it!=it_fp->_output_ports.end();it++)
+ std::cerr << *it << ",";
+ std::cerr << std::endl;
+ std::cerr << "Imports :" ;
+ for(it=it_fp->_imports.begin();it!=it_fp->_imports.end();it++)
+ std::cerr << *it << ",";
+ std::cerr << std::endl;
+ std::cerr << "Errors :" ;
+ for(it=it_fp->_errors.begin();it!=it_fp->_errors.end();it++)
+ std::cerr << *it << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "-----------------------------------------" << std::endl;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2006-2016 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef _Py2yacsTest_hxx_
+#define _Py2yacsTest_hxx_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class Py2yacsTest: public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(Py2yacsTest);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST(t4);
+ CPPUNIT_TEST(t5);
+ CPPUNIT_TEST(no_multiple_returns);
+ CPPUNIT_TEST(unaccepted_statement);
+ CPPUNIT_TEST(unaccepted_statement2);
+ CPPUNIT_TEST(unaccepted_return);
+ CPPUNIT_TEST(unaccepted_return2);
+ CPPUNIT_TEST(syntaxError);
+ CPPUNIT_TEST(badFunctionName);
+ CPPUNIT_TEST(schemaExec);
+ CPPUNIT_TEST(parserErrors);
+ CPPUNIT_TEST(globalVerification);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp();
+ void tearDown();
+
+ void t1();
+ void t2();
+ void t3();
+ void t4();
+ void t5();
+ void no_multiple_returns();
+ void unaccepted_statement();
+ void unaccepted_statement2();
+ void unaccepted_return();
+ void unaccepted_return2();
+ void syntaxError();
+ void badFunctionName();
+ void schemaExec();
+ void parserErrors();
+ void globalVerification();
+};
+
+#endif
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2006-2016 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "Py2yacsTest.hxx"
+#define UNIT_TEST_HEADER " --- TEST Py2yacsTest"
+
+CPPUNIT_TEST_SUITE_REGISTRATION( Py2yacsTest );
+
+#include "BasicMainTest.hxx"
--- /dev/null
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+def p1():
+ return ["a"], ["b"]
+
+def p2(x):
+ return ["a"], ["b"]
+
+def p3(x):
+ return 5, 6
+
+def p4(a):
+ x= a / 0
+ return ["a"], ["b"]
+
+class FunctionProperties:
+ def __init__(self, function_name):
+ self.name = function_name
+ self.inputs=[]
+ self.outputs=None
+ self.errors=[]
+ self.imports=[]
+ pass
+
+def p5(f):
+ fp = FunctionProperties("boo")
+ fp.inputs=["a", 5]
+ return [fp], ["a", "b", "c"]
+
+def p6(f):
+ fp = FunctionProperties("boo")
+ fp.outputs=[7, 5]
+ return [fp], ["a", "b", "c"]
+
+def p7(f):
+ fp = FunctionProperties("boo")
+ fp.errors=[7, 5]
+ return [fp], ["a", "b", "c"]
+
+def p8(f):
+ fp = FunctionProperties("boo")
+ fp.name=[5]
+ return [fp], ["a", "b", "c"]
+
+def p9(f):
+ fp = FunctionProperties("boo")
+ return [fp], "a"
+
+def p10(f):
+ fp = FunctionProperties("boo")
+ return [fp], ["a", fp, "c"]
+
--- /dev/null
+invalid python file
+{
+}
+x += 4;
+return
\ No newline at end of file
--- /dev/null
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <cerrno>
+#include "py2yacs.hxx"
+#include "RuntimeSALOME.hxx"
+
+/*
+#include "Proc.hxx"
+#include "Node.hxx"
+#include "CORBAPorts.hxx"
+#include "InputPort.hxx"
+#include "Executor.hxx"
+*/
+
+int main(int argc, char *argv[])
+{
+ if (argc != 4)
+ {
+ std::cerr << "Usage: " << argv[0] << " pythonfile funcname outfile" << std::endl;
+ return 1;
+ }
+ YACS::ENGINE::RuntimeSALOME::setRuntime();
+ //Py_Initialize();
+ Py2yacs parser;
+ std::ifstream file_stream(argv[1]);
+ if(!file_stream)
+ {
+ std::cerr << "Error when opening file " << argv[1]
+ << ": " << strerror(errno)
+ << std::endl;
+ return 1;
+ }
+ std::stringstream buffer;
+ buffer << file_stream.rdbuf();
+ try
+ {
+ parser.load(buffer.str());
+ parser.save(argv[3], argv[2]);
+
+ /*
+ YACS::ENGINE::Proc* p = parser.createProc(argv[2]);
+ //p->setInPortValue("Schema.default_name", "a", "42.");
+ YACS::ENGINE::Node* n = p->getChildByShortName("default_name");
+ //YACS::ENGINE::Node* n = p->nodeMap["default_name"];
+ if(!n)
+ std::cerr << "Node not found." << std::endl;
+ else
+ n->getInputPort("a")->edInit(42.);
+ p->saveSchema(argv[3]);
+
+ YACS::ENGINE::Executor executor;
+ executor.RunW(p, 0);
+ n->getOutputPort("x")->dump();
+ */
+ }
+ catch(Py2yacsException& e)
+ {
+ std::cerr << e.what() << std::endl;
+ }
+ YACS::ENGINE::getRuntime()->fini();
+ //Py_Finalize();
+}
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2006-2016 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include <Python.h>
+#include <sstream>
+#include "py2yacs.hxx"
+#include "RuntimeSALOME.hxx"
+#include "Proc.hxx"
+#include "InlineNode.hxx"
+#include "AutoGIL.hxx"
+
+Py2yacsException::Py2yacsException(const std::string& what)
+: std::exception(),
+ _what(what)
+{
+}
+
+Py2yacsException::~Py2yacsException()throw ()
+{
+}
+
+const char * Py2yacsException::what() const throw ()
+{
+ return _what.c_str();
+}
+
+
+Py2yacs::Py2yacs()
+: _python_parser_module("py2yacs"),
+ _python_parser_function("get_properties"),
+ _functions(),
+ _global_errors(),
+ _python_code()
+{
+}
+
+Py2yacs::Py2yacs(const std::string& python_parser_module,
+ const std::string& python_parser_function)
+: _python_parser_module(python_parser_module),
+ _python_parser_function(python_parser_function),
+ _functions(),
+ _global_errors(),
+ _python_code()
+{
+}
+
+const std::list<std::string>& Py2yacs::getGlobalErrors() const
+{
+ return _global_errors;
+}
+
+const std::list<FunctionProperties>& Py2yacs::getFunctionProperties()const
+{
+ return _functions;
+}
+
+// Copy a python list of strings to a c++ list of strings.
+// Return an error string. An empty string means no error.
+static
+std::string copyList(PyObject *pyList, std::list<std::string>& cppList)
+{
+ std::string error;
+ if(not PyList_Check(pyList))
+ {
+ error = "Not a python list.\n";
+ //throw Py2yacsException("Not a python list.");
+ }
+ else
+ {
+ int n = PyList_Size(pyList);
+ for(int i=0; i<n; i++)
+ {
+ PyObject *elem = PyList_GetItem(pyList,i);
+ if(not PyString_Check(elem))
+ {
+ std::stringstream message;
+ message << "List element number " << i << " is not a string.\n";
+ error += message.str();
+ // throw Py2yacsException(message.str());
+ }
+ else
+ {
+ const char * portName = PyString_AsString(elem);
+ cppList.push_back(portName);
+ }
+ }
+ }
+ return error;
+}
+
+static
+std::string getPyErrorText()
+{
+ std::string result="";
+ if (PyErr_Occurred())
+ {
+ PyObject *ptype, *pvalue, *ptraceback;
+ PyObject *pystr, *module_name, *pyth_module, *pyth_func;
+ PyErr_Fetch(&ptype, &pvalue, &ptraceback);
+ pystr = PyObject_Str(pvalue);
+ result = PyString_AsString(pystr);
+ result += "\n";
+ Py_DECREF(pystr);
+
+ /* See if we can get a full traceback */
+ if(ptraceback)
+ {
+ module_name = PyString_FromString("traceback");
+ pyth_module = PyImport_Import(module_name);
+ Py_DECREF(module_name);
+ if (pyth_module)
+ {
+ pyth_func = PyObject_GetAttrString(pyth_module, "format_exception");
+ if (pyth_func && PyCallable_Check(pyth_func))
+ {
+ PyObject *pyList;
+ pyList = PyObject_CallFunctionObjArgs(pyth_func, ptype, pvalue, ptraceback, NULL);
+ if(pyList)
+ {
+ int n = PyList_Size(pyList);
+ for(int i=0; i<n; i++)
+ {
+ pystr = PyList_GetItem(pyList,i);
+ result += PyString_AsString(pystr);
+ }
+ Py_DECREF(pyList);
+ }
+ }
+ Py_XDECREF(pyth_func);
+ Py_DECREF(pyth_module);
+ }
+ }
+ Py_XDECREF(ptype);
+ Py_XDECREF(pvalue);
+ Py_XDECREF(ptraceback);
+ }
+ return result;
+}
+
+static
+PyObject* checkAndGetAttribute(PyObject *p,
+ const char* attribute,
+ std::string& error)
+{
+ PyObject *pAttribute = PyObject_GetAttrString(p, attribute);
+ if(not pAttribute)
+ {
+ error += "Attribute '";
+ error += attribute;
+ error += "' not found in the returned value of the parsing function.\n";
+ error += getPyErrorText();
+ }
+ return pAttribute;
+}
+
+void Py2yacs::load(const std::string& python_code)
+{
+ PyObject *pModule, *pDict, *pFunc;
+ PyObject *pArgs, *pValue;
+ int i;
+ std::string errorMessage="";
+ _python_code = python_code;
+ _functions.clear();
+ _global_errors.clear();
+
+ // Py_Initialize();
+ YACS::ENGINE::AutoGIL agil;
+ pValue = PyString_FromString(_python_parser_module.c_str());
+ pModule = PyImport_Import(pValue);
+ Py_DECREF(pValue);
+
+ if (not pModule)
+ {
+ errorMessage = getPyErrorText();
+ errorMessage += "\nFailed to load ";
+ errorMessage += _python_parser_module;
+ errorMessage += ".\n";
+ }
+ else
+ {
+ pFunc = PyObject_GetAttrString(pModule, _python_parser_function.c_str());
+
+ if (pFunc && PyCallable_Check(pFunc))
+ {
+ pArgs = PyTuple_New(1);
+ pValue = PyString_FromString(python_code.c_str());
+ PyTuple_SetItem(pArgs, 0, pValue);
+
+ pValue = PyObject_CallObject(pFunc, pArgs);
+ Py_DECREF(pArgs);
+ if (not pValue)
+ errorMessage = getPyErrorText();
+ else
+ {
+ if (not PyTuple_Check(pValue))
+ {
+ errorMessage += "Parsing function should return a tuple of two string lists.\n";
+ }
+ int n = PyTuple_Size(pValue);
+ if(n != 2)
+ {
+ errorMessage += "Parsing function should return two string lists.\n";
+ }
+ PyObject *pyList = PyTuple_GetItem(pValue, 0);
+ if(not PyList_Check(pyList))
+ {
+ errorMessage += "The first returned value of the parsing function"
+ " should be a python list.\n";
+ }
+ else
+ {
+ n = PyList_Size(pyList);
+ for(int i=0; i<n; i++)
+ {
+ PyObject *fpy = PyList_GetItem(pyList,i);
+ PyObject *pAttribute;
+
+ if(pAttribute = checkAndGetAttribute(fpy, "name", errorMessage))
+ {
+ if(not PyString_Check(pAttribute))
+ {
+ errorMessage += "Attribute 'name' should be a string.\n";
+ Py_DECREF(pAttribute);
+ }
+ else
+ {
+ _functions.push_back(FunctionProperties());
+ FunctionProperties& fcpp = _functions.back();
+ fcpp._name=PyString_AsString(pAttribute);
+ Py_DECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "inputs", errorMessage))
+ errorMessage += copyList(pAttribute, fcpp._input_ports);
+ Py_XDECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "outputs", errorMessage))
+ // None value means no return statement in the function
+ if(pAttribute != Py_None)
+ errorMessage += copyList(pAttribute,fcpp._output_ports);
+ Py_XDECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "errors", errorMessage))
+ errorMessage += copyList(pAttribute, fcpp._errors);
+ Py_XDECREF(pAttribute);
+
+ if(pAttribute = checkAndGetAttribute(fpy, "imports", errorMessage))
+ errorMessage += copyList(pAttribute, fcpp._imports);
+ Py_XDECREF(pAttribute);
+ }
+ }
+ }
+ }
+ errorMessage += copyList(PyTuple_GetItem(pValue, 1), _global_errors);
+ Py_DECREF(pValue);
+ }
+ }
+ else
+ {
+ errorMessage = getPyErrorText();
+ errorMessage += "\nCannot find the parsing function '";
+ errorMessage += _python_parser_function;
+ errorMessage += "' in python module '";
+ errorMessage += _python_parser_module;
+ errorMessage += "'.\n";
+ }
+ Py_XDECREF(pFunc);
+ Py_DECREF(pModule);
+ }
+
+ if(not errorMessage.empty())
+ throw Py2yacsException(errorMessage);
+ // Py_Finalize();
+}
+
+void Py2yacs::save(const std::string& file_path,
+ const std::string& python_function)const
+{
+ YACS::ENGINE::Proc* schema = createProc(python_function);
+ schema->saveSchema(file_path);
+ delete schema;
+}
+
+YACS::ENGINE::Proc* Py2yacs::createProc(const std::string& python_function)const
+{
+ if(not _global_errors.empty())
+ {
+ std::string error_message = "The python script contains errors.\n";
+ std::list<std::string>::const_iterator it;
+ for(it = _global_errors.begin(); it != _global_errors.end(); it++)
+ error_message += (*it) + "\n";
+ throw Py2yacsException(error_message);
+ }
+
+ // find function properties
+ std::list<FunctionProperties>::const_iterator fn_prop = _functions.begin();
+ while(fn_prop != _functions.end() and fn_prop->_name != python_function)
+ fn_prop++;
+
+ if(fn_prop == _functions.end())
+ {
+ throw Py2yacsException(std::string("Function not found: ")+python_function);
+ }
+
+ if(not fn_prop->_errors.empty())
+ {
+ std::string error_message = "Function contains errors.\n";
+ std::list<std::string>::const_iterator it;
+ for(it = fn_prop->_errors.begin(); it != fn_prop->_errors.end(); it++)
+ error_message += (*it) + "\n";
+ throw Py2yacsException(error_message);
+ }
+
+ // add the call to the function at the end of the script
+ std::stringstream fn_call;
+ fn_call << std::endl;
+ std::list<std::string>::const_iterator it;
+ bool first = true;
+ for(it=fn_prop->_output_ports.begin();
+ it!=fn_prop->_output_ports.end();
+ it++)
+ {
+ if (not first)
+ fn_call << ",";
+ first = false;
+ fn_call << *it;
+ }
+ fn_call << "=" << python_function << "(";
+ first = true;
+ for(it = fn_prop->_input_ports.begin();
+ it != fn_prop->_input_ports.end();
+ it++)
+ {
+ if (not first)
+ fn_call << ",";
+ first = false;
+ fn_call << *it;
+ }
+ fn_call << ")" << std::endl;
+ std::string node_body = _python_code + fn_call.str();
+
+ YACS::ENGINE::Proc* schema;
+ YACS::ENGINE::RuntimeSALOME::setRuntime();
+ YACS::ENGINE::RuntimeSALOME* runtime = YACS::ENGINE::getSALOMERuntime();
+
+ // build the YACS schema
+ const char * node_name = "default_name";
+ schema = runtime->createProc("Schema");
+ YACS::ENGINE::InlineNode* node = runtime->createScriptNode("", node_name);
+ schema->edAddChild(node);
+ node->setScript(node_body);
+ YACS::ENGINE::TypeCode *tc_double = runtime->getTypeCode("double");
+
+ for(it = fn_prop->_input_ports.begin();
+ it != fn_prop->_input_ports.end();
+ it++)
+ node->edAddInputPort(*it, tc_double);
+
+ for(it = fn_prop->_output_ports.begin();
+ it != fn_prop->_output_ports.end();
+ it++)
+ node->edAddOutputPort(*it, tc_double);
+
+ return schema;
+}
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2006-2016 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef _PY2YACS_H_
+#define _PY2YACS_H_
+
+#include <string>
+#include <list>
+#include <exception>
+
+class Py2yacsException: std::exception
+{
+ public:
+ Py2yacsException(const std::string& what);
+ virtual ~Py2yacsException()throw ();
+ virtual const char *what() const throw ();
+ private:
+ std::string _what;
+};
+
+namespace YACS
+{
+ namespace ENGINE
+ {
+ class Proc;
+ };
+};
+
+struct FunctionProperties
+{
+ public:
+ std::string _name;
+ std::list<std::string> _input_ports;
+ std::list<std::string> _output_ports;
+ std::list<std::string> _errors;
+ std::list<std::string> _imports;
+};
+
+/*! \brief Converter of a python script to a yacs schema.
+ * This class converts a string containing a python script to a yacs schema
+ * containing a python script node.
+ */
+class Py2yacs
+{
+ public:
+ Py2yacs();
+
+ /*!
+ * This constructor can be used if you want to define your own python parser.
+ * The parser function should be a python function and return a tuple of
+ * two lists.
+ * The first list contains the properties of all the functions in the script
+ * and the second one contains global errors.
+ * \param python_parser_module: name of the parser module
+ * \param python_parser_function: name of the parser function
+ */
+ Py2yacs(const std::string& python_parser_module,
+ const std::string& python_parser_function);
+
+ /*!
+ * \param python_code: contains the python code that will be converted
+ * to a yacs schema.
+ */
+ void load(const std::string& python_code);
+
+ /*!
+ * \param file_path: path to the xml file where to save the yacs schema.
+ * \param python_function: function defined in the python code that will be
+ * called in the yacs node.
+ */
+ void save(const std::string& file_path,
+ const std::string& python_function)const;
+
+ /*!
+ * A new schema is created.
+ * \param python_function: function defined in the python code that will be
+ * called in the yacs node.
+ */
+ YACS::ENGINE::Proc* createProc(const std::string& python_function)const;
+
+ const std::list<std::string>& getGlobalErrors() const;
+ const std::list<FunctionProperties>& getFunctionProperties()const;
+
+ private:
+ std::string _python_parser_module;
+ std::string _python_parser_function;
+ std::list<FunctionProperties> _functions;
+ std::list<std::string> _global_errors;
+ std::string _python_code;
+};
+
+#endif //_PY2YACS_H_
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 *-
+# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+import ast
+
+class FunctionProperties:
+ def __init__(self, function_name):
+ self.name = function_name
+ self.inputs=[]
+ self.outputs=None
+ self.errors=[]
+ self.imports=[]
+ pass
+ def __str__(self):
+ result = "Function:" + self.name + "\n"
+ result+= " Inputs:" + str(self.inputs) + "\n"
+ result+= " Outputs:"+ str(self.outputs) + "\n"
+ result+= " Errors:" + str(self.errors) + "\n"
+ result+= " Imports:"+ str(self.imports) + "\n"
+ return result
+
+class v(ast.NodeVisitor):
+ def visit_Module(self, node):
+ #print type(node).__name__, ":"
+ accepted_tokens = ["Import", "ImportFrom", "FunctionDef", "ClassDef"]
+ #print "module body:"
+ self.global_errors=[]
+ for e in node.body:
+ type_name = type(e).__name__
+ if type_name not in accepted_tokens:
+ error="py2yacs error at line %s: not accepted statement '%s'." % (
+ e.lineno, type_name)
+ self.global_errors.append(error)
+ #print type_name
+ #print "------------------------------------------------------------------"
+ self.functions=[]
+ self.lastfn=""
+ self.infunc=False
+ self.inargs=False
+ self.generic_visit(node)
+ pass
+ def visit_FunctionDef(self, node):
+ #print type(node).__name__, ":", node.name
+ if not self.infunc:
+ self.lastfn = FunctionProperties(node.name)
+ self.functions.append(self.lastfn)
+ self.infunc=True
+ #
+ self.generic_visit(node)
+ #
+ self.lastfn = None
+ self.infunc=False
+ pass
+ def visit_arguments(self, node):
+ #print type(node).__name__, ":"
+ self.inargs=True
+ self.generic_visit(node)
+ self.inargs=False
+ pass
+ def visit_Name(self, node):
+ if self.inargs :
+ #print type(node).__name__, ":", node.id
+ self.lastname=node.id
+ self.generic_visit(node)
+ pass
+ def visit_Param(self, node):
+ #print type(node).__name__, ":", self.lastname
+ self.lastfn.inputs.append(self.lastname)
+ pass
+ def visit_Return(self, node):
+ #print type(node).__name__, ":", node.value
+ if self.lastfn.outputs is not None :
+ error="py2yacs error at line %s: multiple returns." % node.lineno
+ self.lastfn.errors.append(error)
+ return
+ self.lastfn.outputs = []
+ if node.value is None :
+ pass
+ elif 'Tuple' == type(node.value).__name__ :
+ for e in node.value.elts:
+ if 'Name' == type(e).__name__ :
+ self.lastfn.outputs.append(e.id)
+ else :
+ error="py2yacs error at line %s: invalid type returned '%s'." % (
+ node.lineno, type(e).__name__)
+ self.lastfn.errors.append(error)
+ else:
+ if 'Name' == type(node.value).__name__ :
+ self.lastfn.outputs.append(node.value.id)
+ else :
+ error="py2yacs error at line %s: invalid type returned '%s'." %(
+ node.lineno, type(node.value).__name__)
+ self.lastfn.errors.append(error)
+ pass
+ pass
+ pass
+
+ def visit_ClassDef(self, node):
+ # just ignore classes
+ pass
+
+ def visit_Import(self, node):
+ if self.infunc:
+ for n in node.names:
+ self.lastfn.imports.append(n.name)
+ def visit_ImportFrom(self, node):
+ if self.infunc:
+ m=node.module
+ for n in node.names:
+ self.lastfn.imports.append(m+"."+n.name)
+
+class vtest(ast.NodeVisitor):
+ def generic_visit(self, node):
+ #print type(node).__name__
+ ast.NodeVisitor.generic_visit(self, node)
+
+def create_yacs_schema(text, fn_name, fn_args, fn_returns, file_name):
+ import pilot
+ import SALOMERuntime
+ #import loader
+ SALOMERuntime.RuntimeSALOME_setRuntime()
+ runtime = pilot.getRuntime()
+ schema = runtime.createProc("schema")
+ node = runtime.createFuncNode("", "default_name")
+ schema.edAddChild(node)
+ fncall = "\n%s=%s(%s)\n"%(",".join(fn_returns),
+ fn_name,
+ ",".join(fn_args))
+ node.setScript(text+fncall)
+ node.setFname(fn_name)
+ td=schema.getTypeCode("double")
+ for p in fn_args:
+ node.edAddInputPort(p, td)
+ for p in fn_returns:
+ node.edAddOutputPort(p, td)
+ schema.saveSchema(file_name)
+
+def get_properties(text_file):
+ bt=ast.parse(text_file)
+ w=v()
+ w.visit(bt)
+ return w.functions, w.global_errors
+
+if __name__ == '__main__':
+ import argparse
+ parser = argparse.ArgumentParser(description="Generate a YACS schema from a python file containing a function to run.")
+ parser.add_argument("file", help='Path to the python file')
+ parser.add_argument("-o","--output",
+ help='Path to the output file (yacs_schema.xml by default)',
+ default='yacs_schema.xml')
+ parser.add_argument("-d","--def_name",
+ help='Name of the function to call in the yacs node (_exec by default)',
+ default='_exec')
+ args = parser.parse_args()
+ with open(args.file, 'r') as f:
+ text_file = f.read()
+ #bt=ast.parse(text_file)
+ #w=vtest()
+ #w=v()
+ #w.visit(bt)
+ #print "global errors:", w.global_errors
+ #for f in w.functions:
+ # print f
+
+ fn_name = args.def_name
+ functions,errors = get_properties(text_file)
+ print "global errors:", errors
+ for f in functions:
+ print f
+
+ fn_properties = next((f for f in functions if f.name == fn_name), None)
+ if fn_properties is not None :
+ if not fn_properties.errors :
+ create_yacs_schema(text_file, fn_name,
+ fn_properties.inputs, fn_properties.outputs,
+ args.output)
+ else:
+ print "\n".join(fn_properties.errors)
+ else:
+ print "Function not found:", fn_name
+
\ No newline at end of file