@global dump_defined; /** dump.cqct provides code for printing out namespaces and the values associated with typed pointers. */ if (dump_defined == nil) { @local foo; @global printtype, dumpns, objectStr; dump_defined = 1; /** Prints the type t in a way parsable in a .names file. */ @define printtype(t){ @local i, fld, flds, sz, off; if(issu(t)){ printf("%s %s {\n", suekind(t), suetag(t)); flds = fields(t); for(i = 0; i < length(flds); i++){ @local ft,id; fld = vecref(flds, i); off = fieldoff(fld); ft = fieldtype(fld); id = fieldid(fld); if(isnil(off)){ printf("\t"); printf("\t%t;\n", fld); }else if(isbitfield(ft)){ printf("\t@@(8*0x%x+0x%x)", off, bitfieldpos(ft)); printf("\t%t %s : %d;\n", bitfieldcontainer(ft), id, bitfieldwidth(ft)); }else{ printf("\t@0x%x", off); printf("\t%t;\n", fld); } } sz = susize(t); if(!isnil(sz)) printf("\t@0x%x;\n", sz); printf("};\n"); }else if(istypedef(t)) printf("typedef %t %s;\n", typedeftype(t), typedefid(t)); else if(isenum(t)){ @local ens,en; printf("%s %s {\n", suekind(t), suetag(t)); ens = enumconsts(t); for(i = 0; i < length(ens); i++){ en = vecref(ens, i); printf("\t%s = %d,\n", vecref(en, 0), vecref(en, 1)); } printf("};\n"); }else printf("%t;\n", t); }; /** print a namespace in .names file format. */ @define dumpns(dn){ @local ns, vec,i; if(isdom(dn)) ns = dn.ns; else ns = dn; vec = copy(tabvals(ns.enumtype())); sort(vec,@lambda(x,y) { return strcmp(sprintfa("%t",x),sprintfa("%t",y)); }); //possibly wasteful, but makes the output cleaner. for(i = 0; i < length(vec); i++) { if (isbase(vecref(vec,i))) continue; if (isptr(vecref(vec,i))) continue; printtype(vecref(vec, i)); } vec = copy(tabvals(ns.enumsym())); sort(vec,@lambda(x,y) { return strcmp(sprintfa("%s",symid(x)),sprintfa("%s",symid(y))); }); //possibly wasteful, but makes the output cleaner. for(i = 0; i < length(vec); i++) if(!isenumconst(symtype(vecref(vec, i)))) printf("%t;\n", vecref(vec, i)); } /** Function for testing. */ @define foo(){ @local ns, fn, vec, i; ns = @names c32le { typedef struct foo foo_t; enum et { a = 1, b = 2, c = 3, }; struct abc { int x; @0x4; }; struct foo { @0x00 int x; @0x04 int y; @0x08 int z; @0x0c int *xp; @0x10 int (*foo)(); @0x14 int (*bar)(void); @0x18 int (*baz)(int p1); @0x20 int (*baz)(int p1, struct foo *p2); @0x24 char *a[10]; @0x30 struct blah { @0x0 int x; @@35 int y : 4; @0x8; } blahvar; @0x34 foo_t *ptrtofoo; @0x28; }; struct bar { @0x0 int x, y; @0x8; }; struct foo a; @0x100 struct t2 { int x; @0x4; } x; @0x100 struct t2 { int x, y; @0x8; } x; @0x100 struct t2 { int z; @0x4; } x; }; fn = ns.enumtype(); vec = tabvals(fn(ns)); for(i = 0; i < length(vec); i++) printtype(vecref(vec, i)); }; /** * returns a string representation of the object pointed to by x (including * its values in memory). * params: x is a pointer to an object * returns: a string representation of x and its content */ @define objectStr(argv ...) { @local p, t, indent; if (length(argv) == 0) fault(); p = argv[0]; //indent is the amount to indent all except the first line if (length(argv) > 1) indent = argv[1]; else indent = ""; t = @typeof(p); if (isptr(t)) { @local t2; t2 = subtype(t); while(istypedef(t2)) t2 = typedeftype(t2); if (isvoid(t2)) return "VOID"; //check if it is an unspecified array before checking if it is mapped. if (isarray(t2) && arraynelm(t2) == nil) ; //do nothing, no need to check if unspecified array is mapped else if (!ismapped(p)) return "UNMAPPED"; if (issu(t2)) { @local flds, i, nxt_indent, ret; if (strlen(indent)>70 ) return sprintfa("...",p); flds = fields(t2); if (isstruct(t2)) ret = "struct "; else if (isunion(t2)) ret = "union "; else ret = "aggregate "; ret += sprintfa("%s at 0x%x {", suetag(t2), p); for(i=0; i",p); } else if (isarray(t2)) { @local len, i, nxt_indent, ret; nxt_indent = indent+" "; len = arraynelm(t2); if (len == nil) return sprintfa("[] //unknown size"); ret = "["; for(i=0; i