~ubuntu-branches/ubuntu/quantal/mysql-workbench/quantal

« back to all changes in this revision

Viewing changes to library/grt/src/python_context.cpp

  • Committer: Package Import Robot
  • Author(s): Dmitry Smirnov
  • Date: 2012-03-01 21:57:30 UTC
  • Revision ID: package-import@ubuntu.com-20120301215730-o7y8av8y38n162ro
Tags: upstream-5.2.38+dfsg
ImportĀ upstreamĀ versionĀ 5.2.38+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; version 2 of the
 
7
 * License.
 
8
 * 
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
12
 * GNU General Public License for more details.
 
13
 * 
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
17
 * 02110-1301  USA
 
18
 */
 
19
 
 
20
 
 
21
#include "stdafx.h"
 
22
 
 
23
#include "python_context.h"
 
24
#include "grtpp.h"
 
25
#include "grtpp_util.h"
 
26
#include "base/string_utilities.h"
 
27
#include "base/file_functions.h"
 
28
 
 
29
#ifdef ENABLE_PYTHON_MODULES
 
30
 
 
31
// python internals
 
32
#ifdef __APPLE__
 
33
#include <Python/node.h>
 
34
#include <Python/grammar.h>
 
35
#include <Python/parsetok.h>
 
36
#include <Python/errcode.h>
 
37
#include <Python/token.h>
 
38
#else
 
39
#include <node.h>
 
40
#include <grammar.h>
 
41
#include <parsetok.h>
 
42
#include <errcode.h>
 
43
#include <token.h>
 
44
#endif
 
45
 
 
46
 
 
47
#include "python_grtobject.h"
 
48
#include "python_grtlist.h"
 
49
#include "python_grtdict.h"
 
50
 
 
51
#include "base/log.h"
 
52
DEFAULT_LOG_DOMAIN("python context")
 
53
 
 
54
using namespace grt;
 
55
using namespace base;
 
56
 
 
57
const std::string grt::LanguagePython= "python";
 
58
 
 
59
 
 
60
// used to identify a proper GRT context object as a PyCObject
 
61
static const char *GRTTypeSignature= "GRTCONTEXT";
 
62
// used to identify a GRT value as a PyCObject
 
63
static const char *GRTValueSignature= "GRTVALUE";
 
64
 
 
65
 
 
66
static std::string flatten_class_name(std::string name)
 
67
{
 
68
  std::string::size_type p;
 
69
  while ((p= name.find('.')) != std::string::npos)
 
70
    name[p]= '_';
 
71
  return name;
 
72
}
 
73
 
 
74
PythonContext::PythonContext(GRT *grt, const std::string &module_path)
 
75
: _grt(grt)
 
76
{
 
77
  PyObject *main;
 
78
  static const char *argv[2]= { "/dev/null" , NULL };
 
79
 
 
80
  if (getenv("PYTHON_DEBUG"))
 
81
    Py_VerboseFlag = 5;
 
82
 
 
83
#ifdef _WIN32
 
84
  // Hack needed in Windows because Python lib uses C:\Python26 as default pythonhome
 
85
  // That will cause conflicts if there is some other Python installed in there (bug #52949)
 
86
 
 
87
  // Program.cs also does this, but somehow, they don't seem to get reflected here
 
88
  char *path = getenv("PATH");
 
89
  if (path)
 
90
  {
 
91
    // strip away everything with Python in it
 
92
    std::vector<std::string> parts = base::split(path, ";");
 
93
    std::string npath;
 
94
    for (std::vector<std::string>::const_iterator p = parts.begin(); p != parts.end(); ++p)
 
95
    {
 
96
      if (!strstr(base::tolower(*p).c_str(), "python"))
 
97
      {
 
98
        if (!npath.empty())
 
99
          npath.append(";");
 
100
        npath.append(*p);
 
101
      }
 
102
    }
 
103
    putenv(g_strdup_printf("PATH=%s", npath.c_str()));
 
104
  }
 
105
 
 
106
  putenv(g_strdup_printf("PYTHONHOME=%s\\Python", module_path.c_str()));
 
107
  putenv(g_strdup_printf("PYTHONPATH=%s\\Python;%s\\Python\\DLLs;%s\\Python\\Lib", 
 
108
    module_path.c_str(), module_path.c_str(), module_path.c_str()));
 
109
  //putenv("PYTHONHOME=C:\\nowhere");
 
110
#endif
 
111
  Py_InitializeEx(0); // skips signal handler init
 
112
 
 
113
  // Stores the main thread state
 
114
  _main_thread_state = PyThreadState_Get();
 
115
 
 
116
  PySys_SetArgv(1, (char**)argv);
 
117
 
 
118
  PyEval_InitThreads();
 
119
 
 
120
  _grt_list_class= 0;
 
121
  _grt_dict_class= 0;
 
122
  _grt_object_class= 0;
 
123
  _grt_method_class= 0;
 
124
  
 
125
  register_grt_module();
 
126
  
 
127
  main= PyImport_AddModule("__main__");
 
128
  PyDict_SetItemString(PyModule_GetDict(main),
 
129
                       "grt", PyImport_ImportModule("grt"));
 
130
  
 
131
  // make sys.stdout and sys.stderr send stuff to GRT
 
132
  PySys_SetObject((char*)"stdout", get_grt_module());
 
133
  PySys_SetObject((char*)"stderr", get_grt_module());
 
134
  
 
135
  // set stdin to the GRT shell console
 
136
  PySys_SetObject((char*)"stdin", get_grt_module());
 
137
 
 
138
  run_post_init_script();
 
139
  
 
140
  {
 
141
    PyObject *path = from_grt(grt::StringRef(base::Logger::log_filename()));
 
142
    PyDict_SetItemString(PyModule_GetDict(PyImport_AddModule("grt")), "logpath", path);
 
143
    Py_DECREF(path);
 
144
  }
 
145
 
 
146
  PyEval_SaveThread();
 
147
}
 
148
 
 
149
 
 
150
PythonContext::~PythonContext()
 
151
{
 
152
  PyEval_RestoreThread(_main_thread_state);
 
153
  _main_thread_state = NULL;
 
154
 
 
155
  Py_Finalize();
 
156
}
 
157
 
 
158
 
 
159
void PythonContext::add_module_path(const std::string &modpath, bool prepend)
 
160
{
 
161
  // add the path to the search path so that it can be imported
 
162
  PyObject *path_list;
 
163
  PyObject *path= PyString_FromString(modpath.c_str());
 
164
 
 
165
  WillEnterPython lock;
 
166
  
 
167
  path_list= PySys_GetObject((char *) "path"); // cast to (char *) required for gcc 4.3 to avoid warning about deprecated conversion
 
168
                                               // from string constant to 'char*'.
 
169
  Py_ssize_t i;
 
170
  
 
171
 // check if the path is already in it
 
172
  for (i= PyList_Size(path_list)-1; i >= 0; --i)
 
173
  {
 
174
    if (PyObject_Compare(PyList_GetItem(path_list, i), path) == 0)
 
175
      break;
 
176
  }
 
177
  
 
178
  if (i < 0) // not found
 
179
  {
 
180
    if (prepend)
 
181
      PyList_Insert(path_list, 0, path);
 
182
    else
 
183
      PyList_Append(path_list, path);
 
184
  }
 
185
  Py_DECREF(path);
 
186
}
 
187
 
 
188
 
 
189
void PythonContext::set_python_error(const grt::type_error &exc, const std::string &location)
 
190
{
 
191
  PyErr_SetString(PyExc_TypeError, (location.empty() ? exc.what() : location + ": " + exc.what()).c_str());
 
192
}
 
193
 
 
194
 
 
195
void PythonContext::set_python_error(const grt::bad_item &exc, const std::string &location)
 
196
{
 
197
  PyErr_SetString(PyExc_IndexError, (location.empty() ? exc.what() : location + ": " + exc.what()).c_str());
 
198
}
 
199
 
 
200
 
 
201
void PythonContext::set_python_error(const std::exception &exc, const std::string &location)
 
202
{
 
203
  PyErr_SetString(PyExc_SystemError, (location.empty() ? exc.what() : location + ": " + exc.what()).c_str());
 
204
}
 
205
 
 
206
 
 
207
 
 
208
/** Gets the PythonContext from the Python interpreter.
 
209
 */
 
210
PythonContext *PythonContext::get()
 
211
{
 
212
  PyObject *ctx;
 
213
  PyObject *module;
 
214
  PyObject *dict;
 
215
 
 
216
  module= PyDict_GetItemString(PyImport_GetModuleDict(), "grt");
 
217
  if (!module)
 
218
    throw std::runtime_error("GRT module not found in Python runtime");
 
219
  
 
220
  dict= PyModule_GetDict(module);
 
221
  if (!dict)
 
222
    throw std::runtime_error("GRT module is invalid in Python runtime");
 
223
  
 
224
  ctx= PyDict_GetItemString(dict, "__GRT__");
 
225
  if (!ctx)
 
226
    throw std::runtime_error("GRT context not found in Python runtime");
 
227
 
 
228
  if (PyCObject_GetDesc(ctx) == &GRTTypeSignature)
 
229
    return static_cast<PythonContext*>(PyCObject_AsVoidPtr(ctx));
 
230
 
 
231
  throw std::runtime_error("Invalid GRT context in Python runtime");
 
232
}
 
233
 
 
234
 
 
235
PythonContext *PythonContext::get_and_check()
 
236
{
 
237
  try
 
238
  {
 
239
    return PythonContext::get();
 
240
  }
 
241
  catch (std::exception &exc)
 
242
  {
 
243
    PyErr_SetString(PyExc_SystemError, strfmt("Could not get GRT context: %s", exc.what()).c_str());
 
244
  }
 
245
  return NULL;
 
246
}
 
247
 
 
248
 
 
249
static PyObject *grt_print(PyObject *self, PyObject *args)
 
250
{
 
251
  PythonContext *ctx;
 
252
  std::string text;
 
253
    
 
254
  if (!(ctx= PythonContext::get_and_check()))
 
255
    return NULL;
 
256
 
 
257
  PyObject *o;
 
258
  if (!PyArg_ParseTuple(args, "O", &o))
 
259
  {
 
260
    if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
 
261
    {
 
262
      PyErr_Clear();
 
263
      text = "None";
 
264
    }
 
265
    else
 
266
      return NULL;
 
267
  }  
 
268
  else
 
269
    if (!ctx->pystring_to_string(o, text))
 
270
      return NULL;
 
271
  
 
272
#ifdef _WIN32
 
273
  OutputDebugStringA(text.c_str());
 
274
#else
 
275
  g_print("%s", text.c_str()); // g_print is not routed to g_log
 
276
#endif
 
277
  ctx->get_grt()->send_output(text);
 
278
  
 
279
  Py_INCREF(Py_None);
 
280
  return Py_None;
 
281
}
 
282
 
 
283
static PyObject *pylog(base::Logger::LogLevel level, PyObject *args)
 
284
{
 
285
  PythonContext *ctx;
 
286
  std::string text;
 
287
  
 
288
  if (!(ctx= PythonContext::get_and_check()))
 
289
    return NULL;
 
290
  
 
291
  char *domain;
 
292
  PyObject *o;
 
293
  if (!PyArg_ParseTuple(args, "sO", &domain, &o))
 
294
    return NULL;
 
295
  
 
296
  if (!ctx->pystring_to_string(o, text))
 
297
    return NULL;
 
298
  
 
299
  base::Logger::log(level, domain, "%s", text.c_str());
 
300
 
 
301
  Py_INCREF(Py_None);
 
302
  return Py_None;
 
303
}
 
304
 
 
305
 
 
306
static PyObject *grt_log_error(PyObject *self, PyObject *args)
 
307
{
 
308
  return pylog(base::Logger::LogError, args);
 
309
}
 
310
 
 
311
static PyObject *grt_log_warning(PyObject *self, PyObject *args)
 
312
{
 
313
  return pylog(base::Logger::LogWarning, args);
 
314
}
 
315
 
 
316
static PyObject *grt_log_info(PyObject *self, PyObject *args)
 
317
{
 
318
  return pylog(base::Logger::LogInfo, args);
 
319
}
 
320
 
 
321
static PyObject *grt_log_debug(PyObject *self, PyObject *args)
 
322
{
 
323
  return pylog(base::Logger::LogDebug, args);
 
324
}
 
325
 
 
326
static PyObject *grt_log_debug2(PyObject *self, PyObject *args)
 
327
{
 
328
  return pylog(base::Logger::LogDebug2, args);
 
329
}
 
330
 
 
331
static PyObject *grt_log_debug3(PyObject *self, PyObject *args)
 
332
{
 
333
  return pylog(base::Logger::LogDebug3, args);
 
334
}
 
335
 
 
336
static PyObject *grt_send_output(PyObject *self, PyObject *args)
 
337
{
 
338
  PythonContext *ctx;
 
339
  std::string text;
 
340
    
 
341
  if (!(ctx= PythonContext::get_and_check()))
 
342
    return NULL;
 
343
  
 
344
  PyObject *o;
 
345
  if (!PyArg_ParseTuple(args, "O", &o))
 
346
  {
 
347
    if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
 
348
    {
 
349
      PyErr_Clear();
 
350
      text = "None";
 
351
    }
 
352
    else
 
353
      return NULL;
 
354
  }  
 
355
  else
 
356
    if (!ctx->pystring_to_string(o, text))
 
357
      return NULL;
 
358
 
 
359
  ctx->get_grt()->send_output(text);
 
360
  
 
361
  Py_INCREF(Py_None);
 
362
  return Py_None;
 
363
}
 
364
 
 
365
 
 
366
static PyObject *grt_send_warning(PyObject *self, PyObject *args)
 
367
{
 
368
  PythonContext *ctx;
 
369
  std::string text;
 
370
  if (!(ctx= PythonContext::get_and_check()))
 
371
    return NULL;
 
372
  
 
373
  PyObject *o;
 
374
  if (!PyArg_ParseTuple(args, "O", &o))
 
375
  {
 
376
    if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
 
377
    {
 
378
      PyErr_Clear();
 
379
      text = "None";
 
380
    }
 
381
    else
 
382
      return NULL;
 
383
  }  
 
384
  else
 
385
    if (!ctx->pystring_to_string(o, text))
 
386
      return NULL;
 
387
 
 
388
  ctx->get_grt()->send_warning(text);
 
389
  
 
390
  Py_INCREF(Py_None);
 
391
  return Py_None;
 
392
}
 
393
 
 
394
static PyObject *grt_send_info(PyObject *self, PyObject *args)
 
395
{
 
396
  PythonContext *ctx;
 
397
  std::string text;
 
398
  if (!(ctx= PythonContext::get_and_check()))
 
399
    return NULL;
 
400
  
 
401
  PyObject *o;
 
402
  if (!PyArg_ParseTuple(args, "O", &o))
 
403
  {
 
404
    if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
 
405
    {
 
406
      PyErr_Clear();
 
407
      text = "None";
 
408
    }
 
409
    else
 
410
      return NULL;
 
411
  }  
 
412
  else
 
413
    if (!ctx->pystring_to_string(o, text))
 
414
      return NULL;
 
415
 
 
416
  ctx->get_grt()->send_info(text);
 
417
  log_debug2("grt.python", text.c_str());
 
418
 
 
419
  Py_INCREF(Py_None);
 
420
  return Py_None;
 
421
}
 
422
 
 
423
static PyObject *grt_send_error(PyObject *self, PyObject *args)
 
424
{
 
425
  PythonContext *ctx;
 
426
  std::string text;
 
427
  if (!(ctx= PythonContext::get_and_check()))
 
428
    return NULL;
 
429
  
 
430
  PyObject *o;
 
431
  if (!PyArg_ParseTuple(args, "O", &o))
 
432
  {
 
433
    if (PyTuple_Size(args) == 1 && PyTuple_GetItem(args, 0) == Py_None)
 
434
    {
 
435
      PyErr_Clear();
 
436
      text = "None";
 
437
    }
 
438
    else
 
439
      return NULL;
 
440
  }  
 
441
  else
 
442
    if (!ctx->pystring_to_string(o, text))
 
443
      return NULL;
 
444
 
 
445
  ctx->get_grt()->send_error(text);
 
446
  
 
447
  Py_INCREF(Py_None);
 
448
  return Py_None;
 
449
}
 
450
 
 
451
 
 
452
static PyObject *grt_send_progress(PyObject *self, PyObject *args)
 
453
{
 
454
  PythonContext *ctx;
 
455
  if (!(ctx= PythonContext::get_and_check()))
 
456
    return NULL;
 
457
  
 
458
  float pct;
 
459
  char *text, *detail= NULL;
 
460
  if (!PyArg_ParseTuple(args, "fs|s", &pct, &text, &detail))
 
461
    return NULL;
 
462
  
 
463
  ctx->get_grt()->send_progress(pct, text ? text : "", detail ? detail : "", NULL);
 
464
  Py_INCREF(Py_None);
 
465
  return Py_None;
 
466
}
 
467
 
 
468
 
 
469
static PyObject *grt_get_by_path(PyObject *self, PyObject *args)
 
470
{
 
471
  PythonContext *ctx;
 
472
  const char *path= "";
 
473
  PyObject *object;
 
474
  grt::ValueRef value;
 
475
  
 
476
  if (!(ctx= PythonContext::get_and_check()))
 
477
    return NULL;
 
478
  
 
479
  if (!PyArg_ParseTuple(args, "s|O", &path, &object))
 
480
    return NULL;
 
481
 
 
482
  if (object)
 
483
  {
 
484
    try
 
485
    {
 
486
      value= ctx->from_pyobject(object);
 
487
    }
 
488
    catch (grt::type_error &exc)
 
489
    {
 
490
      PyErr_SetString(PyExc_TypeError, exc.what());
 
491
      return NULL;
 
492
    }
 
493
    catch (std::exception &exc)
 
494
    {
 
495
      PythonContext::set_python_error(exc);
 
496
      return NULL;
 
497
    }
 
498
  }
 
499
  else
 
500
    value= ctx->get_grt()->root();
 
501
  
 
502
  if (!path)
 
503
    path= "";
 
504
 
 
505
  try
 
506
  {
 
507
    value= get_value_by_path(value, path);
 
508
  }
 
509
  catch (std::exception &exc)
 
510
  {
 
511
    PythonContext::set_python_error(exc);
 
512
    return NULL;
 
513
  }
 
514
 
 
515
  return ctx->from_grt(value);
 
516
}
 
517
 
 
518
 
 
519
static PyObject *grt_readline(PyObject *self, PyObject *args)
 
520
{
 
521
  PythonContext *ctx;
 
522
  
 
523
  if (!(ctx= PythonContext::get_and_check()))
 
524
    return NULL;
 
525
  
 
526
  if (!PyArg_ParseTuple(args, ""))
 
527
    return NULL;
 
528
  
 
529
  std::string line = ctx->stdin_readline_slot();
 
530
  return Py_BuildValue("s", line.c_str());
 
531
}
 
532
 
 
533
 
 
534
static bool call_handle_output(const std::string &text, PyObject *callable)
 
535
{
 
536
  WillEnterPython lock;
 
537
  PyObject *ret;
 
538
  
 
539
  if (!(ret = PyObject_Call(callable, Py_BuildValue("s", text.c_str()), NULL)))
 
540
  {
 
541
    PythonContext::log_python_error("Error calling Python output handler:");
 
542
    PyErr_Clear();
 
543
    return false;
 
544
  }
 
545
  
 
546
  if (ret == Py_None || ret == Py_False || PyInt_AsLong(ret) == 0)
 
547
  {
 
548
    Py_DECREF(ret);
 
549
    return false;
 
550
  }
 
551
  Py_DECREF(ret);
 
552
  return true;
 
553
}
 
554
 
 
555
 
 
556
static PyObject *grt_push_output_handler(PyObject *self, PyObject *args)
 
557
{
 
558
  PythonContext *ctx;
 
559
  if (!(ctx= PythonContext::get_and_check()))
 
560
    return NULL;
 
561
  
 
562
  PyObject *o;
 
563
  if (!PyArg_ParseTuple(args, "O", &o))
 
564
    return NULL;
 
565
  
 
566
  if (!PyCallable_Check(o))
 
567
    return NULL;
 
568
 
 
569
  ctx->push_output_handler(boost::bind(&call_handle_output,_1, AutoPyObject(o)));
 
570
  Py_INCREF(Py_None);
 
571
  return Py_None;
 
572
}
 
573
 
 
574
static PyObject *grt_pop_output_handler(PyObject *self, PyObject *args)
 
575
{
 
576
  PythonContext *ctx;
 
577
  if (!(ctx= PythonContext::get_and_check()))
 
578
    return NULL;
 
579
 
 
580
  ctx->pop_output_handler();
 
581
  
 
582
  Py_INCREF(Py_None);
 
583
  return Py_None;
 
584
}
 
585
 
 
586
static PyObject *grt_serialize(PyObject *self, PyObject *args)
 
587
{
 
588
  PythonContext *ctx;
 
589
  if (!(ctx= PythonContext::get_and_check()))
 
590
    return NULL;
 
591
  
 
592
  PyObject *object;
 
593
  char *path = NULL;
 
594
  
 
595
  if (!PyArg_ParseTuple(args, "Os", &object, &path))
 
596
    return NULL;
 
597
  
 
598
  grt::ValueRef value(ctx->from_pyobject(object));
 
599
  if (!value.is_valid())
 
600
  {
 
601
    PyErr_SetString(PyExc_TypeError, "First argument must be a GRT object");
 
602
    return NULL;
 
603
  }
 
604
  
 
605
  if (!path)
 
606
  {
 
607
    PyErr_SetString(PyExc_ValueError, "File path expected for argument #2");
 
608
    return NULL;
 
609
  }
 
610
  
 
611
  try
 
612
  {
 
613
    ctx->get_grt()->serialize(value, path);
 
614
  }
 
615
  catch (const std::exception &exc)
 
616
  {
 
617
    PythonContext::set_python_error(exc, "serializing object");
 
618
    return NULL;
 
619
  }
 
620
  
 
621
  Py_INCREF(Py_None);
 
622
  return Py_None;
 
623
}
 
624
 
 
625
 
 
626
static PyObject *grt_unserialize(PyObject *self, PyObject *args)
 
627
{
 
628
  PythonContext *ctx;
 
629
  if (!(ctx= PythonContext::get_and_check()))
 
630
    return NULL;
 
631
  
 
632
  char *path = NULL;
 
633
  if (!PyArg_ParseTuple(args, "s", &path))
 
634
    return NULL;
 
635
  if (!path)
 
636
  {
 
637
    PyErr_SetString(PyExc_ValueError, "File path expected");
 
638
    return NULL;
 
639
  }
 
640
  
 
641
  try
 
642
  {
 
643
    grt::ValueRef value = ctx->get_grt()->unserialize(path);
 
644
    return ctx->from_grt(value);
 
645
  }
 
646
  catch (const std::exception &exc)
 
647
  {
 
648
    PythonContext::set_python_error(exc, base::strfmt("unserializing file %s", path));
 
649
    return NULL;
 
650
  }
 
651
  
 
652
  Py_INCREF(Py_None);
 
653
  return Py_None;
 
654
}
 
655
 
 
656
/** Register grt related functionality as a module
 
657
 
 
658
 Stuff made available in the module include:
 
659
 <li>__GRT__ variable holding a CObject pointer back to PythonContext
 
660
 <li>GRTList, GRTDict and GRTObject types
 
661
 <li>send_output, send_error, send_info etc
 
662
 <li>etc
 
663
 */
 
664
static PyMethodDef GrtModuleMethods[] = {
 
665
{"send_output",  grt_send_output, METH_VARARGS,
 
666
"Write a string in the GRT shell."},
 
667
{"write",  grt_print, METH_VARARGS,
 
668
"Write a string in the GRT shell (alias to send_output)."},
 
669
{"send_error",  grt_send_error, METH_VARARGS,
 
670
"Write an error message to the GRT shell."},
 
671
{"send_warning",  grt_send_warning, METH_VARARGS,
 
672
"Write a warning message to the GRT shell."},
 
673
{"send_info",  grt_send_info, METH_VARARGS,
 
674
"Write a info message to the GRT shell."},
 
675
{"send_progress",  grt_send_progress, METH_VARARGS,
 
676
"Write a progress message."},
 
677
 
 
678
{"log_error", grt_log_error, METH_VARARGS,
 
679
"Logs an error to the log file, in the specified context ex: log_error('myplugin', 'cannot open file')"},
 
680
{"log_warning", grt_log_warning, METH_VARARGS,
 
681
"Logs a warning to the log file, in the specified context ex: log_warning('myplugin', 'cannot open file very well')"},
 
682
{"log_debug", grt_log_debug, METH_VARARGS,
 
683
"Logs a debug message to the log file, in the specified context ex: log_debug('myplugin', 'trying to open file with ')"},
 
684
{"log_debug2", grt_log_debug2, METH_VARARGS,
 
685
 "Logs a verbose debug message to the log file, in the specified context ex: log_debug2('myplugin', 'reading from file')"},
 
686
{"log_debug3", grt_log_debug3, METH_VARARGS,
 
687
 "Logs a very verbose debug message to the log file, in the specified context ex: log_debug3('myplugin', 'processing file')"},
 
688
{"log_info", grt_log_info, METH_VARARGS,
 
689
"Logs an informational message to the log file, in the specified context ex: log_info('myplugin', 'file opened')"},
 
690
  
 
691
{"push_output_handler", grt_push_output_handler, METH_VARARGS,
 
692
"Pushes a callback of the form function(text) to be called when a plugin outputs text."},
 
693
{"pop_output_handler", grt_push_output_handler, METH_NOARGS,
 
694
 "Pops previously pushed handler."},
 
695
 
 
696
{"readline", grt_readline, METH_VARARGS,
 
697
"Waits for a line of text to be input to the scripting shell prompt."},
 
698
 
 
699
{"get", grt_get_by_path, METH_VARARGS,
 
700
"Gets a value from a GRT dict or object (or from the global tree) by path."},
 
701
 
 
702
{"serialize", grt_serialize, METH_VARARGS,
 
703
  "Serializes a GRT object into a XML file. serialize(object, path)"},
 
704
{"unserialize", grt_unserialize, METH_VARARGS,
 
705
  "Unserializes a GRT object from a XML file created by serialize. unserialize(path) -> object"},
 
706
 
 
707
  
 
708
{NULL, NULL, 0, NULL}        /* Sentinel */
 
709
};
 
710
 
 
711
 
 
712
void PythonContext::register_grt_module()
 
713
{
 
714
  PyObject *module = Py_InitModule("grt", GrtModuleMethods);
 
715
  if (module == NULL)
 
716
    throw std::runtime_error("Error initializing GRT module in Python support");
 
717
  
 
718
  _grt_module= module;
 
719
  
 
720
  // add the context ptr
 
721
  PyObject* context_object= PyCObject_FromVoidPtrAndDesc(this, &GRTTypeSignature, NULL);
 
722
  if (context_object != NULL)
 
723
    PyModule_AddObject(module, "__GRT__", context_object);
 
724
  
 
725
  PyModule_AddStringConstant(module, "INT", (char*)type_to_str(IntegerType).c_str());
 
726
  PyModule_AddStringConstant(module, "DOUBLE", (char*)type_to_str(DoubleType).c_str());
 
727
  PyModule_AddStringConstant(module, "STRING", (char*)type_to_str(StringType).c_str());
 
728
  PyModule_AddStringConstant(module, "LIST", (char*)type_to_str(ListType).c_str());
 
729
  PyModule_AddStringConstant(module, "DICT", (char*)type_to_str(DictType).c_str());
 
730
  PyModule_AddStringConstant(module, "OBJECT", (char*)type_to_str(ObjectType).c_str());
 
731
  
 
732
  init_grt_module_type();
 
733
  init_grt_list_type();
 
734
  init_grt_dict_type();
 
735
  init_grt_object_type();
 
736
  
 
737
  _grt_modules_module = Py_InitModule("grt.modules", NULL);
 
738
  if (!_grt_modules_module)
 
739
    throw std::runtime_error("Error initializing grt.modules module in Python support");
 
740
  
 
741
  // AutoPyObject need to keep a reference but PyModule_AddObject steals it
 
742
  // so it is needed to increase it to avoid problems on destruction
 
743
  Py_INCREF(_grt_modules_module);
 
744
  PyModule_AddObject(_grt_module, "modules", _grt_modules_module);
 
745
  
 
746
  _grt_classes_module = Py_InitModule("grt.classes", NULL);
 
747
  if (!_grt_classes_module)
 
748
    throw std::runtime_error("Error initializing grt.classes module in Python support");
 
749
  
 
750
  Py_INCREF(_grt_classes_module);
 
751
  PyModule_AddObject(_grt_module, "classes", _grt_classes_module);
 
752
  
 
753
  PyModule_AddObject(_grt_classes_module, "grt", _grt_module);
 
754
}
 
755
 
 
756
 
 
757
 
 
758
 
 
759
PyObject *PythonContext::get_grt_module()
 
760
{
 
761
  return _grt_module;
 
762
}
 
763
 
 
764
 
 
765
bool PythonContext::import_module(const std::string &name)
 
766
{
 
767
  PyObject *main= PyImport_AddModule("__main__");
 
768
  PyObject *module = PyImport_ImportModule((char*)name.c_str());
 
769
  if (!main || !module)
 
770
  {
 
771
    PythonContext::log_python_error(base::strfmt("Error importing %s", name.c_str()).c_str());
 
772
    return false;
 
773
  }
 
774
  PyDict_SetItemString(PyModule_GetDict(main), name.c_str(), module);
 
775
  
 
776
  return true;
 
777
}
 
778
 
 
779
 
 
780
PyObject *PythonContext::eval_string(const std::string &expression)
 
781
{
 
782
//  LockPython lock(this);
 
783
  
 
784
  PyObject *mainmod= PyImport_AddModule("__main__");
 
785
  if (!mainmod)
 
786
  {
 
787
    PyErr_Clear();
 
788
    return NULL;
 
789
  }
 
790
  PyObject *globals= PyModule_GetDict(mainmod);
 
791
  if (globals)
 
792
  {
 
793
    PyObject *result= PyRun_String(expression.c_str(), Py_eval_input, globals, globals);
 
794
    if (!result)
 
795
      PythonContext::log_python_error(base::strfmt("Error running expr: %s", expression.c_str()).c_str());
 
796
    return result;
 
797
  }
 
798
  PyErr_Clear();
 
799
  return NULL;
 
800
}
 
801
 
 
802
 
 
803
PyObject *PythonContext::get_global(const std::string &value)
 
804
{
 
805
  /*
 
806
  PyObject *mainmod= PyImport_AddModule("__main__");
 
807
  if (!mainmod)
 
808
  {
 
809
    PyErr_Clear();
 
810
    return NULL;
 
811
  }
 
812
  PyObject *globals= PyModule_GetDict(mainmod);
 
813
  if (globals)
 
814
    return PyDict_GetItemString(globals, value.c_str());
 
815
   */
 
816
  return eval_string(value);
 
817
}
 
818
 
 
819
 
 
820
bool PythonContext::set_global(const std::string &name, PyObject *value)
 
821
{
 
822
  PyObject *mainmod= PyImport_AddModule("__main__");
 
823
  if (!mainmod)
 
824
  {
 
825
    PythonContext::log_python_error("Error getting __main__");
 
826
    PyErr_Clear();
 
827
    return false;
 
828
  }
 
829
  PyObject *globals= PyModule_GetDict(mainmod);
 
830
  if (!globals)
 
831
  {
 
832
    PythonContext::log_python_error("Error getting __main__ dict");
 
833
    PyErr_Clear();
 
834
    return false;
 
835
  }
 
836
 
 
837
  PyDict_SetItemString(globals, name.c_str(), value); 
 
838
  return true;
 
839
}
 
840
 
 
841
 
 
842
static void release_value(void *value, void *desc)
 
843
{
 
844
  internal::Value *v= reinterpret_cast<internal::Value*>(value);
 
845
  
 
846
  v->release();
 
847
}
 
848
 
 
849
/** Wraps a grt value in a PyCObject.
 
850
 
 
851
 PyCObjects are used internally to initialize a grt.List/Dict or Object from an existing grt value.
 
852
 */
 
853
PyObject *PythonContext::internal_cobject_from_value(const ValueRef &value)
 
854
{
 
855
  internal::Value *v= value.valueptr();
 
856
  v->retain();
 
857
  return PyCObject_FromVoidPtrAndDesc(v, &GRTValueSignature, release_value);
 
858
}
 
859
 
 
860
 
 
861
ValueRef PythonContext::value_from_internal_cobject(PyObject *value)
 
862
{
 
863
  if (PyCObject_GetDesc(value) == &GRTValueSignature)
 
864
    return ValueRef(reinterpret_cast<internal::Value*>(PyCObject_AsVoidPtr(value)));
 
865
  
 
866
  throw std::runtime_error("attempt to extract GRT value from invalid Python object");
 
867
}
 
868
 
 
869
 
 
870
/** Convert a GRT value to a Python object/value. 
 
871
 *
 
872
 * For objects, it will also wrap in the appropriate object subclass from grt.classes
 
873
 */
 
874
PyObject *PythonContext::from_grt(const ValueRef &value)
 
875
{
 
876
  if (value.is_valid())
 
877
  {
 
878
    switch (value.type())
 
879
    {
 
880
      case IntegerType:
 
881
      {
 
882
        long l = *IntegerRef::cast_from(value);
 
883
        if ((long)(int)l == l)
 
884
          return PyInt_FromLong(l);
 
885
        else
 
886
          return PyLong_FromLong(l);
 
887
      }
 
888
 
 
889
      case DoubleType:
 
890
        return PyFloat_FromDouble(*DoubleRef::cast_from(value));
 
891
        
 
892
      case StringType:
 
893
      {
 
894
        // maybe this should start returning unicode data, but before that all python code
 
895
        // should be tested if it can handle the unicode type. For now we just return utf8 strings.
 
896
        //return PyUnicode_EncodeUTF8();
 
897
        std::string data= *StringRef::cast_from(value);
 
898
        return PyString_FromStringAndSize(data.data(), data.size());
 
899
      }
 
900
      case ListType:
 
901
      {
 
902
        PyObject *content= PythonContext::internal_cobject_from_value(value);
 
903
        PyObject *r= PyObject_Call(_grt_list_class, Py_BuildValue("(ssO)", "", "", content), NULL);
 
904
        Py_XDECREF(content);
 
905
        return r;
 
906
      }
 
907
      case DictType:
 
908
      {
 
909
        PyObject *content= PythonContext::internal_cobject_from_value(value);
 
910
        PyObject *r= PyObject_Call(_grt_dict_class, Py_BuildValue("(ssO)", "", "", content), NULL);
 
911
        Py_XDECREF(content);
 
912
        return r;
 
913
      }
 
914
      case ObjectType:
 
915
      {
 
916
        std::string class_name= grt::ObjectRef::cast_from(value).class_name();
 
917
        PyObject *content= PythonContext::internal_cobject_from_value(value);
 
918
        PyObject *theclass= _grt_class_wrappers[class_name];
 
919
        PyObject *r= PyObject_Call(theclass ? theclass : (PyObject*)_grt_object_class, Py_BuildValue("(sO)", "", content), NULL);
 
920
        Py_XDECREF(content);
 
921
        
 
922
        return r;
 
923
      }
 
924
      default:
 
925
        return NULL;
 
926
    }
 
927
  }
 
928
  Py_INCREF(Py_None);
 
929
  return Py_None;
 
930
}
 
931
 
 
932
bool PythonContext::pystring_to_string(PyObject *strobject, std::string &ret_string)
 
933
{
 
934
  if (PyUnicode_Check(strobject))
 
935
  {
 
936
    PyObject *ref = PyUnicode_AsUTF8String(strobject);
 
937
    if (ref)
 
938
    {
 
939
      char *s;
 
940
      Py_ssize_t len;
 
941
      PyString_AsStringAndSize(ref, &s, &len);
 
942
      if (s)
 
943
        ret_string= std::string(s, len);
 
944
      else
 
945
        ret_string= "";
 
946
      Py_DECREF(ref);
 
947
      return true;
 
948
    }
 
949
    return false;
 
950
  }
 
951
  
 
952
  if (PyString_Check(strobject))
 
953
  {
 
954
    char *s;
 
955
    Py_ssize_t len;
 
956
    PyString_AsStringAndSize(strobject, &s, &len);
 
957
    if (s)
 
958
      ret_string = std::string(s, len);
 
959
    else
 
960
      ret_string = "";
 
961
    return true;
 
962
  }
 
963
  return false;
 
964
}
 
965
 
 
966
ValueRef PythonContext::from_pyobject(PyObject *object)
 
967
{
 
968
  if (!object || object == Py_None)
 
969
    return ValueRef();
 
970
 
 
971
  if (PyInt_Check(object))
 
972
    return IntegerRef(PyInt_AsLong(object));
 
973
 
 
974
  if (PyLong_Check(object))
 
975
    return IntegerRef(PyLong_AsLong(object));
 
976
 
 
977
  if (PyFloat_Check(object))
 
978
    return DoubleRef(PyFloat_AsDouble(object));
 
979
 
 
980
  if (PyUnicode_Check(object) || PyString_Check(object))
 
981
  {
 
982
    std::string tmp;
 
983
    if (pystring_to_string(object, tmp))
 
984
      return StringRef(tmp);
 
985
    return ValueRef();
 
986
  }
 
987
 
 
988
  if (PyTuple_Check(object))
 
989
  {
 
990
    grt::BaseListRef list(_grt);
 
991
    
 
992
    for (Py_ssize_t c= PyTuple_Size(object), i= 0; i < c; i++)
 
993
    {
 
994
      PyObject *item= PyTuple_GetItem(object, i);
 
995
      list.ginsert(from_pyobject(item));
 
996
    }
 
997
    return list;
 
998
  }
 
999
  
 
1000
  if (PyList_Check(object))
 
1001
  {
 
1002
    grt::BaseListRef list(_grt);
 
1003
  
 
1004
    for (Py_ssize_t c= PyList_Size(object), i= 0; i < c; i++)
 
1005
    {
 
1006
      PyObject *item= PyList_GetItem(object, i);
 
1007
      list.ginsert(from_pyobject(item));
 
1008
    }
 
1009
    return list;
 
1010
  }
 
1011
  else if (PyObject_IsInstance(object, _grt_list_class))
 
1012
    return *((PyGRTListObject*)object)->list;
 
1013
  
 
1014
  if (PyDict_Check(object))
 
1015
  {
 
1016
    grt::DictRef dict(_grt);
 
1017
    PyObject *key, *value;
 
1018
    Py_ssize_t pos = 0;
 
1019
    
 
1020
    while (PyDict_Next(object, &pos, &key, &value))
 
1021
    {
 
1022
      dict.set(PyString_AsString(key), from_pyobject(value));
 
1023
    }
 
1024
    
 
1025
    return dict;
 
1026
  }
 
1027
  else if (PyObject_IsInstance(object, _grt_dict_class))
 
1028
    return *((PyGRTDictObject*)object)->dict;
 
1029
  
 
1030
  if (PyObject_IsInstance(object, _grt_object_class))
 
1031
    return *((PyGRTObjectObject*)object)->object;
 
1032
 
 
1033
  return ValueRef();
 
1034
}
 
1035
 
 
1036
 
 
1037
ValueRef PythonContext::simple_type_from_pyobject(PyObject *object, const grt::SimpleTypeSpec &type)
 
1038
{
 
1039
  switch (type.type)
 
1040
  {
 
1041
    case IntegerType:
 
1042
    {
 
1043
      if (PyFloat_Check(object))
 
1044
        return IntegerRef((long)PyFloat_AsDouble(object));
 
1045
      else
 
1046
        PyErr_Clear();
 
1047
 
 
1048
      if (PyInt_Check(object))
 
1049
        return IntegerRef(PyInt_AsLong(object));
 
1050
      else
 
1051
        PyErr_Clear();
 
1052
 
 
1053
      if (!PyLong_Check(object))
 
1054
        return IntegerRef(PyLong_AsLong(object));
 
1055
      else
 
1056
        PyErr_Clear();
 
1057
      
 
1058
      throw grt::type_error("expected integer type x");
 
1059
    }
 
1060
    case DoubleType:
 
1061
    {
 
1062
      if (PyInt_Check(object))
 
1063
        return DoubleRef(PyInt_AsLong(object));
 
1064
      else
 
1065
        PyErr_Clear();
 
1066
      if (!PyFloat_Check(object))
 
1067
        throw grt::type_error("expected double type");
 
1068
      return DoubleRef(PyFloat_AsDouble(object));
 
1069
    }
 
1070
    case StringType:
 
1071
    {
 
1072
      std::string tmp;
 
1073
      if (pystring_to_string(object, tmp))
 
1074
        return StringRef(tmp);
 
1075
      else
 
1076
        throw grt::type_error("expected string type");
 
1077
    }
 
1078
    case ObjectType:
 
1079
    {
 
1080
      if (!PyObject_IsInstance(object, _grt_object_class))
 
1081
        throw grt::type_error("expected GRT object");
 
1082
 
 
1083
      grt::ObjectRef grtobject(*((PyGRTObjectObject*)object)->object);
 
1084
 
 
1085
      if (!type.object_class.empty() && !grtobject->is_instance(type.object_class))
 
1086
        throw grt::type_error(strfmt("expected GRT object of class %s", type.object_class.c_str()));
 
1087
 
 
1088
      return grtobject;
 
1089
    }
 
1090
    default:
 
1091
      return ValueRef();
 
1092
  }
 
1093
}
 
1094
 
 
1095
 
 
1096
ValueRef PythonContext::from_pyobject(PyObject *object, const grt::TypeSpec &expected_type)
 
1097
{
 
1098
  if (object == Py_None)
 
1099
    return ValueRef();
 
1100
 
 
1101
  switch (expected_type.base.type)
 
1102
  {
 
1103
    case ObjectType:
 
1104
    case IntegerType:
 
1105
    case DoubleType:
 
1106
    case StringType:
 
1107
      return simple_type_from_pyobject(object, expected_type.base);
 
1108
      
 
1109
    case ListType:
 
1110
    {
 
1111
      if (PyList_Check(object))
 
1112
      {
 
1113
        grt::BaseListRef list(_grt);
 
1114
        
 
1115
        for (Py_ssize_t c= PyList_Size(object), i= 0; i < c; i++)
 
1116
        {
 
1117
          PyObject *item= PyList_GetItem(object, i);
 
1118
          switch (expected_type.content.type)
 
1119
          {
 
1120
            case ObjectType:
 
1121
            case IntegerType:
 
1122
            case DoubleType:
 
1123
            case StringType:
 
1124
              list.ginsert(simple_type_from_pyobject(item, expected_type.content));
 
1125
              break;
 
1126
            case AnyType:
 
1127
              list.ginsert(from_pyobject(item));
 
1128
              break;
 
1129
            default:
 
1130
              g_warning("invalid type spec requested");
 
1131
              break;
 
1132
          }
 
1133
        }
 
1134
        return list;
 
1135
      }
 
1136
      else if (PyObject_IsInstance(object, _grt_list_class))
 
1137
      {
 
1138
        return *((PyGRTListObject*)object)->list;
 
1139
      }
 
1140
      else
 
1141
        throw grt::type_error("expected list");
 
1142
    }
 
1143
    case DictType:
 
1144
    {
 
1145
      if (PyDict_Check(object))
 
1146
      {
 
1147
        grt::DictRef dict(_grt);
 
1148
        PyObject *key, *value;
 
1149
        Py_ssize_t pos = 0;
 
1150
        
 
1151
        while (PyDict_Next(object, &pos, &key, &value))
 
1152
        {
 
1153
          switch (expected_type.content.type)
 
1154
          {
 
1155
            case ObjectType:
 
1156
            case IntegerType:
 
1157
            case DoubleType:
 
1158
            case StringType:
 
1159
              dict.set(PyString_AsString(key), simple_type_from_pyobject(value, expected_type.content));
 
1160
              break;
 
1161
            case AnyType:
 
1162
              dict.set(PyString_AsString(key), from_pyobject(value));
 
1163
              break;
 
1164
            default:
 
1165
              g_warning("invalid type spec requested");
 
1166
              break;
 
1167
          }
 
1168
        }
 
1169
        
 
1170
        return dict;
 
1171
      }
 
1172
      else if (PyObject_IsInstance(object, _grt_dict_class))
 
1173
      {
 
1174
        return *((PyGRTDictObject*)object)->dict;
 
1175
      }
 
1176
      else
 
1177
        throw grt::type_error("expected dict");
 
1178
    }
 
1179
    default:
 
1180
      return from_pyobject(object);
 
1181
  }
 
1182
  
 
1183
  return ValueRef();
 
1184
}
 
1185
 
 
1186
 
 
1187
int PythonContext::run_file(const std::string &file, bool interactive)
 
1188
{
 
1189
  PyObject *f = PyFile_FromString((char*)base::string_to_path_for_open(file).c_str(), (char*)"r");
 
1190
  if (!f)
 
1191
  {
 
1192
    PythonContext::log_python_error(base::strfmt("Could not open file %s\n", file.c_str()).c_str());
 
1193
    return -1;
 
1194
  }
 
1195
 
 
1196
  log_debug2("About to pyrun '%s'\n", file.c_str());
 
1197
  if (PyRun_SimpleFile(PyFile_AsFile(f), file.c_str()) != 0)
 
1198
  {
 
1199
    Py_DECREF(f);
 
1200
    PythonContext::log_python_error(base::strfmt("Error running file %s\n", file.c_str()).c_str());
 
1201
    return -1;
 
1202
  }
 
1203
  Py_DECREF(f);
 
1204
  
 
1205
  return 0;
 
1206
}
 
1207
 
 
1208
 
 
1209
/** Execute a string as Python code.
 
1210
 
 
1211
 If line_buffer is not null, it will be used as a buffer for multiple-line statements.
 
1212
 It is used by interactive shell, to construct these from single-line components.
 
1213
 
 
1214
 If line_buffer is null, the passed buffer will be expected to contain complete code.
 
1215
 */
 
1216
int PythonContext::run_buffer(const std::string &buffer, std::string *line_buffer)
 
1217
{
 
1218
  node *n;
 
1219
  PyObject *result;
 
1220
  PyObject *mainmod;
 
1221
  PyObject *globals;
 
1222
  
 
1223
  if (line_buffer)
 
1224
    line_buffer->append(buffer);
 
1225
  
 
1226
  WillEnterPython lock;
 
1227
  
 
1228
  n= PyParser_SimpleParseStringFlags(line_buffer ? line_buffer->c_str() : buffer.c_str(),
 
1229
                                     line_buffer ? Py_single_input : Py_file_input,
 
1230
                                     0);
 
1231
  
 
1232
  if (n && (!buffer.empty() && (buffer[0] ==' ' || buffer[0] == '\t')) && line_buffer)
 
1233
  {
 
1234
    return 0; // continued line
 
1235
  }
 
1236
  
 
1237
  if (!n && PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SyntaxError))
 
1238
  {
 
1239
    PyObject *excep;
 
1240
    PyObject *value;
 
1241
    PyObject *message;
 
1242
    PyObject *trace;
 
1243
    PyErr_Fetch(&excep, &value, &trace);
 
1244
    message= PyTuple_GetItem(value, 0);
 
1245
    if (strstr(PyString_AsString(message), "unexpected EOF") ||
 
1246
        strncmp(PyString_AsString(message), "EOF", 3)==0)
 
1247
    {
 
1248
      Py_DECREF(excep);
 
1249
      Py_DECREF(value);
 
1250
      if (trace)
 
1251
        Py_DECREF(trace);
 
1252
      PyErr_Clear();
 
1253
      return 0; // continued line
 
1254
    }
 
1255
    PyErr_Restore(excep, value, trace);
 
1256
  }
 
1257
  
 
1258
  if (!n)
 
1259
  {
 
1260
    PythonContext::log_python_error("Error running buffer");
 
1261
    
 
1262
    if (line_buffer)
 
1263
      line_buffer->clear();
 
1264
    
 
1265
    PyErr_Clear();
 
1266
    return -1;
 
1267
  }
 
1268
  PyNode_Free(n);
 
1269
  PyErr_Clear();
 
1270
  
 
1271
  // command is supposedly complete, try to execute it
 
1272
  
 
1273
  mainmod= PyImport_AddModule("__main__");
 
1274
  if (!mainmod)
 
1275
  {
 
1276
    return -1;
 
1277
  }
 
1278
  globals= PyModule_GetDict(mainmod);
 
1279
  
 
1280
  if (line_buffer)
 
1281
  {
 
1282
    result= PyRun_String(line_buffer->c_str(), Py_single_input, globals, globals);
 
1283
    
 
1284
    line_buffer->clear();
 
1285
  }
 
1286
  else
 
1287
    result= PyRun_String(buffer.c_str(), Py_file_input, globals, globals);
 
1288
  
 
1289
  if (!result)
 
1290
  {
 
1291
    if (PyErr_Occurred())
 
1292
      PythonContext::log_python_error("Error running buffer");
 
1293
    
 
1294
    return -1;
 
1295
  }
 
1296
  else
 
1297
  {    
 
1298
    Py_DECREF(result);
 
1299
  }
 
1300
  
 
1301
  return 0;  
 
1302
}
 
1303
 
 
1304
 
 
1305
// template of a python function to create a wrapper class for a GRT class
 
1306
static const char *create_class_template=
 
1307
"class %s(grt.Object):\n"
 
1308
"  def __init__(self, classname = None, wrapobj = None):\n"
 
1309
"    grt.Object.__init__(self, classname, wrapobj)";
 
1310
 
 
1311
static const char *create_class_template_sub=
 
1312
"class %s(%s):\n"
 
1313
"  def __init__(self, classname = '%s', wrapobj = None):\n"
 
1314
"    %s.__init__(self, classname, wrapobj)";
 
1315
 
 
1316
 
 
1317
 
 
1318
/** Create a Python subclass of our grt.Object class, that will wrap around the given GRT class
 
1319
 */
 
1320
static void create_class_wrapper(grt::MetaClass *meta, PyObject *locals)
 
1321
{
 
1322
  std::string script;
 
1323
  grt::MetaClass *parent;
 
1324
 
 
1325
  if ((parent= meta->parent()) && parent->parent() != 0)
 
1326
  {
 
1327
    std::string parname= flatten_class_name(parent->name());
 
1328
    script= strfmt(create_class_template_sub, 
 
1329
                   flatten_class_name(meta->name()).c_str(), parname.c_str(), 
 
1330
                   meta->name().c_str(),
 
1331
                   parname.c_str());
 
1332
  }
 
1333
  else
 
1334
  {
 
1335
    script= strfmt(create_class_template, 
 
1336
                   flatten_class_name(meta->name()).c_str());
 
1337
  }
 
1338
 
 
1339
  if (!PyRun_String(script.c_str(), Py_single_input, locals, locals))
 
1340
    PythonContext::log_python_error(NULL);
 
1341
}
 
1342
 
 
1343
/** Refresh Python environment with GRT information.
 
1344
 */
 
1345
int PythonContext::refresh()
 
1346
{
 
1347
  WillEnterPython lock;
 
1348
  
 
1349
  PyModule_AddObject(get_grt_module(), "root", from_grt(_grt->root()));
 
1350
  
 
1351
  PyObject *classes_dict= PyModule_GetDict(_grt_classes_module);
 
1352
 
 
1353
  Py_INCREF(classes_dict);
 
1354
 
 
1355
  // Generate Python class hierarchy to wrap GRT classes
 
1356
  const std::list<grt::MetaClass*> &classes(_grt->get_metaclasses());
 
1357
  for (std::list<grt::MetaClass*>::const_iterator iter= classes.begin(); iter != classes.end(); ++iter)
 
1358
  {
 
1359
    create_class_wrapper(*iter, classes_dict);
 
1360
 
 
1361
    _grt_class_wrappers[(*iter)->name()]= PyDict_GetItemString(classes_dict, flatten_class_name((*iter)->name()).c_str());
 
1362
  }
 
1363
 
 
1364
  Py_DECREF(classes_dict);
 
1365
  
 
1366
  // Generate module wrappers
 
1367
  const std::vector<grt::Module*> &modules(_grt->get_modules());
 
1368
  for (std::vector<grt::Module*>::const_iterator iter= modules.begin(); iter != modules.end(); ++iter)
 
1369
  {
 
1370
    PyObject *r= PyObject_Call(_grt_module_class, Py_BuildValue("(s)", (*iter)->name().c_str()), NULL);
 
1371
 
 
1372
    if (!r)
 
1373
      PythonContext::log_python_error("Error refreshing grt modules");
 
1374
    else
 
1375
      if (PyModule_AddObject(_grt_modules_module, (char*)(*iter)->name().c_str(), r) < 0)
 
1376
        PythonContext::log_python_error("Error refreshing grt modules");
 
1377
  }
 
1378
 
 
1379
  return 0;
 
1380
}
 
1381
 
 
1382
 
 
1383
void PythonContext::log_python_error(const char *message)
 
1384
{
 
1385
  PythonContext *ctx = PythonContext::get();
 
1386
  if (ctx)
 
1387
  {
 
1388
    if (message)
 
1389
      base::Logger::log(base::Logger::LogError, "python", "%s", message);
 
1390
    PyObject *grt_dict = PyModule_GetDict(ctx->get_grt_module());
 
1391
    PyObject *_stderr = PyDict_GetItemString(grt_dict, "_log_stderr"); 
 
1392
    PyObject *old_stderr = PySys_GetObject((char*)"stderr");
 
1393
    Py_INCREF(old_stderr);
 
1394
    if (_stderr)
 
1395
      PySys_SetObject((char*)"stderr", _stderr);
 
1396
    PyErr_Print();
 
1397
    
 
1398
    if (_stderr)
 
1399
      PySys_SetObject((char*)"stderr", old_stderr);
 
1400
    Py_DECREF(old_stderr);
 
1401
  }
 
1402
}
 
1403
 
 
1404
 
 
1405
 
 
1406
// script to be executed once GRT is initialized
 
1407
// executed in the grt module namespace
 
1408
static const char *post_init_script = 
 
1409
"import grt\n"
 
1410
"class _grtFileRedirector:\n"
 
1411
"    def __init__(self, logger):\n"
 
1412
"        self.logger = logger\n"
 
1413
"    def write(self, text):\n"
 
1414
"        if type(text) not in (str, unicode):\n"
 
1415
"            text = str(text)\n"
 
1416
"        grt.send_output(text)\n"
 
1417
"        self.logger(grt._log_domain, text)\n"
 
1418
"grt._log_domain = 'python'\n"
 
1419
"grt._log_stdout = _grtFileRedirector(grt.log_info)\n"
 
1420
"grt._log_stderr = _grtFileRedirector(grt.log_error)\n";
 
1421
 
 
1422
void PythonContext::run_post_init_script()
 
1423
{
 
1424
  WillEnterPython lock;
 
1425
 
 
1426
  if (PyRun_SimpleString((char*)post_init_script) < 0)
 
1427
    PythonContext::log_python_error("Error running post-init script:");
 
1428
}
 
1429
 
 
1430
#endif // ENABLE_PYTHON_MODULES