module.cpp
Go to the documentation of this file.00001 /*************************************************************************** 00002 file : $URL: https://frepple.svn.sourceforge.net/svnroot/frepple/trunk/modules/python/module.cpp $ 00003 version : $LastChangedRevision: 732 $ $LastChangedBy: jdetaeye $ 00004 date : $LastChangedDate: 2008-04-05 17:11:47 +0200 (Sat, 05 Apr 2008) $ 00005 ***************************************************************************/ 00006 00007 /*************************************************************************** 00008 * * 00009 * Copyright (C) 2007 by Johan De Taeye * 00010 * * 00011 * This library is free software; you can redistribute it and/or modify it * 00012 * under the terms of the GNU Lesser General Public License as published * 00013 * by the Free Software Foundation; either version 2.1 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * 00019 * General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA * 00024 * * 00025 ***************************************************************************/ 00026 00027 #include "embeddedpython.h" 00028 00029 namespace module_python 00030 { 00031 00032 const MetaClass CommandPython::metadata; 00033 const MetaClass CommandPython::metadata2; 00034 PyThreadState *CommandPython::mainThreadState = NULL; 00035 00036 PyObject* PythonLogicException = NULL; 00037 PyObject* PythonDataException = NULL; 00038 PyObject* PythonRuntimeException = NULL; 00039 00040 00041 // Define the methods to be exposed into Python 00042 PyMethodDef CommandPython::PythonAPI[] = 00043 { 00044 {"log", CommandPython::python_log, METH_VARARGS, 00045 "Prints a string to the frePPLe log file." 00046 }, 00047 {"readXMLdata", CommandPython::python_readXMLdata, METH_VARARGS, 00048 "Processes an XML string passed as argument."}, 00049 {"readXMLfile", CommandPython::python_readXMLfile, METH_VARARGS, 00050 "Read an XML-file."}, 00051 {"saveXMLfile", CommandPython::python_saveXMLfile, METH_VARARGS, 00052 "Save the model to an XML-file."}, 00053 {"saveXMLstring", CommandPython::python_saveXMLstring, METH_NOARGS, 00054 "Returns the model as an XML-formatted string."}, 00055 {"buffers", PythonBufferIterator::create, METH_NOARGS, 00056 "Returns an iterator over the buffers."}, 00057 {"locations", PythonLocationIterator::create, METH_NOARGS, 00058 "Returns an iterator over the locations."}, 00059 {"customers", PythonCustomerIterator::create, METH_NOARGS, 00060 "Returns an iterator over the customer."}, 00061 {"items", PythonItemIterator::create, METH_NOARGS, 00062 "Returns an iterator over the items."}, 00063 {"calendars", PythonCalendarIterator::create, METH_NOARGS, 00064 "Returns an iterator over the calendars."}, 00065 {"demands", PythonDemandIterator::create, METH_NOARGS, 00066 "Returns an iterator over the demands."}, 00067 {"resources", PythonResourceIterator::create, METH_NOARGS, 00068 "Returns an iterator over the resources."}, 00069 {"operations", PythonOperationIterator::create, METH_NOARGS, 00070 "Returns an iterator over the operations."}, 00071 {"operationplans", PythonOperationPlanIterator::create, METH_NOARGS, 00072 "Returns an iterator over the operationplans."}, 00073 {"problems", PythonProblemIterator::create, METH_NOARGS, 00074 "Returns an iterator over the problems."}, 00075 {"solvers", PythonSolverIterator::create, METH_NOARGS, 00076 "Returns an iterator over the solvers."}, 00077 {NULL, NULL, 0, NULL} 00078 }; 00079 00080 00081 MODULE_EXPORT const char* initialize(const CommandLoadLibrary::ParameterList& z) 00082 { 00083 // Initialize only once 00084 static bool init = false; 00085 static const char* name = "python"; 00086 if (init) 00087 { 00088 logger << "Warning: Initializing module python more than once." << endl; 00089 return name; 00090 } 00091 init = true; 00092 00093 // Initialize the metadata. 00094 CommandPython::metadata.registerClass( 00095 "command", 00096 "command_python", 00097 Object::createDefault<CommandPython>); 00098 00099 // Register python also as a processing instruction. 00100 CommandPython::metadata2.registerClass( 00101 "instruction", 00102 "python", 00103 Object::createDefault<CommandPython>); 00104 00105 // Initialize the interpreter 00106 CommandPython::initialize(); 00107 00108 // Return the name of the module 00109 return name; 00110 } 00111 00112 00113 void CommandPython::initialize() 00114 { 00115 // Initialize the interpreter and the frepple module 00116 Py_InitializeEx(0); // The arg 0 indicates that the interpreter doesn't 00117 // implement its own signal handler 00118 PyEval_InitThreads(); // Initializes threads and captures global lock 00119 PyObject* m = Py_InitModule3 00120 ("frepple", CommandPython::PythonAPI, "Access to the frePPLe library"); 00121 if (!m) 00122 { 00123 PyEval_ReleaseLock(); 00124 throw frepple::RuntimeException("Can't initialize Python interpreter"); 00125 } 00126 00127 // Make the datetime types available 00128 PyDateTime_IMPORT; 00129 00130 // Create python exception types 00131 int nok = 0; 00132 PythonLogicException = PyErr_NewException("frepple.LogicException", NULL, NULL); 00133 Py_IncRef(PythonLogicException); 00134 nok += PyModule_AddObject(m, "LogicException", PythonLogicException); 00135 PythonDataException = PyErr_NewException("frepple.DataException", NULL, NULL); 00136 Py_IncRef(PythonDataException); 00137 nok += PyModule_AddObject(m, "DataException", PythonDataException); 00138 PythonRuntimeException = PyErr_NewException("frepple.RuntimeException", NULL, NULL); 00139 Py_IncRef(PythonRuntimeException); 00140 nok += PyModule_AddObject(m, "RuntimeException", PythonRuntimeException); 00141 00142 // Add a string constant for the version 00143 nok += PyModule_AddStringConstant(m, "version", PACKAGE_VERSION); 00144 00145 // Capture the main trhead state, for use during threaded execution 00146 mainThreadState = PyThreadState_Get(); 00147 00148 // Register our new types 00149 nok += PythonPlan::initialize(m); 00150 nok += PythonBuffer::initialize(m); 00151 nok += PythonBufferDefault::initialize(m); 00152 nok += PythonBufferInfinite::initialize(m); 00153 nok += PythonBufferProcure::initialize(m); 00154 nok += PythonBufferIterator::initialize(m); 00155 nok += PythonCalendar::initialize(m); 00156 nok += PythonCalendarIterator::initialize(m); 00157 nok += PythonCalendarBucket::initialize(m); 00158 nok += PythonCalendarBucketIterator::initialize(m); 00159 nok += PythonCalendarBool::initialize(m); 00160 nok += PythonCalendarVoid::initialize(m); 00161 nok += PythonCalendarDouble::initialize(m); 00162 nok += PythonCustomer::initialize(m); 00163 nok += PythonCustomerDefault::initialize(m); 00164 nok += PythonCustomerIterator::initialize(m); 00165 nok += PythonDemand::initialize(m); 00166 nok += PythonDemandIterator::initialize(m); 00167 nok += PythonDemandDefault::initialize(m); 00168 nok += PythonDemandPlanIterator::initialize(m); 00169 nok += PythonPeggingIterator::initialize(m); 00170 nok += PythonFlow::initialize(m); 00171 nok += PythonFlowIterator::initialize(m); 00172 nok += PythonFlowPlan::initialize(m); 00173 nok += PythonFlowPlanIterator::initialize(m); 00174 nok += PythonItem::initialize(m); 00175 nok += PythonItemDefault::initialize(m); 00176 nok += PythonItemIterator::initialize(m); 00177 nok += PythonLoad::initialize(m); 00178 nok += PythonLoadIterator::initialize(m); 00179 nok += PythonLoadPlan::initialize(m); 00180 nok += PythonLoadPlanIterator::initialize(m); 00181 nok += PythonLocation::initialize(m); 00182 nok += PythonLocationDefault::initialize(m); 00183 nok += PythonLocationIterator::initialize(m); 00184 nok += PythonOperation::initialize(m); 00185 nok += PythonOperationAlternate::initialize(m); 00186 nok += PythonOperationFixedTime::initialize(m); 00187 nok += PythonOperationTimePer::initialize(m); 00188 nok += PythonOperationRouting::initialize(m); 00189 nok += PythonOperationIterator::initialize(m); 00190 nok += PythonOperationPlan::initialize(m); 00191 nok += PythonOperationPlanIterator::initialize(m); 00192 nok += PythonProblem::initialize(m); 00193 nok += PythonProblemIterator::initialize(m); 00194 nok += PythonResource::initialize(m); 00195 nok += PythonResourceDefault::initialize(m); 00196 nok += PythonResourceInfinite::initialize(m); 00197 nok += PythonResourceIterator::initialize(m); 00198 nok += PythonSolver::initialize(m); 00199 nok += PythonSolverIterator::initialize(m); 00200 nok += PythonSolverMRP::initialize(m); 00201 00202 // Redirect the stderr and stdout streams of Python 00203 PyRun_SimpleString( 00204 "import frepple, sys\n" 00205 "class redirect:\n" 00206 "\tdef write(self,str):\n" 00207 "\t\tfrepple.log(str)\n" 00208 "sys.stdout = redirect()\n" 00209 "sys.stderr = redirect()" 00210 ); 00211 00212 // Search and execute the initialization file '$FREPPLE_HOME/init.py' 00213 string init = Environment::getHomeDirectory() + "init.py"; 00214 struct stat stat_p; 00215 if (!nok && !stat(init.c_str(), &stat_p)) 00216 { 00217 // Initialization file exists 00218 PyObject *m = PyImport_AddModule("__main__"); 00219 if (!m) 00220 { 00221 PyEval_ReleaseLock(); 00222 throw frepple::RuntimeException("Can't execute Python script 'init.py'"); 00223 } 00224 PyObject *d = PyModule_GetDict(m); 00225 if (!d) 00226 { 00227 PyEval_ReleaseLock(); 00228 throw frepple::RuntimeException("Can't execute Python script 'init.py'"); 00229 } 00230 init = "execfile('" + init + "')\n"; 00231 PyObject *v = PyRun_String(init.c_str(), Py_file_input, d, d); 00232 if (!v) 00233 { 00234 // Print the error message 00235 PyErr_Print(); 00236 // Release the lock 00237 PyEval_ReleaseLock(); 00238 throw frepple::RuntimeException("Error executing Python script 'init.py'"); 00239 } 00240 Py_DECREF(v); 00241 if (Py_FlushLine()) PyErr_Clear(); 00242 } 00243 00244 // Release the lock 00245 PyEval_ReleaseLock(); 00246 00247 // A final check... 00248 if (nok || !mainThreadState) 00249 throw frepple::RuntimeException("Can't initialize Python interpreter"); 00250 } 00251 00252 00253 } // End namespace
Documentation generated by
