Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

/Users/trevorw/projects/release/covered-0.7.4/src/util.c File Reference


Detailed Description

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

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <assert.h>
#include <dirent.h>
#include <ctype.h>
#include "defines.h"
#include "util.h"
#include "link.h"
#include "obfuscate.h"
#include "profiler.h"
#include "vpi.h"

Functions

void set_output_suppression (bool value)
 Sets error suppression to specified value.

void set_debug (bool value)
 Sets global debug flag to specified value.

void set_testmode ()
 Sets the testmode global variable for outputting purposes.

void print_output (const char *msg, int type, const char *file, int line)
 Displays error message to standard output.

bool check_option_value (int argc, const char **argv, int option_index)
 Checks to make sure that a value was properly specified for a given option.

bool is_variable (const char *token)
 Returns TRUE if the specified string is a legal variable name.

bool is_func_unit (const char *token)
 Returns TRUE if the specified string is a legal functional unit value.

bool is_legal_filename (const char *token)
 Returns TRUE if the specified string could be a valid filename.

const char * get_basename (const char *str)
 Extracts filename from file pathname.

char * get_dirname (char *str)
 Extracts directory path from file pathname.

char * get_absolute_path (const char *filename)
 Allocates memory for and gets the absolute pathname for a given filename.

char * get_relative_path (const char *abs_path)
 Allocates memory for and gets the relative pathname for a given absolute filename.

bool directory_exists (const char *dir)
 Returns TRUE if the specified directory exists.

void directory_load (const char *dir, const str_link *ext_head, str_link **file_head, str_link **file_tail)
 Loads contents of specified directory to file list if extension is part of list.

bool file_exists (const char *file)
 Returns TRUE if the specified file exists.

bool util_readline (FILE *file, char **line, unsigned int *line_size)
 Reads line from file and returns it in string form.

bool get_quoted_string (FILE *file, char *line)
 Reads in line from file and returns the contents of the quoted string following optional whitespace.

char * substitute_env_vars (const char *value)
 Searches the specified string for environment variables and substitutes their value if found.

void scope_extract_front (const char *scope, char *front, char *rest)
 Extracts highest level of hierarchy from specified scope.

void scope_extract_back (const char *scope, char *back, char *rest)
 Extracts lowest level of hierarchy from specified scope.

void scope_extract_scope (const char *scope, const char *front, char *back)
 Extracts rest of scope not included in front.

char * scope_gen_printable (const char *str)
 Generates printable version of given signal/instance string.

bool scope_compare (const char *str1, const char *str2)
 Compares two signal names or two instance names.

bool scope_local (const char *scope)
 Returns TRUE if specified scope is local (contains no periods).

void convert_file_to_module (char *mname, int len, char *fname)
str_linkget_next_vfile (str_link *curr, const char *mod)
 Returns next Verilog file to parse.

void * malloc_safe1 (size_t size, const char *file, int line, unsigned int profile_index)
 Performs safe malloc call.

void * malloc_safe_nolimit1 (size_t size, const char *file, int line, unsigned int profile_index)
 Performs safe malloc call without upper bound on byte allocation.

void free_safe1 (void *ptr, unsigned int profile_index)
 Performs safe deallocation of heap memory.

void free_safe2 (void *ptr, size_t size, const char *file, int line, unsigned int profile_index)
 Performs safe deallocation of heap memory.

char * strdup_safe1 (const char *str, const char *file, int line, unsigned int profile_index)
 Safely allocates heap memory by performing a call to strdup.

void * realloc_safe1 (void *ptr, size_t old_size, size_t size, const char *file, int line, unsigned int profile_index)
 Safely reallocates heap memory by performing a call to realloc.

void * calloc_safe1 (size_t num, size_t size, const char *file, int line, unsigned int profile_index)
 Safely callocs heap memory by performing a call to calloc.

void gen_char_string (char *str, char c, int num_chars)
 Creates a string containing space characters.

char * remove_underscores (char *str)
 Removes underscores from the specified string.

void timer_clear (timer **tm)
 Clears the timer, resetting the accumulated time information and allocating timer memory, if needed.

void timer_start (timer **tm)
 Starts timing the specified timer structure and allocates/clears timer memory, if needed.

void timer_stop (timer **tm)
 Stops timing the specified timer structure.

char * timer_to_string (timer *tm)
 Generates a human-readable time-of-day string from the given timer structure.

const char * get_funit_type (int type)
 Returns string representation of the specified functional unit type.

void calc_miss_percent (int hits, int total, int *misses, float *percent)
 Calculates miss and percent information from given hit and total information.

void read_command_file (const char *cmd_file, char ***arg_list, int *arg_num)
 Reads in contents of command file, substitutes environment variables and stores them to the arg_list array.


Variables

bool report_gui
bool flag_use_command_line_debug
Tcl_Interp * interp
bool cli_debug_mode = FALSE
bool output_suppressed
bool warnings_suppressed = FALSE
bool debug_mode
bool test_mode = FALSE
int64 curr_malloc_size = 0
int64 largest_malloc_size = 0
char user_msg [USER_MSG_LENGTH]
const char * funit_types [FUNIT_TYPES+1] = { "module", "named block", "function", "task", "no_score", "afunction", "atask", "named block", "UNKNOWN" }


Function Documentation

void calc_miss_percent int  hits,
int  total,
int *  misses,
float *  percent
 

Calculates miss and percent information from given hit and total information.

Calculates the number of misses and hit percentage information from the given hit and total information, storing the results in the misses and percent storage elements.

Note:
If the total number of items is 0, the hit percentage will be calculated as 100% covered.
Parameters:
hits  Number of items hit during simulation
total  Number of total items
misses  Pointer to a storage element which will contain the calculated number of items missed during simulation
percent  Pointer to a storage element which will contain the calculated hit percent information

01612   { PROFILE(CALC_MISS_PERCENT);
01613 
01614   if( total == 0 ) {
01615     *percent = 100;
01616   } else {
01617     *percent = ((hits / (float)total) * 100);
01618   }
01619 
01620   *misses = (total - hits);
01621 
01622   PROFILE_END;
01623 
01624 }

void* calloc_safe1 size_t  num,
size_t  size,
const char *  file,
int  line,
unsigned int  profile_index
 

Safely callocs heap memory by performing a call to calloc.

Returns:
Returns a pointer to the newly allocated/initialized data
Verifies that the specified size is not oversized, callocs the memory, verifies that the memory pointer returned is not NULL, and performs some memory statistic handling.
Parameters:
num  Number of elements to allocate
size  Size of each element that is allocated
file  Name of file that called this function
line  Line number of file that called this function
profile_index  Profile index of function that called this function

01396   {
01397 
01398   void*  obj;
01399   size_t total = (num * size);
01400 
01401   assert( total > 0 );
01402 
01403   curr_malloc_size += total;
01404 
01405   if( curr_malloc_size > largest_malloc_size ) {
01406     largest_malloc_size = curr_malloc_size;
01407   }
01408 
01409   obj = calloc( num, size );
01410 #ifdef TESTMODE
01411   if( test_mode ) {
01412     printf( "CALLOC (%p) %d bytes (file: %s, line: %d) - %lld\n", obj, total, file, line, curr_malloc_size );
01413   }
01414 #endif
01415   assert( obj != NULL );
01416 
01417   MALLOC_CALL(profile_index);
01418 
01419   return( obj );
01420 
01421 }

bool check_option_value int  argc,
const char **  argv,
int  option_index
 

Checks to make sure that a value was properly specified for a given option.

Returns:
Returns TRUE if the specified option has a valid argument; otherwise, returns FALSE to indicate that there was an error in parsing the command-line.
This function is called whenever a command-line argument requires a value. It verifies that a value was specified (however, it does not make sure that the value is the correct type). Outputs an error message and returns a value of FALSE if a value was not specified; otherwise, returns TRUE.
Parameters:
argc  Number of arguments in the argv parameter list
argv  List of arguments being parsed
option_index  Index of current option being parsed

00284   { PROFILE(CHECK_OPTION_VALUE);
00285 
00286   bool retval = TRUE;  /* Return value for this function */
00287 
00288   if( ((option_index + 1) >= argc) || ((argv[option_index+1][0] == '-') && (strlen(argv[option_index+1]) > 1)) ) {
00289     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Missing option value to the right of the %s option", argv[option_index] );
00290     assert( rv < USER_MSG_LENGTH );
00291     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00292     retval = FALSE;
00293   }
00294 
00295   PROFILE_END;
00296 
00297   return( retval );
00298 
00299 }

void convert_file_to_module char *  mname,
int  len,
char *  fname
[static]
 

Takes in a filename (with possible directory information and/or possible extension) and transforms it into a filename with the directory and extension information stripped off. Much like the the functionality of the unix command "basename". Returns the stripped filename in the mname parameter.

Parameters:
mname  Name of module extracted
len  Length of mname string (we cannot exceed this value)
fname  Name of filename to extract module name from

01102   { PROFILE(CONVERT_FILE_TO_MODULE);
01103 
01104   char* ptr;   /* Pointer to current character in filename */
01105   char* lptr;  /* Pointer to last character in module name */
01106   int   i;     /* Loop iterator */
01107 
01108   /* Set ptr to end of fname string */
01109   ptr  = fname + strlen( fname );
01110   lptr = ptr;
01111 
01112   /* Continue back until period is found */
01113   while( (ptr > fname) && (*ptr != '.') ) {
01114     ptr--;
01115   }
01116 
01117   if( ptr > fname ) {
01118     lptr = ptr;
01119   }
01120 
01121   /* Continue on until ptr == fname or we have reached a non-filename character */
01122   while( (ptr > fname) && (*ptr != '/') ) {
01123     ptr--;
01124   }
01125 
01126   /* Construct new name */
01127   if( ptr > fname ) {
01128     ptr++;
01129   }
01130 
01131   assert( (lptr - ptr) < len );
01132 
01133   i = 0;
01134   while( ptr < lptr ) {
01135     mname[i] = *ptr;
01136     ptr++;
01137     i++;
01138   }
01139   mname[i] = '\0';
01140 
01141   PROFILE_END;
01142 
01143 }

bool directory_exists const char *  dir  ) 
 

Returns TRUE if the specified directory exists.

Returns:
Returns TRUE if the specified directory exists; otherwise, returns FALSE.
Checks to see if the specified directory actually exists in the file structure. If the directory is found to exist, returns TRUE; otherwise, returns FALSE.
Parameters:
dir  Name of directory to check for existence

00611   { PROFILE(DIRECTORY_EXISTS);
00612 
00613   bool        retval = FALSE;  /* Return value for this function */
00614   struct stat filestat;        /* Statistics of specified directory */
00615 
00616   if( stat( dir, &filestat ) == 0 ) {
00617 
00618     if( S_ISDIR( filestat.st_mode ) ) {
00619 
00620       retval = TRUE;
00621 
00622     }
00623 
00624   }
00625 
00626   PROFILE_END;
00627 
00628   return( retval );
00629 
00630 }

void directory_load const char *  dir,
const str_link ext_head,
str_link **  file_head,
str_link **  file_tail
 

Loads contents of specified directory to file list if extension is part of list.

Bug:
Need to order files according to extension first instead of filename.
Exceptions:
anonymous Throw
Opens the specified directory for reading and loads (in order) all files that contain the specified extensions (if ext_head is NULL, load only *.v files). Stores all string filenames to the specified string list.
Parameters:
dir  Name of directory to read files from
ext_head  Pointer to extension list
file_head  Pointer to head element of filename string list
file_tail  Pointer to tail element of filename string list

00646   { PROFILE(DIRECTORY_LOAD);
00647 
00648   DIR*            dir_handle;  /* Pointer to opened directory */
00649   struct dirent*  dirp;        /* Pointer to current directory entry */
00650   const str_link* curr_ext;    /* Pointer to current extension string */
00651   char*           ptr;         /* Pointer to current character in filename */
00652   unsigned int    tmpchars;    /* Number of characters needed to store full pathname for file */
00653   char*           tmpfile;     /* Temporary string holder for full pathname of file */
00654 
00655   if( (dir_handle = opendir( dir )) == NULL ) {
00656 
00657     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to read directory %s", dir );
00658     assert( rv < USER_MSG_LENGTH );
00659     print_output( user_msg, FATAL, __FILE__, __LINE__ );
00660     Throw 0;
00661 
00662   } else {
00663 
00664     unsigned int rv;
00665 
00666     while( (dirp = readdir( dir_handle )) != NULL ) {
00667       ptr = dirp->d_name + strlen( dirp->d_name ) - 1;
00668       /* Work backwards until a dot is encountered */
00669       while( (ptr >= dirp->d_name) && (*ptr != '.') ) {
00670         ptr--;
00671       }
00672       if( *ptr == '.' ) {
00673         ptr++;
00674         curr_ext = ext_head;
00675         while( (curr_ext != NULL) && (strcmp( ptr, curr_ext->str ) != 0) ) {
00676           curr_ext = curr_ext->next;
00677         }
00678         if( curr_ext != NULL ) {
00679           unsigned int rv;
00680           /* Found valid extension, add to list */
00681           tmpchars = strlen( dirp->d_name ) + strlen( dir ) + 2;
00682           tmpfile  = (char*)malloc_safe( tmpchars );
00683           rv = snprintf( tmpfile, tmpchars, "%s/%s", dir, dirp->d_name );
00684           assert( rv < tmpchars );
00685           if( str_link_find( tmpfile, *file_head ) == NULL ) {
00686             (void)str_link_add( tmpfile, file_head, file_tail );
00687             (*file_tail)->suppl = 0x1;
00688           } else {
00689             free_safe( tmpfile, (strlen( tmpfile ) + 1) );
00690           }
00691         }
00692       }
00693     }
00694 
00695     rv = closedir( dir_handle );
00696     assert( rv == 0 );
00697 
00698   }
00699 
00700   PROFILE_END;
00701 
00702 }

bool file_exists const char *  file  ) 
 

Returns TRUE if the specified file exists.

Returns:
Returns TRUE if the specified file exists; otherwise, returns FALSE.
Checks to see if the specified file actually exists in the file structure. If the file is found to exist, returns TRUE; otherwise, returns FALSE.
Parameters:
file  Name of file to check for existence

00712   { PROFILE(FILE_EXISTS);
00713 
00714   bool        retval = FALSE;  /* Return value for this function */
00715   struct stat filestat;        /* Statistics of specified directory */
00716 
00717   if( stat( file, &filestat ) == 0 ) {
00718 
00719     if( S_ISREG( filestat.st_mode ) || S_ISFIFO( filestat.st_mode ) ) {
00720 
00721       retval = TRUE;
00722 
00723     }
00724 
00725   }
00726 
00727   PROFILE_END;
00728 
00729   return( retval );
00730 
00731 }

void free_safe1 void *  ptr,
unsigned int  profile_index
 

Performs safe deallocation of heap memory.

Safely performs a free function of heap memory. Also keeps track of current memory usage for output information at end of program life.

Parameters:
ptr  Pointer to object to deallocate
profile_index  Profile index of function that called this function

01267   {
01268 
01269   if( ptr != NULL ) {
01270     free( ptr );
01271   }
01272 
01273   /* Profile the free */
01274   FREE_CALL(profile_index);
01275 
01276 }

void free_safe2 void *  ptr,
size_t  size,
const char *  file,
int  line,
unsigned int  profile_index
 

Performs safe deallocation of heap memory.

Safely performs a free function of heap memory. Also keeps track of current memory usage for output information at end of program life.

Parameters:
ptr  Pointer to object to deallocate
size  Number of bytes that will be deallocated
file  File that is calling this function
line  Line number in file that is calling this function
profile_index  Profile index of function that called this function

01289   {
01290 
01291   if( ptr != NULL ) {
01292     curr_malloc_size -= size;
01293 #ifdef TESTMODE
01294     if( test_mode ) {
01295       printf( "FREE (%p) %d bytes (file: %s, line: %d) - %lld\n", ptr, size, file, line, curr_malloc_size );
01296     }
01297 #endif
01298     free( ptr );
01299   }
01300 
01301   /* Profile the free */
01302   FREE_CALL(profile_index);
01303 
01304 }

void gen_char_string char *  str,
char  c,
int  num_chars
 

Creates a string containing space characters.

Creates a string that contains num_chars number of characters specified by the value of c, adding a NULL character at the end of the string to allow for correct usage by the strlen and other string functions.

Parameters:
str  Pointer to string to places spaces into
c  Character to write
num_chars  Number of spaces to place in string

01432   { PROFILE(GEN_SPACE);
01433 
01434   int i;     /* Loop iterator */
01435 
01436   for( i=0; i<num_chars; i++ ) {
01437     str[i] = c;
01438   }
01439 
01440   str[i] = '\0';
01441 
01442   PROFILE_END;
01443   
01444 }

char* get_absolute_path const char *  filename  ) 
 

Allocates memory for and gets the absolute pathname for a given filename.

Returns:
Returns absolute path of the given absolute pathname to the current path.
Parameters:
filename  Filename to get the absolute pathname of

00470   { PROFILE(GET_ABSOLUTE_PATH);
00471 
00472   char*        abs_path = NULL;
00473   char*        tmp;
00474   char*        dir;
00475   char         this_cwd[4096];
00476   char*        srv;
00477   unsigned int irv;
00478 
00479   /* Get a copy of the filename and calculate its directory and basename */
00480   tmp = strdup_safe( filename );
00481   dir = get_dirname( tmp );
00482 
00483   /* Get the original working directory so that we can return there */
00484   srv = getcwd( this_cwd, 4096 );
00485   assert( srv != NULL );
00486 
00487   /* If we have a directory to go to, change to the directory */
00488   if( dir[0] != '\0' ) {
00489 
00490     char         cwd[4096];
00491     unsigned int slen;
00492     char*        file = dir + strlen( dir ) + 1;
00493 
00494     /* Change to the specified directory */
00495     irv = chdir( dir );
00496     assert( irv == 0 );
00497 
00498     /* Get the current working directory and create the absolute path */
00499     srv = getcwd( cwd, 4096 );
00500     assert( srv != NULL );
00501 
00502     slen     = strlen( cwd ) + strlen( file ) + 2;
00503     abs_path = (char*)malloc_safe( slen );
00504     irv      = snprintf( abs_path, slen, "%s/%s", cwd, file );
00505     assert( irv < slen );
00506 
00507     /* Return to the original directory */
00508     irv = chdir( this_cwd );
00509     assert( irv == 0 );
00510 
00511   /* Otherwise, the file is in this directory */
00512   } else {
00513 
00514     unsigned int slen;
00515 
00516     slen = strlen( this_cwd ) + strlen( filename ) + 2;
00517 
00518     abs_path = (char*)malloc_safe( slen );
00519     irv      = snprintf( abs_path, slen, "%s/%s", this_cwd, filename );
00520     assert( irv < slen );
00521 
00522   }
00523 
00524   /* Deallocate used memory */
00525   free_safe( tmp, (strlen( filename ) + 1) );
00526 
00527   PROFILE_END;
00528 
00529   return( abs_path );
00530 
00531 }

const char* get_basename const char *  str  ) 
 

Extracts filename from file pathname.

Returns:
Returns pointer to string containing only base filename.
Extracts the file basename of the specified filename string.
Parameters:
str  String containing pathname to file

00416   { PROFILE(GET_BASENAME);
00417 
00418   const char* ptr;  /* Pointer to current character in str */
00419 
00420   ptr = (str + strlen( str )) - 1;
00421 
00422   while( (ptr > str) && (*ptr != '/') ) {
00423     ptr--;
00424   }
00425 
00426   if( *ptr == '/' ) {
00427     ptr++;
00428   }
00429 
00430   PROFILE_END;
00431 
00432   return( ptr );
00433 
00434 }

char* get_dirname char *  str  ) 
 

Extracts directory path from file pathname.

Returns:
Returns pointer to string containing only the directory path
Extracts the directory path from the specified filename (or returns NULL if there is no directory path).

Warning:
Modifies the given string!
Parameters:
str  String containing pathname to file

00447   { PROFILE(GET_DIRNAME);
00448 
00449   char* ptr;  /* Pointer to current character in str */
00450 
00451   ptr = (str + strlen( str )) - 1;
00452 
00453   while( (ptr > str) && (*ptr != '/') ) {
00454     ptr--;
00455   }
00456 
00457   *ptr = '\0';
00458   
00459   PROFILE_END;
00460 
00461   return( str );
00462 
00463 }

const char* get_funit_type int  type  ) 
 

Returns string representation of the specified functional unit type.

Returns:
Returns a string giving the user-readable name of the given functional unit type
Parameters:
type  Type of functional unit (see Functional Unit Types for legal values)

01584   { PROFILE(GET_FUNIT_TYPE);
01585 
01586   const char* type_str;
01587 
01588   if( (type >= 0) && (type < FUNIT_TYPES) ) {
01589     type_str = funit_types[type];
01590   } else {
01591     type_str = funit_types[FUNIT_TYPES];
01592   }
01593 
01594   PROFILE_END;
01595 
01596   return( type_str );
01597 
01598 }

str_link* get_next_vfile str_link curr,
const char *  mod
 

Returns next Verilog file to parse.

Returns:
Returns pointer to next Verilog file to parse or NULL if no files were found.
Iterates through specified file list, searching for next Verilog file to parse. If a file is a library file (suppl field is 'D'), the name of the module to search for is compared with the name of the file.
Parameters:
curr  Pointer to current file in list
mod  Name of module searching for

01155   { PROFILE(GET_NEXT_VFILE);
01156 
01157   str_link* next = NULL;  /* Pointer to next Verilog file to parse */
01158   char      name[256];    /* String holder for module name of file */
01159 
01160   while( (curr != NULL) && (next == NULL) ) {
01161     if( (curr->suppl & 0x1) != 0x1 ) {
01162       next = curr;
01163     } else {
01164       convert_file_to_module( name, 256, curr->str );
01165       if( strcmp( name, mod ) == 0 ) {
01166         next = curr;
01167       } else {
01168         curr = curr->next;
01169       }
01170     }
01171   }
01172 
01173   /* Specify that the returned file will be parsed */
01174   if( next != NULL ) {
01175     next->suppl2 = 1;
01176   }
01177 
01178   PROFILE_END;
01179 
01180   return( next );
01181 
01182 }

bool get_quoted_string FILE *  file,
char *  line
 

Reads in line from file and returns the contents of the quoted string following optional whitespace.

Returns:
Returns TRUE if a quoted string was properly parsed; otherwise, returns FALSE.
Parses a double-quoted string from the file pointer if one exists. Removes quotes.
Parameters:
file  Pointer to file to parse
line  User supplied character array to hold quoted string

00784   { PROFILE(GET_QUOTED_STRING);
00785 
00786   bool found = FALSE;  /* Return value for this function */
00787   char c[128];         /* Temporary whitespace storage */
00788   int  i     = 0;      /* Loop iterator */
00789 
00790   /* First, remove any whitespace and temporarily store it */
00791   while( ((c[i] = getc( file )) != EOF) && isspace( c[i] ) ) i++;
00792 
00793   /* If the character we are looking at is a double-quote, continue parsing */
00794   if( c[i] == '"' ) {
00795 
00796     i = 0;
00797     while( ((line[i] = getc( file )) != EOF) && (line[i] != '"') ) i++;
00798     line[i]  = '\0';
00799     found = TRUE;
00800 
00801   /* Otherwise, ungetc the collected characters */
00802   } else {
00803 
00804     for( ; i >= 0; i-- ) {
00805       (void)ungetc( c[i], file );
00806     }
00807 
00808   }
00809 
00810   PROFILE_END;
00811 
00812   return( found );
00813 
00814 }

char* get_relative_path const char *  abs_path  ) 
 

Allocates memory for and gets the relative pathname for a given absolute filename.

Returns:
Returns relative path of the given absolute pathname to the current path.
Parameters:
abs_path  Absolute pathname of file to get relative path for

00538   { PROFILE(GET_RELATIVE_PATH);
00539 
00540   char*        rel_path = NULL;
00541   char         cwd[4096];
00542   char*        rv;
00543   unsigned int i;
00544 
00545   /* Get the current working directory */
00546   rv = getcwd( cwd, 4096 );
00547   assert( rv != NULL );
00548 
00549   /*
00550    Compare the absolute path to the current working directory path and stop when we see a
00551    miscompare or run into the end of a path string.
00552   */
00553   i = 0;
00554   while( (i < strlen( cwd )) && (i < strlen( abs_path )) && (abs_path[i] == cwd[i]) ) i++;
00555 
00556   /* We should have never gotten to the end of the absolute path */
00557   assert( i < strlen( abs_path ) );
00558 
00559   /*
00560    If the current working directory is completely a part of the absolute path, the relative pathname
00561    is beneath the current working directory.
00562   */
00563   if( i == strlen( cwd ) ) {
00564     rel_path = strdup_safe( abs_path + i + 1 );
00565 
00566   /*
00567    Otherwise, we need to back up and go forward.
00568   */
00569   } else {
00570 
00571     unsigned int save_i;
00572     char         trel[4096];
00573 
00574     /* Find the previous backslash */
00575     while( (i > 0) && (cwd[i] != '/') ) i--;
00576     assert( cwd[i] == '/' );
00577     
00578     /* Save the current position of i */
00579     save_i = i + 1; 
00580 
00581     /* Create back portion of path */
00582     trel[0] = '\0';
00583     for( ; i<strlen( cwd ); i++ ) {
00584       if( cwd[i] == '/' ) {
00585         strcat( trel, "../" );
00586       }
00587     }
00588 
00589     /* Now append the absolute path */
00590     strcat( trel, (abs_path + save_i) );
00591 
00592     /* Finally, make a copy of the calculated relative path */
00593     rel_path = strdup_safe( trel );
00594 
00595   }
00596 
00597   PROFILE_END;
00598 
00599   return( rel_path );
00600 
00601 }

bool is_func_unit const char *  token  ) 
 

Returns TRUE if the specified string is a legal functional unit value.

Returns:
Returns TRUE if the specified token is a valid argument representing a functional unit.
Parameters:
token  Pointer to string to parse

00353   { PROFILE(IS_FUNC_UNIT);
00354 
00355   char* orig;                          /* Temporary string */
00356   char* rest;                          /* Temporary string */
00357   char* front;                         /* Temporary string */
00358   bool  okay = (strlen( token ) > 0);  /* Specifies if this token is a functional unit value or not */
00359 
00360   /* Allocate memory */
00361   orig  = strdup_safe( token );
00362   rest  = strdup_safe( token );
00363   front = strdup_safe( token );
00364 
00365   /* Check to make sure that each value between '.' is a valid variable */
00366   while( (strlen( orig ) > 0) && okay ) {
00367     scope_extract_front( orig, front, rest );
00368     if( !is_variable( front ) ) {
00369       okay = FALSE;
00370     } else {
00371       strcpy( orig, rest );
00372     }
00373   }
00374 
00375   /* Deallocate memory */
00376   free_safe( orig, (strlen( token ) + 1) );
00377   free_safe( rest, (strlen( token ) + 1) );
00378   free_safe( front, (strlen( token ) + 1) );
00379 
00380   PROFILE_END;
00381 
00382   return( okay );
00383 
00384 }

bool is_legal_filename const char *  token  ) 
 

Returns TRUE if the specified string could be a valid filename.

Returns:
Returns TRUE if the specified string would be a legal filename to write to; otherwise, returns FALSE.
Parameters:
token  String to check for valid pathname-ness

00392   { PROFILE(IS_LEGAL_FILENAME);
00393 
00394   bool  retval = FALSE;  /* Return value for this function */
00395   FILE* tmpfile;         /* Temporary file pointer */
00396 
00397   if( (tmpfile = fopen( token, "w" )) != NULL ) {
00398     unsigned int rv = fclose( tmpfile );
00399     assert( rv == 0 );
00400     retval = TRUE;
00401   }
00402 
00403   PROFILE_END;
00404 
00405   return( retval );
00406 
00407 }

bool is_variable const char *  token  ) 
 

Returns TRUE if the specified string is a legal variable name.

Returns:
Returns TRUE if the specified string is a legal variable name; otherwise, returns FALSE.
If the specified string follows all of the rules for a legal program variable (doesn't start with a number, contains only a-zA-Z0-9_ characters), returns a value of TRUE; otherwise, returns a value of FALSE.
Parameters:
token  String to check for valid variable name

00311   { PROFILE(IS_VARIABLE);
00312 
00313   bool retval = TRUE;   /* Return value of this function */
00314 
00315   if( token != NULL ) {
00316 
00317     if( (token[0] >= '0') && (token[0] <= '9') ) {
00318 
00319       retval = FALSE;
00320 
00321     } else {
00322 
00323       while( (token[0] != '\0') && retval ) {
00324         if( !(((token[0] >= 'a') && (token[0] <= 'z')) ||
00325              ((token[0] >= 'A') && (token[0] <= 'Z')) ||
00326              ((token[0] >= '0') && (token[0] <= '9')) ||
00327               (token[0] == '_')) ) {
00328           retval = FALSE;
00329         }
00330         token++;
00331       }
00332 
00333     }
00334 
00335   } else {
00336 
00337     retval = FALSE;
00338 
00339   }
00340 
00341   PROFILE_END;
00342 
00343   return( retval );
00344 
00345 }

void* malloc_safe1 size_t  size,
const char *  file,
int  line,
unsigned int  profile_index
 

Performs safe malloc call.

Returns:
Pointer to allocated memory.
Allocated memory like a malloc() call but performs some pre-allocation and post-allocation checks to be sure that the malloc call works properly.
Parameters:
size  Number of bytes to allocate
file  File that called this function
line  Line number of file that called this function
profile_index  Profile index of function that called this function

01195   {
01196 
01197   void* obj;  /* Object getting malloc address */
01198 
01199   assert( size <= MAX_MALLOC_SIZE );
01200 
01201   curr_malloc_size += size;
01202 
01203   if( curr_malloc_size > largest_malloc_size ) {
01204     largest_malloc_size = curr_malloc_size;
01205   }
01206 
01207   obj = malloc( size );
01208 #ifdef TESTMODE
01209   if( test_mode ) {
01210     printf( "MALLOC (%p) %d bytes (file: %s, line: %d) - %lld\n", obj, size, file, line, curr_malloc_size );
01211   }
01212 #endif
01213   assert( obj != NULL );
01214 
01215   /* Profile the malloc */
01216   MALLOC_CALL(profile_index);
01217 
01218   return( obj );
01219 
01220 }

void* malloc_safe_nolimit1 size_t  size,
const char *  file,
int  line,
unsigned int  profile_index
 

Performs safe malloc call without upper bound on byte allocation.

Returns:
Pointer to allocated memory.
Allocated memory like a malloc() call but performs some pre-allocation and post-allocation checks to be sure that the malloc call works properly. Unlike malloc_safe, there is no upper bound on the amount of memory to allocate.
Parameters:
size  Number of bytes to allocate
file  Name of file that called this function
line  Line number of file that called this function
profile_index  Profile index of function that called this function

01234   {
01235 
01236   void* obj;  /* Object getting malloc address */
01237 
01238   curr_malloc_size += size;
01239 
01240   if( curr_malloc_size > largest_malloc_size ) {
01241     largest_malloc_size = curr_malloc_size;
01242   }
01243 
01244   obj = malloc( size );
01245 #ifdef TESTMODE
01246   if( test_mode ) {
01247     printf( "MALLOC (%p) %d bytes (file: %s, line: %d) - %lld\n", obj, size, file, line, curr_malloc_size );
01248   }
01249 #endif
01250   assert( obj != NULL );
01251 
01252   /* Profile the malloc */
01253   MALLOC_CALL(profile_index);
01254 
01255   return( obj );
01256 
01257 }

void print_output const char *  msg,
int  type,
const char *  file,
int  line
 

Displays error message to standard output.

Displays the specified message to standard output based on the type of message being output.

Parameters:
msg  Message to display
type  Type of message to output (see Output type for legal values)
file  Name of file that called this function
line  Line number that this function was called in

00157   {
00158 
00159   FILE* outf = debug_mode ? stdout : stderr;
00160   char  tmpmsg[USER_MSG_LENGTH];
00161 
00162   switch( type ) {
00163     case DEBUG:
00164       if( debug_mode && (!flag_use_command_line_debug || cli_debug_mode) ) {
00165 #ifdef VPI_ONLY
00166         vpi_print_output( msg );
00167 #else
00168         unsigned int rv;
00169         printf( "%s\n", msg );  rv = fflush( stdout );  assert( rv == 0 );
00170 #endif
00171       }
00172       break;
00173     case NORMAL:
00174       if( !output_suppressed || debug_mode ) {
00175 #ifdef VPI_ONLY
00176         vpi_print_output( msg );
00177 #else
00178         printf( "%s\n", msg );
00179 #endif
00180       }
00181       break;
00182     case WARNING:
00183       if( !output_suppressed && !warnings_suppressed ) {
00184         if( report_gui ) {
00185           unsigned int rv = snprintf( tmpmsg, USER_MSG_LENGTH, "WARNING!  %s\n", msg );
00186           assert( rv < USER_MSG_LENGTH );
00187 #ifndef VPI_ONLY
00188 #ifdef HAVE_TCLTK
00189           Tcl_SetResult( interp, tmpmsg, TCL_VOLATILE );
00190 #endif
00191 #endif
00192         } else {
00193           fprintf( outf, "    WARNING!  %s\n", msg );
00194         }
00195       } else if( debug_mode ) {
00196         if( report_gui ) {
00197           unsigned int rv = snprintf( tmpmsg, USER_MSG_LENGTH, "WARNING!  %s (file: %s, line: %d)\n", msg, file, line );
00198           assert( rv < USER_MSG_LENGTH );
00199 #ifndef VPI_ONLY
00200 #ifdef HAVE_TCLTK
00201           Tcl_SetResult( interp, tmpmsg, TCL_VOLATILE );
00202 #endif
00203 #endif
00204         } else {
00205           fprintf( outf, "    WARNING!  %s (file: %s, line: %d)\n", msg, obf_file( file ), line );
00206         }
00207       }
00208       break;
00209     case WARNING_WRAP:
00210       if( (!output_suppressed && !warnings_suppressed) || debug_mode ) {
00211         if( report_gui ) {
00212           unsigned int rv = snprintf( tmpmsg, USER_MSG_LENGTH, "              %s\n", msg );
00213           assert( rv < USER_MSG_LENGTH );
00214 #ifndef VPI_ONLY
00215 #ifdef HAVE_TCLTK
00216           Tcl_AppendElement( interp, tmpmsg );
00217 #endif
00218 #endif
00219         } else {
00220           fprintf( outf, "              %s\n", msg );
00221         }
00222       }
00223       break; 
00224     case FATAL:
00225       if( debug_mode ) {
00226         if( report_gui ) {
00227           unsigned int rv = snprintf( tmpmsg, USER_MSG_LENGTH, "%s (file: %s, line: %d)\n", msg, file, line );
00228           assert( rv < USER_MSG_LENGTH );
00229 #ifndef VPI_ONLY
00230 #ifdef HAVE_TCLTK
00231           Tcl_SetResult( interp, tmpmsg, TCL_VOLATILE );
00232           fprintf( stderr, "ERROR!  %s (file: %s, line: %d)\n", msg, obf_file( file ), line );
00233 #endif
00234 #endif
00235         } else {
00236           fprintf( stderr, "ERROR!  %s (file: %s, line: %d)\n", msg, obf_file( file ), line );
00237         }
00238       } else {
00239         if( report_gui ) {
00240           unsigned int rv = snprintf( tmpmsg, USER_MSG_LENGTH, "%s\n", msg );
00241           assert( rv < USER_MSG_LENGTH );
00242 #ifndef VPI_ONLY
00243 #ifdef HAVE_TCLTK
00244           Tcl_SetResult( interp, tmpmsg, TCL_VOLATILE );
00245           fprintf( stderr, "ERROR!  %s\n", msg );
00246 #endif
00247 #endif
00248         } else {
00249           fprintf( stderr, "ERROR!  %s\n", msg );
00250         }
00251       }
00252       break;
00253     case FATAL_WRAP:
00254       if( report_gui ) {
00255         unsigned int rv = snprintf( tmpmsg, USER_MSG_LENGTH, "%s\n", msg );
00256         assert( rv < USER_MSG_LENGTH );
00257 #ifndef VPI_ONLY
00258 #ifdef HAVE_TCLTK
00259         Tcl_AppendElement( interp, tmpmsg );
00260 #endif
00261 #endif
00262       } else { 
00263         fprintf( stderr, "        %s\n", msg );
00264       }
00265       break;
00266     default:  break;
00267   }
00268 
00269 }

void read_command_file const char *  cmd_file,
char ***  arg_list,
int *  arg_num
 

Reads in contents of command file, substitutes environment variables and stores them to the arg_list array.

Exceptions:
anonymous Throw Throw Throw substitute_env_vars
Parses the given file specified by the '-f' option to one of Covered's commands which can contain any command-line arguments. Performs environment variable substitution to any $... variables that are found in the file.
Parameters:
cmd_file  Name of file to read commands from
arg_list  List of arguments found in specified command file
arg_num  Number of arguments in arg_list array

01637   { PROFILE(READ_COMMAND_FILE);
01638 
01639   str_link* head    = NULL;  /* Pointer to head element of arg list */
01640   str_link* tail    = NULL;  /* Pointer to tail element of arg list */
01641   FILE*     cmd_handle;      /* Pointer to command file */
01642   char      tmp_str[4096];   /* Temporary holder for read argument */
01643   str_link* curr;            /* Pointer to current str_link element */
01644   int       tmp_num = 0;     /* Temporary argument number holder */
01645   bool      use_stdin;       /* If set to TRUE, uses stdin for the cmd_handle */
01646 
01647   /* Figure out if we should use stdin */
01648   use_stdin = (strcmp( "-", cmd_file ) == 0);
01649 
01650   if( use_stdin || file_exists( cmd_file ) ) {
01651 
01652     if( (cmd_handle = (use_stdin ? stdin : fopen( cmd_file, "r" ))) != NULL ) {
01653 
01654       unsigned int rv;
01655 
01656       Try {
01657 
01658         while( get_quoted_string( cmd_handle, tmp_str ) || fscanf( cmd_handle, "%s", tmp_str ) == 1 ) {
01659           (void)str_link_add( substitute_env_vars( tmp_str ), &head, &tail );
01660           tmp_num++;
01661         }
01662 
01663       } Catch_anonymous {
01664         rv = fclose( cmd_handle );
01665         assert( rv == 0 );
01666         str_link_delete_list( head );
01667         Throw 0;
01668       }
01669 
01670       rv = fclose( cmd_handle );
01671       assert( rv == 0 );
01672 
01673       /* Set the argument list number now */
01674       *arg_num = tmp_num;
01675 
01676       /*
01677        If there were any arguments found in the file, create an argument list and pass it to the
01678        command-line parser.
01679       */
01680       if( tmp_num > 0 ) {
01681 
01682         /* Create argument list */
01683         *arg_list = (char**)malloc_safe( sizeof( char* ) * tmp_num );
01684         tmp_num   = 0;
01685 
01686         curr = head;
01687         while( curr != NULL ) {
01688           (*arg_list)[tmp_num] = strdup_safe( curr->str );
01689           tmp_num++;
01690           curr = curr->next;
01691         } 
01692         
01693         /* Delete list */
01694         str_link_delete_list( head );
01695         
01696       } 
01697         
01698     } else {
01699 
01700       unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to open command file %s for reading", cmd_file );
01701       assert( rv < USER_MSG_LENGTH );
01702       print_output( user_msg, FATAL, __FILE__, __LINE__ );
01703       Throw 0;
01704 
01705     }
01706 
01707   } else {
01708 
01709     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Command file %s does not exist", cmd_file );
01710     assert( rv < USER_MSG_LENGTH );
01711     print_output( user_msg, FATAL, __FILE__, __LINE__ );
01712     Throw 0;
01713         
01714   }
01715 
01716 }

void* realloc_safe1 void *  ptr,
size_t  old_size,
size_t  size,
const char *  file,
int  line,
unsigned int  profile_index
 

Safely reallocates heap memory by performing a call to realloc.

Calls the realloc() function for the specified memory and size, making sure that the memory size doesn't exceed a threshold value and that the requested memory was allocated.

Parameters:
ptr  Pointer to old memory to copy
old_size  Size of originally allocated memory (in bytes)
size  Size of new allocated memory (in bytes)
file  Name of file that called this function
line  Line number of file that called this function
profile_index  Profile index of function that called this function

01351   {
01352 
01353   void* newptr;
01354 
01355   assert( size <= MAX_MALLOC_SIZE );
01356 
01357   curr_malloc_size -= old_size;
01358   curr_malloc_size += size;
01359   if( curr_malloc_size > largest_malloc_size ) {
01360     largest_malloc_size = curr_malloc_size;
01361   }
01362  
01363   if( size == 0 ) {
01364     if( ptr != NULL ) {
01365       free( ptr );
01366     }
01367     newptr = NULL;
01368   } else {
01369     newptr = realloc( ptr, size );
01370     assert( newptr != NULL );
01371   }
01372 #ifdef TESTMODE
01373   if( test_mode ) {
01374     printf( "REALLOC (%p -> %p) %d (%d) bytes (file: %s, line: %d) - %lld\n", ptr, newptr, size, old_size, file, line, curr_malloc_size );
01375   }
01376 #endif
01377 
01378   MALLOC_CALL(profile_index);
01379 
01380   return( newptr );
01381 
01382 }

char* remove_underscores char *  str  ) 
 

Removes underscores from the specified string.

Returns:
Returns a pointer to the modified string (or NULL if the string only contains underscores).
Parameters:
str  String to remove underscore characters from

01452   { PROFILE(REMOVE_UNDERSCORES);
01453 
01454   char*        start = NULL;
01455   unsigned int i;
01456   unsigned int cur   = 1;
01457 
01458   for( i=0; i<strlen( str ); i++ ) {
01459     if( str[i] != '_' ) {
01460       if( start == NULL ) {
01461         start = str + i;
01462       } else {
01463         start[cur++] = str[i];
01464       }
01465     }
01466   }
01467 
01468   if( start != NULL ) {
01469     start[cur] = '\0';
01470   }
01471 
01472   PROFILE_END;
01473 
01474   return( start );
01475 
01476 }

bool scope_compare const char *  str1,
const char *  str2
 

Compares two signal names or two instance names.

Returns:
Returns TRUE if the two strings are equal, properly handling the case where one or both are escaped names (start with an escape character and end with a space).
Parameters:
str1  Pointer to signal/instance name
str2  Pointer to signal/instance name

01032   { PROFILE(SCOPE_COMPARE);
01033 
01034   bool  retval;    /* Return value for this function */
01035   char* new_str1;  /* New form of str1 with escaped sequences removed */
01036   char* new_str2;  /* New form of str1 with escaped sequences removed */
01037 
01038   /* Create printable versions of the strings */
01039   new_str1 = scope_gen_printable( str1 );
01040   new_str2 = scope_gen_printable( str2 );
01041 
01042   /* Perform the compare */
01043   retval = (strcmp( new_str1, new_str2 ) == 0);
01044 
01045   /* Deallocate the memory */
01046   free_safe( new_str1, (strlen( new_str1 ) + 1) );
01047   free_safe( new_str2, (strlen( new_str2 ) + 1) );
01048 
01049   PROFILE_END;
01050 
01051   return( retval );
01052 
01053 }

void scope_extract_back const char *  scope,
char *  back,
char *  rest
 

Extracts lowest level of hierarchy from specified scope.

Extracts the lowest level of hierarchy from the specified scope, returning that instance name to the value of back and the the rest of the hierarchy in the value of rest.

Parameters:
scope  Full scope to extract from
back  Lowest level of hierarchy extracted
rest  Hierarchy left after extraction

00938   { PROFILE(SCOPE_EXTRACT_BACK);
00939 
00940   const char* ptr;      /* Pointer to current character */
00941   char        endchar;  /* Set to the character we are searching for */
00942 
00943   ptr = scope + strlen( scope ) - 1;
00944 
00945   /* Figure out if we are looking for a '.' or a ' ' character */
00946   endchar = (*ptr == ' ') ? '\\' : '.';
00947 
00948   while( (ptr > scope) && (*ptr != endchar) ) {
00949     ptr--;
00950   }
00951 
00952   /* If this is a literal, keep going until we see the '.' character */
00953   if( endchar == '\\' ) {
00954     while( (ptr > scope) && (*ptr != '.') ) {
00955       ptr--;
00956     }
00957   }
00958 
00959   strncpy( rest, scope, (ptr - scope) );
00960   rest[ (ptr - scope) ] = '\0';
00961 
00962   if( *ptr == '.' ) {
00963     ptr++;
00964   }
00965 
00966   strncpy( back, ptr, ((strlen( scope ) + scope) - ptr) );
00967   back[ ((strlen( scope ) + scope) - ptr) ] = '\0';
00968 
00969   PROFILE_END;
00970   
00971 }

void scope_extract_front const char *  scope,
char *  front,
char *  rest
 

Extracts highest level of hierarchy from specified scope.

Extracts the highest level of hierarchy from the specified scope, returning that instance name to the value of front and the the rest of the hierarchy in the value of rest.

Parameters:
scope  Full scope to extract from
front  Highest level of hierarchy extracted
rest  Hierarchy left after extraction

00893   { PROFILE(SCOPE_EXTRACT_FRONT);
00894   
00895   const char* ptr;      /* Pointer to current character */
00896   char        endchar;  /* Set to the character we are searching for */
00897   
00898   ptr = scope;
00899 
00900   /* Figure out if we are looking for a '.' or a ' ' character */
00901   endchar = (*ptr == '\\') ? ' ' : '.';
00902   
00903   while( (*ptr != '\0') && (*ptr != endchar) ) {
00904     ptr++;
00905   }
00906 
00907   /* If this is a literal, keep going until we see the '.' character */
00908   if( endchar == ' ' ) {
00909     while( (*ptr != '\0') && (*ptr != '.') ) {
00910       ptr++;
00911     }
00912   }
00913   
00914   strncpy( front, scope, (ptr - scope) );
00915   front[ (ptr - scope) ] = '\0';
00916   
00917   if( *ptr == '.' ) {
00918     ptr++;
00919     strncpy( rest, ptr, (strlen( scope ) - (ptr - scope)) );
00920     rest[ (strlen( scope ) - (ptr - scope)) ] = '\0';
00921   } else {
00922     rest[0] = '\0';
00923   }
00924 
00925   PROFILE_END;
00926   
00927 }

void scope_extract_scope const char *  scope,
const char *  front,
char *  back
 

Extracts rest of scope not included in front.

Parses the given scope and removes the front portion of this scope (if the front portion of the scope matches the beginning portion of scope) and returns the remaining scope in the array pointed to by back. If front does not exist within scope, back is set to a value of the null string. Assumes that the length of back is allocated and large enough to hold the full value of scope, if necessary.

Parameters:
scope  Full scope to search
front  Leading portion of scope to exclude
back  Following portion of scope that is in scope that is not in front

00983   { PROFILE(SCOPE_EXTRACT_SCOPE);
00984 
00985   back[0] = '\0';
00986 
00987   if( (strncmp( scope, front, strlen( front ) ) == 0) && (strlen( scope ) > strlen( front )) ) {
00988     strcpy( back, (scope + strlen( front ) + 1) );
00989   }
00990 
00991   PROFILE_END;
00992 
00993 }

char* scope_gen_printable const char *  str  ) 
 

Generates printable version of given signal/instance string.

Returns:
Returns printable version of the given string (with any escaped sequences removed)
Allocates memory for and generates a printable version of the given string (a signal or instance name). The calling function is responsible for deallocating the string returned.
Parameters:
str  String to create printable version of

01003   { PROFILE(SCOPE_GEN_PRINTABLE);
01004 
01005   char* new_str;  /* New version of string with escaped sequences removed */
01006 
01007   assert( strlen( obf_sig( str ) ) < 4096 );
01008 
01009   /* Remove escape sequences, if any */
01010   if( str[0] == '\\' ) {
01011     char         tmp_str[4096];
01012     unsigned int rv = sscanf( str, "\\%[^ \n\t\r\b]", tmp_str );
01013     assert( rv == 1 );
01014     new_str = strdup_safe( tmp_str );
01015   } else {
01016     new_str = strdup_safe( obf_sig( str ) );
01017   }
01018 
01019   PROFILE_END;
01020 
01021   return( new_str );
01022 
01023 } 

bool scope_local const char *  scope  ) 
 

Returns TRUE if specified scope is local (contains no periods).

Parameters:
scope  Scope of some signal

01064   { PROFILE(SCOPE_LOCAL);
01065 
01066   const char* ptr;             /* Pointer to current character */
01067   bool        esc;             /* Set to TRUE if current is escaped */
01068   bool        wspace = FALSE;  /* Set if last character seen was a whitespace */
01069 
01070   assert( scope != NULL );
01071 
01072   ptr = scope;
01073   esc = (*ptr == '\\');
01074   while( (*ptr != '\0') && ((*ptr != '.') || esc) ) {
01075     if( (*ptr == ' ') || (*ptr == '\n') || (*ptr == '\t') || (*ptr == '\b') || (*ptr == '\r') ) {
01076       esc    = FALSE;
01077       wspace = TRUE;
01078     } else {
01079       if( wspace && (*ptr == '\\') ) {
01080         esc = TRUE;
01081       }
01082     }
01083     ptr++;
01084   }
01085 
01086   PROFILE_END;
01087 
01088   return( *ptr == '\0' );
01089 
01090 }

void set_debug bool  value  ) 
 

Sets global debug flag to specified value.

Sets the global debug mode to the specified value.

Parameters:
value  Boolean value of debug mode

00132   {
00133 
00134   debug_mode = value;
00135 
00136 }

void set_output_suppression bool  value  ) 
 

Sets error suppression to specified value.

Sets the global variable output_suppressed to the specified value.

Parameters:
value  Boolean value of suppression

00121   {
00122 
00123   output_suppressed = value;
00124 
00125 }

void set_testmode  ) 
 

Sets the testmode global variable for outputting purposes.

Looks at the user's environment and searches for COVERED_TESTMODE, if the environment variable is set, sets the global test_mode variable to TRUE; otherwise, sets it to FALSE.

00142                     {
00143 
00144   test_mode = (getenv( "COVERED_TESTMODE" ) != NULL);
00145 
00146 }

char* strdup_safe1 const char *  str,
const char *  file,
int  line,
unsigned int  profile_index
 

Safely allocates heap memory by performing a call to strdup.

Calls the strdup() function for the specified string, making sure that the string to allocate is a healthy string (contains NULL character).

Parameters:
str  String to duplicate
file  Name of file that called this function
line  Line number of file that called this function
profile_index  Profile index of function that called this function

01315   {
01316 
01317   char* new_str;
01318   int   str_len = strlen( str ) + 1;
01319 
01320   assert( str_len <= MAX_MALLOC_SIZE );
01321   curr_malloc_size += str_len;
01322   if( curr_malloc_size > largest_malloc_size ) {
01323     largest_malloc_size = curr_malloc_size;
01324   }
01325   new_str = strdup( str );
01326 #ifdef TESTMODE
01327   if( test_mode ) {
01328     printf( "STRDUP (%p) %d bytes (file: %s, line: %d) - %lld\n", new_str, str_len, file, line, curr_malloc_size );
01329   }
01330 #endif
01331   assert( new_str != NULL );
01332 
01333   /* Profile the malloc */
01334   MALLOC_CALL(profile_index);
01335 
01336   return( new_str );
01337 
01338 }

char* substitute_env_vars const char *  value  ) 
 

Searches the specified string for environment variables and substitutes their value if found.

Returns:
Returns the given value with environment variables substituted in. This value should be freed by the calling function.
Exceptions:
anonymous Throw
Parameters:
value  Input string that will be searched for environment variables

00824   { PROFILE(SUBSTITUTE_ENV_VARS);
00825 
00826   char*       newvalue      = NULL;   /* New value */
00827   int         newvalue_index;         /* Current index into newvalue */
00828   const char* ptr;                    /* Pointer to current character in value */
00829   char        env_var[4096];          /* Name of found environment variable */
00830   int         env_var_index = 0;      /* Current index to write into env_var string */
00831   bool        parsing_var   = FALSE;  /* Set to TRUE when we are parsing an environment variable */
00832   char*       env_value;              /* Environment variable value */
00833 
00834   newvalue       = (char*)malloc_safe( 1 );
00835   newvalue[0]    = '\0';
00836   ptr            = value;
00837   newvalue_index = 0;
00838 
00839   Try {
00840 
00841     while( *ptr != '\0' || parsing_var ) {
00842       if( parsing_var ) {
00843         if( isalnum( *ptr ) || (*ptr == '_') ) {
00844           env_var[env_var_index] = *ptr;
00845           env_var_index++;
00846         } else {
00847           env_var[env_var_index] = '\0';
00848           if( (env_value = getenv( env_var )) != NULL ) {
00849             newvalue = (char*)realloc_safe( newvalue, (strlen( newvalue ) + 1), (newvalue_index + strlen( env_value ) + 1) );
00850             strcat( newvalue, env_value );
00851             newvalue_index += strlen( env_value );
00852             parsing_var = FALSE;
00853             ptr--;
00854           } else {
00855             unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unknown environment variable $%s in string \"%s\"", env_var, value );
00856             assert( rv < USER_MSG_LENGTH );
00857             print_output( user_msg, FATAL, __FILE__, __LINE__ );
00858             Throw 0;
00859           }
00860         }
00861       } else if( *ptr == '$' ) {
00862         parsing_var   = TRUE;
00863         env_var_index = 0;
00864       } else {
00865         newvalue = (char*)realloc_safe( newvalue, (strlen( newvalue ) + 1), (newvalue_index + 2) );
00866         newvalue[newvalue_index]   = *ptr;
00867         newvalue[newvalue_index+1] = '\0';
00868         newvalue_index++;
00869       }
00870       ptr++;
00871     }
00872 
00873   } Catch_anonymous {
00874     free_safe( newvalue, (strlen( newvalue ) + 1) );
00875     Throw 0;
00876   }
00877 
00878   PROFILE_END;
00879 
00880   return( newvalue );
00881 
00882 }

void timer_clear timer **  tm  ) 
 

Clears the timer, resetting the accumulated time information and allocating timer memory, if needed.

Clears the total accumulated time in the specified timer structure.

Parameters:
tm  Pointer to timer structure to clear

01484   {
01485 
01486   if( *tm == NULL ) {
01487     *tm = (timer*)malloc_safe( sizeof( timer ) );
01488   }
01489 
01490   (*tm)->total = 0;
01491 
01492 }

void timer_start timer **  tm  ) 
 

Starts timing the specified timer structure and allocates/clears timer memory, if needed.

Starts the timer to start timing a segment of code.

Parameters:
tm  Pointer to timer structure to start timing

01499    {
01500 
01501   if( *tm == NULL ) {
01502     *tm = (timer*)malloc_safe( sizeof( timer ) );
01503     timer_clear( tm );
01504   }
01505 
01506   gettimeofday( &((*tm)->start), NULL );
01507 
01508 }

void timer_stop timer **  tm  ) 
 

Stops timing the specified timer structure.

Stops the specified running counter and totals up the amount of user time that has accrued.

Parameters:
tm  Pointer to timer structure to stop timing

01516   {
01517 
01518   struct timeval tmp;  /* Temporary holder for stop time */
01519 
01520   assert( *tm != NULL );
01521 
01522   gettimeofday( &tmp, NULL );
01523   (*tm)->total += ((tmp.tv_sec - (*tm)->start.tv_sec) * 1000000) + (tmp.tv_usec - (*tm)->start.tv_usec);
01524 
01525 }

char* timer_to_string timer tm  ) 
 

Generates a human-readable time-of-day string from the given timer structure.

Returns:
Returns a user-readable version of the timer structure.
Parameters:
tm  Pointer to timer structure

01532   {
01533 
01534   static char str[33];  /* Minimal amount of space needed to store the current time */
01535 
01536 #ifdef TESTMODE
01537   strcpy( str, "NA" );
01538 #else
01539   /* If the time is less than a minute, output the seconds and milliseconds */
01540   if( tm->total < 10 ) {
01541     /*@-duplicatequals -formattype@*/
01542     unsigned int rv = snprintf( str, 33, "0.00000%1llu seconds", tm->total );
01543     /*@=duplicatequals =formattype@*/
01544     assert( rv < 33 );
01545   } else if( tm->total < 100 ) {
01546     /*@-duplicatequals -formattype@*/
01547     unsigned int rv = snprintf( str, 33, "0.0000%1llu seconds", (tm->total / 10) ); 
01548     /*@=duplicatequals =formattype@*/
01549     assert( rv < 33 );
01550   } else if( tm->total < 1000 ) {
01551     /*@-duplicatequals -formattype@*/
01552     unsigned int rv = snprintf( str, 33, "0.000%1llu seconds", (tm->total / 100) );
01553     /*@=duplicatequals =formattype@*/
01554     assert( rv < 33 );
01555   } else if( tm->total < 60000000 ) {
01556     /*@-duplicatequals -formattype@*/
01557     unsigned int rv = snprintf( str, 33, "%2llu.%03llu seconds", (tm->total / 1000000), ((tm->total % 1000000) / 1000) );
01558     /*@=duplicatequals =formattype@*/
01559     assert( rv < 33 );
01560   } else if( tm->total < 3600000000LL ) {
01561     /*@-duplicatequals -formattype@*/
01562     unsigned int rv = snprintf( str, 33, "%2llu minutes, %2llu seconds", (tm->total / 60000000), ((tm->total % 60000000) / 1000000) );
01563     /*@=duplicatequals =formattype@*/
01564     assert( rv < 33 );
01565   } else {
01566     /*@-duplicatequals -formattype@*/
01567     unsigned int rv = snprintf( str, 33, "%2llu hours, %2llu minutes, %2llu seconds", 
01568                                 (tm->total / 3600000000LL), ((tm->total % 3600000000LL) / 60000000), ((tm->total % 60000000) / 1000000) );
01569     /*@=duplicatequals =formattype@*/
01570     assert( rv < 33 );
01571   }
01572 #endif
01573 
01574   return( str );
01575 
01576 }

bool util_readline FILE *  file,
char **  line,
unsigned int *  line_size
 

Reads line from file and returns it in string form.

Returns:
Returns FALSE if feof is encountered; otherwise, returns TRUE.
Reads in a single line of information from the specified file and returns a string containing the read line to the calling function.
Parameters:
file  File to read next line from
line  Pointer to string which will contain read line minus newline character
line_size  Pointer to number of characters allocated for line

00743   { PROFILE(UTIL_READLINE);
00744 
00745   char         c;      /* Character recently read from file */
00746   unsigned int i = 0;  /* Current index of line */
00747 
00748   *line_size = 128;
00749   *line      = (char*)malloc_safe( *line_size );
00750 
00751   while( !feof( file ) && ((c = (char)fgetc( file )) != '\n') ) {
00752 
00753     if( i == (*line_size - 1) ) {
00754       *line_size *= 2;
00755       *line       = (char*)realloc_safe( *line, (*line_size / 2), *line_size );
00756     }
00757 
00758     (*line)[i] = c;
00759     i++;
00760 
00761   }
00762 
00763   if( !feof( file ) ) {
00764     (*line)[i] = '\0';
00765   } else {
00766     free_safe( *line, *line_size );
00767     *line = NULL;
00768   }
00769 
00770   PROFILE_END;
00771 
00772   return( !feof( file ) );
00773 
00774 }


Variable Documentation

bool cli_debug_mode = FALSE [static]
 

int64 curr_malloc_size = 0
 

Contains the total number of bytes malloc'ed during the simulation run. This information is output to the user after simulation as a performance indicator.

bool debug_mode
 

If set to TRUE, causes debug information to be spewed to screen.

bool flag_use_command_line_debug
 

Specifies whether the command-line debugger should be enabled

const char* funit_types[FUNIT_TYPES+1] = { "module", "named block", "function", "task", "no_score", "afunction", "atask", "named block", "UNKNOWN" } [static]
 

Array of functional unit names used for output purposes.

Tcl_Interp* interp
 

TCL interpreter for this application.

int64 largest_malloc_size = 0
 

Holds the largest number of bytes in allocation at one period of time.

bool output_suppressed
 

If set to TRUE, suppresses all non-fatal error messages from being displayed.

bool report_gui
 

If set to a boolean value of TRUE, displays GUI report viewer instead of generating text report files.

bool test_mode = FALSE
 

If set to TRUE, outputs memory information to standard output for processing.

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.

bool warnings_suppressed = FALSE
 

If set to TRUE, suppresses all warnings from being displayed.


Generated on Wed Jun 17 22:19:24 2009 for Covered by doxygen 1.3.4