Reduce code duplication in traceback module

This commit is contained in:
Jeff Epler 2021-08-08 10:36:25 -05:00 committed by Jeff Epler
parent bfea6947e5
commit c1ffab7476
3 changed files with 34 additions and 63 deletions

View File

@ -143,7 +143,7 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) {
}
// helper function to print an exception with traceback
void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) {
void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit) {
if (mp_obj_is_exception_instance(exc) && stack_ok()) {
size_t n, *values;
mp_obj_exception_get_traceback(exc, &n, &values);
@ -156,16 +156,38 @@ void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) {
#endif
const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n");
// Set traceback formatting
// Default: Print full traceback
limit = limit * 3;
mp_int_t i = n - 3, j;
if (limit > 0) {
// Print upto limit traceback
// entries from caller's frame
if ((unsigned)limit > n) {
limit = n;
}
limit = n - limit;
} else if (limit < 0) {
// Print upto limit traceback
// entries from last
if ((unsigned)-limit > n) {
limit = -n;
}
i = 0, limit = limit + 3;
}
// Print the traceback
mp_cprintf(print, MP_ERROR_TEXT("Traceback (most recent call last):\n"));
for (int i = n - 3; i >= 0; i -= 3) {
for (; i >= limit; i -= 3) {
j = (i < 0) ? -i : i;
#if MICROPY_ENABLE_SOURCE_LINE
mp_cprintf(print, frame, values[i], (int)values[i + 1]);
mp_cprintf(print, frame, values[j], (int)values[j + 1]);
#else
mp_printf(print, frame, values[i]);
mp_cprintf(print, frame, values[j]);
#endif
// the block name can be NULL if it's unknown
qstr block = values[i + 2];
// The block name can be NULL if it's unknown
qstr block = values[j + 2];
if (block == MP_QSTRnull) {
mp_print_str(print, "\n");
} else {
@ -178,6 +200,10 @@ void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) {
mp_print_str(print, "\n");
}
void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) {
mp_obj_print_exception_with_limit(print, exc, 0);
}
bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) {
if (arg == mp_const_false) {
return 0;

View File

@ -888,6 +888,7 @@ mp_obj_t mp_obj_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type
void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind);
void mp_obj_print(mp_obj_t o, mp_print_kind_t kind);
void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc);
void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit);
bool mp_obj_is_true(mp_obj_t arg);
bool mp_obj_is_callable(mp_obj_t o_in);

View File

@ -27,61 +27,5 @@
#include "shared-module/traceback/__init__.h"
void shared_module_traceback_print_exception(mp_obj_exception_t *exc, mp_print_t *print, mp_int_t limit) {
// Print traceback
if (exc->traceback != NULL) {
size_t n = exc->traceback->len;
size_t *values = exc->traceback->data;
if (n > 0) {
assert(n % 3 == 0);
// Decompress the format strings
const compressed_string_t *traceback = MP_ERROR_TEXT("Traceback (most recent call last):\n");
#if MICROPY_ENABLE_SOURCE_LINE
const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\", line %d");
#else
const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\"");
#endif
const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n");
// Set traceback formatting
// Default: Print full traceback
limit = limit * 3;
mp_int_t i = n - 3, j;
if (limit > 0) {
// Print upto limit traceback
// entries from caller's frame
if ((unsigned)limit > n) {
limit = n;
}
limit = n - limit;
} else if (limit < 0) {
// Print upto limit traceback
// entries from last
if ((unsigned)-limit > n) {
limit = -n;
}
i = 0, limit = limit + 3;
}
// Print the traceback
mp_cprintf(print, traceback);
for (; i >= limit; i -= 3) {
j = (i < 0) ? -i : i;
#if MICROPY_ENABLE_SOURCE_LINE
mp_cprintf(print, frame, values[j], (int)values[j + 1]);
#else
mp_printf(print, frame, values[j]);
#endif
// The block name can be NULL if it's unknown
qstr block = values[j + 2];
if (block == MP_QSTRnull) {
mp_print_str(print, "\n");
} else {
mp_printf(print, block_fmt, block);
}
}
}
}
// Print exception
mp_obj_print_helper(print, exc, PRINT_EXC);
mp_print_str(print, "\n");
mp_obj_print_exception_with_limit(print, exc, limit);
}