parent
660745d7d5
commit
a50293a217
|
@ -19,13 +19,52 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "Suite.h"
|
#include "Suite.h"
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
/// Suite_InvalidUnitMember - Exception thrown when a Suite tries to access a contained Unit's value that is not
|
/// Suite_InvalidUnitMember - Exception thrown when a Suite tries to access a contained Unit's value that is not
|
||||||
/// present in the Unit.
|
/// present in the Unit.
|
||||||
class Suite_InvalidUnitMember: public std::runtime_error { public:
|
class SuiteException: public std::exception
|
||||||
// TODO rework this to accept the name of the member not able to be fetched.
|
{
|
||||||
Suite_InvalidUnitMember(): std::runtime_error("Suite: Attempted to access a member of a Unit that is not set.") {}
|
public:
|
||||||
|
/** Constructor (C strings).
|
||||||
|
* @param message C-style string error message.
|
||||||
|
* The string contents are copied upon construction.
|
||||||
|
* Hence, responsibility for deleting the char* lies
|
||||||
|
* with the caller.
|
||||||
|
*/
|
||||||
|
explicit SuiteException(const char* message):
|
||||||
|
msg_(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructor (C++ STL strings).
|
||||||
|
* @param message The error message.
|
||||||
|
*/
|
||||||
|
explicit SuiteException(const std::string& message):
|
||||||
|
msg_(message)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/** Destructor.
|
||||||
|
* Virtual to allow for subclassing.
|
||||||
|
*/
|
||||||
|
virtual ~SuiteException() throw (){}
|
||||||
|
|
||||||
|
/** Returns a pointer to the (constant) error description.
|
||||||
|
* @return A pointer to a const char*. The underlying memory
|
||||||
|
* is in posession of the Exception object. Callers must
|
||||||
|
* not attempt to free the memory.
|
||||||
|
*/
|
||||||
|
virtual const char* what() const throw (){
|
||||||
|
return msg_.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Error message.
|
||||||
|
*/
|
||||||
|
std::string msg_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,40 +81,115 @@ class Suite_InvalidUnitMember: public std::runtime_error { public:
|
||||||
/// if the implementor so desires.
|
/// if the implementor so desires.
|
||||||
Suite::Suite(): JSON_Loader() {};
|
Suite::Suite(): JSON_Loader() {};
|
||||||
|
|
||||||
|
|
||||||
|
bool is_file( std::string path)
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
stat( path.c_str(), &buf );
|
||||||
|
return S_ISREG(buf.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_dir( std::string path )
|
||||||
|
{
|
||||||
|
struct stat buf;
|
||||||
|
stat( path.c_str(), &buf );
|
||||||
|
return S_ISDIR(buf.st_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_units_from_dir( std::vector<std::string> * files, std::string path )
|
||||||
|
{
|
||||||
|
DIR* dirFile = opendir( path.c_str() );
|
||||||
|
if ( dirFile )
|
||||||
|
{
|
||||||
|
std::string entry;
|
||||||
|
|
||||||
|
struct dirent* hFile;
|
||||||
|
errno = 0;
|
||||||
|
while (( hFile = readdir( dirFile )) != NULL )
|
||||||
|
{
|
||||||
|
if ( !strcmp( hFile->d_name, "." )) continue;
|
||||||
|
if ( !strcmp( hFile->d_name, ".." )) continue;
|
||||||
|
|
||||||
|
// hidden files
|
||||||
|
if ( hFile->d_name[0] == '.' ) continue;
|
||||||
|
|
||||||
|
// dirFile.name is the name of the file. Do whatever string comparison
|
||||||
|
// you want here. Something like:
|
||||||
|
if ( strstr( hFile->d_name, ".units" ))
|
||||||
|
{
|
||||||
|
std::string full_path = path + hFile->d_name;
|
||||||
|
files->push_back( full_path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir( dirFile );
|
||||||
|
} else {
|
||||||
|
std::cout << "file not found" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Suite::load_units_file - Uses the json_root buffer on each run to append intact Units as they're
|
/// Suite::load_units_file - Uses the json_root buffer on each run to append intact Units as they're
|
||||||
/// deserialized from the provided file.
|
/// deserialized from the provided file.
|
||||||
///
|
///
|
||||||
/// \param filename - The file to pull the JSON-formatted units from.
|
/// \param units_path - The file to pull the JSON-formatted units from.
|
||||||
/// \param verbose - Whether to print verbose output to STDOUT.
|
/// \param verbose - Whether to print verbose output to STDOUT.
|
||||||
void Suite::load_units_file( std::string filename, bool verbose )
|
void Suite::load_units_file( std::string units_path, bool verbose )
|
||||||
{
|
{
|
||||||
// will use json_root buffer on each run to append to this->units vector as valid units are found.
|
std::vector<std::string> unit_files;
|
||||||
this->load_json_file( filename, verbose );
|
|
||||||
|
|
||||||
// staging buffer
|
if ( is_dir( units_path ) )
|
||||||
Json::Value jbuff;
|
|
||||||
|
|
||||||
// fill the jbuff staging buffer with a json::value object in the supplied filename
|
|
||||||
if ( this->get_serialized( jbuff, "units", verbose ) == 0)
|
|
||||||
{
|
{
|
||||||
this->json_root = jbuff;
|
// we have a directory path. find all files ending in *.units and load them into a vector<std::string>
|
||||||
|
get_units_from_dir( &unit_files, units_path );
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate through the json::value members that have been loaded. append to this->units vector
|
if ( is_file( units_path ) )
|
||||||
// buffer for units to append:
|
|
||||||
Unit tmp_U;
|
|
||||||
for ( int index = 0; index < this->json_root.size(); index++ )
|
|
||||||
{
|
{
|
||||||
// assemble the unit from json_root using the built-in value operator
|
unit_files.push_back( units_path );
|
||||||
tmp_U.load_root( this->json_root[ index ] );
|
}
|
||||||
if ( tmp_U.get_active() ) {
|
|
||||||
// append to this->units
|
std::ostringstream infostring;
|
||||||
this->units.push_back( tmp_U );
|
infostring << "Unit files found: " << unit_files.size() << std::endl;
|
||||||
if ( verbose ) {
|
syslog(LOG_INFO, infostring.str().c_str() );
|
||||||
std::cout << "Added unit \"" << tmp_U.get_name() << "\" to Suite." << std::endl;
|
std::cerr << infostring.str();
|
||||||
|
|
||||||
|
for ( int i = 0; i < unit_files.size(); i++ )
|
||||||
|
{
|
||||||
|
// will use json_root buffer on each run to append to this->units vector as valid units are found.
|
||||||
|
this->load_json_file( unit_files[i], verbose );
|
||||||
|
|
||||||
|
// staging buffer
|
||||||
|
Json::Value jbuff;
|
||||||
|
|
||||||
|
// fill the jbuff staging buffer with a json::value object in the supplied units_path
|
||||||
|
if ( this->get_serialized( jbuff, "units", verbose ) == 0)
|
||||||
|
{
|
||||||
|
this->json_root = jbuff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate through the json::value members that have been loaded. append to this->units vector
|
||||||
|
// buffer for units to append:
|
||||||
|
Unit tmp_U;
|
||||||
|
for ( int index = 0; index < this->json_root.size(); index++ )
|
||||||
|
{
|
||||||
|
// assemble the unit from json_root using the built-in value operator
|
||||||
|
tmp_U.load_root( this->json_root[ index ] );
|
||||||
|
if ( tmp_U.get_active() ) {
|
||||||
|
// append to this->units
|
||||||
|
this->units.push_back( tmp_U );
|
||||||
|
if ( verbose ) {
|
||||||
|
std::ostringstream infostring;
|
||||||
|
infostring << "Added unit \"" << tmp_U.get_name() << "\" to Suite." << std::endl;
|
||||||
|
syslog(LOG_INFO, infostring.str().c_str() );
|
||||||
|
std::cout << infostring.str();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Suite::get_unit - returns a contained Unit identified by name attribute.
|
/// Suite::get_unit - returns a contained Unit identified by name attribute.
|
||||||
|
@ -99,8 +213,11 @@ void Suite::get_unit(Unit & result, std::string provided_name)
|
||||||
|
|
||||||
if (! foundMatch )
|
if (! foundMatch )
|
||||||
{
|
{
|
||||||
std::cerr << "Unit name \"" << provided_name << "\" was referenced but not defined!" << std::endl;
|
std::ostringstream infostring;
|
||||||
throw Suite_InvalidUnitMember();
|
infostring << "Unit name \"" << provided_name << "\" was referenced but not defined!" << std::endl;
|
||||||
|
syslog(LOG_ERR, infostring.str().c_str() );
|
||||||
|
std::cerr << infostring.str();
|
||||||
|
throw SuiteException( infostring.str() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue