//  Clint - Source code checker for C++
//  Copyright (C) 2001  David Pashley
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program 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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

#include "python.h"

namespace python {

   // Python * Python::Instance() {{{
   
   Python * Python::m_instance = 0;
   
   Python * Python::Instance() {
      if ( m_instance == 0 ) {
         m_instance = new Python;
      }
      return m_instance;
   }

   // }}}
   // Python::Python() {{{
   
   Python::Python() {
      Py_Initialize();
      m_argc = 0;
      m_argv = 0;
   }

   // }}}
   // int Python::run_interactive_one(string prompt) {{{
   
   int Python::run_interactive_one(string prompt) {
      int result;
      cout << "[" << prompt << "]" << endl;
      result = PyRun_InteractiveOne(stdin,"<stdin>");
      return result;
   }

   // }}}
   // int Python::run_interactive_loop(string prompt) {{{
   
   int Python::run_interactive_loop(string prompt) {
      int result;
      cout << "[" << prompt << " <Ctrl-D to exit>]" << endl;
      result = PyRun_InteractiveLoop(stdin,"<stdin>");
      return result;
   }

   // }}}
   // void Python::set_argv(int argc,char * argv[]) {{{
   
   void Python::set_argv(int argc,char * argv[]) {
      PySys_SetArgv(argc,argv);
      m_argc = argc;
      m_argv = argv;
   }

   // }}}
   // void Python::run_string(string cmd) {{{
   
   void Python::run_string(string cmd) {
      PyRun_SimpleString(const_cast<char *>(cmd.c_str()));
   }

   // }}}
   // void Python::reset() {{{
   
   void Python::reset() {
      Py_Finalize();
      Py_Initialize();
      if (m_argv != 0) {
         PySys_SetArgv(m_argc,m_argv);
      }
   }
   
   // }}}
   // void Python::add_directory_to_path(string directory) {{{
   
   void Python::add_directory_to_path(string directory) {
      run_string("import sys");
      run_string("sys.path = [\"" + directory + "\"] + sys.path");
   }
   
   // }}}
   // Module load_module(string modname) {{{
   
   Module Python::load_module(string modname) {
   DEBUG("Module Python::load_module(string \""<<modname<<"\")");

      Dict modules = get_module_dict();

      if ("__main__" == modname) {
         return add_module(modname);
      } else if (modules.has_key(modname)) {
         Module module = modules.get_item(modname);
         if (module.get_dict().has_key("__dummy__")) {
            return module;
         } else if (m_reload) {
            Module(modules.get_item(modname)).reload();
            return modules.get_item(modname);
         }
      } else { 
         return import_module(modname);
      }

      return (NULL);
   }

   // }}}
   // Object load_attribute(string modname, string attrname) {{{ 

   Object Python::load_attribute(string modname, string attrname) { 
      Module module = load_module(modname);
      if (module.is_null()) {
         return Py_None;
      }
      return module.get_attr(attrname);
   }

   // }}}
   // Dict get_module_dict() {{{ 

   Dict Python::get_module_dict() { 
      return  Dict( PyImport_GetModuleDict(), true ); 
   }

   // }}}
   // Module Python::add_module(string modname) {{{

   Module Python::add_module(string modname) {
      return  PyImport_AddModule( const_cast<char *>( modname.c_str() ) );
   }

   // }}}
   // Module Python::import_module(string modname) {{{

   Module Python::import_module(string modname) {
      DEBUG("Module Python::import_module(string \""<<modname<<"\")");
      return Module(PyImport_ImportModule ( const_cast<char *>( modname.c_str() ) ), true);
   }

   // }}}

   void check_errors() {
      if ( PyErr_Occurred() ) { 
         PyObject *ptype, *pvalue, *ptraceback;
         PyErr_Fetch (&ptype, &pvalue, &ptraceback);
         PyErr_NormalizeException (&ptype, &pvalue, &ptraceback);
         Object type=ptype; 
         //Object bob = pvalue;
         String value = Object(pvalue).as_string();
         Object traceback = ptraceback;
         if (PyErr_GivenExceptionMatches(ptype,PyExc_AssertionError))       { throw AssertionError( value);    
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_AttributeError))       { throw AttributeError( value);
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_EOFError))             { throw EOFError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_FloatingPointError))   { throw FloatingPointError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_IOError))              { throw IOError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_ImportError))          { throw ImportError( value);    
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_IndexError))           { throw IndexError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_KeyError))             { throw KeyError( value);  
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_KeyboardInterrupt))    { throw KeyboardInterrupt( value);  
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_MemoryError))          { throw MemoryError( value);    
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_NameError))            { throw NameError( value);    
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_NotImplementedError))  { throw NotImplementedError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_OSError))              { throw OSError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_OverflowError))        { throw OverflowError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_RuntimeError))         { throw RuntimeError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_SyntaxError))          { throw SyntaxError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_SystemError))          { throw SystemError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_SystemExit))           { throw SystemExit( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_TypeError))            { throw TypeError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_ValueError))           { throw ValueError( value);     
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_ZeroDivisionError))    { throw ZeroDivisionError( value);
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_EnvironmentError))     { throw EnvironmentError( value);  
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_LookupError))          { throw LookupError(value);  
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_ArithmeticError))      { throw ArithmeticError(value);  
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_StandardError))        { throw StandardError(value);  
         } else if (PyErr_GivenExceptionMatches(ptype,PyExc_Exception))                   { throw Exception(value);  
         } else {
            throw Exception("Unknown error has occured"); 
         }
      }
   }
}


syntax highlighted by Code2HTML, v. 0.9.1