Exemple #1
0
int getOccurence(char* funcName){
	//printf("getOccurence\n");
	if(symStack == NULL){
		return 0;
	}
	void* backup = stackNew(sizeof(funcVars*));
	int occ = 0;
	while(!(stackIsEmpty(symStack))){
		funcVars* pk = (funcVars*) malloc (sizeof(funcVars));
		stackPeek(symStack, &pk);
		if(strcmp(pk->funcName,funcName) == 0){
			occ = pk->occurence;
			break;			
		}
		else{
			stackPop(symStack, (&pk));
			stackPush(backup, (&pk));
		}
	}
	while(!(stackIsEmpty(backup))){
		funcVars* b = (funcVars*) malloc (sizeof(funcVars));
		stackPop(backup, (&b));
		stackPush(symStack, (&b));
	}
	return occ;
}
Exemple #2
0
void test_stackPush_given_5numbeer_push_to_stack_should_throw_exception(void)

{

 unsigned int err;

 stackNew(4);



 { jmp_buf *PrevFrame, NewFrame; unsigned int MY_ID = (0); PrevFrame = CExceptionFrames[(0)].pFrame; CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); CExceptionFrames[MY_ID].Exception = (0x5A5A5A5A); if (_setjmp(NewFrame) == 0) { if (&PrevFrame)

 { stackPush(&stack , 1);

  stackPush(&stack , 2);

  stackPush(&stack , 3);

  stackPush(&stack , 4);

  stackPush(&stack , 5);

      UnityFail( ("Should throw error exception"), (_U_UINT)56);;

 }

 else { } CExceptionFrames[MY_ID].Exception = (0x5A5A5A5A); } else { err = CExceptionFrames[MY_ID].Exception; err=err; } CExceptionFrames[MY_ID].pFrame = PrevFrame; } if (CExceptionFrames[(0)].Exception != (0x5A5A5A5A)) {

     UnityAssertEqualNumber((_U_SINT)((ERR_STACK_FULL)), (_U_SINT)((err)), ("Expected ERR_STACK_FULL exception"), (_U_UINT)59, UNITY_DISPLAY_STYLE_INT);

    }

}
Exemple #3
0
void test_stackPush_given_3number_push_to_stack_should_alocate(void)

{

 stackNew(4);

 stackPush(&stack , 1);

 stackPush(&stack , 2);

 stackPush(&stack , 3);





 UnityAssertEqualNumber((_U_SINT)((1)), (_U_SINT)((buffer[0])), (((void *)0)), (_U_UINT)38, UNITY_DISPLAY_STYLE_INT);

 UnityAssertEqualNumber((_U_SINT)((2)), (_U_SINT)((buffer[1])), (((void *)0)), (_U_UINT)39, UNITY_DISPLAY_STYLE_INT);

 UnityAssertEqualNumber((_U_SINT)((3)), (_U_SINT)((buffer[2])), (((void *)0)), (_U_UINT)40, UNITY_DISPLAY_STYLE_INT);

 UnityAssertEqualNumber((_U_SINT)((3)), (_U_SINT)((stack.size)), (((void *)0)), (_U_UINT)41, UNITY_DISPLAY_STYLE_INT);

 UnityAssertEqualNumber((_U_SINT)((4)), (_U_SINT)((stack.length)), (((void *)0)), (_U_UINT)42, UNITY_DISPLAY_STYLE_INT);

}
char *reverseString(char *stringToReverse){

	int i , j = 0;
	char *reversedString , ch;
	
	Stack *stack = stackNew(512);
	
	printf("stack:%p\n", stack);
	printf("size:%d, length:%d\n", stack->size , stack->length);
	
	for(i = 0; stringToReverse[i] != '\0' ; i++)
	{
		stackPush(stack, (int)stringToReverse[i]);
		printf("%c",stringToReverse[i]);
	}
	
	printf("\n");
	reversedString = malloc(sizeof(char) * (i + 1) );
	
	while(!stackisEmpty(stack)) 
	{
		reversedString[j++] = stackPop(stack);
		printf("%c", reversedString[j-1]);
	}
	reversedString[j] = '\0';
	
	return reversedString;
}
Exemple #5
0
int evaluate(char *expression,Stack *dataStack,Stack *operatorStack){
	
	Tokenizer *tokenizer;
	Token *token;
	Token *ansToken;
	ErrorCode e;
	int i;
	int counter =0;
	NumberToken *result;
	
	dataStack=stackNew();
	operatorStack=stackNew();
	tokenizer = tokenizerNew(expression);
	if(expression ==NULL){	
		Throw(ERR_NO_EXPRESSION);
	}
	
	while((token=nextToken(tokenizer))!=NULL){
		if(counter%2==0&&token->type==OPERATOR_TOKEN){
			Throw(ERR_NOT_DATA);
		}
		else if(counter%2==1&&token->type==NUMBER_TOKEN){
			Throw(ERR_NOT_OPERATOR);
		}
		
		if(isNumber(token)){
			
			push(token,dataStack);
		}
		else if(isOperator(token)) 
		{
			tryEvaluateOperatorOnStackThenPush((OperatorToken*)token,dataStack,operatorStack);
		}
		
		counter ++;
	}
	evaluateAllOperatorOnStack(dataStack,operatorStack);
	result=(NumberToken*)pop(dataStack);
	printf("counter needed for each expression : %d \n",counter);
	return result->value;
}
CDGNode *pathToList(CDGNode * head) {
  assert(NULL != head);
  Stack *nodeStack = stackNew(sizeof(CDGNode *));
  CDGNode *node;
  CDGNode *list = NULL;
  postOrder(head, nodeStack);
  while (!stackIsEmpty(nodeStack)) {
    stackPop(nodeStack, &node);
    list = setNextNode(copyToPathNode(newBlankNode(), node), list);
  }
  return list;
}
void deleteCDG(CDGNode * root) {
  if (NULL == root)
    return;
  CDGNode *node;
  Stack *nodeStack = stackNew(sizeof(CDGNode *));
  postOrder(root, nodeStack);
  while (!stackIsEmpty(nodeStack)) {
    stackPop(nodeStack, &node);
    deleteNode(node);
  }
  stackFree(nodeStack);
}
void coverNodes(CDGNode * root, CDGNode * nodes[], int size) {
  assert(NULL != root);
  if (0 == size)
    return;
  Stack *nodeStack = stackNew(sizeof(CDGNode *));
  CDGNode *node;
  postOrder(root, nodeStack);
  while (!stackIsEmpty(nodeStack)) {
    stackPop(nodeStack, &node);
    visitIfExists(node, nodes, size);
  }
  updateCDG(root, 0);
  return;
}
CDGNode *updateCDG(CDGNode * root, int initialize) {
  int size = sizeof(CDGNode *);

  assert(NULL != root);
  Stack *nodeStack = stackNew(size);
  CDGNode *node;
  postOrder(root, nodeStack);
  while (!stackIsEmpty(nodeStack)) {
    stackPop(nodeStack, &node);
    updateScore(node, initialize);
  }
  stackFree(nodeStack);
  return root;
}
Exemple #10
0
void test_stackPop_given_6_should_pop_6(void)

{

 stackNew(4);

 stackPush(&stack , 6);



 UnityAssertEqualNumber((_U_SINT)((6)), (_U_SINT)((stackPop(&stack))), (((void *)0)), (_U_UINT)68, UNITY_DISPLAY_STYLE_INT);

 UnityAssertEqualNumber((_U_SINT)((0)), (_U_SINT)((stack.size)), (((void *)0)), (_U_UINT)69, UNITY_DISPLAY_STYLE_INT);

}
Exemple #11
0
void test_stackPop_given_3number_but_pop_4times_should_throw_exception(void)

{

 unsigned int err;



 stackNew(4);



 stackPush(&stack , 1);

 stackPush(&stack , 2);

 stackPush(&stack , 3);





 { jmp_buf *PrevFrame, NewFrame; unsigned int MY_ID = (0); PrevFrame = CExceptionFrames[(0)].pFrame; CExceptionFrames[MY_ID].pFrame = (jmp_buf*)(&NewFrame); CExceptionFrames[MY_ID].Exception = (0x5A5A5A5A); if (_setjmp(NewFrame) == 0) { if (&PrevFrame)

 {

  stackPop(&stack);

  stackPop(&stack);

  stackPop(&stack);

  stackPop(&stack);



  UnityFail( ("Should throw  exception"), (_U_UINT)91);;

 }

 else { } CExceptionFrames[MY_ID].Exception = (0x5A5A5A5A); } else { err = CExceptionFrames[MY_ID].Exception; err=err; } CExceptionFrames[MY_ID].pFrame = PrevFrame; } if (CExceptionFrames[(0)].Exception != (0x5A5A5A5A)){

    UnityAssertEqualNumber((_U_SINT)((ERR_STACK_EMPTY)), (_U_SINT)((err)), ("Expect ERR_STACK_EMPTY exception"), (_U_UINT)94, UNITY_DISPLAY_STYLE_INT);

     }

}
Exemple #12
0
void funcEntry(char* format, char* args, char* funcName) {
	printf("funcEntry: %s \"%s\" \n", funcName, args);
	int size=0;
	varNames = (char**) malloc(10 * sizeof(char*));
	char s[] = " ";
	char *token;
	char *copy = strdup(args);
	char* tmp = copy;
	int count = 1;
	while (*tmp != '\0') {
		if (*tmp++ == ' ')
			count++;
	}
	char** tokens = (char**) malloc(sizeof(char*) * count);
	token = strtok(copy, s);
	int i = 0;
	while (token != NULL) {
		*(tokens + i) = token;
		token = strtok(NULL, s);
		i++;
	}
	for (i = 0; i < count; i++) {
		funcArg *a = getArgument(*(tokens + i), funcName);
		varNames[size++] = a->vname;
		populateSTable(a);
	}

	funcVars* fv = (funcVars*) malloc (sizeof(funcVars));
	fv->vars = varNames;
	fv->noOfVars = size;
	strcpy(fv->funcName,funcName);
	fv->occurence = getOccurence(funcName)+1;

	if(stackInitFlag){
		stackPush(symStack, (&fv));
	}
	else{
		symStack = stackNew(sizeof(funcVars*));
		stackPush(symStack, (&fv));
		stackInitFlag=1;
	}
	size=0;
    	i=0;
	free(copy);
	printf("Stack depth %d\n", stackSize(symStack));
}
Exemple #13
0
void main()
{
    stack s;
    stackNew(&s);
    printf("LSize = %d\tASize = %d\n", s.LSize, s.ASize);
    int i;
    for( i = 0; i < 9; i++ )
    {
        stackPush(&s, i*i);
    }
    printf("LSize = %d\tASize = %d\n", s.LSize, s.ASize);
    for( i = 0; i < 7; i++ )
    {
        printf("Pop returns %d\n", stackPop(&s));
    }
    printf("LSize = %d\tASize = %d\n", s.LSize, s.ASize);
    stackDispose(&s);
}
void binaryTreeTravesalInOrder(Node *rootPtr){
	Stack *stackPtr = stackNew();
	Node *currentNode;
	currentNode = rootPtr;
	
	currentNode->state = ENTERED_NODE;
	
while(1){
	if(currentNode->state == ENTERED_NODE){
		if(currentNode->left != NULL){
			stackPush(stackPtr,currentNode);
			currentNode = currentNode->left;
			currentNode->state = ENTERED_NODE;
		}
		else
			currentNode->state = VISITED_LEFT_NODE;
	}
	if(currentNode->state == VISITED_LEFT_NODE){
		if(currentNode->right != NULL){
			display(currentNode->data);
			stackPush(stackPtr,currentNode);
			currentNode = currentNode->right;
			currentNode->state = ENTERED_NODE;
		}
		else{
			display(currentNode->data);
			currentNode->state = VISITED_RIGHT_NODE;
		}
	}
	if(currentNode->state == VISITED_RIGHT_NODE){
		currentNode = stackPop(stackPtr);
		
		if(currentNode == NULL)
			break;
		if(currentNode->state == ENTERED_NODE)
			currentNode->state = VISITED_LEFT_NODE;
		else if(currentNode->state == VISITED_LEFT_NODE)
			currentNode->state = VISITED_RIGHT_NODE;	
	}
}
	
	stackDel(stackPtr);
}
void postOrder(CDGNode * root, Stack * s) {
  if (NULL == root)
    return;
  Stack *temp = stackNew(sizeof(CDGNode *));;
  CDGNode *node;
  CDGNode *listNode;
  pushNodeListToStack(temp, root);
  while (!stackIsEmpty(temp)) {
    stackPop(temp, &node);
    if (getTrueNodeSet(node)) {
      pushNodeListToStack(temp, getTrueNodeSet(node));
    }
    if (getFalseNodeSet(node)) {
      pushNodeListToStack(temp, getFalseNodeSet(node));
    }
    stackPush(s, &node);
  }
  stackFree(temp);
}
//////////////////////////////////////////////////////////////////////////////////
/// Parse the fmu. The receiver must call freeElement(md) to release AST memory.
///
///\param xmlPath The xml file to be parsed
///\return the root node md of the AST if no error occurred. NULL to indicate failure
/////////////////////////////////////////////////////////////////////////////////
ModelDescription* parse(const char* xmlPath) {
  ModelDescription* md = NULL;
  FILE *file;
  int done = 0;

  stack = stackNew(100, 10); // Allocate stack memory	  
  if (checkPointer(stack)) return NULL;  // Check if the stack is creatted

  parser = XML_ParserCreate(NULL); // Create an parser
  if (checkPointer(parser)) return NULL;  // Check if the parser is created

  XML_SetElementHandler(parser, startElement, endElement); // Set handler for start and end tags
  XML_SetCharacterDataHandler(parser, handleData); // Set handler for text

	file = fopen(xmlPath, "rb");

	if (file == NULL) {
    printfError("Cannot open file '%s'\n", xmlPath);
    XML_ParserFree(parser); // Free the memory for parser
    return NULL; // Failure
  }

  while (!done) {
    int n = fread(text, sizeof(char), XMLBUFSIZE, file); // Read XMLBUFSIZE characters from file
    if (n != XMLBUFSIZE) done = 1; // Reach the end of file
    if (!XML_Parse(parser, text, n, done)){
      printf("Parse error in file %s at line %d:\n%s\n",
             xmlPath,
             (int)XML_GetCurrentLineNumber(parser),
              XML_ErrorString(XML_GetErrorCode(parser)));
      while (!stackIsEmpty(stack)) md = stackPop(stack);
      if (md) freeElement(md);
      cleanup(file);
      return NULL; // failure
    }
  }

  md = stackPop(stack);
  assert(stackIsEmpty(stack));
  cleanup(file);
  //printElement(1, md); // Print the element for debugging
  return md; // Success if all refs are valid    
}
table* findAllWords (_node** tree, char** grid)
{
    table* allWords = tableNew();

    int i;
    int j;
    for (i = 0; i < SIZE_MAX_GRID; ++i)
    {
        for (j = 0; j < SIZE_MAX_GRID; ++j)
        {
            if (DEBUG) tablePrint(allWords);
            position* p = malloc(sizeof(position));
            p->x = i;
            p->y = j;
            stack* s = stackNew();
            stackPush(s,p);
            looking (tree, grid, &(grid[i][j]), s, allWords);
        }
    }

}
Exemple #18
0
// Returns NULL to indicate failure
// Otherwise, return the root node md of the AST.
// The receiver must call freeElement(md) to release AST memory.
ModelDescription* parse(const char* xmlPath) {
    ModelDescription* md = NULL;
    FILE *file;
    int done = 0;
    stack = stackNew(100, 10);
    if (!checkPointer(stack)) return NULL;  // failure
    parser = XML_ParserCreate(NULL);
    if (!checkPointer(parser)) return NULL;  // failure
    XML_SetElementHandler(parser, startElement, endElement);
    XML_SetCharacterDataHandler(parser, handleData);
  	file = fopen(xmlPath, "rb");
	if (file == NULL) {
        fprintf(stderr,"Cannot open file '%s'\n", xmlPath);
     	XML_ParserFree(parser);
        return NULL; // failure
    }
    while (!done) {
        int n = fread(text, sizeof(char), XMLBUFSIZE, file);
	    if (n != XMLBUFSIZE) done = 1;
        if (!XML_Parse(parser, text, n, done)){
             fprintf(stderr,"Parse error in file %s at line %d:\n%s\n", 
                     xmlPath,
                         (int)XML_GetCurrentLineNumber(parser),
	                 XML_ErrorString(XML_GetErrorCode(parser)));
             while (! stackIsEmpty(stack)) md = stackPop(stack);
             if (md) freeElement(md);
             cleanup(file);
             return NULL; // failure
        }
    }
    md = stackPop(stack);
    assert(stackIsEmpty(stack));
    cleanup(file);
    //printElement(1, md); // debug
    return md; // success if all refs are valid    
}
CDGPath *getTopPaths(CDGContext * ctx, CDGNode * root, int numberOfPaths) {
  CDGPath *pathHead = NULL;
  CDGNode *path;
  CDGPath *currPath;
  CDGNode *node;
  int branch;
  Stack *changedNodes = stackNew(sizeof(CDGNode *));
  Stack *changedBranches = stackNew(sizeof(int));
  while (numberOfPaths--) {
    path = getTopPath(root, changedNodes, changedBranches);
    if (NULL == path)
      break;
    if (NULL == pathHead) {
      pathHead = setPathNode(newPath(), path);
      currPath = pathHead;
    } else {
      setNextPath(currPath, setPathNode(newPath(), path));
      currPath = getNextPath(currPath);
    }
    updateCDG(root, 0);
  }
  while (!stackIsEmpty(changedNodes) && !stackIsEmpty(changedBranches)) {
    stackPop(changedNodes, &node);
    stackPop(changedBranches, &branch);
    if (isLeaf(node)) {
      setScore(node, 1);
    } else {
      if (branch)
	setBranchInfo(getID(node), 0, getBranchInfo(getID(node), 0));
      else
	setBranchInfo(getID(node), getBranchInfo(getID(node), 1), 0);
    }

  }
  updateCDG(root, 0);
  stackFree(changedNodes);
  stackFree(changedBranches);

  /* Updating context */
  (*ctx).topPaths = pathHead;

  /* Ensuring atleast one path was found */
  if (NULL == pathHead)
    return NULL;

  /* Creating list of nodes from complicated path form */
  CDGPath *outPathHead = NULL;
  currPath = NULL;
  path = NULL;
  while (NULL != pathHead) {
    path = getPathNode(pathHead);
    if (NULL == outPathHead) {
      outPathHead = setPathNode(newPath(), pathToList(path));
      currPath = outPathHead;
    } else {
      setNextPath(currPath, setPathNode(newPath(), pathToList(path)));
      currPath = getNextPath(currPath);
    }
    pathHead = getNextPath(pathHead);
  }

  return outPathHead;
}
Exemple #20
0
void funcEntry(char* args, char* locals, char* funcName) {
    
    //to avoid entries in itables/ftables
    noInsertionInTables = 1;
    //...........................//
     
    printf("funcEntry: %s \"%s\" \n", funcName, args);
    int size=0,localSize = 0;
    currentOccurence = getOccurence(funcName);
    printf("entry occurence of %s : %d\n", funcName,currentOccurence);
	
    if(currentOccurence < 2){//bound on recursion

	//---------------------KEEP TRACK IF FuncEntry EXECUTED (Recursion Bound)	
        
        int* flag = (int *)malloc(sizeof(int));
        *flag = 1;

        if(stackInitFlag2){
            stackPush(didFuncEntryExecute, (&flag));
	}
	else{
	    didFuncEntryExecute = stackNew(sizeof(int*));
	    stackPush(didFuncEntryExecute, (&flag));
	    stackInitFlag2=1;
	}
	printf("Pushed \"%d\" in didFuncEntryExecute\n", 1);
	
	//---------------------HANDLE FORMALS OF "funcName"
	
	
	if(strcmp(args,"") != 0){ //handle functions with no arguments
	    char s[] = "#";
	    char *token2;
	    char *copy = strdup(args);
	    char* tmp = copy;
	    int count = 1;
	    while (*tmp != '\0') {
		if (*tmp++ == '#')
		    count++;
	    }
	    varNames = (char**) malloc(count * sizeof(char*));
	    char** tokens = (char**) malloc(sizeof(char*) * count);
	    token2 = strtok(copy, s);
	    int i = 0;
	    while (token2 != NULL) {
		*(tokens + i) = token2;
		token2 = strtok(NULL, s);
		i++;
	    }
	    for (i = 0; i < count; i++) {
		funcArg *a = getArgument(*(tokens + i), funcName);
		varNames[size++] = a->vname;
		populateSTable(a);
	    }
	    free(copy);
	}
	
	//------------------------HANDLE LOCALS
	
	
	if(strcmp(locals,"") != 0){ //handle functions with no locals
	    char s[] = " ";
	    char *token;
	    char *copy = strdup(locals);
	    char* tmp = copy;
	    int count = 1;
	    while (*tmp != '\0') {
		if (*tmp++ == ' ')
		    count++;
	    }
	    localNames = (char**) malloc(count * sizeof(char*));
	    char** tokens = (char**) malloc(sizeof(char*) * count);
	    token = strtok(copy, s);
	    int i = 0;
	    while (token != NULL) {
		*(tokens + i) = token;
		token = strtok(NULL, s);
		i++;
	    }
	    for (i = 0; i < count; i++) {
		char* tmp = (char*)malloc(50*sizeof(char));
		strcpy(tmp, *(tokens + i));
		localNames[localSize++] = tmp;
		populateSTableWithLocals(tmp);
		//populateSTable(a);
	    }
	    free(copy);
	}


	//-----------------------HANDLE STACK_PUSH
	
	funcVars* fv = (funcVars*) malloc (sizeof(funcVars));
	fv->vars = varNames;
	fv->noOfVars = size;
	strcpy(fv->funcName,funcName);
	fv->noOfLocals = localSize;
	fv->locals = localNames;
	fv->occurence = currentOccurence+1;
	
	if(stackInitFlag){
	    stackPush(symStack, (&fv));
	}
	else{
	    symStack = stackNew(sizeof(funcVars*));
	    stackPush(symStack, (&fv));
	    stackInitFlag=1;
	}
	localSize = 0;
	size=0;
    	i=0;
	printf("Stack depth %d\n", stackSize(symStack));
    }
    else{
        int* flag = (int *)malloc(sizeof(int));
        *flag = 0;
        stackPush(didFuncEntryExecute, (&flag));
        printf("Recursive depth exceeded, nothing pushed, proceeding with concolic execution...\n");
        printf("Pushed \"%d\" in didFuncEntryExecute\n", 0);
    }
    
    //to avoid entries in itables/ftables
    noInsertionInTables = 0;
    //...........................//
}
Exemple #21
0
void binaryTreeTraverseInOrder(Node *root)
{
    Stack *stack = stackNew();
    Node *currentNode = root;
    printf("created a stack\n");

    printf("currentNode->data: %d\n", currentNode->data);
    currentNode->state = UNKNOWN_NODE_STATE;

    do{
        if(currentNode->left == NULL && currentNode->right == NULL)
        {
            if(currentNode->state == VISITED_RIGHT_NODE)
            {
                currentNode = stackPop(stack);
                if(currentNode != NULL)
                {
                    printf("pop: %d\n", currentNode->data);
                    if(currentNode->left == NULL)
                    {
                        currentNode->right = NULL;
                        currentNode->state = VISITED_RIGHT_NODE;
                    }
                    else
                        currentNode->left = NULL;
                }
            }
            else
            {
                display(currentNode->data);
                printf("display: %d\n", currentNode->data);
                currentNode = stackPop(stack);
                if(currentNode != NULL)
                {
                    printf("pop: %d\n", currentNode->data);
                    if(currentNode->state == VISITED_LEFT_NODE)
                    {
                        currentNode->state = VISITED_RIGHT_NODE;
                        currentNode->right = NULL;
                    }
                    else
                    {
                        currentNode->state = VISITED_LEFT_NODE;
                        currentNode->left = NULL;
                    }
                }
            }
        }
        else if(currentNode->left != NULL)
        {
            currentNode->state = ENTERED_NODE;
            stackPush(stack, (Node *)currentNode);
            printf("push: %d\n", currentNode->data);
            currentNode = currentNode->left;    //visiting left child node
            printf("currentNode->data: %d\n", currentNode->data);
        }
        else if(currentNode->right != NULL)
        {
            display(currentNode->data);
            printf("display: %d\n", currentNode->data);
            currentNode->state = VISITED_LEFT_NODE;
            stackPush(stack, (Node *)currentNode);
            printf("push: %d\n", currentNode->data);
            currentNode = currentNode->right;   //visiting right child node
            printf("currentNode->data: %d\n", currentNode->data);
        }
    }while(currentNode != NULL);

    stackDel(stack);
    printf("deleted a stack\n");
}
Exemple #22
0
bool decode(FILE* infile, FILE* outfile)
{
    // get the header info
    unsigned int maxBits = getBits(NBITS_MAXBITS, infile);
    unsigned int window = getBits(NBITS_WINDOW, infile);
    char eFlag = getBits(NBITS_EFLAG, infile);

    stringTable* table = (eFlag == 1) ? stringTableNew(maxBits, true) : stringTableNew(maxBits, false);
    pruneInfo* pi = pruneInfoNew(maxBits);

    unsigned int oldCode = EMPTY_PREFIX; // the previous code read from infile
    unsigned int newCode; // the code just read from infile
    unsigned int code; // initially equal to newCode, but then set to its
    // prefixes to obtain the entire string of newCode

    unsigned char finalK = 0, k; // characters in newCode
    stack* kStack = stackNew(); // holds characters from newCode in order to
    // put them in the correct order by reversal

    unsigned char nbits = (eFlag) ? 2 : 9; // number of bits per code

    while((newCode = code = getBits(nbits, infile)) != STOP_CODE)
    {
        switch(code)
        {
        case EOF:
        {
            // getting EOF before the STOP_CODE is an error
            stringTableDelete(table);
            stackDelete(kStack);
            pruneInfoDelete(pi);
            return false;
            break;
        }

        case GROW_NBITS_CODE:
        {
            nbits++;
            if(nbits > maxBits)
            {
                stringTableDelete(table);
                stackDelete(kStack);
                pruneInfoDelete(pi);
                return false;
            }
            break;
        }

        case PRUNE_CODE:
        {
            if(window == 0)
            {
                stringTableDelete(table);
                stackDelete(kStack);
                pruneInfoDelete(pi);
                return false;
            }
            else
            {
                table = stringTablePrune(table, pi, window, &oldCode);

                oldCode = EMPTY_PREFIX;

                // update nbits
                for(nbits = 2;
                        (1 << nbits) -1 < table->highestCode;
                        nbits++);
            }
            break;
        }

        case ESCAPE_CODE:
        {
            if(eFlag == 0)
            {
                stringTableDelete(table);
                stackDelete(kStack);
                pruneInfoDelete(pi);
                return false;
            }

            unsigned char escapedChar = getBits(8, infile);
            fputc(escapedChar, outfile);

            if(oldCode != EMPTY_PREFIX)
            {
                stringTableAdd(table, oldCode, escapedChar, NULL);
            }

            unsigned int tempCode;
            stringTableAdd(table, EMPTY_PREFIX, escapedChar, &tempCode);
            pruneInfoSawCode(pi, tempCode);

            oldCode = EMPTY_PREFIX; // reset prefix to EMPTY
            break;
        }

        default:
        {
            pruneInfoSawCode(pi, newCode);

            if(!stringTableCodeSearch(table, code))
            {
                stackPush(kStack, finalK);
                code = oldCode;
            }

            // push string for code onto kStack until we get to the code
            // with an empty prefix, which goes into finalK
            tableElt* elt = stringTableCodeSearch(table, code);
            while(elt && elt->prefix != EMPTY_PREFIX)
            {
                stackPush(kStack, elt->k);
                code = elt->prefix;

                elt = stringTableCodeSearch(table, code);
            }
            finalK = elt->k;

            // print the characters in correct order now that they've been
            // reversed by pushing them onto kStack
            fputc(finalK, outfile);
            while(stackPop(kStack, &k))
            {
                fputc(k, outfile);
            }

            // add oldCode to the table, then update it to the current code
            if(oldCode != EMPTY_PREFIX)
            {
                stringTableAdd(table, oldCode, finalK, NULL);
            }
            oldCode = newCode;
            break;
        }
        }
    }

    stringTableDelete(table);
    stackDelete(kStack);
    pruneInfoDelete(pi);
    return true;
}