diff --git a/CMakeLists.txt b/CMakeLists.txt index cccba0f85a..99a275b3a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -720,6 +720,7 @@ endif() add_library(OpenSeesPy SHARED EXCLUDE_FROM_ALL ${OPS_SRC_DIR}/interpreter/PythonModule.cpp ${OPS_SRC_DIR}/actor/objectBroker/FEM_ObjectBrokerAllClasses.cpp + ${OPS_SRC_DIR}/api/packages.cpp ) set_target_properties(OpenSeesPy PROPERTIES PREFIX "") diff --git a/SRC/interpreter/PythonModule.cpp b/SRC/interpreter/PythonModule.cpp index a42aadd40f..5f078334c9 100644 --- a/SRC/interpreter/PythonModule.cpp +++ b/SRC/interpreter/PythonModule.cpp @@ -179,53 +179,53 @@ PythonModule::getDouble(double *data, int numArgs) { return 0; } -int PythonModule::getDoubleList(int* size, Vector* data) -{ +int PythonModule::getDoubleList(int* size, Vector* data) +{ if (wrapper.getCurrentArg() >= wrapper.getNumberArgs()) { return -1; - } - - PyObject* o = PyTuple_GetItem(wrapper.getCurrentArgv(), wrapper.getCurrentArg()); - wrapper.incrCurrentArg(); - - if (PyList_Check(o)) { - *size = PyList_Size(o); - data->resize(*size); - for (int i = 0; i < *size; i++) { - PyErr_Clear(); - PyObject* item = PyList_GetItem(o, i); - if (!(PyLong_Check(item) || PyFloat_Check(item) || PyBool_Check(item))) { - opserr << "PythonModule::getDoubleList error: item " << i << " in list is not a float (or int or bool)\n"; - return -1; - } - (*data)(i) = PyFloat_AsDouble(item); - if (PyErr_Occurred()) { - return -1; - } - } - } - else if (PyTuple_Check(o)) { - *size = PyTuple_Size(o); - data->resize(*size); - for (int i = 0; i < *size; i++) { - PyErr_Clear(); - PyObject* item = PyTuple_GetItem(o, i); - if (!(PyLong_Check(item) || PyFloat_Check(item) || PyBool_Check(item))) { - opserr << "PythonModule::getDoubleList error: item " << i << " in tuple is not a float (or int or bool)\n"; - return -1; - } - (*data)(i) = PyFloat_AsDouble(item); - if (PyErr_Occurred()) { - return -1; - } - } - } - else { - opserr << "PythonModule::getDoubleList error: input is neither a list nor a tuple\n"; - return -1; - } - - return 0; + } + + PyObject* o = PyTuple_GetItem(wrapper.getCurrentArgv(), wrapper.getCurrentArg()); + wrapper.incrCurrentArg(); + + if (PyList_Check(o)) { + *size = (int)PyList_Size(o); + data->resize(*size); + for (int i = 0; i < *size; i++) { + PyErr_Clear(); + PyObject* item = PyList_GetItem(o, i); + if (!(PyLong_Check(item) || PyFloat_Check(item) || PyBool_Check(item))) { + opserr << "PythonModule::getDoubleList error: item " << i << " in list is not a float (or int or bool)\n"; + return -1; + } + (*data)(i) = PyFloat_AsDouble(item); + if (PyErr_Occurred()) { + return -1; + } + } + } + else if (PyTuple_Check(o)) { + *size = (int)PyTuple_Size(o); + data->resize(*size); + for (int i = 0; i < *size; i++) { + PyErr_Clear(); + PyObject* item = PyTuple_GetItem(o, i); + if (!(PyLong_Check(item) || PyFloat_Check(item) || PyBool_Check(item))) { + opserr << "PythonModule::getDoubleList error: item " << i << " in tuple is not a float (or int or bool)\n"; + return -1; + } + (*data)(i) = PyFloat_AsDouble(item); + if (PyErr_Occurred()) { + return -1; + } + } + } + else { + opserr << "PythonModule::getDoubleList error: input is neither a list nor a tuple\n"; + return -1; + } + + return 0; } const char * @@ -324,41 +324,41 @@ PythonModule::getStringCopy(char **stringPtr) { return -1; }*/ -int -PythonModule::evalDoubleStringExpression(const char* theExpression, double& current_val) -{ +int +PythonModule::evalDoubleStringExpression(const char* theExpression, double& current_val) +{ if (theExpression == 0) { - opserr << "OPS_EvalDoubleStringExpression Error: Expression not set\n"; + opserr << "PythonModule::evalDoubleStringExpression error: Expression not set\n"; return -1; } // run the string and get results PyObject* py_main = PyImport_AddModule("__main__"); if (py_main == NULL) { - opserr << "OPS_EvalDoubleStringExpression Error: cannot add module __main__\n"; + opserr << "PythonModule::evalDoubleStringExpression error: cannot add module __main__\n"; return -1; } PyObject* py_dict = PyModule_GetDict(py_main); if (py_main == NULL) { - opserr << "OPS_EvalDoubleStringExpression Error: cannot get dict of module __main__\n"; + opserr << "PythonModule::evalDoubleStringExpression error: cannot get dict of module __main__\n"; return -1; } PyObject* PyRes = PyRun_String(theExpression, Py_eval_input, py_dict, py_dict); if (PyRes == NULL) { - opserr << "OPS_EvalDoubleStringExpression Error: failed to evaluate expression\n"; + opserr << "PythonModule::evalDoubleStringExpression error: failed to evaluate expression\n"; return -1; } // get results if (!(PyLong_Check(PyRes) || PyFloat_Check(PyRes) || PyBool_Check(PyRes))) { - opserr << "OPS_EvalDoubleStringExpression Error: the expression must return a float (or int or bool)\n"; + opserr << "PythonModule::evalDoubleStringExpression error: the expression must return a float (or int or bool)\n"; return -1; } current_val = PyFloat_AsDouble(PyRes); // done - return 0; + return 0; } void diff --git a/SRC/interpreter/PythonWrapper.cpp b/SRC/interpreter/PythonWrapper.cpp index e1d020f897..3d09a2aefc 100644 --- a/SRC/interpreter/PythonWrapper.cpp +++ b/SRC/interpreter/PythonWrapper.cpp @@ -1170,7 +1170,7 @@ static PyObject *Py_ops_setNodeDisp(PyObject *self, PyObject *args) static PyObject *Py_ops_getNodeTemperature(PyObject *self, PyObject *args) { - wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + wrapper->resetCommandLine((int)PyTuple_Size(args), 1, args); if (OPS_getNodeTemperature() < 0) { opserr<<(void*)0; @@ -1182,7 +1182,7 @@ static PyObject *Py_ops_getNodeTemperature(PyObject *self, PyObject *args) static PyObject *Py_ops_setNodeTemperature(PyObject *self, PyObject *args) { - wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + wrapper->resetCommandLine((int)PyTuple_Size(args), 1, args); if (OPS_setNodeTemperature() < 0) { opserr<<(void*)0; @@ -2419,7 +2419,7 @@ static PyObject *Py_ops_randomVariable(PyObject *self, PyObject *args) static PyObject *Py_ops_filter(PyObject *self, PyObject *args) { - wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + wrapper->resetCommandLine((int)PyTuple_Size(args), 1, args); if (OPS_filter() < 0) { opserr<<(void*)0; @@ -2431,7 +2431,7 @@ static PyObject *Py_ops_filter(PyObject *self, PyObject *args) static PyObject *Py_ops_spectrum(PyObject *self, PyObject *args) { - wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + wrapper->resetCommandLine((int)PyTuple_Size(args), 1, args); if (OPS_spectrum() < 0) { opserr<<(void*)0; @@ -2443,7 +2443,7 @@ static PyObject *Py_ops_spectrum(PyObject *self, PyObject *args) static PyObject *Py_ops_modulatingFunction(PyObject *self, PyObject *args) { - wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + wrapper->resetCommandLine((int)PyTuple_Size(args), 1, args); if (OPS_modulatingFunction() < 0) { opserr<<(void*)0; @@ -2894,7 +2894,7 @@ static PyObject *Py_ops_findDesignPoint(PyObject *self, static PyObject *Py_ops_findCurvatures(PyObject *self, PyObject *args) { - wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + wrapper->resetCommandLine((int)PyTuple_Size(args), 1, args); if (OPS_findCurvatures() < 0) { opserr << (void *)0; @@ -2916,7 +2916,7 @@ static PyObject *Py_ops_runFORMAnalysis(PyObject *self, PyObject *args) { } static PyObject *Py_ops_runSORMAnalysis(PyObject *self, PyObject *args) { - wrapper->resetCommandLine(PyTuple_Size(args), 1, args); + wrapper->resetCommandLine((int)PyTuple_Size(args), 1, args); if (OPS_runSORMAnalysis() < 0) { opserr << (void *)0; diff --git a/SRC/interpreter/TclInterpreter.cpp b/SRC/interpreter/TclInterpreter.cpp index 63639ccb44..caaff5bf0d 100644 --- a/SRC/interpreter/TclInterpreter.cpp +++ b/SRC/interpreter/TclInterpreter.cpp @@ -541,6 +541,38 @@ TclInterpreter::getDouble(double *data, int numArgs) { return 0; } +int +TclInterpreter::getDoubleList(int* size, Vector* data) +{ + TCL_Char** strings; + + if (Tcl_SplitList(interp, wrapper.getCurrentArgv()[wrapper.getCurrentArg()], + size, &strings) != TCL_OK) { + opserr << "TclInterpreter::getDoubleList error: problem splitting list " + << wrapper.getCurrentArgv()[wrapper.getCurrentArg()] << " \n"; + return -1; + } + + data->resize(*size); + for (int i = 0; i < *size; i++) { + double value; + if (Tcl_GetDouble(interp, strings[i], &value) != TCL_OK) { + opserr << "TclInterpreter::getDoubleList error: problem reading data value " + << strings[i] << " \n"; + // free up the array of strings .. see tcl man pages as to why + Tcl_Free((char*)strings); + return -1; + } + (*data)(i) = value; + } + // free up the array of strings .. see tcl man pages as to why + Tcl_Free((char*)strings); + + wrapper.incrCurrentArg(); + + return 0; +} + const char* TclInterpreter::getString() { @@ -559,6 +591,19 @@ TclInterpreter::getStringCopy(char **stringPtr) { return -1; } +int +TclInterpreter::evalDoubleStringExpression( + const char* theExpression, double& current_val) { + + if (Tcl_ExprDouble(interp, theExpression, ¤t_val) != TCL_OK) { + opserr << "TclInterpreter::evalDoubleStringExpression -- expression \"" << theExpression; + opserr << "\" caused error:" << endln << Tcl_GetStringResult(interp) << endln; + return -1; + } + + return 0; +} + void TclInterpreter::resetInput(int cArg) { diff --git a/SRC/interpreter/TclInterpreter.h b/SRC/interpreter/TclInterpreter.h index e6269a9b9a..37037984b3 100644 --- a/SRC/interpreter/TclInterpreter.h +++ b/SRC/interpreter/TclInterpreter.h @@ -61,8 +61,10 @@ class TclInterpreter: public DL_Interpreter virtual int getNumRemainingInputArgs(void); virtual int getInt(int *, int numArgs); virtual int getDouble(double *, int numArgs); + virtual int getDoubleList(int* size, Vector* data); virtual const char* getString(); virtual int getStringCopy(char **stringPtr); + virtual int evalDoubleStringExpression(const char* theExpression, double& current_val); virtual void resetInput(int cArg); // methods for interpreters to output results diff --git a/SRC/interpreter/TclWrapper.cpp b/SRC/interpreter/TclWrapper.cpp index fabeba3114..1b4525f37d 100644 --- a/SRC/interpreter/TclWrapper.cpp +++ b/SRC/interpreter/TclWrapper.cpp @@ -1670,10 +1670,38 @@ static int Tcl_ops_partition(ClientData clientData, Tcl_Interp *interp, int argc static int Tcl_ops_loadPackage(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { wrapper->resetCommandLine(argc, 1, argv); - - if (OPS_loadPackage() < 0) return TCL_ERROR; - - return TCL_OK; + + if (OPS_GetNumRemainingInputArgs() < 1) { + opserr << "WARNING insufficient arguments\n"; + opserr << "Want: loadPackage libName? \n"; + return TCL_ERROR; + } + + int res = -1; + void* libHandle; + int (*funcPtr)(ClientData clientData, Tcl_Interp *interp, int argc, + TCL_Char **argv, Domain*); + + // get the library function + if (argc == 2) { + res = getLibraryFunction(argv[1], argv[1], &libHandle, (void**)&funcPtr); + } + else if (argc == 3) { + res = getLibraryFunction(argv[1], argv[2], &libHandle, (void**)&funcPtr); + } + + // get the Domain + Domain* theDomain = OPS_GetDomain(); + + // finally load the package (i.e., load the function from the library) + if (res == 0) { + res = (*funcPtr)(clientData, interp, argc, argv, theDomain); + } + else { + opserr << "Error: Could not find function: " << argv[1] << endln; + } + + return res; } ////////////////////////////////////////////// @@ -1872,5 +1900,5 @@ TclWrapper::addOpenSeesCommands(Tcl_Interp* interp) addCommand(interp,"stiffnessDegradation", &Tcl_ops_strengthDegradation); addCommand(interp,"unloadingRule", &Tcl_ops_unloadingRule); addCommand(interp,"partition", &Tcl_ops_partition); - addCommand(interp, "loadPackage", &Tcl_ops_loadPackage); + addCommand(interp,"loadPackage", &Tcl_ops_loadPackage); } diff --git a/SRC/modelbuilder/tcl/TclModelBuilder.cpp b/SRC/modelbuilder/tcl/TclModelBuilder.cpp index e6bb2e3e75..4092b7c4bf 100644 --- a/SRC/modelbuilder/tcl/TclModelBuilder.cpp +++ b/SRC/modelbuilder/tcl/TclModelBuilder.cpp @@ -4788,34 +4788,40 @@ TclCommand_addFrictionModel(ClientData clientData, } int -TclCommand_Package(ClientData clientData, Tcl_Interp *interp, int argc, TCL_Char **argv) +TclCommand_Package(ClientData clientData, Tcl_Interp* interp, int argc, TCL_Char** argv) { - - void *libHandle; - int (*funcPtr)(ClientData clientData, Tcl_Interp *interp, int argc, - TCL_Char **argv, Domain*, TclModelBuilder*); - - const char *funcName = 0; - int res = -1; - - if (argc == 2) { - res = getLibraryFunction(argv[1], argv[1], &libHandle, (void **)&funcPtr); - } else if (argc == 3) { - res = getLibraryFunction(argv[1], argv[2], &libHandle, (void **)&funcPtr); - } - - if (res == 0) { - int result = (*funcPtr)(clientData, interp, argc, argv, theTclDomain, theTclBuilder); - } else { - opserr << "Error: Could not find function: " << argv[1] << endln; - return -1; - } - - return res; + // make sure correct number of arguments on command line + if (argc < 1) { + opserr << "WARNING insufficient arguments\n"; + printCommand(argc, argv); + opserr << "Want: loadPackage libName? \n"; + return TCL_ERROR; + } + + int res = -1; + void* libHandle; + int (*funcPtr)(ClientData clientData, Tcl_Interp * interp, + int argc, TCL_Char * *argv, Domain*); + + // get the library function + if (argc == 2) { + res = getLibraryFunction(argv[1], argv[1], &libHandle, (void**)&funcPtr); + } + else if (argc == 3) { + res = getLibraryFunction(argv[1], argv[2], &libHandle, (void**)&funcPtr); + } + + // finally load the package (i.e., load the function from the library) + if (res == 0) { + res = (*funcPtr)(clientData, interp, argc, argv, theTclDomain); + } + else { + opserr << "Error: Could not find function: " << argv[1] << endln; + } + + return res; } - - // Added by Alborz Ghofrani - U.Washington extern int TclCommand_GenerateInterfacePoints(ClientData clientData, Tcl_Interp *interp, int argc,