struct sr_java_frame * sr_java_frame_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "frame")) return NULL; struct sr_java_frame *result = sr_java_frame_new(); bool success = JSON_READ_STRING(root, "name", &result->name) && JSON_READ_STRING(root, "file_name", &result->file_name) && JSON_READ_UINT32(root, "file_line", &result->file_line) && JSON_READ_STRING(root, "class_path", &result->class_path) && JSON_READ_BOOL(root, "is_native", &result->is_native) && JSON_READ_BOOL(root, "is_exception", &result->is_exception) && JSON_READ_STRING(root, "message", &result->message); if (!success) { sr_java_frame_free(result); return NULL; } return result; }
struct sr_java_frame * sr_java_frame_dup(struct sr_java_frame *frame, bool siblings) { struct sr_java_frame *result = sr_java_frame_new(); memcpy(result, frame, sizeof(*result)); /* Handle siblings. */ if (siblings) { if (result->next) result->next = sr_java_frame_dup(result->next, true); } else result->next = NULL; /* Do not copy that. */ /* Duplicate all strings. */ if (result->file_name) result->file_name = sr_strdup(result->file_name); if (result->name) result->name = sr_strdup(result->name); if (result->class_path) result->class_path = sr_strdup(result->class_path); if (result->message) result->message = sr_strdup(result->message); return result; }
/* 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; }
struct sr_java_frame * sr_java_frame_parse(const char **input, struct sr_location *location) { const char *mark = *input; int lines, columns; /* at SimpleTest.throwNullPointerException(SimpleTest.java:36) [file:/usr/lib/java/foo.class] */ const char *cursor = sr_strstr_location(mark, "at", &lines, &columns); if (!cursor) { location->message = "Frame expected"; return NULL; } /* SimpleTest.throwNullPointerException(SimpleTest.java:36) [file:/usr/lib/java/foo.class] */ cursor = mark = cursor + 2; sr_location_add(location, lines, columns + 2); /* SimpleTest.throwNullPointerException(SimpleTest.java:36) [file:/usr/lib/java/foo.class] */ cursor = sr_skip_whitespace(cursor); sr_location_add(location, 0, cursor - mark); mark = cursor; sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "(\n")); struct sr_java_frame *frame = sr_java_frame_new(); if (cursor != mark) frame->name = sr_strndup(mark, cursor - mark); /* (SimpleTest.java:36) [file:/usr/lib/java/foo.class] */ if (*cursor == '(') { ++cursor; sr_location_add(location, 0, 1); mark = cursor; sr_location_add(location, 0, sr_skip_char_cspan(&cursor, ":)\n")); if (mark != cursor) { if (sr_java_frame_parse_is_native_method(mark)) frame->is_native = true; else if (!sr_java_frame_parse_is_unknown_source(mark)) { /* DO NOT set file_name if input says that source isn't known */ frame->file_name = sr_strndup(mark, cursor - mark); frame->file_name = anonymize_path(frame->file_name); } } if (*cursor == ':') { ++cursor; sr_location_add(location, 0, 1); mark = cursor; sr_parse_uint32(&cursor, &(frame->file_line)); sr_location_add(location, 0, cursor - mark); } } /* [file:/usr/lib/java/foo.class] */ mark = sr_java_frame_parse_frame_url(frame, cursor, location); cursor = strchrnul(mark, '\n'); if (*cursor == '\n') { *input = cursor + 1; sr_location_add(location, 2, 0); } else { *input = cursor; /* don't take \0 Byte into account */ sr_location_add(location, 0, (cursor - mark) - 1); } return frame; }