#include <stdio.h>
#include <stdlib.h>
#include "binding.h"
#include "db.h"
#include "defines.h"
#include "info.h"
#include "merge.h"
#include "sim.h"
#include "util.h"
Functions | |
| void | merge_usage () |
| bool | merge_parse_args (int argc, int last_arg, const char **argv) |
| void | command_merge (int argc, int last_arg, const char **argv) |
| Parses command-line for merge options and performs merge command. | |
Variables | |
| db ** | db_list |
| unsigned int | curr_db |
| int | merged_code |
| char | user_msg [USER_MSG_LENGTH] |
| char * | cdd_message |
| char * | merged_file = NULL |
| str_link * | merge_in_head = NULL |
| str_link * | merge_in_tail = NULL |
| str_link * | merge_in_cl_last = NULL |
| int | merge_in_num = 0 |
| int | merge_er_value = MERGE_ER_NONE |
|
||||||||||||||||
|
Parses command-line for merge options and performs merge command. Performs merge command functionality.
00345 { PROFILE(COMMAND_MERGE);
00346
00347 int i; /* Loop iterator */
00348 unsigned int rv; /* Return value from snprintf calls */
00349 bool error = FALSE;
00350
00351 /* Output header information */
00352 rv = snprintf( user_msg, USER_MSG_LENGTH, COVERED_HEADER );
00353 assert( rv < USER_MSG_LENGTH );
00354 print_output( user_msg, NORMAL, __FILE__, __LINE__ );
00355
00356 Try {
00357
00358 str_link* strl;
00359 bool stop_merging;
00360 int curr_leading_hier_num = 0;
00361
00362 /* Parse score command-line */
00363 if( !merge_parse_args( argc, last_arg, argv ) ) {
00364
00365 /* Read in base database */
00366 rv = snprintf( user_msg, USER_MSG_LENGTH, "Reading CDD file \"%s\"", merge_in_head->str );
00367 assert( rv < USER_MSG_LENGTH );
00368 print_output( user_msg, NORMAL, __FILE__, __LINE__ );
00369 db_read( merge_in_head->str, READ_MODE_MERGE_NO_MERGE );
00370
00371 /* If the currently read CDD didn't contain any merged CDDs it is a leaf CDD so mark it as such */
00372 if( (db_list[curr_db]->leading_hier_num - curr_leading_hier_num) == 1 ) {
00373 merge_in_head->suppl = 1;
00374 }
00375 curr_leading_hier_num = db_list[curr_db]->leading_hier_num;
00376
00377 /* Read in databases to merge */
00378 strl = merge_in_head->next;
00379 stop_merging = (strl == merge_in_head);
00380 while( (strl != NULL) && !stop_merging ) {
00381 rv = snprintf( user_msg, USER_MSG_LENGTH, "Merging CDD file \"%s\"", strl->str );
00382 assert( rv < USER_MSG_LENGTH );
00383 print_output( user_msg, NORMAL, __FILE__, __LINE__ );
00384 db_read( strl->str, READ_MODE_MERGE_NO_MERGE );
00385
00386 /* If we have not merged any CDD files from this CDD, this is a leaf CDD so mark it as such */
00387 if( (db_list[curr_db]->leading_hier_num - curr_leading_hier_num) == 1 ) {
00388 strl->suppl = 1;
00389 }
00390 curr_leading_hier_num = db_list[curr_db]->leading_hier_num;
00391
00392 stop_merging = (strl == merge_in_cl_last);
00393 strl = strl->next;
00394 }
00395
00396 /* Perform the tree merges */
00397 db_merge_instance_trees();
00398
00399 /* Bind */
00400 bind_perform( TRUE, 0 );
00401
00402 /* Write out new database to output file */
00403 db_write( merged_file, FALSE, TRUE, FALSE );
00404
00405 print_output( "\n*** Merging completed successfully! ***", NORMAL, __FILE__, __LINE__ );
00406
00407 }
00408
00409 } Catch_anonymous {
00410 error = TRUE;
00411 }
00412
00413 /* Close database */
00414 db_close();
00415
00416 /* Deallocate other memory */
00417 str_link_delete_list( merge_in_head );
00418 free_safe( merged_file, (strlen( merged_file ) + 1) );
00419
00420 if( error ) {
00421 Throw 0;
00422 }
00423
00424 PROFILE_END;
00425
00426 }
|
|
||||||||||||||||
|
00133 {
00134
00135 int i;
00136 str_link* strl;
00137 str_link* ext_head = NULL;
00138 str_link* ext_tail = NULL;
00139 str_link* dir_head = NULL;
00140 str_link* dir_tail = NULL;
00141 bool help_found = FALSE;
00142
00143 i = last_arg + 1;
00144
00145 while( (i < argc) && !help_found ) {
00146
00147 if( strncmp( "-h", argv[i], 2 ) == 0 ) {
00148
00149 merge_usage();
00150 help_found = TRUE;
00151
00152 } else if( strncmp( "-o", argv[i], 2 ) == 0 ) {
00153
00154 if( check_option_value( argc, argv, i ) ) {
00155 i++;
00156 if( is_legal_filename( argv[i] ) ) {
00157 merged_file = strdup_safe( argv[i] );
00158 } else {
00159 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Output file \"%s\" is not writable", argv[i] );
00160 assert( rv < USER_MSG_LENGTH );
00161 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00162 Throw 0;
00163 }
00164 } else {
00165 Throw 0;
00166 }
00167
00168 } else if( strncmp( "-f", argv[i], 2 ) == 0 ) {
00169
00170 if( check_option_value( argc, argv, i ) ) {
00171 char** arg_list = NULL;
00172 int arg_num = 0;
00173 unsigned int j;
00174 i++;
00175 Try {
00176 read_command_file( argv[i], &arg_list, &arg_num );
00177 help_found = merge_parse_args( arg_num, -1, (const char**)arg_list );
00178 } Catch_anonymous {
00179 for( j=0; j<arg_num; j++ ) {
00180 free_safe( arg_list[j], (strlen( arg_list[j] ) + 1) );
00181 }
00182 free_safe( arg_list, (sizeof( char* ) * arg_num) );
00183 Throw 0;
00184 }
00185 for( j=0; j<arg_num; j++ ) {
00186 free_safe( arg_list[j], (strlen( arg_list[j] ) + 1) );
00187 }
00188 free_safe( arg_list, (sizeof( char* ) * arg_num) );
00189 } else {
00190 Throw 0;
00191 }
00192
00193 } else if( strncmp( "-d", argv[i], 2 ) == 0 ) {
00194
00195 if( check_option_value( argc, argv, i ) ) {
00196 i++;
00197 if( directory_exists( argv[i] ) ) {
00198 (void)str_link_add( strdup_safe( argv[i] ), &dir_head, &dir_tail );
00199 } else {
00200 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Specified -d directory (%s) does not exist", argv[i] );
00201 assert( rv < USER_MSG_LENGTH );
00202 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00203 Throw 0;
00204 }
00205 } else {
00206 Throw 0;
00207 }
00208
00209 } else if( strncmp( "-er", argv[i], 3 ) == 0 ) {
00210
00211 if( check_option_value( argc, argv, i ) ) {
00212 i++;
00213 if( strncmp( "first", argv[i], 5 ) == 0 ) {
00214 merge_er_value = MERGE_ER_FIRST;
00215 } else if( strncmp( "last", argv[i], 4 ) == 0 ) {
00216 merge_er_value = MERGE_ER_LAST;
00217 } else if( strncmp( "all", argv[i], 3 ) == 0 ) {
00218 merge_er_value = MERGE_ER_ALL;
00219 } else if( strncmp( "new", argv[i], 3 ) == 0 ) {
00220 merge_er_value = MERGE_ER_NEW;
00221 } else if( strncmp( "old", argv[i], 3 ) == 0 ) {
00222 merge_er_value = MERGE_ER_OLD;
00223 } else {
00224 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Illegal value to use for the -er option (%s). Valid values are: first, last, all, new, old", argv[i] );
00225 assert( rv < USER_MSG_LENGTH );
00226 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00227 Throw 0;
00228 }
00229 } else {
00230 Throw 0;
00231 }
00232
00233 } else if( strncmp( "-ext", argv[i], 4 ) == 0 ) {
00234
00235 if( check_option_value( argc, argv, i ) ) {
00236 i++;
00237 (void)str_link_add( strdup_safe( argv[i] ), &ext_head, &ext_tail );
00238 } else {
00239 Throw 0;
00240 }
00241
00242 } else if( strncmp( "-m", argv[i], 2 ) == 0 ) {
00243
00244 if( check_option_value( argc, argv, i ) ) {
00245 i++;
00246 if( cdd_message != NULL ) {
00247 print_output( "Only one -m option is allowed on the merge command-line. Using first value...", WARNING, __FILE__, __LINE__ );
00248 } else {
00249 cdd_message = strdup_safe( argv[i] );
00250 }
00251 } else {
00252 Throw 0;
00253 }
00254
00255 } else {
00256
00257 /* The name of a file to merge */
00258 if( file_exists( argv[i] ) ) {
00259
00260 /* Create absolute filename */
00261 char* file = get_absolute_path( argv[i] );
00262
00263 /* If we have not specified a merge file explicitly, set it implicitly to the first CDD file found */
00264 if( (merge_in_head == NULL) && (merged_file == NULL) ) {
00265 merged_file = strdup_safe( file );
00266 }
00267
00268 /* Add the specified merge file to the list */
00269 (void)str_link_add( file, &merge_in_head, &merge_in_tail );
00270
00271 } else {
00272
00273 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "CDD file (%s) does not exist", argv[i] );
00274 assert( rv < USER_MSG_LENGTH );
00275 print_output( user_msg, FATAL, __FILE__, __LINE__ );
00276 Throw 0;
00277
00278 }
00279
00280 }
00281
00282 i++;
00283
00284 }
00285
00286 if( !help_found ) {
00287
00288 Try {
00289
00290 /* Load any merge files found in specified directories */
00291 strl = dir_head;
00292 while( strl != NULL ) {
00293 directory_load( strl->str, ext_head, &merge_in_head, &merge_in_tail );
00294 strl = strl->next;
00295 }
00296
00297 } Catch_anonymous {
00298 str_link_delete_list( ext_head );
00299 str_link_delete_list( dir_head );
00300 Throw 0;
00301 }
00302
00303 /* Set the last command-line pointer to the current tail */
00304 merge_in_cl_last = merge_in_tail;
00305
00306 /* Make sure that we have at least 2 files to merge */
00307 strl = merge_in_head;
00308 while( strl != NULL ) {
00309 merge_in_num++;
00310 strl = strl->next;
00311 }
00312
00313 /* Check to make sure that the user specified at least two files to merge */
00314 if( merge_in_num < 2 ) {
00315 print_output( "Must specify at least two CDD files to merge", FATAL, __FILE__, __LINE__ );
00316 Throw 0;
00317 }
00318
00319 /*
00320 If no -o option was specified and no merge files were specified, don't presume that the first file found in
00321 the directory will be that file.
00322 */
00323 if( merged_file == NULL ) {
00324 print_output( "Must specify the -o option or a specific CDD file for containing the merged results", FATAL, __FILE__, __LINE__ );
00325 Throw 0;
00326 }
00327
00328 }
00329
00330 /* Deallocate the temporary lists */
00331 str_link_delete_list( ext_head );
00332 str_link_delete_list( dir_head );
00333
00334 return( help_found );
00335
00336 }
|
|
|
Outputs usage informaiton to standard output for merge command.
00082 {
00083
00084 printf( "\n" );
00085 printf( "Usage: covered merge (-h | [<options>] <existing_database> <database_to_merge>+)\n" );
00086 printf( "\n" );
00087 printf( " -h Displays this help information.\n" );
00088 printf( "\n" );
00089 printf( " Options:\n" );
00090 printf( " -o <filename> File to output new database to. If this argument is not\n" );
00091 printf( " specified, the <existing_database> is used as the output\n" );
00092 printf( " database name.\n" );
00093 printf( " -f <filename> Name of file containing additional arguments to parse.\n" );
00094 printf( " -d <directory> Directory to search for CDD files to include. This option is used in\n" );
00095 printf( " conjunction with the -ext option which specifies the file extension\n" );
00096 printf( " to use for determining which files in the directory are CDD files.\n" );
00097 printf( " -er <value> Specifies how to handle exclusion reason resolution. If two or more CDD files being\n" );
00098 printf( " merged have exclusion reasons specified for the same coverage point, the exclusion\n" );
00099 printf( " reason needs to be resolved (unless it is the same string value). If this option\n" );
00100 printf( " is not specified and a conflict is found, Covered will interactively request input\n" );
00101 printf( " for each exclusion as to how to handle it. If this option is specified, it tells\n" );
00102 printf( " Covered how to handle all exclusion reason conflicts. The values are as follows:\n" );
00103 printf( " first - CDD file that contained the first exclusion reason is used.\n" );
00104 printf( " last - CDD file that contained the last exclusion reason is used.\n" );
00105 printf( " all - All exclusion reasons are used (concatenated).\n" );
00106 printf( " new - Use the newest exclusion reason specified.\n" );
00107 printf( " old - Use the oldest exclusion reason specified.\n" );
00108 printf( " -ext <extension> Used in conjunction with the -d option. If no -ext options are specified\n" );
00109 printf( " on the command-line, the default value of '.cdd' is used. Note that\n" );
00110 printf( " a period (.) should be specified.\n" );
00111 printf( " -m <message> Allows the user to specify information about this CDD file. This information\n" );
00112 printf( " can be anything (messages with whitespace should be surrounded by double-quotation\n" );
00113 printf( " marks), but may include something about the simulation arguments to more easily\n" );
00114 printf( " link the CDD file to its simulation for purposes of recreating the CDD file.\n" );
00115 printf( "\n" );
00116
00117 }
|
|
|
User-supplied message to include in the CDD database |
|
|
Index of current database in db_list array that is being handled. |
|
|
Array of database pointers storing all currently loaded databases. |
|
|
Specifies the value of the -er option. |
|
|
Pointer to last input name from command-line. |
|
|
Pointer to head of list containing names of the input CDD files. |
|
|
Specifies the number of merged CDD files. |
|
|
Pointer to tail of list containing names of the input CDD files. |
|
|
|
|
|
Specifies the output filename of the CDD file that contains the merged data. |
|
|
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. |
1.3.4