search.c File Reference

#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>
#include "defines.h"
#include "search.h"
#include "link.h"
#include "func_unit.h"
#include "util.h"
#include "instance.h"

Functions

void search_init ()
 Initializes search maintained pointers.
void search_add_include_path (const char *path)
 Adds an include directory to the list of directories to search for `include directives.
void search_add_directory_path (const char *path)
 Adds a directory to the list of directories to find unspecified Verilog modules.
void search_add_file (const char *file)
 Adds a specific Verilog module to the list of modules to score.
void search_add_no_score_funit (const char *funit)
 Adds specified functional unit to list of functional units not to score.
void search_add_extensions (const char *ext_list)
 Adds specified extensions to allowed file extension list.
void search_free_lists ()
 Deallocates all used memory for search lists.

Variables

str_linkinc_paths_head = NULL
static str_linkinc_paths_tail = NULL
str_linkuse_files_head = NULL
static str_linkuse_files_tail = NULL
str_linkno_score_head = NULL
static str_linkno_score_tail = NULL
static str_linkextensions_head = NULL
static str_linkextensions_tail = NULL
db ** db_list
unsigned int db_size
unsigned int curr_db
char * top_module
char * top_instance
char user_msg [USER_MSG_LENGTH]
func_unitglobal_funit
func_unitcurr_funit
unsigned int flag_global_generation

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
11/27/2001

Function Documentation

void search_add_directory_path ( const char *  path  ) 

Adds a directory to the list of directories to find unspecified Verilog modules.

Parameters:
path Name of directory to find unspecified Verilog files
Exceptions:
anonymous directory_load

Adds the given library directory path to the list if the pathname is valid.

References directory_exists(), directory_load(), print_output(), PROFILE, str_link_add(), strdup_safe, user_msg, USER_MSG_LENGTH, and WARNING.

Referenced by score_parse_args().

00194   { PROFILE(SEARCH_ADD_DIRECTORY_PATH);
00195 
00196   if( directory_exists( path ) ) {
00197     /* If no library extensions have been specified, assume *.v */
00198     if( extensions_head == NULL ) {
00199       (void)str_link_add( strdup_safe( "v" ), &(extensions_head), &(extensions_tail) );
00200     }
00201     directory_load( path, extensions_head, &(use_files_head), &(use_files_tail) );
00202   } else {
00203     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Library directory %s does not exist", path );
00204     assert( rv < USER_MSG_LENGTH );
00205     print_output( user_msg, WARNING, __FILE__, __LINE__ );
00206   }
00207 
00208 }

void search_add_extensions ( const char *  ext_list  ) 

Adds specified extensions to allowed file extension list.

Parameters:
ext_list String containing extensions to allow in search.
Exceptions:
anonymous Throw Throw

Parses the given +libext argument, extracting all extensions listed and storing them into the globally accessible extensions list.

References FATAL, FATAL_WRAP, gen_char_string(), print_output(), PROFILE, str_link_add(), strdup_safe, Throw, user_msg, and USER_MSG_LENGTH.

Referenced by score_parse_args().

00279   { PROFILE(SEARCH_ADD_EXTENSIONS);
00280 
00281   char        ext[30];               /* Holder for extension */
00282   int         ext_index = 0;         /* Index to ext array */
00283   const char* tmp       = ext_list;  /* Temporary extension name */
00284 
00285   assert( ext_list != NULL );
00286 
00287   while( *tmp != '\0' ) {
00288     assert( ext_index < 30 );
00289     if( *tmp == '+' ) { 
00290       ext[ext_index] = '\0';
00291       ext_index      = 0;
00292       (void)str_link_add( strdup_safe( ext ), &extensions_head, &extensions_tail );
00293     } else if( *tmp == '.' ) {
00294       if( ext_index > 0 ) {
00295         Throw 0;
00296       }
00297     } else {
00298       ext[ext_index] = *tmp;
00299       ext_index++;
00300     }
00301     tmp++;
00302   }
00303 
00304   /* If extension list is not empty, we have hit a parsing error */
00305   if( (strlen( tmp ) > 0) || (ext_index > 0) ) {
00306     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Parsing error in +libext+%s  ", ext_list );
00307     assert( rv < USER_MSG_LENGTH );
00308     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00309     gen_char_string( user_msg, ' ', (25 + (strlen( ext_list ) - strlen( tmp ))) );
00310     strcat( user_msg, "^" );
00311     print_output( user_msg, FATAL_WRAP, __FILE__, __LINE__ );
00312     Throw 0;
00313   }
00314 
00315 }

void search_add_file ( const char *  file  ) 

Adds a specific Verilog module to the list of modules to score.

Parameters:
file Name of Verilog file to add to scoring list.
Exceptions:
anonymous Throw

Adds the given file to the search path list if the file exists.

References FATAL, file_exists(), print_output(), PROFILE, str_link_add(), str_link_find(), strdup_safe, str_link_s::suppl, Throw, user_msg, and USER_MSG_LENGTH.

Referenced by score_parse_args().

00219   { PROFILE(SEARCH_ADD_FILE);
00220 
00221   char* tmp;  /* Temporary filename */
00222 
00223   if( file_exists( file ) ) {
00224 
00225     str_link* strl;
00226 
00227     if( (strl = str_link_find( file, use_files_head )) == NULL ) {
00228       tmp = strdup_safe( file );
00229       (void)str_link_add( tmp, &use_files_head, &use_files_tail );
00230     } else {
00231       strl->suppl = 0x0;
00232     }
00233 
00234   } else {
00235     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "File %s does not exist", file );
00236     assert( rv < USER_MSG_LENGTH );
00237     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00238     Throw 0;
00239   }
00240 
00241 }

void search_add_include_path ( const char *  path  ) 

Adds an include directory to the list of directories to search for `include directives.

Parameters:
path Name of include path to search for `include directives.

Adds the given include directory path to the include path list if the pathname exists.

References directory_exists(), print_output(), PROFILE, str_link_add(), strdup_safe, user_msg, USER_MSG_LENGTH, and WARNING.

Referenced by score_parse_args().

00170   { PROFILE(SEARCH_ADD_INCLUDE_PATH);
00171 
00172   char* tmp;  /* Temporary directory name */
00173 
00174   if( directory_exists( path ) ) {
00175     tmp = strdup_safe( path );
00176     (void)str_link_add( tmp, &inc_paths_head, &inc_paths_tail );
00177   } else {
00178     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Include directory %s does not exist", path );
00179     assert( rv < USER_MSG_LENGTH );
00180     print_output( user_msg, WARNING, __FILE__, __LINE__ );
00181   }
00182 
00183 }

void search_add_no_score_funit ( const char *  funit  ) 

Adds specified functional unit to list of functional units not to score.

Parameters:
funit Name of functional unit to specifically not score
Exceptions:
anonymous Throw

Checks the given functional unit name and adds this name to the list of functional units to exclude from coverage.

References FATAL, is_func_unit(), print_output(), PROFILE, str_link_add(), strdup_safe, Throw, user_msg, and USER_MSG_LENGTH.

Referenced by ovl_add_assertions_to_no_score_list(), and score_parse_args().

00253   { PROFILE(SEARCH_ADD_NO_SCORE_FUNIT);
00254 
00255   char* tmp;  /* Temporary module name */
00256 
00257   if( is_func_unit( funit ) ) {
00258     tmp = strdup_safe( funit );
00259     (void)str_link_add( tmp, &no_score_head, &no_score_tail );
00260   } else {
00261     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Value of -e option (%s) is not a valid block name", funit );
00262     assert( rv < USER_MSG_LENGTH );
00263     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00264     Throw 0;
00265   }
00266 
00267 }

void search_free_lists (  ) 

Deallocates all used memory for search lists.

This function should be called after all parsing is completed. Deletes all initialized lists.

References PROFILE, PROFILE_END, and str_link_delete_list().

Referenced by command_score().

00321                          { PROFILE(SEARCH_FREE_LISTS);
00322 
00323   str_link_delete_list( inc_paths_head );
00324   str_link_delete_list( use_files_head );
00325   str_link_delete_list( extensions_head );
00326   str_link_delete_list( no_score_head );
00327 
00328   PROFILE_END;
00329 
00330 }

void search_init (  ) 

Initializes search maintained pointers.

Exceptions:
anonymous Throw

Creates root module for module_node tree. If a module_node points to this node as its parent, that node is considered the root node of the tree.

References funit_inst_s::child_head, funit_inst_s::child_tail, curr_db, FALSE, FATAL, func_unit_s::filename, flag_global_generation, funit_create(), funit_head, funit_link_add(), FUNIT_MODULE, db_s::funit_tail, GENERATION_SV, inst_link_s::inst, inst_head, db_s::inst_head, inst_link_add(), instance_create(), db_s::leading_hier_num, db_s::leading_hierarchies, func_unit_s::name, funit_inst_s::next, funit_inst_s::parent, print_output(), PROFILE, realloc_safe, scope_extract_back(), scope_extract_front(), strdup_safe, Throw, top_instance, top_module, func_unit_s::ts_unit, and func_unit_s::type.

Referenced by command_score().

00069                    { PROFILE(SEARCH_INIT);
00070 
00071   func_unit* mod;            /* Pointer to newly created module node from top module */
00072   char       dutname[4096];  /* Instance name of top-level DUT module */
00073   char       lhier[4096];    /* Temporary storage of leading hierarchy */
00074 
00075   /* Check to make sure that the user specified a -t option value */
00076   if( top_module == NULL ) {
00077     print_output( "No top module was specified with the -t option.  Please see \"covered -h\" for usage.",
00078                   FATAL, __FILE__, __LINE__ );
00079     Throw 0;
00080   }
00081 
00082   /* If the global generation type is SystemVerilog support, create the global $root module space */
00083   if( flag_global_generation == GENERATION_SV ) {
00084 
00085     /* Create the global functional unit */
00086     global_funit           = funit_create();
00087     global_funit->name     = strdup_safe( "$root" );
00088     global_funit->type     = FUNIT_MODULE;
00089     global_funit->filename = strdup_safe( "NA" );
00090     global_funit->ts_unit  = 2;
00091     (void)funit_link_add( global_funit, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) );
00092     curr_funit = global_funit;
00093 
00094     /* Add it in the first instance tree */
00095     (void)inst_link_add( instance_create( global_funit, "$root", FALSE, FALSE, FALSE, NULL ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
00096   }
00097 
00098   /* Now create top-level module of design */
00099   mod       = funit_create();
00100   mod->type = FUNIT_MODULE;
00101   mod->name = strdup_safe( top_module );
00102 
00103   /* Initialize functional unit linked list */
00104   (void)funit_link_add( mod, &(db_list[curr_db]->funit_head), &(db_list[curr_db]->funit_tail) );
00105 
00106   /* Initialize instance tree */
00107   if( top_instance == NULL ) {
00108     top_instance = strdup_safe( top_module );
00109     (void)inst_link_add( instance_create( mod, top_instance, FALSE, FALSE, FALSE, NULL ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
00110     db_list[curr_db]->leading_hierarchies = (char**)realloc_safe( db_list[curr_db]->leading_hierarchies, (sizeof( char* ) * db_list[curr_db]->leading_hier_num), (sizeof( char* ) * (db_list[curr_db]->leading_hier_num + 1)) );
00111     db_list[curr_db]->leading_hierarchies[db_list[curr_db]->leading_hier_num] = strdup_safe( "*" );
00112     db_list[curr_db]->leading_hier_num++;
00113   } else {
00114     scope_extract_back( top_instance, dutname, lhier );
00115     if( lhier[0] == '\0' ) {
00116       db_list[curr_db]->leading_hierarchies = (char**)realloc_safe( db_list[curr_db]->leading_hierarchies, (sizeof( char* ) * db_list[curr_db]->leading_hier_num), (sizeof( char* ) * (db_list[curr_db]->leading_hier_num + 1)) );
00117       db_list[curr_db]->leading_hierarchies[db_list[curr_db]->leading_hier_num] = strdup_safe( "*" );
00118       db_list[curr_db]->leading_hier_num++;
00119       (void)inst_link_add( instance_create( mod, dutname, FALSE, FALSE, FALSE, NULL ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
00120     } else {
00121       char        tmp1[4096];
00122       char        tmp2[4096];
00123       char        tmp3[4096];
00124       inst_link*  instl;
00125       funit_inst* parent;
00126       funit_inst* child;
00127       (void)strcpy( tmp1, lhier );
00128       scope_extract_front( tmp1, tmp2, tmp3 );
00129       instl  = inst_link_add( instance_create( NULL, tmp2, FALSE, FALSE, FALSE, NULL ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
00130       parent = instl->inst;
00131       while( tmp3[0] != '\0' ) {
00132         (void)strcpy( tmp1, tmp3 );
00133         scope_extract_front( tmp1, tmp2, tmp3 );
00134         child = instance_create( NULL, tmp2, FALSE, FALSE, FALSE, NULL );
00135         child->parent = parent;
00136         if( parent->child_head == NULL ) {
00137           parent->child_head       = child;
00138           parent->child_tail       = child;
00139         } else {
00140           parent->child_tail->next = child;
00141           parent->child_tail       = child;
00142         }
00143         parent = child;
00144       }
00145       child = instance_create( mod, dutname, FALSE, FALSE, FALSE, NULL );
00146       child->parent = parent;
00147       if( parent->child_head == NULL ) {
00148         parent->child_head       = child;
00149         parent->child_tail       = child;
00150       } else {
00151         parent->child_tail->next = child;
00152         parent->child_tail       = child;
00153       }
00154       // (void)inst_link_add( instance_create( mod, dutname, FALSE, FALSE, FALSE, NULL ), &(db_list[curr_db]->inst_head), &(db_list[curr_db]->inst_tail) );
00155       db_list[curr_db]->leading_hierarchies = (char**)realloc_safe( db_list[curr_db]->leading_hierarchies, (sizeof( char* ) * db_list[curr_db]->leading_hier_num), (sizeof( char* ) * (db_list[curr_db]->leading_hier_num + 1)) );
00156       db_list[curr_db]->leading_hierarchies[db_list[curr_db]->leading_hier_num] = strdup_safe( lhier );
00157       db_list[curr_db]->leading_hier_num++;
00158     }
00159   }
00160 
00161 }


Variable Documentation

unsigned int curr_db

Index of current database in db_list array that is being handled.

Pointer to the functional unit structure for the functional unit that is currently being parsed.

Array of database pointers storing all currently loaded databases.

unsigned int db_size

Size of the db_list array.

Referenced by db_close(), db_create(), and report_read_cdd_and_ready().

str_link* extensions_head = NULL [static]

Pointer to head element of extensions list

str_link* extensions_tail = NULL [static]

Pointer to tail element of extensions list

unsigned int flag_global_generation

Specifies the supported global generation value

Pointer to the global function unit that is available in SystemVerilog.

Pointer to head element of include paths list

str_link* inc_paths_tail = NULL [static]

Pointer to tail element of include paths list

Pointer to head element of functional units not-to-score list

str_link* no_score_tail = NULL [static]

Pointer to tail element of functional units not-to-score list

char* top_instance

Name of top-level instance name

char* top_module

Name of top-level module to score

Pointer to head element of used files list

str_link* use_files_tail = NULL [static]

Pointer to tail element of used files list

char user_msg[USER_MSG_LENGTH]

Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.

Generated on Sun Nov 21 00:55:41 2010 for Covered by  doxygen 1.6.3