/*! @file Explanations.cc * @brief Explanations Implementation * * This file contains the implementation of the functions * which provide a base level of functionality of a Explanations. */ #include #include #include #include #include #include "Explanations.h" #include "app_common.h" namespace Coverage { Explanations::Explanations() { } Explanations::~Explanations() { } void Explanations::load( const char* const explanations ) { #define MAX_LINE_LENGTH 512 FILE *explain; char *cStatus; Explanation *e; int line = 1; if (!explanations) return; explain = ::fopen( explanations, "r" ); if (!explain) { std::ostringstream what; what << "Unable to open " << explanations; throw rld::error( what, "Explanations::load" ); } while ( 1 ) { e = new Explanation; // Read the starting line of this explanation and // skip blank lines between do { inputBuffer[0] = '\0'; cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, explain ); if (cStatus == NULL) { goto done; } inputBuffer[ strlen(inputBuffer) - 1] = '\0'; line++; } while ( inputBuffer[0] == '\0' ); // Have we already seen this one? if (set.find( inputBuffer ) != set.end()) { std::ostringstream what; what << "line " << line << "contains a duplicate explanation (" << inputBuffer << ")"; throw rld::error( what, "Explanations::load" ); } // Add the starting line and file e->startingPoint = std::string(inputBuffer); e->found = false; // Get the classification cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, explain ); if (cStatus == NULL) { std::ostringstream what; what << "line " << line << "out of sync at the classification"; throw rld::error( what, "Explanations::load" ); } inputBuffer[ strlen(inputBuffer) - 1] = '\0'; e->classification = inputBuffer; line++; // Get the explanation while (1) { cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, explain ); // fprintf( stderr, "%d - %s\n", line, inputBuffer ); if (cStatus == NULL) { std::ostringstream what; what << "line " << line << "out of sync at the explanation"; throw rld::error( what, "Explanations::load" ); } inputBuffer[ strlen(inputBuffer) - 1] = '\0'; line++; const char delimiter[4] = "+++"; if (!strncmp( inputBuffer, delimiter, 3 )) { break; } // XXX only taking last line. Needs to be a vector e->explanation.push_back( inputBuffer ); } // Add this to the set of Explanations set[ e->startingPoint ] = *e; } done: ; #undef MAX_LINE_LENGTH } const Explanation *Explanations::lookupExplanation( std::string& start ) { if (set.find( start ) == set.end()) { #if 0 std::cerr << "Warning: Unable to find explanation for " << start << std::endl; #endif return NULL; } set[ start ].found = true; return &set[ start ]; } void Explanations::writeNotFound( const char* const fileName ) { FILE* notFoundFile; bool notFoundOccurred = false; if (!fileName) return; notFoundFile = fopen( fileName, "w" ); if (!fileName) { std::ostringstream what; what << "Unable to open " << fileName << "out of sync at the explanation"; throw rld::error( what, "Explanations::writeNotFound" ); } for (std::map::iterator itr = set.begin(); itr != set.end(); itr++) { Explanation e = (*itr).second; std::string key = (*itr).first; if (!e.found) { notFoundOccurred = true; fprintf( notFoundFile, "%s\n", e.startingPoint.c_str() ); } } fclose( notFoundFile ); if (!notFoundOccurred) { if (!unlink( fileName )) { std::cerr << "Warning: Unable to unlink " << fileName << std::endl << std::endl; } } } }