blob: 0ccfb5ba45ae6d9d2fac03858f89bd4eddd3f847 [file] [log] [blame]
/*************************************************************************
*
* PathFinder: finding a series of labeled nodes within a
* two-layer directed, cyclic graph.
* Copyright (2013) Sandia Corporation
*
* Copyright (2013) Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
* retains certain rights in this software.
*
* This file is part of PathFinder.
*
* PathFinder is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* PathFinder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PathFinder. If not, see <http://www.gnu.org/licenses/>.
*
* Questions? Contact J. Brian Rigdon (jbrigdo@sandia.gov)
*
*/
/*
* systemCallMap.c
*
* Created on: Feb 5, 2013
* Author: Brian "Rig" Rigdon, Marcus Smith, Samuel Mulder
*/
#include "systemCallMap.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Element constructor */
SystemCallMapElement *SystemCallMapElement_new ( char *label, int initialSize )
{
SystemCallMapElement *element = malloc ( sizeof( SystemCallMapElement ) );
if ( element )
{
element->label = strdup ( label );
element->index = -1; /* Set by the insertion algorithm */
if ( !element->label )
{
free( element );
return( NULL );
}
element->nodes = NodePtrVec_new( initialSize );
if ( !element->nodes )
{
free( element->label );
free( element );
return( NULL );
}
}
return( element );
}
/* Element destructor */
void SystemCallMapElement_delete( SystemCallMapElement *trash )
{
/* free the mallocs! */
if ( trash )
{
if ( trash->label )
free( trash->label );
NodePtrVec_delete ( trash->nodes );
}
}
/* Constructor */
SystemCallMap *SystemCallMap_new ( int initialSize )
{
SystemCallMap *map = NULL;
SystemCallMapElement **vector = NULL;
if ( initialSize <= 0 )
return NULL;
vector = malloc( initialSize * sizeof( SystemCallMapElement* ) );
if ( vector )
{
map = malloc ( sizeof( SystemCallMap ) );
if ( map )
{
map->allocatedSize = initialSize;
map->contentSize = 0;
map->vector = vector;
}
else
free( vector );
}
return map;
}
/* destructor for an ENTIRE MAP!!! */
void SystemCallMap_delete( SystemCallMap *trash )
{
int i;
/* basic error checking */
if ( !trash )
return;
for ( i = 0; i < trash->contentSize; ++i )
{
SystemCallMapElement_delete( trash->vector[i] );
}
}
/* setter */
bool SystemCallMap_insert ( SystemCallMap *map, char *label, Node *node )
{
int i = 0;
SystemCallMapElement *newElement = NULL;
bool success = false;
/* Some basic error checking */
if ( !map || !label || !node )
return( false );
/* See if this label has already been implemented */
for ( i = 0; i < map->contentSize; ++i )
{
if ( strcmp( label, map->vector[i]->label ) == 0 )
{
/* found it! */
node->label = map->vector[i]->label;
node->labelIdx = i;
return( NodePtrVec_push( map->vector[i]->nodes, node ) );
}
}
/* If we make it here, we have a new label */
if ( map->contentSize == map->allocatedSize )
{
/* Full up! Need a new vector */
map->vector = realloc( map->vector, (map->allocatedSize*2 * sizeof( SystemCallMapElement * )) );
if ( map->vector )
{
map->allocatedSize *= 2;
}
else
return( false );
}
newElement = SystemCallMapElement_new( label, 8 ); /* arbitrary size of 8 */
if ( !newElement )
return( false );
success = NodePtrVec_push( newElement->nodes, node );
if ( !success )
SystemCallMapElement_delete( newElement );
node->label = newElement->label;
node->labelIdx = newElement->index = map->contentSize; /* Does newElement really need the index? */
map->vector[map->contentSize] = newElement;
map->contentSize += 1;
return( true );
}
/* Finds all nodes associated with a label. */
NodePtrVec *SystemCallMap_findLabeledNodes( SystemCallMap *systemCalls, char *label )
{
int i;
/* Debug --> * /
printf("Inside SystemCallMap_findLabeledNodes, label: %s\n", label);
/ *<-- end debug */
if ( !systemCalls || !label )
return( NULL );
for( i = 0; i < systemCalls->contentSize; ++i )
{
/* Debug -->* /
printf("\t...checking against %s...\n", systemCalls->vector[i]->label);
/ * <-- end debug */
if ( strcmp( label, systemCalls->vector[i]->label ) == 0 )
return( systemCalls->vector[i]->nodes );
}
/* Debug --> * /
printf("\tleaving SystemCallMap_findLabeledNodes, nothing found.\n");
/ *<-- end debug */
return( NULL );
}
/* Returns the index of a given label */
int SystemCallMap_getLabelIndex( SystemCallMap *map, char *label )
{
int i;
/* See if this label has already been implemented */
for ( i = 0; i < map->contentSize; ++i )
{
if ( strcmp( label, map->vector[i]->label ) == 0 )
{
return( i );
}
}
/* If we made it here, this label is not represented */
return( -1 );
}
/*
* Determines if all the labels in a given signature are represented
* within this graph. If not, we know the search will fail. There's
* gotta be a better name for this...
*/
bool SystemCallMap_signatureRepresented( SystemCallMap *map, Signature signature )
{
int i;
bool foundByLabel = true;
for ( i = 0; signature[i] != NULL && foundByLabel; ++i )
{
/* if the signature is in the map, its index will be >=0 */
if ( SystemCallMap_getLabelIndex( map, signature[i] ) < 0 )
foundByLabel = false;
}
return( foundByLabel );
}