info.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "db.h"
#include "defines.h"
#include "info.h"
#include "link.h"
#include "score.h"
#include "util.h"

Functions

void score_add_args (const char *arg1, const char *arg2)
 Adds the given argument(s) from the command-line to the score array such that no arguments are duplicated.
void info_set_vector_elem_size ()
void info_db_write (FILE *file)
 Writes info line to specified CDD file.
bool info_db_read (char **line, int read_mode)
 Reads info line from specified line and stores information.
void args_db_read (char **line)
 Reads score args line from specified line and stores information.
void message_db_read (char **line)
 Reads user-specified message from specified line and stores information.
void merged_cdd_db_read (char **line)
 Reads merged CDD information from specified line and stores information.
void info_dealloc ()
 Deallocates all memory associated with the information section of a database file.

Variables

db ** db_list
unsigned int curr_db
str_linkmerge_in_head
str_linkmerge_in_tail
int merge_in_num
char * merged_file
uint64 num_timesteps
char * cdd_message
char user_msg [USER_MSG_LENGTH]
isuppl info_suppl = {0}
int cdd_version = CDD_VERSION
char score_run_path [4096]
str_linkscore_args_head = NULL
str_linkscore_args_tail = NULL

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
2/12/2003

Function Documentation

void args_db_read ( char **  line  ) 

Reads score args line from specified line and stores information.

Exceptions:
anonymous Throw

Reads score command-line args line from specified string and stores its information.

Parameters:
line Pointer to string containing information line to parse

References FATAL, print_output(), PROFILE, PROFILE_END, score_add_args(), score_run_path, and Throw.

Referenced by db_read().

00321   { PROFILE(ARGS_DB_READ);
00322 
00323   int  chars_read;  /* Number of characters scanned in from this line */
00324   char tmp1[4096];  /* Temporary string */
00325   char tmp2[4096];  /* Temporary string */
00326   int  arg_num;
00327 
00328   if( sscanf( *line, "%s%n", score_run_path, &chars_read ) == 1 ) {
00329 
00330     *line = *line + chars_read;
00331 
00332     /* Store score command-line arguments */
00333     while( sscanf( *line, "%d%n", &arg_num, &chars_read ) == 1 ) {
00334       *line = *line + chars_read;
00335       if( (arg_num == 1) && (sscanf( *line, "%s%n", tmp1, &chars_read ) == 1) ) {
00336         score_add_args( tmp1, NULL );
00337       } else if( (arg_num == 2) && (sscanf( *line, "%s (%[^)])%n", tmp1, tmp2, &chars_read ) == 2) ) {
00338         score_add_args( tmp1, tmp2 );
00339       }
00340       *line = *line + chars_read;
00341     }
00342 
00343   } else {
00344 
00345     print_output( "CDD file being read is incompatible with this version of Covered", FATAL, __FILE__, __LINE__ );
00346     Throw 0;
00347 
00348   }
00349 
00350   PROFILE_END;
00351 
00352 }

bool info_db_read ( char **  line,
int  read_mode 
)

Reads info line from specified line and stores information.

Exceptions:
anonymous Throw Throw Throw
Returns:
Returns TRUE if the CDD file read should continue; otherwise, stop reading in the current CDD.

Reads information line from specified string, stores its information, and creates a new database in the database list.

Parameters:
line Pointer to string containing information line to parse
read_mode Type of read being performed

References isuppl_u::all, CDD_VERSION, curr_db, db_create(), FALSE, FATAL, db_s::leading_hier_num, db_s::leading_hierarchies, db_s::leading_hiers_differ, merge_in_num, num_timesteps, isuppl_u::part, print_output(), PROFILE, PROFILE_END, READ_MODE_MERGE_NO_MERGE, realloc_safe, isuppl_u::scored, strdup_safe, Throw, and TRUE.

Referenced by db_read().

00236   { PROFILE(INFO_DB_READ);
00237 
00238   int          chars_read;  /* Number of characters scanned in from this line */
00239   unsigned int version;     /* Contains CDD version from file */
00240   char         tmp[4096];   /* Temporary string */
00241   isuppl       info   = info_suppl;
00242   bool         retval = TRUE;
00243   bool         scored;
00244 
00245   /* Save off original scored value */
00246   scored = info_suppl.part.scored;
00247 
00248   if( sscanf( *line, "%x%n", &version, &chars_read ) == 1 ) {
00249 
00250     *line = *line + chars_read;
00251 
00252     if( version != CDD_VERSION ) {
00253       print_output( "CDD file being read is incompatible with this version of Covered", FATAL, __FILE__, __LINE__ );
00254       Throw 0;
00255     }
00256 
00257     /*@-formattype -formatcode -duplicatequals@*/
00258     if( sscanf( *line, "%x %" FMT64 "u %s%n", &(info.all), &num_timesteps, tmp, &chars_read ) == 3 ) {
00259     /*@=formattype =formatcode =duplicatequals@*/
00260 
00261       *line = *line + chars_read;
00262 
00263       /* If this CDD contains useful information, continue on */
00264       if( (info.part.scored != 0) || (read_mode != READ_MODE_MERGE_NO_MERGE) ) {
00265 
00266         /* Create a new database element */
00267         (void)db_create();
00268 
00269         /* Set leading_hiers_differ to TRUE if this is not the first hierarchy and it differs from the first */
00270         if( (db_list[curr_db]->leading_hier_num > 0) && (strcmp( db_list[curr_db]->leading_hierarchies[0], tmp ) != 0) ) {
00271           db_list[curr_db]->leading_hiers_differ = TRUE;
00272         }
00273 
00274         /* Assign this hierarchy to the leading hierarchies array */
00275         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)) );
00276         db_list[curr_db]->leading_hierarchies[db_list[curr_db]->leading_hier_num] = strdup_safe( tmp );
00277         db_list[curr_db]->leading_hier_num++;
00278 
00279         /* Save off the info supplemental information */
00280         info_suppl.all = info.all;
00281 
00282         /* Set scored flag to correct value */
00283         if( info.part.scored == 0 ) {
00284           info_suppl.part.scored = scored;
00285         }
00286 
00287       } else {
00288 
00289         merge_in_num--;
00290         retval = FALSE;
00291 
00292       }
00293 
00294     } else {
00295 
00296       print_output( "CDD file being read is incompatible with this version of Covered", FATAL, __FILE__, __LINE__ );
00297       Throw 0;
00298 
00299     }
00300 
00301   } else {
00302 
00303     print_output( "CDD file being read is incompatible with this version of Covered", FATAL, __FILE__, __LINE__ );
00304     Throw 0;
00305 
00306   }
00307 
00308   PROFILE_END;
00309 
00310   return( retval );
00311 
00312 }

void info_db_write ( FILE *  file  ) 

Writes info line to specified CDD file.

Writes information line to specified file.

Parameters:
file Pointer to file to write information to

References isuppl_u::all, cdd_message, CDD_VERSION, curr_db, DB_TYPE_INFO, DB_TYPE_MERGED_CDD, DB_TYPE_MESSAGE, DB_TYPE_SCORE_ARGS, info_set_vector_elem_size(), db_s::leading_hierarchies, merge_in_num, merged_file, str_link_s::next, num_timesteps, PROFILE, PROFILE_END, score_run_path, str_link_s::str, str_link_s::str2, and str_link_s::suppl.

Referenced by db_write().

00153   { PROFILE(INFO_DB_WRITE);
00154 
00155   str_link* arg;
00156 
00157   assert( db_list[curr_db]->leading_hier_num > 0 );
00158 
00159   /* Calculate vector element size */
00160   info_set_vector_elem_size();
00161 
00162   /*@-formattype -formatcode -duplicatequals@*/
00163   fprintf( file, "%d %x %x %" FMT64 "u %s\n",
00164            DB_TYPE_INFO,
00165            CDD_VERSION,
00166            info_suppl.all,
00167            num_timesteps,
00168            db_list[curr_db]->leading_hierarchies[0] );
00169   /*@=formattype =formatcode =duplicatequals@*/
00170 
00171   /* Display score arguments */
00172   fprintf( file, "%d %s", DB_TYPE_SCORE_ARGS, score_run_path );
00173 
00174   arg = score_args_head;
00175   while( arg != NULL ) {
00176     if( arg->str2 != NULL ) {
00177       fprintf( file, " 2 %s (%s)", arg->str, arg->str2 );
00178     } else {
00179       fprintf( file, " 1 %s", arg->str );
00180     }
00181     arg = arg->next;
00182   }
00183 
00184   fprintf( file, "\n" );
00185 
00186   /* Display the CDD message, if there is one */
00187   if( cdd_message != NULL ) {
00188     fprintf( file, "%d %s\n", DB_TYPE_MESSAGE, cdd_message );
00189   }
00190 
00191   /* Display the merged CDD information, if there are any */
00192   if( db_list[curr_db]->leading_hier_num == merge_in_num ) {
00193     str_link*    strl = merge_in_head;
00194     unsigned int i    = 0;
00195     while( strl != NULL ) {
00196       if( strl->suppl < 2 ) {
00197         if( ((merged_file == NULL) || (strcmp( strl->str, merged_file ) != 0)) && (strl->suppl == 1) ) {
00198           fprintf( file, "%d %s %s\n", DB_TYPE_MERGED_CDD, strl->str, db_list[curr_db]->leading_hierarchies[i++] );
00199         } else {
00200           i++;
00201         }
00202       }
00203       strl = strl->next; 
00204     }
00205   } else { 
00206     str_link*    strl = merge_in_head;
00207     unsigned int i    = 1; 
00208     assert( (db_list[curr_db]->leading_hier_num - 1) == merge_in_num );
00209     while( strl != NULL ) {
00210       if( strl->suppl < 2 ) {
00211         if( ((merged_file == NULL) || (strcmp( strl->str, merged_file ) != 0)) && (strl->suppl == 1) ) {
00212           fprintf( file, "%d %s %s\n", DB_TYPE_MERGED_CDD, strl->str, db_list[curr_db]->leading_hierarchies[i++] );
00213         } else {
00214           i++;
00215         }
00216       }
00217       strl = strl->next;
00218     }
00219   }
00220 
00221   PROFILE_END;
00222 
00223 }

void info_dealloc (  ) 

Deallocates all memory associated with the information section of a database file.

Deallocates all memory associated with the database information section. Needs to be called when the database is closed.

References cdd_message, free_safe, merge_in_num, PROFILE, PROFILE_END, and str_link_delete_list().

Referenced by db_close().

00428                     { PROFILE(INFO_DEALLOC);
00429 
00430   str_link_delete_list( score_args_head );
00431   score_args_head = NULL;
00432   score_args_tail = NULL;
00433 
00434   /* Free merged arguments */
00435   str_link_delete_list( merge_in_head );
00436   merge_in_head = NULL;
00437   merge_in_tail = NULL;
00438   merge_in_num  = 0;
00439 
00440   /* Free user message */
00441   free_safe( cdd_message, (strlen( cdd_message ) + 1) );
00442   cdd_message = NULL;
00443 
00444   PROFILE_END;
00445 
00446 }

void info_set_vector_elem_size (  ) 

Sets the vector element size in the global info_suppl structure based on the current machine unsigned long byte size.

References FATAL, isuppl_u::part, print_output(), PROFILE, PROFILE_END, Throw, and isuppl_u::vec_ul_size.

Referenced by info_db_write().

00129                                  { PROFILE(INFO_SET_VECTOR_ELEM_SIZE);
00130 
00131   switch( sizeof( ulong ) ) {
00132     case 1 :  info_suppl.part.vec_ul_size = 0;  break;
00133     case 2 :  info_suppl.part.vec_ul_size = 1;  break;
00134     case 4 :  info_suppl.part.vec_ul_size = 2;  break;
00135     case 8 :  info_suppl.part.vec_ul_size = 3;  break;
00136     default:
00137       print_output( "Unsupported unsigned long size", FATAL, __FILE__, __LINE__ );
00138       Throw 0;
00139       /*@-unreachable@*/
00140       break;
00141       /*@=unreachable@*/
00142   }
00143 
00144   PROFILE_END;
00145 
00146 }

void merged_cdd_db_read ( char **  line  ) 

Reads merged CDD information from specified line and stores information.

Parses given line for merged CDD information and stores this information in the appropriate global variables.

Parameters:
line Pointer to string containing merged CDD line to parse

References curr_db, FATAL, free_safe, get_relative_path(), db_s::leading_hier_num, db_s::leading_hierarchies, db_s::leading_hiers_differ, merge_in_num, print_output(), PROFILE, PROFILE_END, realloc_safe, str_link_add(), str_link_find(), strdup_safe, str_link_s::suppl, Throw, TRUE, user_msg, and USER_MSG_LENGTH.

Referenced by db_read().

00375   { PROFILE(MERGED_CDD_DB_READ);
00376 
00377   char tmp1[4096];  /* Temporary string */
00378   char tmp2[4096];  /* Temporary string */
00379   int  chars_read;  /* Number of characters read */
00380 
00381   if( sscanf( *line, "%s %s%n", tmp1, tmp2, &chars_read ) == 2 ) {
00382 
00383     *line = *line + chars_read;
00384 
00385     /* Add merged file */
00386     if( str_link_find( tmp1, merge_in_head) == NULL ) {
00387 
00388       str_link* strl = str_link_add( strdup_safe( tmp1 ), &merge_in_head, &merge_in_tail );
00389       strl->suppl = 1;
00390       merge_in_num++;
00391 
00392       /* Set leading_hiers_differ to TRUE if this is not the first hierarchy and it differs from the first */
00393       if( strcmp( db_list[curr_db]->leading_hierarchies[0], tmp2 ) != 0 ) {
00394         db_list[curr_db]->leading_hiers_differ = TRUE;
00395       }
00396 
00397       /* Add its hierarchy */
00398       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)) );
00399       db_list[curr_db]->leading_hierarchies[db_list[curr_db]->leading_hier_num] = strdup_safe( tmp2 );
00400       db_list[curr_db]->leading_hier_num++;
00401 
00402     } else if( merge_in_num > 0 ) {
00403 
00404       char* file = get_relative_path( tmp1 );
00405       unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "File %s in CDD file has been specified on the command-line", file );
00406       assert( rv < USER_MSG_LENGTH );
00407       free_safe( file, (strlen( file ) + 1) );
00408       print_output( user_msg, FATAL, __FILE__, __LINE__ );
00409       Throw 0;
00410 
00411     }
00412 
00413   } else {
00414 
00415     print_output( "CDD file being read is incompatible with this version of Covered", FATAL, __FILE__, __LINE__ );
00416     Throw 0;
00417 
00418   }
00419 
00420   PROFILE_END;
00421 
00422 }

void message_db_read ( char **  line  ) 

Reads user-specified message from specified line and stores information.

Read user-specified message from specified string and stores its information.

Parameters:
line Pointer to string containing information line to parse

References cdd_message, PROFILE, PROFILE_END, and strdup_safe.

Referenced by db_read().

00359   { PROFILE(MESSAGE_DB_READ);
00360 
00361   /* All we need to do is copy the message */
00362   if( (cdd_message == NULL) && (strlen( *line + 1 ) > 0) ) {
00363     cdd_message = strdup_safe( *line + 1 );
00364   }
00365 
00366   PROFILE_END;
00367 
00368 }

void score_add_args ( const char *  arg1,
const char *  arg2 
)

Adds the given argument(s) from the command-line to the score array such that no arguments are duplicated.

Adds the specified argument to the list of score arguments that will be written to the CDD file.

Parameters:
arg1 First argument from score command
arg2 Second argument from score command

References FALSE, str_link_s::next, PROFILE, str_link_s::str, str_link_s::str2, str_link_add(), strdup_safe, and TRUE.

Referenced by args_db_read(), and score_parse_args().

00085   { PROFILE(SCORE_ADD_ARGS);
00086 
00087   str_link* arg    = score_args_head;
00088   bool      done   = FALSE;
00089   bool      nondup = ((strncmp( arg1, "-vpi", 4 ) == 0) ||
00090                       (strncmp( arg1, "-lxt", 4 ) == 0) ||
00091                       (strncmp( arg1, "-fst", 4 ) == 0) ||
00092                       (strncmp( arg1, "-vcd", 4 ) == 0) ||
00093                       (strncmp( arg1, "-t",   2 ) == 0) ||
00094                       (strncmp( arg1, "-i",   2 ) == 0) ||
00095                       (strncmp( arg1, "-o",   2 ) == 0));
00096 
00097   while( !done ) {
00098 
00099     /* Check to see if the specified arguments already exist */
00100     while( (arg != NULL) && (strcmp( arg->str, arg1 ) != 0) ) {
00101       arg = arg->next;
00102     }
00103 
00104     /* If the argument doesn't exist, just add it and be done */
00105     if( arg == NULL ) {
00106       arg = str_link_add( strdup_safe( arg1 ), &score_args_head, &score_args_tail );
00107       if( arg2 != NULL ) {
00108         arg->str2 = strdup_safe( arg2 );
00109       }
00110       done = TRUE;
00111 
00112     /* If the first option exists and its either a non-duplicatible option or it already exists, be done */
00113     } else if( nondup || ((arg2 != NULL) && (strcmp( arg2, arg->str2 ) == 0)) ) {
00114       done = TRUE;
00115 
00116     /* Otherwise, advance the arg pointer */
00117     } else {
00118       arg = arg->next;
00119     }
00120 
00121   }
00122 
00123 }


Variable Documentation

char* cdd_message

User-supplied message to include in the CDD database

Referenced by info_db_write(), info_dealloc(), merge_parse_args(), message_db_read(), report_print_header(), and score_parse_args().

int cdd_version = CDD_VERSION

Contains the CDD version number of all CDD files that this version of Covered can write and read.

unsigned int curr_db

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

Array of database pointers storing all currently loaded databases.

Informational line for the CDD file.

Pointer to head of list containing names of the input CDD files.

Specifies the number of merged CDD files.

Referenced by info_db_read(), info_db_write(), info_dealloc(), merge_check(), and merged_cdd_db_read().

Pointer to tail of list containing names of the input CDD files.

char* merged_file

Specifies the output filename of the CDD file that contains the merged data.

Referenced by command_merge(), info_db_write(), merge_check(), and merge_parse_args().

uint64 num_timesteps

Specifies the number of timesteps that have transpired during this simulation.

Pointer to the head of the score arguments list.

Pointer to the tail of the score arguments list.

char score_run_path[4096]

Specifes the pathname where the score command was originally run from.

Referenced by args_db_read(), info_db_write(), and score_parse_args().

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:39 2010 for Covered by  doxygen 1.6.3