Example #1
0
void python_script_error_jump(const char *filepath, int *lineno, int *offset)
{
  PyObject *exception, *value;
  PyTracebackObject *tb;

  *lineno = -1;
  *offset = 0;

  PyErr_Fetch(&exception, &value, (PyObject **)&tb);

  if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
    /* no traceback available when SyntaxError.
     * python has no api's to this. reference parse_syntax_error() from pythonrun.c */
    PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
    PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */

    if (value) { /* should always be true */
      PyObject *message;
      PyObject *filename_py, *text_py;

      if (parse_syntax_error(value, &message, &filename_py, lineno, offset, &text_py)) {
        const char *filename = _PyUnicode_AsString(filename_py);
        /* python adds a '/', prefix, so check for both */
        if ((BLI_path_cmp(filename, filepath) == 0) ||
            ((filename[0] == '\\' || filename[0] == '/') &&
             BLI_path_cmp(filename + 1, filepath) == 0)) {
          /* good */
        }
        else {
          *lineno = -1;
        }
      }
      else {
        *lineno = -1;
      }
    }
  }
  else {
    PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
    PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
    PyErr_Print();

    for (tb = (PyTracebackObject *)PySys_GetObject("last_traceback");
         tb && (PyObject *)tb != Py_None;
         tb = tb->tb_next) {
      PyObject *coerce;
      const char *tb_filepath = traceback_filepath(tb, &coerce);
      const int match = ((BLI_path_cmp(tb_filepath, filepath) == 0) ||
                         ((tb_filepath[0] == '\\' || tb_filepath[0] == '/') &&
                          BLI_path_cmp(tb_filepath + 1, filepath) == 0));
      Py_DECREF(coerce);

      if (match) {
        *lineno = tb->tb_lineno;
        /* used to break here, but better find the inner most line */
      }
    }
  }
}
Example #2
0
void python_script_error_jump(const char *filepath, int *lineno, int *offset)
{
	PyObject *exception, *value;
	PyTracebackObject *tb;

	*lineno= -1;
	*offset= 0;

	PyErr_Fetch(&exception, &value, (PyObject **)&tb);

	if(exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
		/* no traceback available when SyntaxError.
		 * python has no api's to this. reference parse_syntax_error() from pythonrun.c */
		PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
		PyErr_Restore(exception, value, (PyObject *)tb);	/* takes away reference! */

		if(value) { /* should always be true */
			PyObject *message;
			const char *filename, *text;

			if(parse_syntax_error(value, &message, &filename, lineno, offset, &text)) {
				/* python adds a '/', prefix, so check for both */
				if(	(strcmp(filename, filepath) == 0) || 
					((filename[0] == '\\' || filename[0] == '/') && strcmp(filename + 1, filepath) == 0)
				) {
					/* good */
				}
				else {
					*lineno= -1;
				}
			}
			else {
				*lineno= -1;
			}
		}
	}
	else {
		PyErr_NormalizeException(&exception, &value, (PyObject **)&tb);
		PyErr_Restore(exception, value, (PyObject *)tb);	/* takes away reference! */
		PyErr_Print();

		for(tb= (PyTracebackObject *)PySys_GetObject("last_traceback"); tb && (PyObject *)tb != Py_None; tb= tb->tb_next) {
			if(strcmp(traceback_filepath(tb), filepath) != 0) {
				*lineno= tb->tb_lineno;
				break;
			}
		}
	}
}