User Manual, Developers Guide and API Documentation

View.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 16, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 // Since Python may define some pre-processor definitions which affect the
00029 // standard headers on some systems, you must include Python.h before any
00030 // standard headers are included.
00031 #include <WNS/Python.hpp>
00032 
00033 #include <WNS/pyconfig/View.hpp>
00034 #include <WNS/Exception.hpp>
00035 #include <WNS/Assure.hpp>
00036 
00037 #include <sstream>
00038 #include <iostream>
00039 #include <csignal>
00040 
00041 using namespace wns::pyconfig;
00042 
00043 View::View() :
00044     dict(NULL),
00045     viewExpression()
00046 {
00047     ++View::getCount();
00048     this->initializePython();
00049 }
00050 
00051 View::View(const View& other, const std::string &newViewExpression) :
00052     dict(NULL),
00053     viewExpression("")
00054 {
00055     ++View::getCount();
00056     this->initializePython();
00057 
00058     assure(!PyErr_Occurred(), "Dirty python context!");
00059 
00060     Object pyObject = other.getObject(newViewExpression);
00061     if(pyObject.isNull())
00062     {
00063         other.couldntRetrieve(newViewExpression);
00064         this->showdown("Couldn't resolve viewExpression.");
00065     }
00066 
00067     // not needed any longer
00068     pyObject.decref();
00069 
00070     std::stringstream ss;
00071     // the following python code snippet creates the context
00072     // for the new view.
00073     // View is a subclass of dict. you can find View in the
00074     // pyconfig::Parser module of the wns package.
00075     ss << "__import__('openwns.pyconfig').pyconfig.View(" << newViewExpression << ")";
00076 
00077     this->dict = Object(PyRun_String(ss.str().c_str(),
00078                      Py_eval_input,
00079                      other.dict.obj_,
00080                      other.dict.obj_));
00081     if(this->dict.isNull())
00082     {
00083         other.couldntRetrieve(newViewExpression);
00084         showdown("Couldn't resolve viewExpression.");
00085     }
00086     assert(!this->dict.isNull());
00087 
00088     this->viewExpression = other.viewExpression + "::" + newViewExpression;
00089 } // View
00090 
00091 
00092 View::View(const View& other, const std::string &newViewExpression, int at) :
00093     dict(NULL),
00094     viewExpression("")
00095 {
00096     ++View::getCount();
00097     this->initializePython();
00098     assure(!PyErr_Occurred(), "Dirty python context!");
00099 
00100     std::stringstream subscription;
00101     subscription << newViewExpression << "[" << at << "]";
00102 
00103     Object pyObject = other.getObject(subscription.str());
00104     if(pyObject.isNull())
00105     {
00106         other.couldntRetrieve(newViewExpression);
00107         showdown("Couldn't resolve viewExpression.");
00108     }
00109 
00110     // Not needed any longer
00111     pyObject.decref();
00112 
00113     {
00114         std::stringstream ss;
00115         ss << "__import__('openwns.pyconfig').pyconfig.View("
00116            << newViewExpression
00117            << "[" << at << "]"
00118            << ")";
00119 
00120         dict = Object(PyRun_String(ss.str().c_str(),
00121                        Py_eval_input,
00122                        other.dict.obj_,
00123                        other.dict.obj_));
00124         assert(!dict.isNull());
00125     }
00126 
00127     {
00128         std::stringstream ss;
00129 
00130         ss << other.viewExpression
00131            << "::" << newViewExpression << "[" << at << "]";
00132         viewExpression = ss.str();
00133     }
00134 } // View
00135 
00136 
00137 View::View(const Sequence& seq, int at) :
00138     dict(NULL),
00139     viewExpression("")
00140 {
00141     ++View::getCount();
00142     this->initializePython();
00143     assure(!PyErr_Occurred(), "Dirty python context!");
00144 
00145     assure(!seq.isSequenceAt(at), "Trying to create pyconfig::View from nested sequence!");
00146 
00147     Object pyDict(PyDict_New());
00148         assure(!pyDict.isNull(), "Creation of Python Dict Failed");
00149 
00150     int result = PyDict_SetItemString(pyDict.obj_, "dummy", seq.sequence.obj_);
00151         assure(result==0, "Inserting of element into Dict failed!");
00152 
00153     result = PyDict_SetItemString(pyDict.obj_, "__builtins__", PyImport_ImportModule("__builtin__"));
00154         assure(result==0, "Initializing __builtins__ failed!");
00155 
00156     {
00157         std::stringstream ss;
00158         ss << "__import__('openwns.pyconfig').pyconfig.View("
00159            << "dummy[" << at << "]"
00160            << ")";
00161 
00162         dict = Object(PyRun_String(ss.str().c_str(),
00163                        Py_eval_input,
00164                        pyDict.obj_,
00165                        pyDict.obj_));
00166         if (dict.isNull())
00167             showdown("couldn't create View from sequence item!", true);
00168     }
00169     pyDict.decref();
00170 
00171     {
00172         std::stringstream ss;
00173 
00174         ss << seq.pathName << "[" << at << "]";
00175         viewExpression = ss.str();
00176     }
00177 }
00178 
00179 View::~View()
00180 {
00181     // can happen that dict is NULL if View() has been called but not object
00182     // has not been used.
00183     if(!dict.isNull())
00184     {
00185         dict.decref();
00186     }
00187 
00188     --View::getCount();
00189     this->finalizePython();
00190 } //~View
00191 
00192 wns::pyconfig::View
00193 View::getView(const std::string& newViewExpression) const
00194 {
00195     return View(*this, newViewExpression);
00196 } // getView
00197 
00198 wns::pyconfig::Sequence
00199 View::getSequence(const std::string& sequenceExpression) const
00200 {
00201     if (!this->isSequence(sequenceExpression))
00202     {
00203         Exception e;
00204         e << "Cannot retrieve sequence named '" << sequenceExpression
00205           << "' from this view.\n\n"
00206           << "Context: " << this->context() << "\n\n"
00207           << "Content: " << this->asString() << "\n\n";
00208         throw e;
00209     }
00210     return pyconfig::Sequence(getObject(sequenceExpression),
00211                   this->viewExpression+"::"+sequenceExpression);
00212 } // getSequence
00213 
00214 wns::pyconfig::View
00215 View::getView(const std::string& newViewExpression, int at) const
00216 {
00217     return View(*this, newViewExpression, at);
00218 } // getView
00219 
00220 Object
00221 View::getObject(const std::string& optionExpression) const
00222 {
00223     assure(!PyErr_Occurred(), "Dirty python context!");
00224 
00225     return Object(PyRun_String(optionExpression.c_str(),
00226                    Py_eval_input,
00227                    dict.obj_,
00228                    dict.obj_));
00229 } // getObject
00230 
00231 
00232 Object
00233 View::getObject(const std::string& optionExpression, int at) const
00234 {
00235     Object seq = getObject(optionExpression);
00236     if(seq.isNull())
00237     {
00238         return Object();
00239     }
00240 
00241     if(!PySequence_Check(seq.obj_))
00242     {
00243         seq.decref();
00244         return Object();
00245     }
00246 
00247     Object o(PySequence_GetItem(seq.obj_, at));
00248     seq.decref();
00249 
00250     return o;
00251 } // getObject
00252 
00253 
00254 bool
00255 View::len(int& result, const std::string& optionExpression) const
00256 {
00257     assure(!PyErr_Occurred(), "Dirty python context!");
00258 
00259     Object o = getObject(optionExpression);
00260     if(o.isNull())
00261     {
00262         PyErr_Clear();
00263         return false;
00264     }
00265 
00266     if(!PySequence_Check(o.obj_))
00267     {
00268         o.decref();
00269         return false;
00270     }
00271 
00272     result = PySequence_Length(o.obj_);
00273     o.decref();
00274     return true;
00275 } // len
00276 
00277 
00278 int
00279 View::len(const std::string& optionExpression) const
00280 {
00281     assure(!PyErr_Occurred(), "Dirty python context!");
00282 
00283     int result;
00284 
00285     if(!len(result, optionExpression))
00286     {
00287         couldntRetrieve(optionExpression);
00288 
00289         showdown("Unknown thang in View::len.");
00290     }
00291 
00292     return result;
00293 } // len
00294 
00295 bool
00296 View::knows(const std::string& optionExpression) const
00297 {
00298     assure(!PyErr_Occurred(), "Dirty python context!");
00299 
00300     Object o = getObject(optionExpression);
00301     if(o.isNull())
00302     {
00303         PyErr_Clear();
00304         return false;
00305     }
00306 
00307     o.decref();
00308     return true;
00309 } // knows
00310 
00311 long long int
00312 View::getId() const
00313 {
00314     // id(object) returns long long since python2.5
00315     // Using PY_LONG_LONG here yields a compile error
00316     // if PY_LONG_LONG cannot be converted to long long int,
00317     // which moves the problem from runtime to compile time
00318     // fixes bug lp:174730
00319     return get<PY_LONG_LONG>("__id__");
00320 } // getId
00321 
00322 std::string
00323 View::context() const
00324 {
00325     return viewExpression;
00326 } // context
00327 
00328 
00329 void
00330 View::patch(const std::string& expression)
00331 {
00332     assure(!PyErr_Occurred(), "Dirty python context!");
00333 
00334     Object o(PyRun_String(expression.c_str(), Py_file_input, dict.obj_, dict.obj_));
00335     if(o.isNull())
00336     {
00337         showdown("couldn't patch View.", true);
00338     }
00339 
00340     o.decref();
00341 } // patch
00342 
00343 bool
00344 View::isNone(const std::string& expression) const
00345 {
00346     Object o = this->getObject(expression);
00347     bool isNone = o.isNone();
00348     o.decref();
00349     return isNone;
00350 } // isNone
00351 
00352 bool
00353 View::isSequence(const std::string& expression) const
00354 {
00355     Object o = this->getObject(expression);
00356 
00357         if(o.isNull())
00358         {
00359                 this->couldntRetrieve(expression);
00360                 this->showdown("Couldn't resolve viewExpression.");
00361         }
00362 
00363     if (PySequence_Check(o.obj_) == 1)
00364     {
00365         o.decref();
00366         return true;
00367     }
00368     else
00369     {
00370         o.decref();
00371         return false;
00372     }
00373 }
00374 
00375 View::View(const View& other)
00376 {
00377     ++View::getCount();
00378     this->initializePython();
00379     viewExpression = other.viewExpression;
00380     dict = other.dict;
00381     dict.incref();
00382 } // copy constructor
00383 
00384 
00385 View&
00386 View::operator=(const View& other)
00387 {
00388     viewExpression = other.viewExpression;
00389     dict = other.dict;
00390     dict.incref();
00391 
00392     return *this;
00393 } // assignment operator
00394 
00395 
00396 bool
00397 View::operator==(const View& other) const
00398 {
00399     return getId() == other.getId();
00400 } // equality operator
00401 
00402 bool
00403 View::operator!=(const View& other) const
00404 {
00405     return !(*this == other);
00406 } // inequality operator
00407 
00408 bool
00409 View::operator<(const View& other) const
00410 {
00411     return getId() < other.getId();
00412 } // less than operator
00413 
00414 bool
00415 View::doConvert(bool& value, Object o) const
00416 {
00417     switch(PyObject_IsTrue(o.obj_))
00418     {
00419         case 1:
00420             value = true;
00421             break;
00422         case 0:
00423             value = false;
00424             break;
00425         default:
00426             return false;
00427     }
00428 
00429     return true;
00430 } // convert
00431 
00432 bool
00433 View::doConvert(std::string& value, Object o) const
00434 {
00435     if(!o.isConvertibleToString())
00436     {
00437         return false;
00438     }
00439 
00440     value = o.toString();
00441 
00442     return true;
00443 } // convert
00444 
00445 void
00446 View::couldntRetrieve(const std::string& optionExpression) const
00447 {
00448     std::cerr << "PyConfig says:\n"
00449           << "The configuration entry "
00450           << "'" << optionExpression << "' "
00451           << "could not be retrieved from:\n    "
00452           << context() << "\n"
00453           << "Following configuration entries are available:\n";
00454     {
00455         PyObject *ptype, *pvalue, *ptraceback;
00456         PyErr_Fetch(&ptype, &pvalue, &ptraceback);
00457 
00458         PyRun_String(
00459             "__import__('sys').stderr.write( __visible__ + '\\n')\n",
00460             Py_file_input,
00461             dict.obj_,
00462             dict.obj_);
00463 
00464         PyErr_Restore(ptype, pvalue, ptraceback);
00465     }
00466 } // couldntRetrieve
00467 
00468 
00469 void
00470 View::showdown(const std::string& reason, bool raise) const
00471 {
00472     std::cerr << "PyConfig says:\n";
00473     PyErr_Print();
00474     std::cerr << "\n";
00475 
00476     PyErr_Clear();
00477 
00478     if(raise)
00479         throw Exception(reason);
00480 } // showdown
00481 
00482 std::string
00483 View::asString() const
00484 {
00485     return this->get<std::string>("__stringRepresentation__");
00486 } // asString
00487 
00488 void
00489 View::initializePython()
00490 {
00491     if(View::getCount() == 1)
00492     {
00493         assure(Py_IsInitialized() == false, "called initializePython() although interpreter is already initialized!");
00494         void (*handler)(int);
00495         handler = std::signal(2, SIG_DFL);
00496         Py_Initialize();
00497         std::signal(2, handler);
00498     }
00499 }
00500 
00501 void
00502 View::finalizePython()
00503 {
00504     if(View::getCount() == 0)
00505     {
00506         assure(Py_IsInitialized() == true, "called finalizePython although interpreter has not been initialized!");
00507         void (*handler)(int);
00508         handler = std::signal(2, SIG_DFL);
00509         Py_Finalize();
00510         std::signal(2, handler);
00511     }
00512 }
00513 
00514 int&
00515 View::getCount()
00516 {
00517     static int count = 0;
00518     assure(count >=0, "Internal reference counting is broken!");
00519     return count;
00520 }
00521 
00522 
00523 

Generated on Sat May 26 03:31:48 2012 for openWNS by  doxygen 1.5.5