#include #include // the function trace stack is a simple linked list of // pointers to function identifiers // the head of the list is the op of the stack struct TRACE_NODE_STRUCT { char* floc; // ptr to function identifier struct TRACE_NODE_STRUCT* next; // ptr to next frama }; typedef struct TRACE_NODE_STRUCT TRACE_NODE; static TRACE_NODE* TRACETop = NULL; // ptr to the top of the stack /* function PUSH_TRACE ---------------------------------------------- */ void PUSH_TRACE(char* p) // push p on the stack { TRACE_NODE* tnode; static char glob[]="global"; if (TRACETop==NULL) { // initialize the stack with "global" identifier TRACETop=(TRACE_NODE*) malloc(sizeof(TRACE_NODE)); // no recovery needed if allocation failed, this is only // used in debugging, not in production if (TRACETop==NULL) { printf("PUSH_TRACE: memory allocation error\n"); exit(1); } TRACETop->floc = glob; TRACETop->next=NULL; } // now create the node for p tnode = (TRACE_NODE*) malloc(sizeof(TRACE_NODE)); // no recovery needed if allocation failed, this is only // used in debugging, not in production if (tnode==NULL) { printf("PUSH_TRACE: memory allocation error\n"); exit(1); } tnode->floc=p; tnode->next = TRACETop; // insert fnode as the first in the list TRACETop=tnode; // point TRACETop to the first node }/*end PUSH_TRACE*/ /* function POP_TRACE ---------------------------------------------- */ void POP_TRACE() // remove the op of the stack { TRACE_NODE* tnode; tnode = TRACETop; TRACETop = tnode->next; free(tnode); }/*end POP_TRACE*/ /* report `depth' top entries from the stack in the form fun1:fun2:fun3:....:funk meaning fun1 called from fun2 that was called from fun3 ... that was called from funk where k = depth The calling path may be up to 100 characters, if longer it is truncated */ /* function REPORT_TRACE ---------------------------------------------- */ char* REPORT_TRACE(int depth) { int i, length, j; TRACE_NODE* tnode; static char buf[100]; if (TRACETop==NULL) { // stack not initialized yet, so we are strcpy(buf,"global"); // still in the `global' area return buf; } /* peek at the depth top entries on the stactk, but do not go over 100 chars and do not go over the bottom of the stack */ sprintf(buf,"%s",TRACETop->floc); length = strlen(buf); // length of the string so far for(i=1, tnode=TRACETop->next; tnode!=NULL && i < depth; i++,tnode=tnode->next) { j = strlen(tnode->floc); // length of what we want to add if (length+j+1 < 100) { // total length is ok sprintf(buf+length,":%s",tnode->floc); length += j+1; }else // it would be too long break; } return buf; }