4 static char *fmt
, *fp
, *fmtend
; /* format string, current & limit pointer */
5 static Tree args
; /* printf arguments */
6 static Symbol frameno
; /* local holding frame number */
8 /* appendstr - append str to the evolving format string, expanding it if necessary */
9 static void appendstr(char *str
) {
13 char *s
= allocate(2*(fmtend
- fmt
), FUNC
);
14 strncpy(s
, fmt
, fmtend
- fmt
);
15 fp
= s
+ (fmtend
- fmt
);
16 fmtend
= s
+ 2*(fmtend
- fmt
);
19 fp
= fmt
= allocate(80, FUNC
);
23 while ((*fp
++ = *str
++) != 0);
27 /* tracevalue - append format and argument to print the value of e */
28 static void tracevalue(Tree e
, int lev
) {
29 Type ty
= unqual(e
->type
);
33 if (ty
== chartype
|| ty
== signedchar
)
34 appendstr("'\\x%02x'");
35 else if (ty
== longtype
)
41 if (ty
== chartype
|| ty
== unsignedchar
)
42 appendstr("'\\x%02x'");
43 else if (ty
== unsignedlong
)
55 if (unqual(ty
->type
) == chartype
56 || unqual(ty
->type
) == signedchar
57 || unqual(ty
->type
) == unsignedchar
) {
60 null
= mkstr("(null)");
61 tracevalue(cast(e
, unsignedtype
), lev
+ 1);
62 appendstr(" \"%.30s\"");
63 e
= condtree(e
, e
, pointer(idtree(null
->u
.c
.loc
)));
65 appendstr("("); appendstr(typestring(ty
, "")); appendstr(")0x%x");
70 appendstr("("); appendstr(typestring(ty
, "")); appendstr("){");
71 for (q
= ty
->u
.sym
->u
.s
.flist
; q
; q
= q
->link
) {
72 appendstr(q
->name
); appendstr("=");
73 tracevalue(field(addrof(e
), q
->name
), lev
+ 1);
81 appendstr("("); appendstr(typestring(ty
, "")); appendstr("){...}");
84 if (lev
&& ty
->type
->size
> 0) {
88 for (i
= 0; i
< ty
->size
/ty
->type
->size
; i
++) {
89 Tree p
= (*optree
['+'])(ADD
, e
, consttree(i
, inttype
));
90 if (isptr(p
->type
) && isarray(p
->type
->type
))
91 p
= retype(p
, p
->type
->type
);
96 tracevalue(p
, lev
+ 1);
100 appendstr(typestring(ty
, ""));
105 e
= cast(e
, promote(ty
));
106 args
= tree(mkop(ARG
,e
->type
), e
->type
, e
, args
);
109 /* tracefinis - complete & generate the trace call to print */
110 static void tracefinis(Symbol printer
) {
115 p
= mkstr(string(fmt
));
116 for (ap
= &args
; *ap
; ap
= &(*ap
)->kids
[1])
118 *ap
= tree(ARG
+P
, charptype
, pointer(idtree(p
->u
.c
.loc
)), 0);
119 walk(calltree(pointer(idtree(printer
)), freturn(printer
->type
), args
, NULL
), 0, 0);
124 /* tracecall - generate code to trace entry to f */
125 static void tracecall(Symbol printer
, Symbol f
) {
127 Symbol counter
= genident(STATIC
, inttype
, GLOBAL
);
129 defglobal(counter
, BSS
);
130 (*IR
->space
)(counter
->type
->size
);
131 frameno
= genident(AUTO
, inttype
, level
);
133 appendstr(f
->name
); appendstr("#");
134 tracevalue(asgn(frameno
, incr(INCR
, idtree(counter
), consttree(1, inttype
))), 0);
136 for (i
= 0; f
->u
.f
.callee
[i
]; i
++) {
139 appendstr(f
->u
.f
.callee
[i
]->name
); appendstr("=");
140 tracevalue(idtree(f
->u
.f
.callee
[i
]), 0);
142 if (variadic(f
->type
))
144 appendstr(") called\n");
148 /* tracereturn - generate code to trace return e */
149 static void tracereturn(Symbol printer
, Symbol f
, Tree e
) {
150 appendstr(f
->name
); appendstr("#");
151 tracevalue(idtree(frameno
), 0);
152 appendstr(" returned");
153 if (freturn(f
->type
) != voidtype
&& e
) {
161 /* trace_init - initialize for tracing */
162 void trace_init(int argc
, char *argv
[]) {
169 type_init(argc
, argv
);
171 for (i
= 1; i
< argc
; i
++)
172 if (strncmp(argv
[i
], "-t", 2) == 0 && strchr(argv
[i
], '=') == NULL
) {
173 Symbol printer
= mksymbol(EXTERN
,
174 argv
[i
][2] ? &argv
[i
][2] : "printf",
175 ftype(inttype
, ptr(qual(CONST
, chartype
))));
176 printer
->defined
= 0;
177 attach((Apply
)tracecall
, printer
, &events
.entry
);
178 attach((Apply
)tracereturn
, printer
, &events
.returns
);