#include #include #include #include "nontermutils.h" /* nodecount holds the number of node accesses in this run of the program */ long nodecount; /* This function searches for the root of the ART graph. The function * scans through the file linearly, looking for an ExpConstDef node * which points to an Atom called 'main'. This is (sort of) the root of * the graph. It's good enough, anyway */ FileOffset getRootNode( void ) { FileOffset curr, root, atom; int err; char tag; Ident *atomvariable; q_position = 0x10; fseek(HatFileSeq,q_position,SEEK_SET); root = 0x00; while (root == 0x00) { nodecount++; curr = q_position; err = q_fread(&tag,sizeof(unsigned char),1,HatFileSeq); if (tag == ExpConstDef) { q_readFO(); // throw away the parent q_readFO(); // throw away the result atom = q_readFO(); atomvariable = readAtomAt(atom); if ( strcmp( atomvariable->idname, "main") == 0 ) { root = curr; } free(atomvariable); } q_skipNode(tag); } return root; } /* take a FileOffset pointing to a node and get the node that * immediately follows it in the ART file. This uses q_skipNode, which * is a Hat function that skips a filenode, but which requires a tag * giving the node type. The nextFileNode function mainly just gets that * tag. */ FileOffset nextFileNode( FileOffset fo ) { int err; char tag; if ( q_position != fo ) { q_position = fo; fseek(HatFileSeq,q_position,SEEK_SET); } err = q_fread(&tag,sizeof(unsigned char),1,HatFileSeq); q_skipNode(tag); if (q_position <= filesize ) { return q_position; } else { return 0; } } /* get the pointer to an Expression Application's function. This just * involves using readFO to pull out the correct pointer. */ FileOffset getFuncPtr( FileOffset fo ) { char *id, c; FileOffset ptr = 0; freadAt(fo,&c,sizeof(char),1,HatFileRandom); //fprintf(stderr, "considering 1st expression at %x\n", fo); switch (lower5(c)) { case ExpApp: if (hasSrcPos(c)) { readFO(); } readFO(); /* skip parent */ readFO(); /* skip result */ fo = readFO(); /* value app */ freadAt(fo,&c,sizeof(char),1,HatFileRandom); //fprintf(stderr, "considering 2nd expression at %x\n", fo); readFO(); /* skip srcref */ readFO(); /* skip parent */ ptr = readFO(); /* function ptr */ break; default: fprintf(stderr, "%s: expected Expression Application at 0x%x\n", progname,fo); exit(1); } //fprintf(stderr, "pointer: %x\n", ptr); return ptr; } /* take a FileOffset pointing to a function atom and get its name */ char * getFuncNm( FileOffset fo ) { char *name; Ident *func; func = readAtomAt(fo); name = func->idname; free(func); return(name); } /* take a FileOffset pointing to a function atom and get the module name */ char * getFuncMod(FileOffset fo) { char *mod; Ident *func; func = readAtomAt(fo); mod = func->modname; free(func); return(mod); } /* initialise the counter variable for the number of accesses to the ART * nodes */ void initialiseCount(void) { nodecount = 0; } /* increment the node-access count by the value of the argument */ void incCount(long x) { nodecount = nodecount + x; } /* get the node-access count */ long getCount(void) { return nodecount; } /* This is a modified version of the Hat function getExpArg. The * original function takes a filenode, and gets the value of a * particular agument. However, it also followed some of the argument * pointers, specifically the pointers for Expression Applications. This * had some odd results for black-hat, so I've stopped it following most * pointers. The getResultRestricted function takes the place of * getResult, and only follows a small number of pointer-types. */ FileOffset getImmediateExpArg (FileOffset fo, int n) { char c; int i=0; FileOffset ptr; nodecount++; //fprintf(stderr,"getExpArg 0x%x\n",fo); freadAt(fo,&c,sizeof(char),1,HatFileRandom); switch (lower5(c)) { case ExpApp: if (hasSrcPos(c)) { readFO(); } /* skip usage position */ readFO(); /* skip parent */ readFO(); /* skip result */ ptr = readFO(); /* fun/constructor */ if (n==0) return getResultRestricted(ptr); fread(&c,sizeof(char),1,HatFileRandom); /* get arity */ if (n<=c) { for (i=1; i