@@ -37,10 +37,10 @@ int assertion_depth=1;
*/
void se_prinT0(FILE* file, T0** o) {
if (*o == NULL) {
fprintf(file,"Void");
fprintf(file,"Void");
}
else {
fprintf(file,"#%p",(void*)*o);
fprintf(file,"#%p",(void*)*o);
}
}

@@ -64,22 +64,22 @@ static void se_print_character(FILE* file, char c) {
/* Produce a visible output of `c' using an Eiffelish notation.
*/
if ((' ' <= c)&&(c <= '~')&&(c != '\'')&&(c != '\"')&&(c != '%')) {
putc(c,file);
putc(c,file);
}
else {
switch (c) {
case '\b': fprintf(file,"%%B"); break;
case '\f': fprintf(file,"%%F"); break;
case '\n': fprintf(file,"%%N"); break;
case '\r': fprintf(file,"%%R"); break;
case '\t': fprintf(file,"%%T"); break;
case '\0': fprintf(file,"%%U"); break;
case '\'': fprintf(file,"%%\'"); break;
case '\"': fprintf(file,"%%\""); break;
case '%': fprintf(file,"%%%%"); break;
default:
fprintf(file,"%%/%d/", (int) ((unsigned char) c));
}
switch (c) {
case '\b': fprintf(file,"%%B"); break;
case '\f': fprintf(file,"%%F"); break;
case '\n': fprintf(file,"%%N"); break;
case '\r': fprintf(file,"%%R"); break;
case '\t': fprintf(file,"%%T"); break;
case '\0': fprintf(file,"%%U"); break;
case '\'': fprintf(file,"%%\'"); break;
case '\"': fprintf(file,"%%\""); break;
case '%': fprintf(file,"%%%%"); break;
default:
fprintf(file,"%%/%d/", (int) ((unsigned char) c));
}
}
}

@@ -103,35 +103,35 @@ void se_prinT12(FILE* file, EIF_REAL_EXTENDED* o) {

void se_prinT6(FILE* file, EIF_BOOLEAN* o) {
if (*o) {
fprintf(file,"True");
fprintf(file,"True");
}
else {
fprintf(file,"False");
fprintf(file,"False");
}
}

void se_prinT7(FILE* file, EIF_STRING* o) {
if (*o == NULL) {
fprintf(file,"Void");
fprintf(file,"Void");
}
else {
T3* storage = (*o)->_storage;
int count = (*o)->_count;
int i = 0;
putc('\"',file);
while (i < count) {
se_print_character(file, storage[i++]);
}
putc('\"',file);
T3* storage = (*o)->_storage;
int count = (*o)->_count;
int i = 0;
putc('\"',file);
while (i < count) {
se_print_character(file, storage[i++]);
}
putc('\"',file);
}
}

void se_prinT8(FILE* file, EIF_POINTER* o) {
if (*o == NULL) {
fprintf(file,"NULL");
fprintf(file,"NULL");
}
else {
fprintf(file,"POINTER#%p",(void*)*o);
fprintf(file,"POINTER#%p",(void*)*o);
}
}

@@ -147,72 +147,130 @@ int se_stack_size(se_dump_stack* ds) {
}

void se_print_run_time_stack(void) {
se_print_run_time_stack_in(SE_ERR);
/* ANY.print_run_time_stack */
se_print_run_time_stack_in(SE_ERR, se_dst, NULL, 0);
}

void se_print_run_time_stack_in(FILE* file) {
/* ANY.print_run_time_stack */
se_dump_stack* origin;
static se_print_run_time_stack_(FILE* file, se_dump_stack* top, se_dump_stack* cur, int is_compact, int exception_depth) {
se_dump_stack* ds;
se_dump_stack* ds2;
int frame_count = 1;
int rescue = 0;
char tag[24];

handle(SE_HANDLE_ENTER_PRINT_STACK, NULL);
origin = se_dst;
if (origin == NULL) {
fprintf(file,"Empty stack.\n");
return ;
if (exception_depth == 0) {
sprintf(tag, "run-time");
}
else {
while (origin->exception_origin != NULL) {
origin = origin->exception_origin;
}
sprintf(tag, "exception#%d", exception_depth);
}

ds = origin;
while (ds->caller != NULL) {
ds = ds->caller;
frame_count++;
if (top == NULL) {
if (is_compact) {
fprintf(file,"Empty %s stack.\n", tag);
} else {
fprintf(file,"==== Empty %s stack.\n", tag);
}
return;
}

ds = top;
while (ds->caller != NULL) {
ds = ds->caller;
frame_count++;
}

if (is_compact) {
fprintf(file,"==== %d frames in %s stack:\n",frame_count, tag);
}
else {
fprintf(file,"%d frames in %s stack.\n",frame_count, tag);
fprintf(file,"==== Bottom of %s stack ====\n", tag);
}
fprintf(file,"%d frames in current stack.\n",frame_count);
fprintf(file,"===== Bottom of run-time stack =====\n");
while (ds != NULL) {
se_print_one_frame_in(file,ds);
/* Note: this loop would have been simpler if recursive. We don't
do that because that could potentially trigger some weird stack
overflow exception.
Anyway performance is not critical here.
*/
frame_count--;

if (ds->exception_origin != NULL) {
se_print_run_time_stack_(file, ds->exception_origin, cur, is_compact, exception_depth + 1);

/* the rescue stack is part of the run-time stack */
if (is_compact) {
fprintf(file,"==== Rescue:\n");
}
else {
fprintf(file,"==== Rescue stack ====\n", tag);
}
}

se_print_one_frame_in(file,ds,cur,is_compact);

/* Next frame : */
if (ds == origin) {
if (ds == top) {
ds = NULL;
}
else if (ds->exception_origin != NULL) {
rescue = 1;
ds = ds->exception_origin;
}
else {
ds2 = se_dst;
ds2 = top;
while (ds2->caller != ds) {
ds2 = ds2->caller;
ds2 = ds2->caller;
}
ds = ds2;
}
if (--frame_count) {
if (!rescue) {

if (!is_compact) {
fprintf(file,"======================================\n");
}
else {
fprintf(file,"==== Rescue stack =================\n");
}
}
}
fprintf(file,"===== Top of run-time stack =====\n");
if (!is_compact) {
fprintf(file,"==== Top of %s stack ====\n", tag);
}
}

void se_print_run_time_stack_in(FILE* file, se_dump_stack* top, se_dump_stack* cur, int is_compact) {
handle(SE_HANDLE_ENTER_PRINT_STACK, NULL);
se_print_run_time_stack_(file, top, cur, is_compact, 0);
handle(SE_HANDLE_EXIT_PRINT_STACK, NULL);
}

int se_print_one_frame(se_dump_stack* ds) {
return se_print_one_frame_in(SE_ERR, ds);
return se_print_one_frame_in(SE_ERR, ds, NULL, 0);
}

static char* se_basename(char* path) {
char* result = path;
int again = 1;

while (*result) result++;

while (again) {
result--;
if (result == path) {
again = 0;
}
else {
switch(*result) {
case '\\':
case '/':
case ':':
case ']':
result++;
again = 0;
break;
default:
break;
}
}
}
while (*result==' ') result++;

return result;
}

int se_print_one_frame_in(FILE* file, se_dump_stack* ds) {
int se_print_one_frame_in(FILE* file, se_dump_stack* ds, se_dump_stack* cur, int is_compact) {
/* Return 1 for an ordinary frame (not a cecil frame or some dynamic
dispatch extra frame). */
se_frame_descriptor* fd = ds->fd;
@@ -223,12 +281,31 @@ int se_print_one_frame_in(FILE* file, se_dump_stack* ds) {
int id;
void** var;

int li = ds->p == 0 ? 0 : se_position2line(ds->p);
int fi = ds->p == 0 ? 0 : se_position2path_id(ds->p);

if (is_compact) {
if (li == 0) {
fprintf(file," %c", (cur==ds?'*':' '));
} else if (p[fi] == NULL) {
fprintf(file, " :%-4d %c", li, (cur==ds?'*':' '));
} else {
fprintf(file, "%35.35s:%-4d %c", se_basename(p[fi]), li, (cur==ds?'*':' '));
}
}

if (fd == NULL) {
fprintf(file,"External CECIL call.\n");
fprintf(file,"External call (may be a -cecil call).\n");
return 0;
}
if (is_compact) {
fprintf(file,"%s\n",fd->name);
if (li == 0) return 0;
return 1;
}

fprintf(file,"%s\n",fd->name);
if (ds->p == 0) return 0;
if (li == 0) return 0;
local_format = fd->local_format;
if (fd->use_current) {
fprintf(file,"Current = ");
@@ -274,11 +351,11 @@ int se_print_one_frame_in(FILE* file, se_dump_stack* ds) {
fprintf(file,"\n");
local_count++;
}
fprintf(file,"line %d ",se_position2line(ds->p));
fprintf(file,"line %d ",li);
fflush(file);
fprintf(file,"column %d ",se_position2column(ds->p));
fflush(file);
fprintf(file,"file %s \n",p[se_position2path_id(ds->p)]);
fprintf(file,"file %s \n",p[fi]);
fflush(file);
return 1;
}
@@ -296,11 +373,11 @@ int se_rci(se_dump_stack*caller,void*C) {
}
else {
if (fd->use_current) {
if (fd->local_format[1] == 'R') {
if ((*((void**)caller->current)) == C) {
return 0;
}
}
if (fd->local_format[1] == 'R') {
if ((*((void**)caller->current)) == C) {
return 0;
}
}
}
}
}
@@ -509,9 +586,9 @@ int ac_lvc(int lc,int lv1,int lv2) {
internal_exception_handler(Loop_variant);
#else
{
char msg [64];
sprintf(msg,"Bad First Variant Value = %d\n",lv2);
error0(msg,NULL);
char msg [64];
sprintf(msg,"Bad First Variant Value = %d\n",lv2);
error0(msg,NULL);
}
#endif
}
@@ -526,9 +603,9 @@ int ac_lvc(int lc,int lv1,int lv2) {
{
char msg [512];
sprintf(msg,
"Bad loop variant.\nLoop body counter = %d (done)\n"
"Previous Variant = %d\nNew Variant = %d\n",
lc,lv1,lv2);
"Bad loop variant.\nLoop body counter = %d (done)\n"
"Previous Variant = %d\nNew Variant = %d\n",
lc,lv1,lv2);
error0(msg,NULL);
}
#endif
@@ -552,16 +629,16 @@ T0* se_evobt(T0* o, se_position position) {
*/
if (!o) {
#ifdef SE_EXCEPTIONS
internal_exception_handler(Void_call_target);
internal_exception_handler(Void_call_target);
#else
error1("Target is Void.",position);
error1("Target is Void.",position);
#endif
}
else {
#ifdef SE_EXCEPTIONS
internal_exception_handler(System_level_type_error);
internal_exception_handler(System_level_type_error);
#else
error2(o,position);
error2(o,position);
#endif
}
return o; /* Dummy return to avoid C warnings. */
@@ -614,134 +691,134 @@ se_dump_stack* se_new_dump_stack(se_dump_stack* copy) {
if (result != NULL) {
result->fd = fd;
result->p = copy->p;
result->caller = copy->caller;
result->caller = NULL;
result->current = NULL;
result->locals = NULL;
result->exception_origin = NULL;

if (fd != NULL) {
local_format = fd->local_format;
i = 0;
if (fd->use_current) {
result->current = copy->current;
/* Place i after the Current definition: */
i = 2;
id = 0;
while (local_format[i] != '%') {
id = (id * 10) + (local_format[i++] - '0');
}
i++;
}

/*
*
* p: sum of the number of pointers ("indirections") per local
* -> 1 for an expanded
* -> 2 for a reference
*
* o: total malloc'ed size
*
* _i: access to the first indirection pointer
*
* _ref: access to the second indirection pointer of a reference object
* _ref == (T0*)(*_i)
*
* _exp: access to a copy of the expanded object
* _exp == *((char*)_i)
*
*
*
* For instance, if "0" is the first local, a reference and "4" is the
* second local, an expanded type (say, a 6-byte structure noted
* "XXXXXXXXXXX", with 64-bit padding "/"):
*
*
*
* result->locals
* | ------------
* | | |
* | -----------|------------v--------------
* -->| | | | |===+===|===+===|XXXXXXXXXXX|/|/|
* |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|0|1|2|3|
* |===+===| | | | |===+===| | | | | | | | |
* ---|------------^--|-------------------
* | | |
* ------------ --------------------------> object
*
* |-> _i |-> _ref _exp <-|
*
*
*
* Note: Those "|->" denote the start value and way of
* progression of the pointers
*
*
* result->locals is defined as a (void***) but its real "type" depends on
* which element is accessed (as in the live stack; but in the live stack,
* only the first indirection is in the struct; the remaining data is on
* the native stack).
*
*/

if (copy->locals != NULL) {
j = i;

local_count = local_size = p = o = 0;

while (local_count < fd->local_count) {
while (local_format[i++] != '%');
expanded = ((local_format[i++] == 'E')?1:0);
id = 0;
while (local_format[i] != '%') {
id = (id * 10) + (local_format[i++] - '0');
}
i++;
if (expanded) {
p++;
o = se_strucT[id];
o = (o + 7) & ~7; /* 64-bit align: should be fine for most systems */
local_size += o;
}
else {
p+=2;
}
local_count++;
}

o = p * sizeof(void*) + local_size;
result->locals = (void***)se_malloc(o);
_i = result->locals;
_exp = (char*)_i + o;
_ref = (void**)_i + local_count;

i = j;
local_count = 0;
while (local_count < fd->local_count) {
while (local_format[i++] != '%');
expanded = ((local_format[i++] == 'E')?1:0);
id = 0;
while (local_format[i] != '%') {
id = (id * 10) + (local_format[i++] - '0');
}
i++;
var = (copy->locals)[local_count];
if (expanded) {
o = n = se_strucT[id];
o = (o + 7) & ~7; /* 64-bit align: should be fine for most systems */
_exp -= o;
*(char**)_i = _exp;
memset(_exp, 0, o);
memcpy(_exp, var, n);
}
else {
*_i = _ref;
*_ref = *var;
_ref++;
}
local_count++;
_i++;
}
}
local_format = fd->local_format;
i = 0;
if (fd->use_current) {
result->current = copy->current;
/* Place i after the Current definition: */
i = 2;
id = 0;
while (local_format[i] != '%') {
id = (id * 10) + (local_format[i++] - '0');
}
i++;
}

/*
*
* p: sum of the number of pointers ("indirections") per local
* -> 1 for an expanded
* -> 2 for a reference
*
* o: total malloc'ed size
*
* _i: access to the first indirection pointer
*
* _ref: access to the second indirection pointer of a reference object
* _ref == (T0*)(*_i)
*
* _exp: access to a copy of the expanded object
* _exp == *((char*)_i)
*
*
*
* For instance, if "0" is the first local, a reference and "4" is the
* second local, an expanded type (say, a 6-byte structure noted
* "XXXXXXXXXXX", with 64-bit padding "/"):
*
*
*
* result->locals
* | ------------
* | | |
* | -----------|------------v--------------
* -->| | | | |===+===|===+===|XXXXXXXXXXX|/|/|
* |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|0|1|2|3|
* |===+===| | | | |===+===| | | | | | | | |
* ---|------------^--|-------------------
* | | |
* ------------ --------------------------> object
*
* |-> _i |-> _ref _exp <-|
*
*
*
* Note: Those "|->" denote the start value and way of
* progression of the pointers
*
*
* result->locals is defined as a (void***) but its real "type" depends on
* which element is accessed (as in the live stack; but in the live stack,
* only the first indirection is in the struct; the remaining data is on
* the native stack).
*
*/

if (copy->locals != NULL) {
j = i;

local_count = local_size = p = o = 0;

while (local_count < fd->local_count) {
while (local_format[i++] != '%');
expanded = ((local_format[i++] == 'E')?1:0);
id = 0;
while (local_format[i] != '%') {
id = (id * 10) + (local_format[i++] - '0');
}
i++;
if (expanded) {
p++;
o = se_strucT[id];
o = (o + 7) & ~7; /* 64-bit align: should be fine for most systems */
local_size += o;
}
else {
p+=2;
}
local_count++;
}

o = p * sizeof(void*) + local_size;
result->locals = (void***)se_malloc(o);
_i = result->locals;
_exp = (char*)_i + o;
_ref = (void**)_i + local_count;

i = j;
local_count = 0;
while (local_count < fd->local_count) {
while (local_format[i++] != '%');
expanded = ((local_format[i++] == 'E')?1:0);
id = 0;
while (local_format[i] != '%') {
id = (id * 10) + (local_format[i++] - '0');
}
i++;
var = (copy->locals)[local_count];
if (expanded) {
o = n = se_strucT[id];
o = (o + 7) & ~7; /* 64-bit align: should be fine for most systems */
_exp -= o;
*(char**)_i = _exp;
memset(_exp, 0, o);
memcpy(_exp, var, n);
}
else {
*_i = _ref;
*_ref = *var;
_ref++;
}
local_count++;
_i++;
}
}
}
}
}
@@ -781,12 +858,12 @@ void se_print_locals_in(FILE* file, se_dump_stack* ds, int enter) {
display = (strncmp(local_format+i, "Result%", 7)==0) != enter;
if (display) {
if (printed)
fprintf(file,", ");
fprintf(file,", ");
else
fprintf(file,"(");
fprintf(file,"(");
printed++;
}

while (local_format[i] != '%') {
if (display) fprintf(file,"%c",local_format[i]);
i++;
@@ -802,19 +879,19 @@ void se_print_locals_in(FILE* file, se_dump_stack* ds, int enter) {
i++;
if (display) {
if (ds->locals == NULL) {
fprintf(file,"<unavailable>");
fprintf(file,"<unavailable>");
}
else {
var = (ds->locals)[local_count];
if (expanded) {
(se_prinT[id])(file, (void**)(var));
}
else if (*var == NULL) {
fprintf(file,"Void");
}
else {
(se_prinT[((T0*)(*var))->id])(file, (void**)(var));
}
var = (ds->locals)[local_count];
if (expanded) {
(se_prinT[id])(file, (void**)(var));
}
else if (*var == NULL) {
fprintf(file,"Void");
}
else {
(se_prinT[((T0*)(*var))->id])(file, (void**)(var));
}
}
}
local_count++;
@@ -833,7 +910,7 @@ void se_print_call_trace(se_dump_stack *ds) {
int i;
if (ds) {
int enter = ds->caller == se_dst;

if (enter)
se_call_depth++;

@@ -849,10 +926,10 @@ void se_print_call_trace(se_dump_stack *ds) {
se_print_locals_in(stdout, ds, 1);
} else {
if (se_dst) {
printf("leave ");
printf("%s", se_dst->fd->name);
se_print_locals_in(stdout, se_dst, 0);
se_call_depth--;
printf("leave ");
printf("%s", se_dst->fd->name);
se_print_locals_in(stdout, se_dst, 0);
se_call_depth--;
}
}
} else {
@@ -96,9 +96,9 @@ extern int se_dst_depth;

int se_stack_size(se_dump_stack* ds);
void se_print_run_time_stack(void);
void se_print_run_time_stack_in(FILE* file);
void se_print_run_time_stack_in(FILE* file, se_dump_stack* top, se_dump_stack* cur, int is_compact);
int se_print_one_frame(se_dump_stack*ds);
int se_print_one_frame_in(FILE* file, se_dump_stack*ds);
int se_print_one_frame_in(FILE* file, se_dump_stack*ds, se_dump_stack* cur, int is_compact);

int se_rci(se_dump_stack*caller,void*C);
void error0(char*m,char*vv);
@@ -116,26 +116,26 @@ static int sedb_ensure_directory(char* path) {
if (errno == ENOENT) {
n = mkdir(path, 0700);
if (n == -1) {
if (errno == ENOENT) {
p = c = path;
while (*c != '\0') {
if (*c == '/') {
p = c;
}
c++;
}
if (p == path) {
return 0;
}
*p = '\0';
if (sedb_ensure_directory(path)) {
*p = '/';
if (sedb_ensure_directory(path)) {
return 1;
}
}
}
return 0;
if (errno == ENOENT) {
p = c = path;
while (*c != '\0') {
if (*c == '/') {
p = c;
}
c++;
}
if (p == path) {
return 0;
}
*p = '\0';
if (sedb_ensure_directory(path)) {
*p = '/';
if (sedb_ensure_directory(path)) {
return 1;
}
}
}
return 0;
}
return 1;
}
@@ -286,8 +286,8 @@ static int sedb_vprintf(FILE*f, char* format, va_list args) {
r = write(fd, s+i, 1);
if (r != -1) break;
if (errno != EAGAIN) {
perror("write");
exit(1);
perror("write");
exit(1);
}
FD_SET(fd, &wait);
select(fd+1, NULL, &wait, NULL, NULL);
@@ -572,7 +572,7 @@ static void sedb_on_line_help(char* line) {
sedb_printf(out,
"MISCELLANEOUS\n"
" G : run the garbage collector now\n"
" g : show garbage collector information\n"
" g : show garbage collector information\n"
" T : switch to the \"trace.se\" file mode\n"
" Enter : repeat the previous debugger command\n"
"\n");
@@ -735,6 +735,9 @@ static void sedb_on_line_more_help(void) {
"The default option is the compact display; in that case, the current stack\n"
"frame is marked by a star. The expanded stack display shows the stack as\n"
"displayed when an exception is raised.\n"
"\n"
"Note that if there is a rescue stack, those frames *cannot* be reached\n"
"by 'u' and 'd'.\n"
"\n");
}
}
@@ -787,7 +790,7 @@ static void sedb_show_point(se_dump_stack*ds, int l, int c, int f) {

sedb_printf(out,"---- Stack-frame: %d ---- inside ",se_stack_size(ds));
fflush(out);
if (!se_print_one_frame_in(out,ds)) {
if (!se_print_one_frame_in(out,ds,NULL,0)) {
fflush(out);
return ;
}
@@ -821,9 +824,9 @@ static void sedb_show_point(se_dump_stack*ds, int l, int c, int f) {
}
else {
if (cc == '\t')
sedb_printf(out," ");
sedb_printf(out," ");
else
sedb_printf(out,"%c",cc);
sedb_printf(out,"%c",cc);
}
}
sedb_printf(out,"\n>%d++\t",line);
@@ -835,9 +838,9 @@ static void sedb_show_point(se_dump_stack*ds, int l, int c, int f) {
}
else {
if (cc == '\t')
sedb_printf(out," ");
sedb_printf(out," ");
else
sedb_printf(out,"%c",cc);
sedb_printf(out,"%c",cc);
}
}
after = l + 3;
@@ -854,9 +857,9 @@ static void sedb_show_point(se_dump_stack*ds, int l, int c, int f) {
}
else {
if (cc == '\t')
sedb_printf(out," ");
sedb_printf(out," ");
else
sedb_printf(out,"%c",cc);
sedb_printf(out,"%c",cc);
}
}
sedb_printf(out,"\n");
@@ -1061,7 +1064,7 @@ static int sedb_string_match(char* indication, char* frame) {
}

static int sedb_breakpoint_match(se_dump_stack*ds, int l, int f,
int breakpointNumber, se_breakpoint* bp) {
int breakpointNumber, se_breakpoint* bp) {
/* Does this `bp' match the current point. */
int StackSize;
int stack_automatic = 0;
@@ -1131,84 +1134,6 @@ static void sedb_force_exit(int exit_arg) {
exit(exit_arg);
}

static char* sedb_basename(char* path) {
char* result = path;
int again = 1;
while (*result) result++;
while (again) {
result--;
if (result == path) {
again = 0;
}
else {
switch(*result) {
case '\\':
case '/':
case ':':
case ']':
result++;
again = 0;
break;
default:
break;
}
}
}
while (*result==' ') result++;
return result;
}

static void sedb_compact_view_of_the_stack(se_dump_stack* top, se_dump_stack* cur) {
se_dump_stack* ds = NULL;
int frame_count = 1;
FILE* out = sedb_output();

ds = top;
if (ds == NULL) {
sedb_printf(out,"Empty stack.\n");
return ;
}
else {
while (ds->caller != NULL) {
ds = ds->caller;
frame_count++;
}
}
sedb_printf(out,"===== %d frames in current stack:\n",frame_count);
while (ds != NULL) {
se_position position = ds->p;
se_frame_descriptor* fd = ds->fd;

int li = se_position2line(position);
int fi = se_position2path_id(position);

if (p[fi] == NULL) {
sedb_printf(out,"%c ", (cur==ds?'*':' '));
} else {
sedb_printf(out,"%c [%s:%d]\t", (cur==ds?'*':' '), sedb_basename(p[fi]), li);
}

if (fd == NULL) {
sedb_printf(out,"External call (may be a -cecil call).\n");
}
else {
sedb_printf(out,"%s\n",fd->name);
}
/* Next frame : */
if (ds == top) {
ds = NULL;
}
else {
se_dump_stack* ds2;
ds2 = top;
while (ds2->caller != ds) {
ds2 = ds2->caller;
}
ds = ds2;
}
}
}

/* ---------------------------------------------------------------------- */
/* sedb interface */

@@ -1219,7 +1144,7 @@ void sedb(se_dump_stack*ds, se_position position, char info_code) {
'N' at Instruction level (the n command)
'S' at expression level (the s command)
'X' just before the eXit of the enclosing function
'K' from the sedb_break C function
'K' from the sedb_break C function
*/
ds->p = position; /* Update the stack information. */
if (se_general_trace_switch) { /* The GENERAL.trace_switch is set: */
@@ -1237,19 +1162,19 @@ void sedb(se_dump_stack*ds, se_position position, char info_code) {
case SEDB_FINISH_CMD:
_sedb_running_status(ds,position);
if ((ds == sedb_previous_ds) && (info_code == 'X')) {
sedb_show_point(ds, se_position2line(position), se_position2column(position), se_position2path_id(position));
strcpy(sedb_last_command,"f");
sedb_status = SEDB_WAITING_KBD;
_sedb_waiting_kbd(ds, position);
sedb_show_point(ds, se_position2line(position), se_position2column(position), se_position2path_id(position));
strcpy(sedb_last_command,"f");
sedb_status = SEDB_WAITING_KBD;
_sedb_waiting_kbd(ds, position);
}
break;
case SEDB_NEXT_CMD:
_sedb_running_status(ds,position);
if ((ds == sedb_previous_ds) && ((info_code == 'N') || (info_code == 'X'))) {
sedb_show_point(ds,se_position2line(position) ,se_position2column(position), se_position2path_id(position));
strcpy(sedb_last_command,"n");
sedb_status = SEDB_WAITING_KBD;
_sedb_waiting_kbd(ds, position);
sedb_show_point(ds,se_position2line(position) ,se_position2column(position), se_position2path_id(position));
strcpy(sedb_last_command,"n");
sedb_status = SEDB_WAITING_KBD;
_sedb_waiting_kbd(ds, position);
}
break;
case SEDB_START_STATUS:
@@ -1449,12 +1374,9 @@ static void _sedb_waiting_kbd(se_dump_stack*ds, se_position position) {
/* -------------------- View the stack trace */
case 'S':
strcpy(sedb_last_command,line);
if (sedb_yes_or_no("Compact view of the stack",1)) {
sedb_compact_view_of_the_stack(ds, plus_minus);
}
else {
se_print_run_time_stack_in(out);
}
se_print_run_time_stack_in(out, ds, plus_minus,
sedb_yes_or_no("Compact view of the stack", 1));
fflush(out);
read_again = 1;
break;

@@ -1549,10 +1471,10 @@ static void _sedb_waiting_kbd(se_dump_stack*ds, se_position position) {

/* -------------------- Show GC info */
case 'g':
strcpy(sedb_last_command,line);
sedb_show_gc_info();
read_again = 1;
break;
strcpy(sedb_last_command,line);
sedb_show_gc_info();
read_again = 1;
break;

/* -------------------- Continue to the next breakpoint */
case 'c':
@@ -1766,7 +1688,7 @@ static void* sedb_find_name(se_dump_stack* ds, char* name, int* type, int* expan
i++;
}
i++;
/* se_introspecT[id] cannot be NULL because Current's type is always known */
/* se_introspecT[id] cannot be NULL because Current's type is always known */
result = se_introspecT[id](ds->current, name, type, expanded);
if (*type == -1) {
result = NULL;
@@ -1806,7 +1728,7 @@ static void* sedb_find_name(se_dump_stack* ds, char* name, int* type, int* expan
if (result == NULL) {
sedb_message("There is a bug in SmartEiffel (sorry): no result available in that frame\n");
found = 0;
*type = -1;
*type = -1;
}
else if (*(T0**)result != NULL) {
*type = (*(T0**)result)->id;
@@ -1847,25 +1769,25 @@ static void _sedb_eval(se_dump_stack*ds, char* expr, int eval_again) {
sedb_message("Adding missing leading dot.\n");
}
else {
while ((expr[0] == '.')&&(expr[1] == '.')) { /* go "up" */
if (len == 0) {
sedb_message("Too many 'up'. Extra ones ignored.\n");
while (expr[0] == '.') expr++;
break;
}
while ((len>0) && (sedb_eval_expression[--len] != '.'));
while ((expr[0] == '.')&&(expr[1] == '.')) { /* go "up" */
if (len == 0) {
sedb_message("Too many 'up'. Extra ones ignored.\n");
while (expr[0] == '.') expr++;
break;
}
while ((len>0) && (sedb_eval_expression[--len] != '.'));
sedb_eval_expression[len] = '\0';
expr += 2;
}
if (expr[0] == '.') expr++;
expr += 2;
}
if (expr[0] == '.') expr++;
}
if ((expr[0] != '\0') && (len > 0)){
sedb_eval_expression[len++] = '.';
sedb_eval_expression[len] = '\0';
sedb_eval_expression[len++] = '.';
sedb_eval_expression[len] = '\0';
}
if (len + strlen(expr) + 1 > SEDB_BUFMAX) {
sedb_message("The line is too long; it will be truncated.\n");
expr[SEDB_BUFMAX - len - 1] = '\0';
sedb_message("The line is too long; it will be truncated.\n");
expr[SEDB_BUFMAX - len - 1] = '\0';
}
sprintf(evalexp, "%s%s", sedb_eval_expression, expr);
}
@@ -1915,26 +1837,26 @@ static void _sedb_eval(se_dump_stack*ds, char* expr, int eval_again) {
}

if (*(T0**)obj == NULL) {
sedb_message("%s.%s is Void.\n", keep, attrib);
obj = NULL;
sedb_message("%s.%s is Void.\n", keep, attrib);
obj = NULL;
} else if (se_introspecT[id] == NULL) {
sedb_message("No known introspection function for id %d (%s.%s)\n", id, keep, attrib);
obj = NULL;
id = -1;
sedb_message("No known introspection function for id %d (%s.%s)\n", id, keep, attrib);
obj = NULL;
id = -1;
} else {
obj = se_introspecT[id](obj, attrib, &id, &exp);
if (!exp && se_introspecT[id] == NULL) {
/* find the correct id (the found id is a class not at run time; find the correct heir id) */
if (obj == NULL) {
sedb_message("There is a bug in SmartEiffel (sorry): no object available in %s.%s\n", keep, attrib);
id = -1;
}
else if (*(T0**)obj != NULL) {
id = (*(T0**)obj)->id;
} else {
id = -1;
}
}
obj = se_introspecT[id](obj, attrib, &id, &exp);
if (!exp && se_introspecT[id] == NULL) {
/* find the correct id (the found id is a class not at run time; find the correct heir id) */
if (obj == NULL) {
sedb_message("There is a bug in SmartEiffel (sorry): no object available in %s.%s\n", keep, attrib);
id = -1;
}
else if (*(T0**)obj != NULL) {
id = (*(T0**)obj)->id;
} else {
id = -1;
}
}
}
}
}