示例#1
0
/* constructor */
PyObject *
sr_py_java_frame_new(PyTypeObject *object, PyObject *args, PyObject *kwds)
{
    struct sr_py_java_frame *fo = (struct sr_py_java_frame*)
        PyObject_New(struct sr_py_java_frame, &sr_py_java_frame_type);

    if (!fo)
        return PyErr_NoMemory();

    const char *str = NULL;
    if (!PyArg_ParseTuple(args, "|s", &str))
        return NULL;

    if (str)
    {
        struct sr_location location;
        sr_location_init(&location);
        fo->frame = sr_java_frame_parse(&str, &location);

        if (!fo->frame)
        {
            PyErr_SetString(PyExc_ValueError, location.message);
            return NULL;
        }
    }
    else
        fo->frame = sr_java_frame_new();

    return (PyObject*)fo;
}
示例#2
0
文件: java_frame.c 项目: abrt/satyr
struct sr_java_frame *
sr_java_frame_parse_exception(const char **input,
                              struct sr_location *location)
{
    /* java.lang.NullPointerException: foo */
    const char *cursor = sr_skip_whitespace(*input);
    sr_location_add(location, 0, cursor - *input);
    const char *mark = cursor;

    sr_location_add(location, 0, sr_skip_char_cspan(&cursor, ": \t\n"));

    if (mark == cursor)
    {
        location->message = "Expected exception name";
        return NULL;
    }

    struct sr_java_frame *exception = sr_java_frame_new_exception();
    exception->name = sr_strndup(mark, cursor - mark);

    /* : foo */
    if (*cursor == ':')
    {
        ++cursor;
        sr_location_add(location, 0, 1);
        mark = cursor;

        /* foo */
        cursor = sr_skip_whitespace(mark);
        sr_location_add(location, 0, cursor - mark);
        mark = cursor;

        sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "\n"));

        if (mark != cursor)
            exception->message = sr_strndup(mark, cursor - mark);
    }
    else
    {
        /* just to be sure, that we skip white space behind exception name */
        sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "\n"));
    }

    if (*cursor == '\n')
    {
        ++cursor;
        /* this adds one line */
        sr_location_add(location, 2, 0);
    }
    /* else *cursor == '\0' */

    mark = cursor;

    struct sr_java_frame *frame = NULL;
    /* iterate line by line
       best effort - continue on error */
    while (*cursor != '\0')
    {
        cursor = sr_skip_whitespace(mark);
        sr_location_add(location, 0, cursor - mark);

        /* Each inner exception has '...' at its end */
        if (strncmp("... ", cursor, strlen("... ")) == 0)
            goto current_exception_done;

        /* Suppressed exceptions follow after the end of current exception */
        if (strncmp("Suppressed: ", cursor, strlen("Suppressed: ")) == 0)
            goto current_exception_done;

        /* The top most exception does not have '...' at its end */
        if (strncmp("Caused by: ", cursor, strlen("Caused by: ")) == 0)
            goto parse_inner_exception;

        struct sr_java_frame *parsed = sr_java_frame_parse(&cursor, location);

        if (parsed == NULL)
        {
            sr_java_frame_free(exception);
            return NULL;
        }

        mark = cursor;

        if (exception->next == NULL)
            exception->next = parsed;
        else
        {
            assert(frame);
            frame->next = parsed;
        }

        frame = parsed;
    }
    /* We are done with the top most exception without inner exceptions */
    /* because of no 'Caused by:' and no '...' */
    goto exception_parsing_successful;

current_exception_done:
    sr_skip_to_next_line_location(&cursor, &location->line, &location->column);

    mark = cursor;
    cursor = sr_skip_whitespace(mark);
    sr_location_add(location, 0, cursor - mark);

    if (strncmp("Suppressed: ", cursor, strlen("Suppressed: ")) == 0)
    {
        /* Skip all lines related to the suppressed exception. We can do
         * this by skipping all lines that begin with a whitespace - the
         * main exception chain always begins without preceding whitespace.
         */
        sr_skip_to_next_line_location(&cursor, &location->line, &location->column);

        while (cursor && isspace(*cursor))
            sr_skip_to_next_line_location(&cursor, &location->line, &location->column);
    }

    if (strncmp("Caused by: ", cursor, strlen("Caused by: ")) == 0)
    {
parse_inner_exception:
        cursor += strlen("Caused by: ");
        sr_location_add(location, 0, strlen("Caused by: "));

        struct sr_java_frame *inner = sr_java_frame_parse_exception(&cursor, location);
        if (inner == NULL)
        {
            sr_java_frame_free(exception);
            return NULL;
        }

        struct sr_java_frame *last_inner = sr_java_frame_get_last(inner);
        last_inner->next = exception;
        exception = inner;
    }

exception_parsing_successful:
    *input = cursor;

    return exception;
}