#include <smop/base.h>
#include <smop/s0native.h>
#include <smop/dump.h>
#include <stdlib.h>
#include <stdio.h>
SMOP__ResponderInterface* SMOP__DUMP_RI;
SMOP__ResponderInterface* SMOP__DUMP_int_RI;
SMOP__ResponderInterface* SMOP__DUMP_obj_RI;
SMOP__ResponderInterface* SMOP__DUMP_obj_array_RI;
SMOP__Object* smop_bool_dump(SMOP__Object* interpreter,
SMOP__ResponderInterface* responder,
SMOP__Object* obj) {
return
smop_dump_create((SMOP__Object*[]) {
smop_dump_attr_create(
"RI"
),
smop_dump_obj_create((SMOP__Object*)obj->RI),
smop_dump_attr_create(
"value"
),
smop_dump_int_create(obj == SMOP__NATIVE__bool_true),
NULL
});
}
SMOP__Object* smop_idconst_dump(SMOP__Object* interpreter,
SMOP__ResponderInterface* responder,
SMOP__Object* obj) {
int
len;
char
* str = SMOP__NATIVE__idconst_fetch_with_null(obj,&len);
return
smop_dump_create((SMOP__Object*[]) {
smop_dump_attr_create(
"RI"
),
smop_dump_obj_create((SMOP__Object*)obj->RI),
smop_dump_attr_create(
"content"
),
smop_dump_str_create(str),
NULL
});
free
(str);
}
void
smop_dump_init() {
SMOP__DUMP_RI =
calloc
(1,
sizeof
(SMOP__ResponderInterface));
SMOP__DUMP_RI->MESSAGE = smop_placeholder_message;
SMOP__DUMP_RI->REFERENCE = smop_noop_reference;
SMOP__DUMP_RI->RELEASE = smop_noop_release;
SMOP__DUMP_RI->WEAKREF = smop_noop_weakref;
SMOP__DUMP_RI->id =
"result of DUMP"
;
SMOP__DUMP_RI->RI = (SMOP__ResponderInterface *)SMOP__metaRI;
SMOP__DUMP_int_RI =
calloc
(1,
sizeof
(SMOP__ResponderInterface));
SMOP__DUMP_int_RI->MESSAGE = smop_placeholder_message;
SMOP__DUMP_int_RI->REFERENCE = smop_noop_reference;
SMOP__DUMP_int_RI->RELEASE = smop_noop_release;
SMOP__DUMP_int_RI->WEAKREF = smop_noop_weakref;
SMOP__DUMP_int_RI->id =
"DUMP int"
;
SMOP__DUMP_int_RI->RI = (SMOP__ResponderInterface *)SMOP__metaRI;
SMOP__DUMP_obj_RI =
calloc
(1,
sizeof
(SMOP__ResponderInterface));
SMOP__DUMP_obj_RI->MESSAGE = smop_placeholder_message;
SMOP__DUMP_obj_RI->REFERENCE = smop_noop_reference;
SMOP__DUMP_obj_RI->RELEASE = smop_noop_release;
SMOP__DUMP_obj_RI->WEAKREF = smop_noop_weakref;
SMOP__DUMP_obj_RI->id =
"DUMP obj"
;
SMOP__DUMP_obj_RI->RI = (SMOP__ResponderInterface *)SMOP__metaRI;
SMOP__DUMP_obj_array_RI =
calloc
(1,
sizeof
(SMOP__ResponderInterface));
SMOP__DUMP_obj_array_RI->MESSAGE = smop_placeholder_message;
SMOP__DUMP_obj_array_RI->REFERENCE = smop_noop_reference;
SMOP__DUMP_obj_array_RI->RELEASE = smop_noop_release;
SMOP__DUMP_obj_array_RI->WEAKREF = smop_noop_weakref;
SMOP__DUMP_obj_array_RI->id =
"DUMP obj array"
;
SMOP__DUMP_obj_array_RI->RI = (SMOP__ResponderInterface *)SMOP__metaRI;
SMOP__metaRI->RI->DUMP = smop_ri_dump;
SMOP__NATIVE__bool_true->RI->DUMP = smop_bool_dump;
SMOP__NATIVE__idconst_RI->DUMP = smop_idconst_dump;
}
SMOP__Object* smop_ri_dump(SMOP__Object* interpreter,
SMOP__ResponderInterface* responder,
SMOP__Object* obj) {
SMOP__ResponderInterface* ri = (SMOP__ResponderInterface*) obj;
return
smop_dump_create((SMOP__Object*[]) {
smop_dump_attr_create(
"RI"
),
smop_dump_obj_create((SMOP__Object*)ri->RI),
smop_dump_attr_create(
"id"
),
smop_dump_str_create(ri->id),
NULL
});
}
SMOP__Object* smop_dump_create(SMOP__Object** data) {
int
size = 0;
SMOP__Object** d = data;
while
(*d != NULL) {
d++;
size++;
}
smop_dump* dump = (smop_dump*)
malloc
(
sizeof
(smop_dump));
dump->size = size;
dump->data = (SMOP__Object**)
malloc
(
sizeof
(SMOP__Object*) * (size));
dump->RI = SMOP__DUMP_RI;
int
i;
for
(i=0;i<size;i++) {
dump->data[i] = data[i];
}
return
(SMOP__Object*) dump;
}
SMOP__Object* smop_dump_obj_array_create(SMOP__Object** data,
int
size) {
smop_dump_obj_array* array = (smop_dump_obj_array*)
malloc
(
sizeof
(smop_dump_obj_array));
array->size = size;
array->data = (SMOP__Object**)
malloc
(
sizeof
(SMOP__Object*) * (size));
array->RI = SMOP__DUMP_obj_array_RI;
int
i;
for
(i=0;i<size;i++) {
array->data[i] = data[i];
}
return
(SMOP__Object*) array;
}
SMOP__Object* smop_dump_int_create(
int
value) {
smop_dump_int* obj =
malloc
(
sizeof
(smop_dump_int));
obj->value = value;
obj->RI = SMOP__DUMP_int_RI;
return
(SMOP__Object*) obj;
}
SMOP__Object* smop_dump_obj_create(SMOP__Object* value) {
smop_dump_obj* obj =
malloc
(
sizeof
(smop_dump_obj));
obj->value = value;
obj->RI = SMOP__DUMP_obj_RI;
return
(SMOP__Object*) obj;
}
SMOP__Object* smop_dump_str_create(
char
* value) {
return
SMOP__NATIVE__idconst_create(value);
}
SMOP__Object* smop_dump_attr_create(
char
* value) {
return
SMOP__NATIVE__idconst_create(value);
}
void
smop_dump_destr() {
free
(SMOP__DUMP_RI);
free
(SMOP__DUMP_int_RI);
}
typedef
struct
list {
struct
list* next;
SMOP__Object* value;
} list;
static
list* list_add(list* l,SMOP__Object* value) {
list* new_node =
malloc
(
sizeof
(list));
new_node->value = value;
new_node->next = l;
return
new_node;
}
static
int
in_list(list* l,SMOP__Object* value) {
while
(l) {
if
(l->value == value)
return
1;
l = l->next;
}
return
0;
}
static
void
list_destroy(list* l) {
while
(l) {
list* old = l;
l = l->next;
free
(old);
}
}
static
int
dump_id;
void
smop_dump_print(SMOP__Object* interpreter,SMOP__Object* obj,
char
* file_template) {
char
file[200];
snprintf(file,200,file_template,dump_id);
dump_id++;
printf
(
"dumping to %s\n"
,file);
FILE
* f =
fopen
(file,
"w"
);
if
(!f) {
perror
(
"can't dump the object:"
);
}
fprintf
(f,
"dump of %p\n"
,obj);
list* visited = NULL;
list* to_visit = list_add(NULL,obj);
SMOP__ResponderInterface* idconst_ri = SMOP__NATIVE__idconst_create(
"example"
)->RI;
while
(to_visit) {
list* current = to_visit;
to_visit = to_visit->next;
if
(!current->value) {
printf
(
"DUMPing a null\n"
);
exit
(0);
}
else
if
(!current->value->RI) {
printf
(
"value has no RI\n"
);
exit
(0);
}
else
if
(!current->value->RI->DUMP) {
printf
(
"no DUMP for %s\n"
,current->value->RI->id);
exit
(0);
}
smop_dump* dump = (smop_dump*) SMOP_DUMP(interpreter,current->value);
current->next = visited;
visited = current;
fprintf
(f,
"dumping %p {\n"
,current->value);
int
i;
for
(i=0; i< dump->size;i++) {
fprintf
(f,
" "
);
if
(dump->data[i]->RI == SMOP__DUMP_int_RI) {
fprintf
(f,
"%d\n"
,((smop_dump_int*)dump->data[i])->value);
}
else
if
(dump->data[i]->RI == SMOP__DUMP_obj_RI) {
SMOP__Object* obj = ((smop_dump_obj*)dump->data[i])->value;
if
(obj && !in_list(visited,obj) && !in_list(to_visit,obj)) {
to_visit = list_add(to_visit,obj);
}
fprintf
(f,
"%p\n"
,obj);
}
else
if
(dump->data[i]->RI == idconst_ri) {
int
len;
char
* str = SMOP__NATIVE__idconst_fetch_with_null(dump->data[i],&len);
int
i;
fputc
(
'"'
,f);
for
(i=0;i < len;i++) {
if
(str[i] ==
'\n'
) {
fputc
(
'\\'
,f);
fputc
(
'n'
,f);
}
else
if
(str[i] ==
'"'
) {
fputc
(
'\\'
,f);
fputc
(
'"'
,f);
}
else
{
fputc
(str[i],f);
}
}
fputc
(
'"'
,f);
fputc
(
'\n'
,f);
free
(str);
}
else
if
(dump->data[i]->RI == SMOP__DUMP_obj_array_RI) {
smop_dump_obj_array* array = (smop_dump_obj_array*) dump->data[i];
fprintf
(f,
"[\n"
);
int
i;
for
(i=0; i< array->size;i++) {
fprintf
(f,
"%p\n"
,(
void
*)array->data[i]);
if
(array->data[i] && !in_list(visited,array->data[i]) && !in_list(to_visit,array->data[i])) {
to_visit = list_add(to_visit,array->data[i]);
}
}
fprintf
(f,
"]\n"
);
}
else
{
fprintf
(f,
"unknown %s\n"
,dump->data[i]->RI->id);
}
}
fprintf
(f,
"}\n"
);
}
fclose
(f);
list_destroy(visited);
}