CSlimTools.cc 5.08 KB
/**
 * CSlimTools.cc
 *
 *  Created on: 17 oct. 2012
 *      Author: AKKA IS
 */

#include "CSlimTools.hh"
#include <math.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <boost/tokenizer.hpp>
#include <stdlib.h>
#include <stdio.h>

using namespace std;
using namespace boost;

CSlimTools::CSlimTools() {
}

CSlimTools::~CSlimTools() {
}

#define MaxAnswer 250
char* CSlimTools::intToString(int i) {
	stringstream ss;
	static char str[MaxAnswer];
	ss << i;
	strncpy(str, ss.str().c_str(), MaxAnswer - 1);
	str[MaxAnswer - 1] = '\0';
	return str;
}

/**
 * compare line "data val1 val2 ... valN
 * @return "0" if lineRigjht == LineLeft
 */
char * CSlimTools::compareLine(string lineLeft, string lineRight, double epsilon, int lineNumber, double& maxEpsilon) {
	static char str[MaxAnswer];
	str[0] = '\0';
	  boost::char_separator<char> sep(" ");

	boost::tokenizer<boost::char_separator<char> > tokLeft(lineLeft, sep);
	boost::tokenizer<boost::char_separator<char> > tokRight(lineRight, sep);

	boost::tokenizer<boost::char_separator<char> >::iterator itLeft = tokLeft.begin();
	boost::tokenizer<boost::char_separator<char> >::iterator itRight = tokRight.begin();
	bool test = true;
	if (itLeft != tokLeft.end() && itRight != tokRight.end()) {
		string sLeft = (*itLeft);
		string sRight = (*itRight);
		if(sLeft !=sRight ) {
			stringstream ss;
			cout << "line "<< lineNumber <<": "<< sLeft << "' != '" <<  sRight << endl;
			ss << "line "<< lineNumber <<": "<< sLeft << "' != '" <<  sRight;

			strncpy(str, ss.str().c_str(), MaxAnswer - 1);
			str[MaxAnswer - 1] = '\0';
			test = false;

		}
		++itLeft;
		++itRight;
		while (itLeft != tokLeft.end() && itRight != tokRight.end()) {
			string sLeft = (*itLeft);
			string sRight = (*itRight);
			double valLeft = atof(sLeft.c_str());
			double valRight = atof(sRight.c_str());
			double result = 0;
			bool lTest;
			if (valLeft != 0.0) {
				lTest = ((result = fabs((valLeft - valRight) / valLeft)) <= epsilon);
			} else if (valRight != 0.0) {
				lTest = ((result = fabs((valLeft - valRight) / valRight)) <= epsilon);
				}
			else {
				lTest = true;
			}
			lTest = lTest
					|| ( sLeft == sRight)
					|| (sLeft == "nan" && sRight =="inf")
					|| (sRight == "nan" && sLeft =="inf")
					|| (sLeft == "nan" && sRight =="-inf")
					|| (sRight == "nan" && sLeft =="-inf")
					|| (sLeft == "nan" && sRight =="-nan")
					|| (sRight == "nan" && sLeft =="-nan");
			if(!lTest) {

				stringstream ss;
				cout << "line "<< lineNumber <<": | ("<< sLeft << "' - '" <<  sRight<< ") / "<< sLeft << " |  = "  << fabs((valLeft - valRight)/ valLeft)  << " >= " << epsilon << endl;
				ss << "| ("<< sLeft << "' - '" <<  sRight<< ") / "<< sLeft << " |  = "  << fabs((valLeft - valRight)/ valLeft)  << " > " << epsilon;
				if ( result > maxEpsilon) {
					strncpy(str, ss.str().c_str(), MaxAnswer - 1);
					str[MaxAnswer - 1] = '\0';
					maxEpsilon=result;
					test = false;
				}
			}
			++itLeft;
			++itRight;
		}
	}

	if (itLeft != tokLeft.end() || itRight != tokRight.end()) {
		cout << "line "<< lineNumber <<" nb columns different" << endl;
		strncpy(str, "nb columns different", MaxAnswer - 1);
		test = false;
	}
	if(test) {
		strcpy(str, "0");
	}

	return str;
}

char *CSlimTools::compareFile(std::string fileNameLeft,
		std::string fileNameRight, double epsilon) {
	static char str[MaxAnswer];
	ifstream fileLeft(fileNameLeft.c_str());
	ifstream fileRight(fileNameRight.c_str());
	bool ret = true;
	if (fileLeft.good() && fileRight.good()) {
		int lineNumber = 0;
		double maxEpsilon=0;
		while (fileLeft.good() && fileRight.good()) {
			string lineLeft;
			string lineRight;
			++lineNumber;
			getline(fileLeft, lineLeft);
			getline(fileRight, lineRight);
			char *tmp =compareLine(lineLeft, lineRight, epsilon, lineNumber, maxEpsilon);
			if((tmp[0] != '0' || tmp[1] != '\0')) {
				stringstream ss;
				ss << "line " << lineNumber << ": " << tmp;
				strncpy(str, ss.str().c_str(), MaxAnswer - 1);
				str[MaxAnswer - 1] = '\0';
				ret = false;
			}
		}
		if  (!(fileLeft.eof()) || !(fileRight.eof())) {
			cout << "line "<< lineNumber <<" nb lines different" << endl;
			strcpy(str, "nb lines different");
			ret = false;
		}
	}
	else {
		if(fileRight.good()) {
			cout << "file '"<< fileNameLeft <<"' not found"  << endl;
			strcpy(str, (std::string("file '")+ fileNameLeft +"' not found").c_str() );
			ret = false;
		}
		else {
			cout << "file '"<< fileNameRight <<"' not found"  << endl;
			strcpy(str, (std::string("file '")+ fileNameRight +"' not found").c_str() );
			ret = false;
		}
	}
	if (ret) {
		return const_cast<char *>("0");
	} else {
		return str;
	}
}

char* CSlimTools::traitReturnSystem(int status) {
	stringstream ss;
	static char str[MaxAnswer];
	if (WIFEXITED(status)) {
		int res = WEXITSTATUS(status);
		ss << (res > 124 ? res - 256 : res);
	} else {
		if (WIFSIGNALED(status)) {
			ss << "End cause by signal " << WTERMSIG(status);
		}
		if (WCOREDUMP(status)) {
			ss << " a core dump is generated";
		}
	}
	strncpy(str, ss.str().c_str(), MaxAnswer - 1);
	str[MaxAnswer - 1] = '\0';
	return str;
}