<commit_before>// chathistory.cpp : Defines the entry point for the DLL application.
//

#include "bzfsAPI.h"
#include <string>
#include <algorithm>
#include <sstream>
#include <stdarg.h>
#include <vector>
#include <stdio.h>
#include <assert.h>
#include <map>
#include <vector>

inline std::string tolower(const std::string& s)
{
  std::string trans = s;

  for (std::string::iterator i=trans.begin(), end=trans.end(); i!=end; ++i)
    *i = ::tolower(*i);
  return trans;
}

std::string format(const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  char	temp[2048];
  vsprintf(temp,fmt, args);
  std::string result = temp;
  va_end(args);
  return result;
}

std::vector<std::string> tokenize(const std::string& in, const std::string &delims, const int maxTokens, const bool useQuotes){
  std::vector<std::string> tokens;
  int numTokens = 0;
  bool inQuote = false;

  std::ostringstream currentToken;

  std::string::size_type pos = in.find_first_not_of(delims);
  int currentChar  = (pos == std::string::npos) ? -1 : in[pos];
  bool enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));

  while (pos != std::string::npos && !enoughTokens) {

    // get next token
    bool tokenDone = false;
    bool foundSlash = false;

    currentChar = (pos < in.size()) ? in[pos] : -1;
    while ((currentChar != -1) && !tokenDone){

      tokenDone = false;

      if (delims.find(currentChar) != std::string::npos && !inQuote) { // currentChar is a delim
	pos ++;
	break; // breaks out of while loop
      }

      if (!useQuotes){
	currentToken << char(currentChar);
      } else {

	switch (currentChar){
	  case '\\' : // found a backslash
	    if (foundSlash){
	      currentToken << char(currentChar);
	      foundSlash = false;
	    } else {
	      foundSlash = true;
	    }
	    break;
	  case '\"' : // found a quote
	    if (foundSlash){ // found \"
	      currentToken << char(currentChar);
	      foundSlash = false;
	    } else { // found unescaped "
	      if (inQuote){ // exiting a quote
		// finish off current token
		tokenDone = true;
		inQuote = false;
		//slurp off one additional delimeter if possible
		if (pos+1 < in.size() &&
		    delims.find(in[pos+1]) != std::string::npos) {
		  pos++;
		}

	      } else { // entering a quote
		// finish off current token
		tokenDone = true;
		inQuote = true;
	      }
	    }
	    break;
	  default:
	    if (foundSlash){ // don't care about slashes except for above cases
	      currentToken << '\\';
	      foundSlash = false;
	    }
	    currentToken << char(currentChar);
	    break;
	}
      }

      pos++;
      currentChar = (pos < in.size()) ? in[pos] : -1;
    } // end of getting a Token

    if (currentToken.str().size() > 0){ // if the token is something add to list
      tokens.push_back(currentToken.str());
      currentToken.str("");
      numTokens ++;
    }

    enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));
    if (enoughTokens){
      break;
    } else{
      pos = in.find_first_not_of(delims,pos);
    }

  } // end of getting all tokens -- either EOL or max tokens reached

  if (enoughTokens && pos != std::string::npos) {
    std::string lastToken = in.substr(pos);
    if (lastToken.size() > 0)
      tokens.push_back(lastToken);
  }

  return tokens;
}

BZ_GET_PLUGIN_VERSION

class LastChatCommand : public bz_CustomSlashCommandHandler
{
public:
  virtual ~LastChatCommand(){};
  virtual bool handle ( int playerID, bz_ApiString command, bz_ApiString message, bz_APIStringList *param );
};

LastChatCommand lastChatCommand;

// event handler callback
class ChatEvents : public bz_EventHandler
{
public:
  virtual ~ChatEvents(){};
  virtual void process ( bz_EventData *eventData );
};

ChatEvents chatEvents;

typedef std::vector<std::string>	tvChatHistory;

std::map<std::string,tvChatHistory>	chatHistories;

unsigned int		maxChatLines;

BZF_PLUGIN_CALL int bz_Load ( const char* commandLine )
{
  bz_debugMessage(4,"ChatEvents plugin loaded");

  maxChatLines = 1000;
  if (commandLine)
  {
    int realLines = atoi(commandLine);
    maxChatLines  = realLines;
  }

  bz_registerCustomSlashCommand("last",&lastChatCommand);
  bz_registerCustomSlashCommand("flushchat",&lastChatCommand);

  bz_registerEvent(bz_eRawChatMessageEvent,&chatEvents);

  return 0;
}

BZF_PLUGIN_CALL int bz_Unload ( void )
{
  bz_removeCustomSlashCommand("last");
  bz_removeCustomSlashCommand("flushchat");

  bz_removeEvent(bz_eRawChatMessageEvent,&chatEvents);

  bz_debugMessage(4,"ChatEvents plugin unloaded");
  return 0;
}

bool LastChatCommand::handle ( int playerID, bz_ApiString _command, bz_ApiString _message, bz_APIStringList * /*_param*/ )
{
  std::string command = _command.c_str();
  std::string message = _message.c_str();

  bz_BasePlayerRecord *fromPlayer = bz_getPlayerByIndex(playerID);

  if ( !fromPlayer->admin )
  {
    bz_sendTextMessage(BZ_SERVER,playerID,"You must be admin to use the ChatHistory plugin");
    return true;
  }

  if ( command == "list")
  {
    std::vector<std::string> params = tokenize(message,std::string(" "),1,false);
    if ( params.size() <2)
    {
      bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /last <NUMBER OF LINES> <CALLSIGN>");
      return true;
    }

    unsigned int numLines = (unsigned int)atoi(params[0].c_str());
    if ( numLines == 0 )
      numLines = 5;

    std::map<std::string,tvChatHistory>::iterator itr = chatHistories.find(tolower(params[1]));

    if ( itr == chatHistories.end() || !itr->second.size())
    {
      bz_sendTextMessage(BZ_SERVER,playerID,"That player has no chat history.");
      return true;
    }

    tvChatHistory &history = itr->second;

    if ( history.size() < numLines )
      numLines = (unsigned int )history.size();

    bz_sendTextMessage(BZ_SERVER,playerID,format("Last %d message for %s",numLines,params[1].c_str()).c_str());

    for ( unsigned int i = 0; i < numLines-1; i++ )
    {
      std::string chatItem = history[history.size()-i];
      bz_sendTextMessage(BZ_SERVER,playerID,format("%d<%s> %s",i,params[1].c_str(),chatItem.c_str()).c_str());
    }

    return true;
  }

  if ( command == "flushchat")
  {
    chatHistories.clear();
    bz_sendTextMessage(BZ_SERVER,playerID,"Chat History has been flushed");
    return true;
  }

  return false;
}

void ChatEvents::process ( bz_EventData *eventData )
{
  bz_ChatEventData_V1	*chatEventData = (bz_ChatEventData_V1*)eventData;

  bz_BasePlayerRecord *fromPlayer = bz_getPlayerByIndex(chatEventData->from);

  std::string message = chatEventData->message.c_str();

  std::string callsign = fromPlayer->callsign.c_str();
  callsign = tolower(callsign);

  switch( eventData->eventType)
  {
  default:
    break;

  case bz_eRawChatMessageEvent:
    std::map<std::string,tvChatHistory>::iterator itr = chatHistories.find(callsign);
    if (itr == chatHistories.end())
    {
      tvChatHistory h;
      chatHistories[callsign] = h;
    }

    tvChatHistory &history = chatHistories[callsign];

    history.push_back(message);
    if (history.size() > maxChatLines)
      history.erase(history.begin());
    break;

  }

  bz_freePlayerRecord(fromPlayer);

}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>when parsing the params for /list use all the fields, and let callsigns be in quotes.<commit_after>// chathistory.cpp : Defines the entry point for the DLL application.
//

#include "bzfsAPI.h"
#include <string>
#include <algorithm>
#include <sstream>
#include <stdarg.h>
#include <vector>
#include <stdio.h>
#include <assert.h>
#include <map>
#include <vector>

inline std::string tolower(const std::string& s)
{
  std::string trans = s;

  for (std::string::iterator i=trans.begin(), end=trans.end(); i!=end; ++i)
    *i = ::tolower(*i);
  return trans;
}

std::string format(const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  char	temp[2048];
  vsprintf(temp,fmt, args);
  std::string result = temp;
  va_end(args);
  return result;
}

std::vector<std::string> tokenize(const std::string& in, const std::string &delims, const int maxTokens, const bool useQuotes){
  std::vector<std::string> tokens;
  int numTokens = 0;
  bool inQuote = false;

  std::ostringstream currentToken;

  std::string::size_type pos = in.find_first_not_of(delims);
  int currentChar  = (pos == std::string::npos) ? -1 : in[pos];
  bool enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));

  while (pos != std::string::npos && !enoughTokens) {

    // get next token
    bool tokenDone = false;
    bool foundSlash = false;

    currentChar = (pos < in.size()) ? in[pos] : -1;
    while ((currentChar != -1) && !tokenDone){

      tokenDone = false;

      if (delims.find(currentChar) != std::string::npos && !inQuote) { // currentChar is a delim
	pos ++;
	break; // breaks out of while loop
      }

      if (!useQuotes){
	currentToken << char(currentChar);
      } else {

	switch (currentChar){
	  case '\\' : // found a backslash
	    if (foundSlash){
	      currentToken << char(currentChar);
	      foundSlash = false;
	    } else {
	      foundSlash = true;
	    }
	    break;
	  case '\"' : // found a quote
	    if (foundSlash){ // found \"
	      currentToken << char(currentChar);
	      foundSlash = false;
	    } else { // found unescaped "
	      if (inQuote){ // exiting a quote
		// finish off current token
		tokenDone = true;
		inQuote = false;
		//slurp off one additional delimeter if possible
		if (pos+1 < in.size() &&
		    delims.find(in[pos+1]) != std::string::npos) {
		  pos++;
		}

	      } else { // entering a quote
		// finish off current token
		tokenDone = true;
		inQuote = true;
	      }
	    }
	    break;
	  default:
	    if (foundSlash){ // don't care about slashes except for above cases
	      currentToken << '\\';
	      foundSlash = false;
	    }
	    currentToken << char(currentChar);
	    break;
	}
      }

      pos++;
      currentChar = (pos < in.size()) ? in[pos] : -1;
    } // end of getting a Token

    if (currentToken.str().size() > 0){ // if the token is something add to list
      tokens.push_back(currentToken.str());
      currentToken.str("");
      numTokens ++;
    }

    enoughTokens = (maxTokens && (numTokens >= (maxTokens-1)));
    if (enoughTokens){
      break;
    } else{
      pos = in.find_first_not_of(delims,pos);
    }

  } // end of getting all tokens -- either EOL or max tokens reached

  if (enoughTokens && pos != std::string::npos) {
    std::string lastToken = in.substr(pos);
    if (lastToken.size() > 0)
      tokens.push_back(lastToken);
  }

  return tokens;
}

BZ_GET_PLUGIN_VERSION

class LastChatCommand : public bz_CustomSlashCommandHandler
{
public:
  virtual ~LastChatCommand(){};
  virtual bool handle ( int playerID, bz_ApiString command, bz_ApiString message, bz_APIStringList *param );
};

LastChatCommand lastChatCommand;

// event handler callback
class ChatEvents : public bz_EventHandler
{
public:
  virtual ~ChatEvents(){};
  virtual void process ( bz_EventData *eventData );
};

ChatEvents chatEvents;

typedef std::vector<std::string>	tvChatHistory;

std::map<std::string,tvChatHistory>	chatHistories;

unsigned int		maxChatLines;

BZF_PLUGIN_CALL int bz_Load ( const char* commandLine )
{
  bz_debugMessage(4,"ChatEvents plugin loaded");

  maxChatLines = 1000;
  if (commandLine)
  {
    int realLines = atoi(commandLine);
    maxChatLines  = realLines;
  }

  bz_registerCustomSlashCommand("last",&lastChatCommand);
  bz_registerCustomSlashCommand("flushchat",&lastChatCommand);

  bz_registerEvent(bz_eRawChatMessageEvent,&chatEvents);

  return 0;
}

BZF_PLUGIN_CALL int bz_Unload ( void )
{
  bz_removeCustomSlashCommand("last");
  bz_removeCustomSlashCommand("flushchat");

  bz_removeEvent(bz_eRawChatMessageEvent,&chatEvents);

  bz_debugMessage(4,"ChatEvents plugin unloaded");
  return 0;
}

bool LastChatCommand::handle ( int playerID, bz_ApiString _command, bz_ApiString _message, bz_APIStringList * /*_param*/ )
{
  std::string command = _command.c_str();
  std::string message = _message.c_str();

  bz_BasePlayerRecord *fromPlayer = bz_getPlayerByIndex(playerID);

  if ( !fromPlayer->admin )
  {
    bz_sendTextMessage(BZ_SERVER,playerID,"You must be admin to use the ChatHistory plugin");
    return true;
  }

  if ( command == "list")
  {
    std::vector<std::string> params = tokenize(message,std::string(" "),0,true);
    if ( params.size() <2)
    {
      bz_sendTextMessage(BZ_SERVER,playerID,"Usage: /last <NUMBER OF LINES> <CALLSIGN>");
      return true;
    }

    unsigned int numLines = (unsigned int)atoi(params[0].c_str());
    if ( numLines == 0 )
      numLines = 5;

	std::string callsign = params[1];
    std::map<std::string,tvChatHistory>::iterator itr = chatHistories.find(tolower(callsign));

    if ( itr == chatHistories.end() || !itr->second.size())
    {
      bz_sendTextMessage(BZ_SERVER,playerID,"That player has no chat history.");
      return true;
    }

    tvChatHistory &history = itr->second;

    if ( history.size() < numLines )
      numLines = (unsigned int )history.size();

    bz_sendTextMessage(BZ_SERVER,playerID,format("Last %d message for %s",numLines,callsign.c_str()).c_str());

    for ( unsigned int i = 0; i < numLines-1; i++ )
    {
      std::string chatItem = history[history.size()-i];
      bz_sendTextMessage(BZ_SERVER,playerID,format("%d<%s> %s",i,callsign.c_str(),chatItem.c_str()).c_str());
    }

    return true;
  }

  if ( command == "flushchat")
  {
    chatHistories.clear();
    bz_sendTextMessage(BZ_SERVER,playerID,"Chat History has been flushed");
    return true;
  }

  return false;
}

void ChatEvents::process ( bz_EventData *eventData )
{
  bz_ChatEventData_V1	*chatEventData = (bz_ChatEventData_V1*)eventData;

  bz_BasePlayerRecord *fromPlayer = bz_getPlayerByIndex(chatEventData->from);

  std::string message = chatEventData->message.c_str();

  std::string callsign = fromPlayer->callsign.c_str();
  callsign = tolower(callsign);

  switch( eventData->eventType)
  {
  default:
    break;

  case bz_eRawChatMessageEvent:
    std::map<std::string,tvChatHistory>::iterator itr = chatHistories.find(callsign);
    if (itr == chatHistories.end())
    {
      tvChatHistory h;
      chatHistories[callsign] = h;
    }

    tvChatHistory &history = chatHistories[callsign];

    history.push_back(message);
    if (history.size() > maxChatLines)
      history.erase(history.begin());
    break;

  }

  bz_freePlayerRecord(fromPlayer);

}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>#include "../../include/EnemyTypes/Lich.h"

Lich::Lich() {
	name = "Lich";
	ExperienceAmount = 100;
	CoinsDrop = 50 + rand() % 100;
}

EnemyType Lich::GetType() {
    return etLich;
}

int Lich::ReturnDamage() {
	return 5 + rand() % 20;
}

int Lich::ReturnRiskAttackDamage() {
	int selector = rand() % 6;
	switch (selector) {
	case 0: case 1: case 2: case 3:
		return 2;
		break;
	case 4: case 5:
		return 30;
		break;
	default:
		return 0;
		break;
	}
}

int Lich::ReturnHealAmount() {
	return 5 + rand() % 25;
}
<commit_msg>Added introduction for Lich<commit_after>#include "../../include/EnemyTypes/Lich.h"

Lich::Lich() {
	name = "Lich";
	ExperienceAmount = 100;
	CoinsDrop = 50 + rand() % 100;
}

EnemyType Lich::GetType() {
    return etLich;
}

int Lich::ReturnDamage() {
	return 5 + rand() % 20;
}

int Lich::ReturnRiskAttackDamage() {
	int selector = rand() % 6;
	switch (selector) {
	case 0: case 1: case 2: case 3:
		return 2;
		break;
	case 4: case 5:
		return 30;
		break;
	default:
		return 0;
		break;
	}
}

int Lich::ReturnHealAmount() {
	return 5 + rand() % 25;
}<|endoftext|>


<commit_before>class Solution {
    public:
        RandomListNode *copyRandomList(RandomListNode *head) {
            if(head == NULL) return NULL;
            RandomListNode *headNew = NULL, *curNew = headNew, *curOriginal = head, *rand = head->random;
            while(curOriginal != NULL){
                if(headNew == NULL){
                    headNew = new RandomListNode(curOriginal->label);
                    curNew = headNew;
                }
                else{
                    curNew->next = new RandomListNode(curOriginal->label);
                    curNew = curNew->next;
                }
                curOriginal = curOriginal->next;
            }
            curOriginal = head; curNew = headNew;
            while(curOriginal != NULL && curNew != NULL){
                RandomListNode *cur1 = head, *cur2 = headNew;
                if(curOriginal->random == NULL) curNew->random = NULL;
                else{
                    while(cur1 != curOriginal->random){
                        cur1 = cur1->next;
                        cur2 = cur2->next;
                    }
                    curNew->random = cur2;
                }
                curOriginal = curOriginal->next;
                curNew = curNew->next;
            }
            return headNew;
        }
};
<commit_msg>solved by unordered_map, O(n) time and O(n) space<commit_after>class Solution {
    public:
        RandomListNode *copyRandomList(RandomListNode *head) {
            if(head == NULL) return NULL;
            RandomListNode *headNew = NULL, *curNew = headNew, *curOriginal = head;
            unordered_map<RandomListNode*, RandomListNode*> mapping;
            while(curOriginal != NULL){
                if(headNew == NULL){
                    headNew = new RandomListNode(curOriginal->label);
                    curNew = headNew;
                }
                else{
                    curNew->next = new RandomListNode(curOriginal->label);
                    curNew = curNew->next;
                }
                mapping[curOriginal] = curNew;
                curOriginal = curOriginal->next;
            }
            curOriginal = head; curNew = headNew;
            mapping[NULL] = NULL;
            while(curOriginal != NULL && curNew != NULL){
                curNew->random = mapping[curOriginal->random];
                curOriginal = curOriginal->next;
                curNew = curNew->next;
            }
            return headNew;
        }

};
<|endoftext|>


<commit_before>// vi: set ts=2:
//
// $Id: mainframe.C,v 1.62.8.6 2007/06/12 05:42:24 oliver Exp $
//

#include "mainframe.h"
#include "icons.h"
#include "demoTutorialDialog.h"

#include <BALL/VIEW/RENDERING/POVRenderer.h>
#include <BALL/VIEW/RENDERING/VRMLRenderer.h>
#include <BALL/VIEW/WIDGETS/molecularStructure.h>
#include <BALL/VIEW/WIDGETS/molecularControl.h>
#include <BALL/VIEW/WIDGETS/geometricControl.h>
#include <BALL/VIEW/WIDGETS/logView.h>
#include <BALL/VIEW/WIDGETS/helpViewer.h>
#include <BALL/VIEW/WIDGETS/datasetControl.h>
#include <BALL/VIEW/WIDGETS/editableScene.h>
#include <BALL/VIEW/WIDGETS/fileObserver.h>
#include <BALL/VIEW/WIDGETS/testFramework.h>
#include <BALL/VIEW/DIALOGS/pubchemDialog.h>
#include <BALL/VIEW/DIALOGS/downloadPDBFile.h>
#include <BALL/VIEW/DIALOGS/labelDialog.h>
#include <BALL/VIEW/DIALOGS/displayProperties.h>
#include <BALL/VIEW/DIALOGS/molecularFileDialog.h>
#include <BALL/VIEW/DATATYPE/standardDatasets.h>
#ifdef BALL_PYTHON_SUPPORT
#	include <BALL/VIEW/WIDGETS/pyWidget.h>
#endif

#include <BALL/SYSTEM/path.h>
#include <BALL/KERNEL/forEach.h>
#include <BALL/COMMON/version.h>

#include <QtGui/QKeyEvent>
#include <QtGui/QTreeWidget>

#include <BALL/CONCEPT/moleculeObjectCreator.h>
#ifdef BALL_HAS_ASIO
#include <BALL/VIEW/KERNEL/serverWidget.h>
#endif

#ifdef BALL_COMPILER_MSVC
# include "ui_aboutDialog.h"
#else
# include "aboutDialog.h"
#endif

// NOTE: this does not yet work correctly on windows
#ifndef BALL_COMPILER_MSVC
#include <BALL/VIEW/DIALOGS/pluginDialog.h>
#endif

using namespace std;
//#define BALL_VIEW_DEBUG

namespace BALL
{
	using namespace std;
	using namespace BALL::VIEW;

	Mainframe::Mainframe(QWidget* parent, const char* name)
		:	MainControl(parent, name, ".BALLView"),
			scene_(0)
	{
		#ifdef BALL_VIEW_DEBUG
		Log.error() << "new Mainframe " << this << std::endl;
		#endif

		// ---------------------
		// setup main window
		// ---------------------
		setWindowTitle("BALLView");
		setWindowIcon(QPixmap(bucky_64x64_xpm));
		// make sure submenus are the first
		initPopupMenu(FILE_OPEN);
		initPopupMenu(EDIT);
		initPopupMenu(BUILD);
		initPopupMenu(DISPLAY);
		initPopupMenu(MOLECULARMECHANICS);
		initPopupMenu(TOOLS);
	#ifdef BALL_PYTHON_SUPPORT
		initPopupMenu(TOOLS_PYTHON);
		initPopupMenu(MainControl::USER);
	#endif
		initPopupMenu(WINDOWS);
		initPopupMenu(MACRO);

		// ---------------------
		// Logstream setup -----
		// ---------------------
//   		Log.remove(std::cout);
//   		Log.remove(std::cerr);
		setLoggingFilename("BALLView.log");

		// Display Menu
		String description = "Shortcut|Display|Toggle_Fullscreen";
		insertMenuEntry(MainControl::DISPLAY, "Toggle Fullscreen", this,
										SLOT(toggleFullScreen()), description,
										QKeySequence(tr("Alt+X", description.c_str())));

		insertPopupMenuSeparator(DISPLAY);
		initPopupMenu(DISPLAY_VIEWPOINT);

		new MolecularFileDialog(this, "MolecularFileDialog");
		new DownloadPDBFile(		this, "DownloadPDBFile", false);
		new PubChemDialog(this, "PubChemDialog");
#ifndef BALL_COMPILER_MSVC
		new PluginDialog(this, "PluginDialog");
#endif
 		addDockWidget(Qt::LeftDockWidgetArea, new MolecularControl(this, "Structures"));
		addDockWidget(Qt::LeftDockWidgetArea, new GeometricControl(this, "Representations"));
		addDockWidget(Qt::TopDockWidgetArea,  new DatasetControl(this, "Datasets"));
		DatasetControl* dc = DatasetControl::getInstance(0);
		dc->registerController(new RegularData3DController());
		dc->registerController(new TrajectoryController());
		dc->registerController(new VectorGridController());
		dc->registerController(new DockResultController());
		dc->registerController(new RaytraceableGridController());

		DatasetControl::getInstance(0)->hide();

		new DemoTutorialDialog(this, "BALLViewDemo");

		HelpViewer* BALL_docu = new HelpViewer(this, "BALL Docu");
		addDockWidget(Qt::BottomDockWidgetArea, BALL_docu);
		String dirp = getDataPath() + ".." + FileSystem::PATH_SEPARATOR + "doc" +
									FileSystem::PATH_SEPARATOR + "BALL" + FileSystem::PATH_SEPARATOR;
		BALL_docu->setBaseDirectory(dirp);
		BALL_docu->setWhatsThisEnabled(false);
		BALL_docu->setProject("BALL");
		BALL_docu->setDefaultPage("index.html");

		addDockWidget(Qt::BottomDockWidgetArea, new HelpViewer(this, "BALLView Docu"));

		new LabelDialog(				this, "LabelDialog");
		new MolecularStructure(	this, "MolecularStructure");
 		addDockWidget(Qt::BottomDockWidgetArea, new LogView(this, "Logs"));
		addDockWidget(Qt::BottomDockWidgetArea, new FileObserver(  this, "FileObserver"));

		Scene::stereoBufferSupportTest();
		scene_ = new EditableScene(this, "3D View");
		setCentralWidget(scene_);
		setAcceptDrops(true);

		new DisplayProperties(	this, "DisplayProperties");

		// setup the VIEW server
		#ifdef BALL_HAS_ASIO
			ServerWidget* server = new ServerWidget(this);
		// registering object generator
		MoleculeObjectCreator* object_creator = new MoleculeObjectCreator;
		server->registerObjectCreator(*object_creator);
		#endif

		new TestFramework(this, "Test Framework");

		#ifdef BALL_PYTHON_SUPPORT
			addDockWidget(Qt::BottomDockWidgetArea, new PyWidget(this, "Python Interpreter"));
		#endif

		// ---------------------
		// Menus ---------------
		// ---------------------

		description = "Shortcut|File|Open|Project";
		insertMenuEntry(MainControl::FILE_OPEN, "Project", this,
										SLOT(loadBALLViewProjectFile()), description);

		description = "Shortcut|File|Save_Project";
		save_project_action_ = insertMenuEntry(MainControl::FILE, "Save Project", this,
											 										 SLOT(saveBALLViewProjectFile()), description);

			// Help-Menu -------------------------------------------------------------------
		QAction* action = 0;

		description = "Shortcut|Help|About";
		action = insertMenuEntry(MainControl::HELP, "About", this, SLOT(about()), description);
		setMenuHint(action, "Show informations on this version of BALLView");

		description = "Shortcut|Help|How_to_cite";
		action = insertMenuEntry(MainControl::HELP, "How to cite", this, SLOT(howToCite()), description);
		setMenuHint(action, "Show infos on how to cite BALL and BALLView");

		// TODO: why is this done here and not, e.g., in mainControl()???
		description = "Shortcut|MolecularMechanics|Abort_Calculation";
		stop_simulation_action_ = insertMenuEntry(MainControl::MOLECULARMECHANICS, "Abort Calculation", this,
																							SLOT(stopSimulation()), description,
																							QKeySequence(tr("Alt+C", description.c_str())));
		stop_simulation_action_->setEnabled(false);
		insertPopupMenuSeparator(MainControl::MOLECULARMECHANICS);
		setMenuHint(stop_simulation_action_, "Abort a running simulation");
		Path path;
		String filename = path.find("graphics/stop.png");
		stop_simulation_action_->setIcon(QIcon(filename.c_str()));

		description = "Shortcut|Edit|Toggle_Selection";
		complement_selection_action_ = insertMenuEntry(MainControl::EDIT, "Toggle Selection", this,
																									 SLOT(complementSelection()), description);

 		qApp->installEventFilter(this);

		setStatusbarText("Ready.");
	}

	Mainframe::~Mainframe()
	{
	}

	bool Mainframe::eventFilter(QObject* sender, QEvent* event)
	{
		if (event->type() != QEvent::KeyPress) return false;

		QKeyEvent* e = dynamic_cast<QKeyEvent*>(event);

		if (e->key() == Qt::Key_Escape &&
				HelpViewer::getInstance(1)->isWhatsThisEnabled())
		{
			HelpViewer::getInstance(1)->exitWhatsThisMode();
		}

		QPoint point = QCursor::pos();
		QWidget* widget = qApp->widgetAt(point);
		if (widget == scene_ &&
 				qApp->focusWidget() != scene_)
		{
 			scene_->keyPressEvent(e);
			return true;
		}

 		if (e->key() == Qt::Key_Delete &&
				RTTI::isKindOf<QTreeWidget>(*sender))
 		{
 			deleteClicked();
			return true;
 		}

		if (e->key() == Qt::Key_Enter)
		{
			if (composite_manager_.getNumberOfComposites() == 0) return false;

			if (getMolecularControlSelection().size() == 0)
			{
				control_selection_.push_back(*composite_manager_.begin());
			}

			MolecularStructure::getInstance(0)->centerCamera();
			return true;
		}

		// check all menu entries if Alt or CTRL is pressed to enable shortcuts
		if (e->key() == Qt::Key_Alt ||
				e->key() == Qt::Key_Control)
		{
			checkMenus();
			return false;
		}

		#ifdef BALL_PYTHON_SUPPORT
 			PyWidget::getInstance(0)->reactTo(*e);
			e->accept();
		#endif

		return false;
	}

	void Mainframe::reset()
	{
		if (composites_locked_ || getRepresentationManager().updateRunning()) return;

		clearData();

		DisplayProperties* dp = DisplayProperties::getInstance(0);
		dp->setDrawingPrecision(DRAWING_PRECISION_HIGH);
		dp->selectModel(MODEL_STICK);
		dp->selectColoringMethod(COLORING_ELEMENT);
		dp->selectMode(DRAWING_MODE_SOLID);
		dp->setTransparency(0);
		dp->setSurfaceDrawingPrecision(6.5);
	}

	void Mainframe::howToCite()
	{
		HelpViewer::getInstance(1)->showHelp("tips.html", "cite");
	}

	void Mainframe::show()
	{
		// prevent multiple inserting of menu entries, by calls of showFullScreen(), ...
		if (preferences_action_ != 0)
		{
			MainControl::show();
			return;
		}

		QToolBar* tb = new QToolBar("Main Toolbar", this);
		tb->setObjectName("Main Toolbar");
		tb->setIconSize(QSize(23,23));
		tb->layout()->setMargin(2);
		tb->layout()->setSpacing(2);
		addToolBar(Qt::TopToolBarArea, tb);

		MainControl::show();

		initPopupMenu(MainControl::WINDOWS)->addSeparator();
		initPopupMenu(MainControl::WINDOWS)->addAction(tb->toggleViewAction());
		MolecularFileDialog::getInstance(0)->addToolBarEntries(tb);
		DownloadPDBFile::getInstance(0)->addToolBarEntries(tb);
		PubChemDialog::getInstance(0)->addToolBarEntries(tb);
		Path path;

		QIcon load_icon(path.find("graphics/quickload.png").c_str());
		qload_action_ = new QAction(load_icon, "quickload", this);
		qload_action_->setObjectName("quickload");
		connect(qload_action_, SIGNAL(triggered()), this, SLOT(quickLoadConfirm()));
		HelpViewer::getInstance(1)->registerForHelpSystem(qload_action_, "tips.html#quickload");
		tb->addAction(qload_action_);

		QIcon save_icon(path.find("graphics/quicksave.png").c_str());
		qsave_action_ = new QAction(save_icon, "quicksave", this);
		qsave_action_->setObjectName("quicksave");
		connect(qsave_action_, SIGNAL(triggered()), this, SLOT(quickSave()));
		HelpViewer::getInstance(1)->registerForHelpSystem(qsave_action_, "tips.html#quickload");
		tb->addAction(qsave_action_);

		tb->addSeparator();
		DisplayProperties::getInstance(0)->addToolBarEntries(tb);
		MolecularStructure::getInstance(0)->addToolBarEntries(tb);
		scene_->addToolBarEntries(tb);
		tb->addAction(stop_simulation_action_);
		tb->addAction(preferences_action_);
		HelpViewer::getInstance(1)->addToolBarEntries(tb);

		// we have changed the child widgets stored in the maincontrol (e.g. toolbars), so we have
		// to restore the window state again!
		restoreWindows();

		// finally, apply all values our modular widgets have fetched from their preferences
		applyPreferences();
	}

	void Mainframe::about()
	{
		Log.info() << sizeof(Mainframe) <<std::endl;
		// Display about dialog
		QDialog w;
 		Ui_AboutDialog about;
		about.setupUi(&w);
		QString version = QString("QT ") + qVersion();
#ifdef BALL_QT_HAS_THREADS
		version += "(mt)";
#endif
		about.qt_version_label->setText(version);
		QFont font = about.BALLView_version_label->font();
		about.BALLView_version_label->setText(QString("BALLView ") + BALL_RELEASE_STRING);
		font.setPixelSize(18);
		about.BALLView_version_label->setFont(font);
		about.BALL_version_label->setText(__DATE__);
		w.exec();
	}

}
<commit_msg>Remove a stupid debug output that has sneaked in lately.<commit_after>// vi: set ts=2:
//
// $Id: mainframe.C,v 1.62.8.6 2007/06/12 05:42:24 oliver Exp $
//

#include "mainframe.h"
#include "icons.h"
#include "demoTutorialDialog.h"

#include <BALL/VIEW/RENDERING/POVRenderer.h>
#include <BALL/VIEW/RENDERING/VRMLRenderer.h>
#include <BALL/VIEW/WIDGETS/molecularStructure.h>
#include <BALL/VIEW/WIDGETS/molecularControl.h>
#include <BALL/VIEW/WIDGETS/geometricControl.h>
#include <BALL/VIEW/WIDGETS/logView.h>
#include <BALL/VIEW/WIDGETS/helpViewer.h>
#include <BALL/VIEW/WIDGETS/datasetControl.h>
#include <BALL/VIEW/WIDGETS/editableScene.h>
#include <BALL/VIEW/WIDGETS/fileObserver.h>
#include <BALL/VIEW/WIDGETS/testFramework.h>
#include <BALL/VIEW/DIALOGS/pubchemDialog.h>
#include <BALL/VIEW/DIALOGS/downloadPDBFile.h>
#include <BALL/VIEW/DIALOGS/labelDialog.h>
#include <BALL/VIEW/DIALOGS/displayProperties.h>
#include <BALL/VIEW/DIALOGS/molecularFileDialog.h>
#include <BALL/VIEW/DATATYPE/standardDatasets.h>
#ifdef BALL_PYTHON_SUPPORT
#	include <BALL/VIEW/WIDGETS/pyWidget.h>
#endif

#include <BALL/SYSTEM/path.h>
#include <BALL/KERNEL/forEach.h>
#include <BALL/COMMON/version.h>

#include <QtGui/QKeyEvent>
#include <QtGui/QTreeWidget>

#include <BALL/CONCEPT/moleculeObjectCreator.h>
#ifdef BALL_HAS_ASIO
#include <BALL/VIEW/KERNEL/serverWidget.h>
#endif

#ifdef BALL_COMPILER_MSVC
# include "ui_aboutDialog.h"
#else
# include "aboutDialog.h"
#endif

// NOTE: this does not yet work correctly on windows
#ifndef BALL_COMPILER_MSVC
#include <BALL/VIEW/DIALOGS/pluginDialog.h>
#endif

using namespace std;
//#define BALL_VIEW_DEBUG

namespace BALL
{
	using namespace std;
	using namespace BALL::VIEW;

	Mainframe::Mainframe(QWidget* parent, const char* name)
		:	MainControl(parent, name, ".BALLView"),
			scene_(0)
	{
		#ifdef BALL_VIEW_DEBUG
		Log.error() << "new Mainframe " << this << std::endl;
		#endif

		// ---------------------
		// setup main window
		// ---------------------
		setWindowTitle("BALLView");
		setWindowIcon(QPixmap(bucky_64x64_xpm));
		// make sure submenus are the first
		initPopupMenu(FILE_OPEN);
		initPopupMenu(EDIT);
		initPopupMenu(BUILD);
		initPopupMenu(DISPLAY);
		initPopupMenu(MOLECULARMECHANICS);
		initPopupMenu(TOOLS);
	#ifdef BALL_PYTHON_SUPPORT
		initPopupMenu(TOOLS_PYTHON);
		initPopupMenu(MainControl::USER);
	#endif
		initPopupMenu(WINDOWS);
		initPopupMenu(MACRO);

		// ---------------------
		// Logstream setup -----
		// ---------------------
//   		Log.remove(std::cout);
//   		Log.remove(std::cerr);
		setLoggingFilename("BALLView.log");

		// Display Menu
		String description = "Shortcut|Display|Toggle_Fullscreen";
		insertMenuEntry(MainControl::DISPLAY, "Toggle Fullscreen", this,
										SLOT(toggleFullScreen()), description,
										QKeySequence(tr("Alt+X", description.c_str())));

		insertPopupMenuSeparator(DISPLAY);
		initPopupMenu(DISPLAY_VIEWPOINT);

		new MolecularFileDialog(this, "MolecularFileDialog");
		new DownloadPDBFile(		this, "DownloadPDBFile", false);
		new PubChemDialog(this, "PubChemDialog");
#ifndef BALL_COMPILER_MSVC
		new PluginDialog(this, "PluginDialog");
#endif
 		addDockWidget(Qt::LeftDockWidgetArea, new MolecularControl(this, "Structures"));
		addDockWidget(Qt::LeftDockWidgetArea, new GeometricControl(this, "Representations"));
		addDockWidget(Qt::TopDockWidgetArea,  new DatasetControl(this, "Datasets"));
		DatasetControl* dc = DatasetControl::getInstance(0);
		dc->registerController(new RegularData3DController());
		dc->registerController(new TrajectoryController());
		dc->registerController(new VectorGridController());
		dc->registerController(new DockResultController());
		dc->registerController(new RaytraceableGridController());

		DatasetControl::getInstance(0)->hide();

		new DemoTutorialDialog(this, "BALLViewDemo");

		HelpViewer* BALL_docu = new HelpViewer(this, "BALL Docu");
		addDockWidget(Qt::BottomDockWidgetArea, BALL_docu);
		String dirp = getDataPath() + ".." + FileSystem::PATH_SEPARATOR + "doc" +
									FileSystem::PATH_SEPARATOR + "BALL" + FileSystem::PATH_SEPARATOR;
		BALL_docu->setBaseDirectory(dirp);
		BALL_docu->setWhatsThisEnabled(false);
		BALL_docu->setProject("BALL");
		BALL_docu->setDefaultPage("index.html");

		addDockWidget(Qt::BottomDockWidgetArea, new HelpViewer(this, "BALLView Docu"));

		new LabelDialog(				this, "LabelDialog");
		new MolecularStructure(	this, "MolecularStructure");
 		addDockWidget(Qt::BottomDockWidgetArea, new LogView(this, "Logs"));
		addDockWidget(Qt::BottomDockWidgetArea, new FileObserver(  this, "FileObserver"));

		Scene::stereoBufferSupportTest();
		scene_ = new EditableScene(this, "3D View");
		setCentralWidget(scene_);
		setAcceptDrops(true);

		new DisplayProperties(	this, "DisplayProperties");

		// setup the VIEW server
		#ifdef BALL_HAS_ASIO
			ServerWidget* server = new ServerWidget(this);
		// registering object generator
		MoleculeObjectCreator* object_creator = new MoleculeObjectCreator;
		server->registerObjectCreator(*object_creator);
		#endif

		new TestFramework(this, "Test Framework");

		#ifdef BALL_PYTHON_SUPPORT
			addDockWidget(Qt::BottomDockWidgetArea, new PyWidget(this, "Python Interpreter"));
		#endif

		// ---------------------
		// Menus ---------------
		// ---------------------

		description = "Shortcut|File|Open|Project";
		insertMenuEntry(MainControl::FILE_OPEN, "Project", this,
										SLOT(loadBALLViewProjectFile()), description);

		description = "Shortcut|File|Save_Project";
		save_project_action_ = insertMenuEntry(MainControl::FILE, "Save Project", this,
											 										 SLOT(saveBALLViewProjectFile()), description);

			// Help-Menu -------------------------------------------------------------------
		QAction* action = 0;

		description = "Shortcut|Help|About";
		action = insertMenuEntry(MainControl::HELP, "About", this, SLOT(about()), description);
		setMenuHint(action, "Show informations on this version of BALLView");

		description = "Shortcut|Help|How_to_cite";
		action = insertMenuEntry(MainControl::HELP, "How to cite", this, SLOT(howToCite()), description);
		setMenuHint(action, "Show infos on how to cite BALL and BALLView");

		// TODO: why is this done here and not, e.g., in mainControl()???
		description = "Shortcut|MolecularMechanics|Abort_Calculation";
		stop_simulation_action_ = insertMenuEntry(MainControl::MOLECULARMECHANICS, "Abort Calculation", this,
																							SLOT(stopSimulation()), description,
																							QKeySequence(tr("Alt+C", description.c_str())));
		stop_simulation_action_->setEnabled(false);
		insertPopupMenuSeparator(MainControl::MOLECULARMECHANICS);
		setMenuHint(stop_simulation_action_, "Abort a running simulation");
		Path path;
		String filename = path.find("graphics/stop.png");
		stop_simulation_action_->setIcon(QIcon(filename.c_str()));

		description = "Shortcut|Edit|Toggle_Selection";
		complement_selection_action_ = insertMenuEntry(MainControl::EDIT, "Toggle Selection", this,
																									 SLOT(complementSelection()), description);

 		qApp->installEventFilter(this);

		setStatusbarText("Ready.");
	}

	Mainframe::~Mainframe()
	{
	}

	bool Mainframe::eventFilter(QObject* sender, QEvent* event)
	{
		if (event->type() != QEvent::KeyPress) return false;

		QKeyEvent* e = dynamic_cast<QKeyEvent*>(event);

		if (e->key() == Qt::Key_Escape &&
				HelpViewer::getInstance(1)->isWhatsThisEnabled())
		{
			HelpViewer::getInstance(1)->exitWhatsThisMode();
		}

		QPoint point = QCursor::pos();
		QWidget* widget = qApp->widgetAt(point);
		if (widget == scene_ &&
 				qApp->focusWidget() != scene_)
		{
 			scene_->keyPressEvent(e);
			return true;
		}

 		if (e->key() == Qt::Key_Delete &&
				RTTI::isKindOf<QTreeWidget>(*sender))
 		{
 			deleteClicked();
			return true;
 		}

		if (e->key() == Qt::Key_Enter)
		{
			if (composite_manager_.getNumberOfComposites() == 0) return false;

			if (getMolecularControlSelection().size() == 0)
			{
				control_selection_.push_back(*composite_manager_.begin());
			}

			MolecularStructure::getInstance(0)->centerCamera();
			return true;
		}

		// check all menu entries if Alt or CTRL is pressed to enable shortcuts
		if (e->key() == Qt::Key_Alt ||
				e->key() == Qt::Key_Control)
		{
			checkMenus();
			return false;
		}

		#ifdef BALL_PYTHON_SUPPORT
 			PyWidget::getInstance(0)->reactTo(*e);
			e->accept();
		#endif

		return false;
	}

	void Mainframe::reset()
	{
		if (composites_locked_ || getRepresentationManager().updateRunning()) return;

		clearData();

		DisplayProperties* dp = DisplayProperties::getInstance(0);
		dp->setDrawingPrecision(DRAWING_PRECISION_HIGH);
		dp->selectModel(MODEL_STICK);
		dp->selectColoringMethod(COLORING_ELEMENT);
		dp->selectMode(DRAWING_MODE_SOLID);
		dp->setTransparency(0);
		dp->setSurfaceDrawingPrecision(6.5);
	}

	void Mainframe::howToCite()
	{
		HelpViewer::getInstance(1)->showHelp("tips.html", "cite");
	}

	void Mainframe::show()
	{
		// prevent multiple inserting of menu entries, by calls of showFullScreen(), ...
		if (preferences_action_ != 0)
		{
			MainControl::show();
			return;
		}

		QToolBar* tb = new QToolBar("Main Toolbar", this);
		tb->setObjectName("Main Toolbar");
		tb->setIconSize(QSize(23,23));
		tb->layout()->setMargin(2);
		tb->layout()->setSpacing(2);
		addToolBar(Qt::TopToolBarArea, tb);

		MainControl::show();

		initPopupMenu(MainControl::WINDOWS)->addSeparator();
		initPopupMenu(MainControl::WINDOWS)->addAction(tb->toggleViewAction());
		MolecularFileDialog::getInstance(0)->addToolBarEntries(tb);
		DownloadPDBFile::getInstance(0)->addToolBarEntries(tb);
		PubChemDialog::getInstance(0)->addToolBarEntries(tb);
		Path path;

		QIcon load_icon(path.find("graphics/quickload.png").c_str());
		qload_action_ = new QAction(load_icon, "quickload", this);
		qload_action_->setObjectName("quickload");
		connect(qload_action_, SIGNAL(triggered()), this, SLOT(quickLoadConfirm()));
		HelpViewer::getInstance(1)->registerForHelpSystem(qload_action_, "tips.html#quickload");
		tb->addAction(qload_action_);

		QIcon save_icon(path.find("graphics/quicksave.png").c_str());
		qsave_action_ = new QAction(save_icon, "quicksave", this);
		qsave_action_->setObjectName("quicksave");
		connect(qsave_action_, SIGNAL(triggered()), this, SLOT(quickSave()));
		HelpViewer::getInstance(1)->registerForHelpSystem(qsave_action_, "tips.html#quickload");
		tb->addAction(qsave_action_);

		tb->addSeparator();
		DisplayProperties::getInstance(0)->addToolBarEntries(tb);
		MolecularStructure::getInstance(0)->addToolBarEntries(tb);
		scene_->addToolBarEntries(tb);
		tb->addAction(stop_simulation_action_);
		tb->addAction(preferences_action_);
		HelpViewer::getInstance(1)->addToolBarEntries(tb);

		// we have changed the child widgets stored in the maincontrol (e.g. toolbars), so we have
		// to restore the window state again!
		restoreWindows();

		// finally, apply all values our modular widgets have fetched from their preferences
		applyPreferences();
	}

	void Mainframe::about()
	{
		// Display about dialog
		QDialog w;
 		Ui_AboutDialog about;
		about.setupUi(&w);
		QString version = QString("QT ") + qVersion();
#ifdef BALL_QT_HAS_THREADS
		version += "(mt)";
#endif
		about.qt_version_label->setText(version);
		QFont font = about.BALLView_version_label->font();
		about.BALLView_version_label->setText(QString("BALLView ") + BALL_RELEASE_STRING);
		font.setPixelSize(18);
		about.BALLView_version_label->setFont(font);
		about.BALL_version_label->setText(__DATE__);
		w.exec();
	}

}
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: XDRPersistenceManager_test.C,v 1.15 2004/07/07 23:04:02 amoll Exp $
//

#include <BALL/CONCEPT/classTest.h>

///////////////////////////

#include <BALL/CONCEPT/XDRPersistenceManager.h>
#include <BALL/CONCEPT/composite.h>
#include <BALL/FORMAT/PDBFile.h>
#include <BALL/FORMAT/HINFile.h>
#include <BALL/KERNEL/bond.h>

///////////////////////////

START_TEST(XDRPersistenceManager, "$Id: XDRPersistenceManager_test.C,v 1.15 2004/07/07 23:04:02 amoll Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;
using namespace std;

XDRPersistenceManager* pm_ptr = 0;
CHECK(XDRPersistenceManager() throw())
	pm_ptr = new XDRPersistenceManager;
	TEST_NOT_EQUAL(pm_ptr, 0)
RESULT

CHECK(~XDRPersistenceManager())
	delete pm_ptr;
RESULT

String filename;
NEW_TMP_FILE(filename)
CHECK(XDRPersistenceManager(std::ostream& os) throw())
	ofstream os(filename.c_str(), std::ios::out);
	Composite comp;
	XDRPersistenceManager pm(os);
	comp >> pm;
	os.close();
RESULT

CHECK(XDRPersistenceManager(std::istream& is) throw())
	ifstream is(filename.c_str());
	XDRPersistenceManager pm(is);
	PersistentObject* po = pm.readObject();
	is.close();
	TEST_NOT_EQUAL(po, 0)
	TEST_EQUAL(RTTI::isKindOf<Composite>(*po), true)
	delete po;
RESULT

CHECK(XDRPersistenceManager(std::istream& is, std::ostream& os) throw())
	String outfilename;
	NEW_TMP_FILE(outfilename);
	ifstream is(filename.c_str());
	ofstream os(outfilename.c_str(), std::ios::out);
	XDRPersistenceManager pm(is, os);
	PersistentObject* po = pm.readObject();
	is.close();
	TEST_NOT_EQUAL(po, 0)
	TEST_EQUAL(RTTI::isKindOf<Composite>(*po), true)
	// *po >> pm;
	os.close();
	delete po;
RESULT

CHECK(void writeHeader(const char* type_name, const char* name, PointerSizeUInt ptr) throw())
	String outfilename;
	NEW_TMP_FILE(outfilename);
	ofstream os(outfilename.c_str(), std::ios::out);
	XDRPersistenceManager pm(os);
	Composite composite;
	// composite >> pm;
	os.close();
	TEST_FILE_REGEXP(outfilename.c_str(), "data/XDRPersistenceManager_test1.txt")
RESULT

CHECK(bool checkHeader(const char* type_name, const char* name, PointerSizeUInt& ptr) throw())
  //?????
RESULT

CHECK(void writeTrailer(const char* name = 0) throw())
  //?????
RESULT

CHECK(bool checkTrailer(const char* name = 0) throw())
  //?????
RESULT

CHECK(void writeStreamHeader() throw())
  //?????
RESULT

CHECK(void writeStreamTrailer() throw())
  //?????
RESULT

CHECK(bool checkStreamHeader() throw())
  //?????
RESULT

CHECK(bool checkStreamTrailer() throw())
  //?????
RESULT

CHECK(bool getObjectHeader(String& type_name, PointerSizeUInt& ptr) throw())
  //?????
RESULT

CHECK(void writeName(const char* name) throw())
  //?????
RESULT

CHECK(bool checkName(const char* name) throw())
  //?????
RESULT

CHECK(void writeStorableHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkStorableHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writePrimitiveHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkPrimitiveHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writeStorableTrailer() throw())
  //?????
RESULT

CHECK(bool checkStorableTrailer() throw())
  //?????
RESULT

CHECK(void writePrimitiveTrailer() throw())
  //?????
RESULT

CHECK(bool checkPrimitiveTrailer() throw())
  //?????
RESULT

CHECK(void writeObjectPointerHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkObjectPointerHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writeObjectReferenceHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkObjectReferenceHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writeObjectPointerArrayHeader(const char* type_name, const char* name, Size size) throw())
  //?????
RESULT

CHECK(bool checkObjectPointerArrayHeader(const char* type_name, const char* name, Size& size) throw())
  //?????
RESULT

CHECK(void writeObjectPointerArrayTrailer() throw())
  //?????
RESULT

CHECK(bool checkObjectPointerArrayTrailer() throw())
  //?????
RESULT

NEW_TMP_FILE(filename)
std::ofstream outfile(filename.c_str(), std::ios::out);

XDRPersistenceManager pm;
pm.setOstream(outfile);
pm.initializeOutputStream();
pm.writeStreamHeader();
CHECK(void put(const char c) throw())
	pm.put((char)0);
	pm.put((char)85);
	pm.put((char)-86);
	pm.put((char)-1);
RESULT

CHECK(void put(const Byte b) throw())
	pm.put((Byte)0);
	pm.put((Byte)85);
	pm.put((Byte)170);
	pm.put((Byte)255);
RESULT

CHECK(void put(const Index i) throw())
	pm.put((Index)0);
	pm.put((Index)-1);
	pm.put((Index)0xAA55CC33);
	pm.put((Index)0xCC33AA55);
RESULT

CHECK(void put(const Size s) throw())
	pm.put((Size)0);
	pm.put((Size)0xAA55CC33);
	pm.put((Size)0xCC33AA55);
	pm.put((Size)0xFFFFFFFF);
RESULT

CHECK(void put(const bool b) throw())
	pm.put(true);
	pm.put(false);
RESULT

CHECK(void put(const Real f) throw())
  pm.put((Real)0.0);
	pm.put((Real)1.234567);
	pm.put((Real)-9.87654e37);
RESULT

CHECK(void put(const DoubleReal d) throw())
  pm.put((DoubleReal)0.0);
	pm.put((DoubleReal)1.234567);
	pm.put((DoubleReal)-9.87654e300);
RESULT

CHECK(void put(const string& s) throw())
  pm.put(String(""));
	pm.put(String("ABCDEFGHIJKLMNOPQRSTUVWxyz"));
RESULT

PointerSizeUInt psi1 = 0x01234567;
psi1 <<= 32;
psi1 += 0xFEDCBA98;
PointerSizeUInt psi2 = 0xFEDCBA98;
psi2 <<= 32;
psi2 += 0x01234567;

CHECK(void put(const PointerSizeUInt p) throw())
	pm.put((PointerSizeUInt)0);
	pm.put(psi1);
	pm.put(psi2);
RESULT

pm.writeStreamTrailer();
pm.finalizeOutputStream();
outfile.close();

std::ifstream infile(filename.c_str());
pm.setIstream(infile);
pm.initializeInputStream();
pm.checkStreamHeader();

CHECK(void get(char& c) throw())
	char c;
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, 0)
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, 85)
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, -86)
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, -1)
RESULT

CHECK(void get(Byte& c) throw())
	Byte c;
	pm.get(c);
	TEST_EQUAL((Size)c, 0)
	pm.get(c);
	TEST_EQUAL((Size)c, 85)
	pm.get(c);
	TEST_EQUAL((Size)c, 170)
	pm.get(c);
	TEST_EQUAL((Size)c, 255)
RESULT

CHECK(void get(Index& s) throw())
	Index i;
	pm.get(i);
	TEST_EQUAL(i, (Index)0)
	pm.get(i);
	TEST_EQUAL(i, (Index)-1)
	pm.get(i);
	TEST_EQUAL(i, (Index)0xAA55CC33)
	pm.get(i);
	TEST_EQUAL(i, (Index)0xCC33AA55)
RESULT

CHECK(void get(Size& s) throw())
	Size s;
	pm.get(s);
	TEST_EQUAL(s, (Size)0)
	pm.get(s);
	TEST_EQUAL(s, (Size)0xAA55CC33)
	pm.get(s);
	TEST_EQUAL(s, (Size)0xCC33AA55)
	pm.get(s);
	TEST_EQUAL(s, (Size)0xFFFFFFFF)
RESULT

CHECK(void get(bool& b) throw())
  bool b;
	pm.get(b);
	TEST_EQUAL(b, true)
	pm.get(b);
	TEST_EQUAL(b, false)
RESULT

CHECK(void get(Real& f) throw())
	Real x;
	pm.get(x);
  TEST_REAL_EQUAL(x, (Real)0.0)
	pm.get(x);
  TEST_REAL_EQUAL(x, (Real)1.234567)
	pm.get(x);
  TEST_REAL_EQUAL(x, (Real)-9.87654e37)
RESULT

CHECK(void get(DoubleReal& d) throw())
	DoubleReal x;
	pm.get(x);
  TEST_REAL_EQUAL(x, (DoubleReal)0.0)
	pm.get(x);
  TEST_REAL_EQUAL(x, (DoubleReal)1.234567)
	pm.get(x);
  TEST_REAL_EQUAL(x, (DoubleReal)-9.87654e300)
RESULT

CHECK(void get(string& s) throw())
	string s;
	pm.get(s);
	TEST_EQUAL(s, "")
	pm.get(s);
	TEST_EQUAL(s, "ABCDEFGHIJKLMNOPQRSTUVWxyz")
RESULT

CHECK(void get(PointerSizeUInt& p) throw())
	PointerSizeUInt p;
	pm.get(p);
	TEST_EQUAL(p, 0)
	pm.get(p);
	TEST_EQUAL(p, psi1)
	pm.get(p);
	TEST_EQUAL(p, psi2)
RESULT

pm.finalizeInputStream();
infile.close();

CHECK(void finalizeInputStream() throw())
  // ???
RESULT

CHECK(void finalizeOutputStream() throw())
	// ???
RESULT

CHECK(void initializeInputStream() throw())
	// ???
RESULT

CHECK(void initializeOutputStream() throw())
	// ???
RESULT

CHECK([Extra] full_test0)
	String filename;
	Bond b1;

	NEW_TMP_FILE(filename);
	ofstream os(filename.c_str(), std::ios::out);
	XDRPersistenceManager pm(os);
	b1 >> pm;
	os.close();

	ifstream is(filename.c_str(), std::ios::in);
	XDRPersistenceManager pm2(is);
	PersistentObject* po =  pm2.readObject();
	is.close();
RESULT

CHECK([Extra] full_test1)
	String filename;

	System s1;
	Protein p1;
	Chain c1;
	SecondaryStructure ss1;
	Residue r1;
	PDBAtom a1;
	PDBAtom a2;
	s1.insert(p1);
	p1.insert(c1);
	c1.insert(ss1);
	ss1.insert(r1);
	r1.insert(a1);
	r1.insert(a2);
	Bond b1;
	TEST_NOT_EQUAL(b1.createBond(b1, a2, a1), 0)

	NEW_TMP_FILE(filename);
	ofstream os(filename.c_str(), std::ios::out | std::ios::binary);
	XDRPersistenceManager pm(os);
	s1 >> pm;
	os.close();

	ifstream is(filename.c_str(), std::ios::in);
	XDRPersistenceManager pm2(is);
	PersistentObject* po =  pm2.readObject();
	System* s2 = (System*) po;
	is.close();

	TEST_EQUAL(s1.countAtoms(), s2->countAtoms())
RESULT

CHECK([Extra] full_test2)
	String filename;
	HINFile hin("data/AlaGlySer.hin");
	System s;
	hin >> s;

	NEW_TMP_FILE(filename);
	ofstream os(filename.c_str(), std::ios::out | std::ios::binary);
	XDRPersistenceManager pm(os);
	s >> pm;
	os.close();

	ifstream is(filename.c_str(), std::ios::in);
	XDRPersistenceManager pm2(is);
	System* s2 = (System*) pm2.readObject();
	is.close();

	TEST_EQUAL(s.countAtoms(), s2->countAtoms())
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST

<commit_msg>added some extra tests<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: XDRPersistenceManager_test.C,v 1.16 2004/11/02 14:00:08 amoll Exp $
//

#include <BALL/CONCEPT/classTest.h>

///////////////////////////

#include <BALL/CONCEPT/XDRPersistenceManager.h>
#include <BALL/CONCEPT/composite.h>
#include <BALL/FORMAT/PDBFile.h>
#include <BALL/FORMAT/HINFile.h>
#include <BALL/KERNEL/bond.h>

///////////////////////////

START_TEST(XDRPersistenceManager, "$Id: XDRPersistenceManager_test.C,v 1.16 2004/11/02 14:00:08 amoll Exp $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

using namespace BALL;
using namespace std;

XDRPersistenceManager* pm_ptr = 0;
CHECK(XDRPersistenceManager() throw())
	pm_ptr = new XDRPersistenceManager;
	TEST_NOT_EQUAL(pm_ptr, 0)
RESULT

CHECK(~XDRPersistenceManager())
	delete pm_ptr;
RESULT

String filename;
NEW_TMP_FILE(filename)
CHECK(XDRPersistenceManager(std::ostream& os) throw())
	ofstream os(filename.c_str(), std::ios::out);
	Composite comp;
	XDRPersistenceManager pm(os);
	comp >> pm;
	os.close();
RESULT

CHECK(XDRPersistenceManager(std::istream& is) throw())
	ifstream is(filename.c_str());
	XDRPersistenceManager pm(is);
	PersistentObject* po = pm.readObject();
	is.close();
	TEST_NOT_EQUAL(po, 0)
	TEST_EQUAL(RTTI::isKindOf<Composite>(*po), true)
	delete po;
RESULT

CHECK(XDRPersistenceManager(std::istream& is, std::ostream& os) throw())
	String outfilename;
	NEW_TMP_FILE(outfilename);
	ifstream is(filename.c_str());
	ofstream os(outfilename.c_str(), std::ios::out);
	XDRPersistenceManager pm(is, os);
	PersistentObject* po = pm.readObject();
	is.close();
	TEST_NOT_EQUAL(po, 0)
	TEST_EQUAL(RTTI::isKindOf<Composite>(*po), true)
	// *po >> pm;
	os.close();
	delete po;
RESULT

CHECK(void writeHeader(const char* type_name, const char* name, PointerSizeUInt ptr) throw())
	String outfilename;
	NEW_TMP_FILE(outfilename);
	ofstream os(outfilename.c_str(), std::ios::out);
	XDRPersistenceManager pm(os);
	Composite composite;
	// composite >> pm;
	os.close();
	TEST_FILE_REGEXP(outfilename.c_str(), "data/XDRPersistenceManager_test1.txt")
RESULT

CHECK(bool checkHeader(const char* type_name, const char* name, PointerSizeUInt& ptr) throw())
  //?????
RESULT

CHECK(void writeTrailer(const char* name = 0) throw())
  //?????
RESULT

CHECK(bool checkTrailer(const char* name = 0) throw())
  //?????
RESULT

CHECK(void writeStreamHeader() throw())
  //?????
RESULT

CHECK(void writeStreamTrailer() throw())
  //?????
RESULT

CHECK(bool checkStreamHeader() throw())
  //?????
RESULT

CHECK(bool checkStreamTrailer() throw())
  //?????
RESULT

CHECK(bool getObjectHeader(String& type_name, PointerSizeUInt& ptr) throw())
  //?????
RESULT

CHECK(void writeName(const char* name) throw())
  //?????
RESULT

CHECK(bool checkName(const char* name) throw())
  //?????
RESULT

CHECK(void writeStorableHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkStorableHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writePrimitiveHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkPrimitiveHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writeStorableTrailer() throw())
  //?????
RESULT

CHECK(bool checkStorableTrailer() throw())
  //?????
RESULT

CHECK(void writePrimitiveTrailer() throw())
  //?????
RESULT

CHECK(bool checkPrimitiveTrailer() throw())
  //?????
RESULT

CHECK(void writeObjectPointerHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkObjectPointerHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writeObjectReferenceHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(bool checkObjectReferenceHeader(const char* type_name, const char* name) throw())
  //?????
RESULT

CHECK(void writeObjectPointerArrayHeader(const char* type_name, const char* name, Size size) throw())
  //?????
RESULT

CHECK(bool checkObjectPointerArrayHeader(const char* type_name, const char* name, Size& size) throw())
  //?????
RESULT

CHECK(void writeObjectPointerArrayTrailer() throw())
  //?????
RESULT

CHECK(bool checkObjectPointerArrayTrailer() throw())
  //?????
RESULT

NEW_TMP_FILE(filename)
std::ofstream outfile(filename.c_str(), std::ios::out);

XDRPersistenceManager pm;
pm.setOstream(outfile);
pm.initializeOutputStream();
pm.writeStreamHeader();
CHECK(void put(const char c) throw())
	pm.put((char)0);
	pm.put((char)85);
	pm.put((char)-86);
	pm.put((char)-1);
RESULT

CHECK(void put(const Byte b) throw())
	pm.put((Byte)0);
	pm.put((Byte)85);
	pm.put((Byte)170);
	pm.put((Byte)255);
RESULT

CHECK(void put(const Index i) throw())
	pm.put((Index)0);
	pm.put((Index)-1);
	pm.put((Index)0xAA55CC33);
	pm.put((Index)0xCC33AA55);
RESULT

CHECK(void put(const Size s) throw())
	pm.put((Size)0);
	pm.put((Size)0xAA55CC33);
	pm.put((Size)0xCC33AA55);
	pm.put((Size)0xFFFFFFFF);
RESULT

CHECK(void put(const bool b) throw())
	pm.put(true);
	pm.put(false);
RESULT

CHECK(void put(const Real f) throw())
  pm.put((Real)0.0);
	pm.put((Real)1.234567);
	pm.put((Real)-9.87654e37);
RESULT

CHECK(void put(const DoubleReal d) throw())
  pm.put((DoubleReal)0.0);
	pm.put((DoubleReal)1.234567);
	pm.put((DoubleReal)-9.87654e300);
RESULT

CHECK(void put(const string& s) throw())
  pm.put(String(""));
	pm.put(String("ABCDEFGHIJKLMNOPQRSTUVWxyz"));
RESULT

PointerSizeUInt psi1 = 0x01234567;
psi1 <<= 32;
psi1 += 0xFEDCBA98;
PointerSizeUInt psi2 = 0xFEDCBA98;
psi2 <<= 32;
psi2 += 0x01234567;

CHECK(void put(const PointerSizeUInt p) throw())
	pm.put((PointerSizeUInt)0);
	pm.put(psi1);
	pm.put(psi2);
RESULT

pm.writeStreamTrailer();
pm.finalizeOutputStream();
outfile.close();

std::ifstream infile(filename.c_str());
pm.setIstream(infile);
pm.initializeInputStream();
pm.checkStreamHeader();

CHECK(void get(char& c) throw())
	char c;
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, 0)
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, 85)
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, -86)
	pm.get(c);
	TEST_EQUAL((Index)(signed char)c, -1)
RESULT

CHECK(void get(Byte& c) throw())
	Byte c;
	pm.get(c);
	TEST_EQUAL((Size)c, 0)
	pm.get(c);
	TEST_EQUAL((Size)c, 85)
	pm.get(c);
	TEST_EQUAL((Size)c, 170)
	pm.get(c);
	TEST_EQUAL((Size)c, 255)
RESULT

CHECK(void get(Index& s) throw())
	Index i;
	pm.get(i);
	TEST_EQUAL(i, (Index)0)
	pm.get(i);
	TEST_EQUAL(i, (Index)-1)
	pm.get(i);
	TEST_EQUAL(i, (Index)0xAA55CC33)
	pm.get(i);
	TEST_EQUAL(i, (Index)0xCC33AA55)
RESULT

CHECK(void get(Size& s) throw())
	Size s;
	pm.get(s);
	TEST_EQUAL(s, (Size)0)
	pm.get(s);
	TEST_EQUAL(s, (Size)0xAA55CC33)
	pm.get(s);
	TEST_EQUAL(s, (Size)0xCC33AA55)
	pm.get(s);
	TEST_EQUAL(s, (Size)0xFFFFFFFF)
RESULT

CHECK(void get(bool& b) throw())
  bool b;
	pm.get(b);
	TEST_EQUAL(b, true)
	pm.get(b);
	TEST_EQUAL(b, false)
RESULT

CHECK(void get(Real& f) throw())
	Real x;
	pm.get(x);
  TEST_REAL_EQUAL(x, (Real)0.0)
	pm.get(x);
  TEST_REAL_EQUAL(x, (Real)1.234567)
	pm.get(x);
  TEST_REAL_EQUAL(x, (Real)-9.87654e37)
RESULT

CHECK(void get(DoubleReal& d) throw())
	DoubleReal x;
	pm.get(x);
  TEST_REAL_EQUAL(x, (DoubleReal)0.0)
	pm.get(x);
  TEST_REAL_EQUAL(x, (DoubleReal)1.234567)
	pm.get(x);
  TEST_REAL_EQUAL(x, (DoubleReal)-9.87654e300)
RESULT

CHECK(void get(string& s) throw())
	string s;
	pm.get(s);
	TEST_EQUAL(s, "")
	pm.get(s);
	TEST_EQUAL(s, "ABCDEFGHIJKLMNOPQRSTUVWxyz")
RESULT

CHECK(void get(PointerSizeUInt& p) throw())
	PointerSizeUInt p;
	pm.get(p);
	TEST_EQUAL(p, 0)
	pm.get(p);
	TEST_EQUAL(p, psi1)
	pm.get(p);
	TEST_EQUAL(p, psi2)
RESULT

pm.finalizeInputStream();
infile.close();

CHECK(void finalizeInputStream() throw())
  // ???
RESULT

CHECK(void finalizeOutputStream() throw())
	// ???
RESULT

CHECK(void initializeInputStream() throw())
	// ???
RESULT

CHECK(void initializeOutputStream() throw())
	// ???
RESULT

CHECK([Extra] full_test0)
	String filename;
	Bond b1;

	NEW_TMP_FILE(filename);
	ofstream os(filename.c_str(), std::ios::out);
	XDRPersistenceManager pm(os);
	b1 >> pm;
	os.close();

	ifstream is(filename.c_str(), std::ios::in);
	XDRPersistenceManager pm2(is);
	PersistentObject* po =  pm2.readObject();
	is.close();
	TEST_EQUAL(RTTI::isKindOf<Bond>(*po), true)
	delete po;
RESULT

CHECK([Extra] full_test1)
	String filename;

	System s1;
	Protein p1;
	Chain c1;
	SecondaryStructure ss1;
	Residue r1;
	PDBAtom a1;
	PDBAtom a2;
	s1.insert(p1);
	p1.insert(c1);
	c1.insert(ss1);
	ss1.insert(r1);
	r1.insert(a1);
	r1.insert(a2);
	Bond b1;
	TEST_NOT_EQUAL(b1.createBond(b1, a2, a1), 0)

	NEW_TMP_FILE(filename);
	ofstream os(filename.c_str(), std::ios::out | std::ios::binary);
	XDRPersistenceManager pm(os);
	s1 >> pm;
	os.close();

	ifstream is(filename.c_str(), std::ios::in);
	XDRPersistenceManager pm2(is);
	PersistentObject* po =  pm2.readObject();
	System* s2 = (System*) po;
	is.close();

	TEST_EQUAL(s1.countAtoms(), s2->countAtoms())
	delete s2;
RESULT

CHECK([Extra] full_test2)
	String filename;
	HINFile hin("data/AlaGlySer.hin");
	System s;
	hin >> s;

	NEW_TMP_FILE(filename);
	ofstream os(filename.c_str(), std::ios::out | std::ios::binary);
	XDRPersistenceManager pm(os);
	s >> pm;
	os.close();

	ifstream is(filename.c_str(), std::ios::in);
	XDRPersistenceManager pm2(is);
	System* s2 = (System*) pm2.readObject();
	is.close();

	TEST_EQUAL(s.countAtoms(), s2->countAtoms())
RESULT

CHECK([Extra] full_test3)
	String filename;
	PDBFile in("data/bpti.pdb");
	System s;
	in >> s;

	NEW_TMP_FILE(filename);
	ofstream os(filename.c_str(), std::ios::out | std::ios::binary);
	XDRPersistenceManager pm(os);
	s >> pm;
	os.close();

	ifstream is(filename.c_str(), std::ios::in);
	XDRPersistenceManager pm2(is);
	System* s2 = (System*) pm2.readObject();
	is.close();

	TEST_EQUAL(s.countAtoms(), s2->countAtoms())
	delete s2;
RESULT

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST

<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * HDF5Common.cpp
 *
 *  Created on: April 20, 2017
 *      Author: Junmin
 */

#include "HDF5Common.h"

#include <complex>
#include <iostream>

#include "adios2/ADIOSMPI.h"

namespace adios
{

#define H5_ERROR std::cout << "[ADIOS H5 ERROR] "

HDF5Common::HDF5Common()
: m_WriteMode(false), m_CurrentTimeStep(0), m_NumTimeSteps(0)
{
    m_DefH5TypeComplexFloat =
        H5Tcreate(H5T_COMPOUND, sizeof(std::complex<float>));
    H5Tinsert(m_DefH5TypeComplexFloat, "freal", 0, H5T_NATIVE_FLOAT);
    H5Tinsert(m_DefH5TypeComplexFloat, "fimg", H5Tget_size(H5T_NATIVE_FLOAT),
              H5T_NATIVE_FLOAT);

    m_DefH5TypeComplexDouble =
        H5Tcreate(H5T_COMPOUND, sizeof(std::complex<double>));
    H5Tinsert(m_DefH5TypeComplexDouble, "dreal", 0, H5T_NATIVE_DOUBLE);
    H5Tinsert(m_DefH5TypeComplexDouble, "dimg", H5Tget_size(H5T_NATIVE_DOUBLE),
              H5T_NATIVE_DOUBLE);

    m_DefH5TypeComplexLongDouble =
        H5Tcreate(H5T_COMPOUND, sizeof(std::complex<long double>));
    H5Tinsert(m_DefH5TypeComplexLongDouble, "ldouble real", 0,
              H5T_NATIVE_LDOUBLE);
    H5Tinsert(m_DefH5TypeComplexLongDouble, "ldouble img",
              H5Tget_size(H5T_NATIVE_LDOUBLE), H5T_NATIVE_LDOUBLE);
}

void HDF5Common::Init(const std::string name, MPI_Comm comm, bool toWrite)
{
    m_WriteMode = toWrite;

    //
    m_PropertyListId = H5Pcreate(H5P_FILE_ACCESS);

#ifdef ADIOS2_HAVE_MPI
    H5Pset_fapl_mpio(m_PropertyListId, comm, MPI_INFO_NULL);
#endif

    std::string ts0 = "/TimeStep0";

    if (toWrite)
    {
        /*
         * Create a new file collectively and release property list identifier.
         */
        m_FileId = H5Fcreate(name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT,
                             m_PropertyListId);
        if (m_FileId >= 0)
        {
            m_GroupId = H5Gcreate2(m_FileId, ts0.c_str(), H5P_DEFAULT,
                                   H5P_DEFAULT, H5P_DEFAULT);
            if (m_GroupId < 0)
            {
                std::clog << "H5Common::Init: ERROR" << std::endl;
                throw std::runtime_error("HDF5: Unable to create group " + ts0);
            }
        }
    }
    else
    {
        // read a file collectively
        m_FileId = H5Fopen(name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
        if (m_FileId >= 0)
        {
            m_GroupId = H5Gopen(m_FileId, ts0.c_str(), H5P_DEFAULT);
        }
    }

    H5Pclose(m_PropertyListId);
}

void HDF5Common::WriteTimeSteps()
{
    if (m_FileId < 0)
    {
        // std::cerr<<"[ADIOS HDF5Error]: Invalid file to record timestep
        // to."<<std::endl;
        H5_ERROR << "Invalid file to record timestep to." << std::endl;
        return;
    }

    if (!m_WriteMode)
    {
        return;
    }

    hid_t s = H5Screate(H5S_SCALAR);

    hid_t attr = H5Acreate(m_FileId, "NumTimeSteps", H5T_NATIVE_UINT, s,
                           H5P_DEFAULT, H5P_DEFAULT);
    uint totalTimeSteps = m_CurrentTimeStep + 1;

    if (m_GroupId < 0)
    {
        totalTimeSteps = m_CurrentTimeStep;
    }

    H5Awrite(attr, H5T_NATIVE_UINT, &totalTimeSteps);

    H5Sclose(s);
    H5Aclose(attr);
}

unsigned int HDF5Common::GetNumTimeSteps()
{
    if (m_WriteMode)
    {
        return -1;
    }

    if (m_FileId < 0)
    {
        std::cerr
            << "[ADIOS HDF5Error]: Invalid file to read timestep attribute."
            << std::endl;
        return -1;
    }

    if (m_NumTimeSteps <= 0)
    {
        hid_t attr = H5Aopen(m_FileId, "NumTimeSteps", H5P_DEFAULT);

        H5Aread(attr, H5T_NATIVE_UINT, &m_NumTimeSteps);
        H5Aclose(attr);
    }

    return m_NumTimeSteps;
}

void HDF5Common::Close()
{
    if (m_FileId < 0)
    {
        return;
    }

    WriteTimeSteps();

    if (m_GroupId >= 0)
    {
        H5Gclose(m_GroupId);
    }

    H5Fclose(m_FileId);
    m_FileId = -1;
    m_GroupId = -1;

    H5Tclose(m_DefH5TypeComplexFloat);
    H5Tclose(m_DefH5TypeComplexDouble);
    H5Tclose(m_DefH5TypeComplexLongDouble);
}

void HDF5Common::Advance()
{
    if (m_GroupId >= 0)
    {
        H5Gclose(m_GroupId);
        m_GroupId = -1;
    }

    if (m_WriteMode)
    {
        // m_GroupId = H5Gcreate2(m_FileId, tsname.c_str(), H5P_DEFAULT,
        //                       H5P_DEFAULT, H5P_DEFAULT);
    }
    else
    {
        if (m_NumTimeSteps == 0)
        {
            GetNumTimeSteps();
        }
        if (m_CurrentTimeStep + 1 >= m_NumTimeSteps)
        {
            return;
        }

        std::string timeStepName =
            "/TimeStep" + std::to_string(m_CurrentTimeStep + 1);
        m_GroupId = H5Gopen(m_FileId, timeStepName.c_str(), H5P_DEFAULT);
        if (m_GroupId < 0)
        {
            throw std::runtime_error("HDF5: Unable to open group " +
                                     timeStepName);
        }
    }
    ++m_CurrentTimeStep;
}

void HDF5Common::CheckWriteGroup()
{
    if (!m_WriteMode)
    {
        return;
    }
    if (m_GroupId >= 0)
    {
        return;
    }

    std::string timeStepName = "/TimeStep" + std::to_string(m_CurrentTimeStep);
    m_GroupId = H5Gcreate2(m_FileId, timeStepName.c_str(), H5P_DEFAULT,
                           H5P_DEFAULT, H5P_DEFAULT);
    if (m_GroupId < 0)
    {
        throw std::runtime_error("HDF5: Unable to create group " +
                                 timeStepName);
    }
}
}
<commit_msg>HDF5Common.cpp moved to a new location and this one is no longer used<commit_after><|endoftext|>


<commit_before>// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*--
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines GRSimpleVals, a sub-class of GRTransferFuncs that
//  provides transfer functions for performing simple value tracking with
//  limited support for symbolics.
//
//===----------------------------------------------------------------------===//

#include "GRSimpleVals.h"
#include "BasicObjCFoundationChecks.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathSensitive/ValueState.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "llvm/Support/Compiler.h"
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Bug Descriptions.
//===----------------------------------------------------------------------===//

namespace {

class VISIBILITY_HIDDEN NullDeref : public BugDescription {
public:
  virtual const char* getName() const {
    return "null dereference";
  }
  virtual const char* getDescription() const {
    return "Dereference of null pointer.";
  }
};

class VISIBILITY_HIDDEN UndefDeref : public BugDescription {
public:
  virtual const char* getName() const {
    return "bad dereference";
  }
  virtual const char* getDescription() const {
    return "Dereference of undefined value.";
  }
};

class VISIBILITY_HIDDEN UndefBranch : public BugDescription {
public:
  virtual const char* getName() const {
    return "uninitialized value";
  }
  virtual const char* getDescription() const {
    return "Branch condition evaluates to an uninitialized value.";
  }
};

class VISIBILITY_HIDDEN DivZero : public BugDescription {
public:
  virtual const char* getName() const {
    return "divide-by-zero";
  }
  virtual const char* getDescription() const {
    return "Division by zero/undefined value.";
  }
};

class VISIBILITY_HIDDEN UndefResult : public BugDescription {
public:
  virtual const char* getName() const {
    return "undefined result";
  }
  virtual const char* getDescription() const {
    return "Result of operation is undefined.";
  }
};

class VISIBILITY_HIDDEN BadCall : public BugDescription {
public:
  virtual const char* getName() const {
    return "invalid function call";
  }
  virtual const char* getDescription() const {
    return "Called function is a NULL or undefined function pointer value.";
  }
};

class VISIBILITY_HIDDEN BadArg : public BugDescription {
public:
  virtual const char* getName() const {
    return "bad argument";
  }
  virtual const char* getDescription() const {
    return "Pass-by-value argument in function is undefined.";
  }
};

class VISIBILITY_HIDDEN BadMsgExprArg : public BugDescription {
public:
  virtual const char* getName() const {
    return "bad argument";
  }
  virtual const char* getDescription() const {
    return "Pass-by-value argument in message expression is undefined.";
  }
};

class VISIBILITY_HIDDEN BadReceiver : public BugDescription {
public:
  virtual const char* getName() const {
    return "invalid message expression";
  }
  virtual const char* getDescription() const {
    return "Receiver in message expression is an uninitialized value.";
  }
};

class VISIBILITY_HIDDEN RetStack : public BugDescription {
public:
  virtual const char* getName() const {
    return "return of stack address";
  }
  virtual const char* getDescription() const {
    return "Address of stack-allocated variable returned.";
  }
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//

template <typename ITERATOR> static inline
ExplodedNode<ValueState>* GetNode(ITERATOR I) {
  return *I;
}

template <> static inline
ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
  return I->first;
}

//===----------------------------------------------------------------------===//
// Analysis Driver.
//===----------------------------------------------------------------------===//

template <typename ITERATOR>
static void EmitWarning(Diagnostic& Diag, PathDiagnosticClient* PD,
                        ASTContext& Ctx, BugReporter& BR,
                        const BugDescription& Desc,
                        ExplodedGraph<GRExprEngine>& G,
                        ITERATOR I, ITERATOR E) {

  for (; I != E; ++I)
    BR.EmitPathWarning(Diag, PD, Ctx, Desc, G, GetNode(I));
}

namespace clang {

unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
                         Diagnostic& Diag, PathDiagnosticClient* PD,
                         bool Visualize, bool TrimGraph) {

  GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
  GRExprEngine* CS = &Eng.getCheckerState();

  // Set base transfer functions.
  GRSimpleVals GRSV;
  CS->setTransferFunctions(GRSV);

  // Add extra checkers.
  llvm::OwningPtr<GRSimpleAPICheck> FoundationCheck(
    CreateBasicObjCFoundationChecks(Ctx, &CS->getStateManager()));

  CS->AddObjCMessageExprCheck(FoundationCheck.get());

  // Execute the worklist algorithm.
  Eng.ExecuteWorkList(120000);

  BugReporter BR;
  ExplodedGraph<GRExprEngine>& G = Eng.getGraph();

  EmitWarning(Diag, PD, Ctx, BR, NullDeref(), G,
              CS->null_derefs_begin(), CS->null_derefs_end());

  EmitWarning(Diag, PD, Ctx, BR, UndefDeref(), G,
              CS->undef_derefs_begin(), CS->undef_derefs_end());

  EmitWarning(Diag, PD, Ctx, BR, UndefBranch(), G,
              CS->undef_branches_begin(), CS->undef_branches_end());

  EmitWarning(Diag, PD, Ctx, BR, DivZero(), G,
              CS->explicit_bad_divides_begin(), CS->explicit_bad_divides_end());

  EmitWarning(Diag, PD, Ctx, BR, UndefResult(), G,
              CS->undef_results_begin(), CS->undef_results_end());

  EmitWarning(Diag, PD, Ctx, BR, BadCall(), G,
              CS->bad_calls_begin(), CS->bad_calls_end());

  EmitWarning(Diag, PD, Ctx, BR, BadArg(), G,
              CS->undef_arg_begin(), CS->undef_arg_end());

  EmitWarning(Diag, PD, Ctx, BR, BadMsgExprArg(), G,
              CS->msg_expr_undef_arg_begin(), CS->msg_expr_undef_arg_end());

  EmitWarning(Diag, PD, Ctx, BR, BadReceiver(), G,
              CS->undef_receivers_begin(), CS->undef_receivers_end());

  EmitWarning(Diag, PD, Ctx, BR, RetStack(), G,
              CS->ret_stackaddr_begin(), CS->ret_stackaddr_end());

  FoundationCheck.get()->ReportResults(Diag, PD, Ctx, BR, G);
#ifndef NDEBUG
  if (Visualize) CS->ViewGraph(TrimGraph);
#endif

  return Eng.getGraph().size();
}

} // end clang namespace

//===----------------------------------------------------------------------===//
// Transfer function for Casts.
//===----------------------------------------------------------------------===//

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {

  if (!isa<nonlval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType()
                  || T->isObjCQualifiedIdType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  if (T->isPointerType())
    return lval::ConcreteInt(BasicVals.getValue(V));
  else
    return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Casts.

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {

  if (T->isPointerLikeType() || T->isObjCQualifiedIdType())
    return X;

  assert (T->isIntegerType());

  if (!isa<lval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Unary operators.

RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);

    default:
      return UnknownVal();
  }
}

RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());

    default:
      return UnknownVal();
  }
}

// Binary operators.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             NonLVal L, NonLVal R)  {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  while (1) {

    switch (L.getSubKind()) {
      default:
        return UnknownVal();

      case nonlval::ConcreteIntKind:

        if (isa<nonlval::ConcreteInt>(R)) {
          const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
          const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
          return L_CI.EvalBinOp(BasicVals, Op, R_CI);
        }
        else {
          NonLVal tmp = R;
          R = L;
          L = tmp;
          continue;
        }

      case nonlval::SymbolValKind: {

        if (isa<nonlval::ConcreteInt>(R)) {
          const SymIntConstraint& C =
            BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
                                    cast<nonlval::ConcreteInt>(R).getValue());

          return nonlval::SymIntConstraintVal(C);
        }
        else
          return UnknownVal();
      }
    }
  }
}

// Binary Operators (except assignments and comma).

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, LVal R) {

  switch (Op) {

    default:
      return UnknownVal();

    case BinaryOperator::EQ:
      return EvalEQ(Eng, L, R);

    case BinaryOperator::NE:
      return EvalNE(Eng, L, R);
  }
}

// Pointer arithmetic.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, NonLVal R) {
  return UnknownVal();
}

// Equality operators for LVals.

RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "EQ not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() ==
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {

        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {

      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement == for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L == R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, false);
}

RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "NE not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() !=
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {
      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement != for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();

      break;
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L != R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, true);
}

//===----------------------------------------------------------------------===//
// Transfer function for Function Calls.
//===----------------------------------------------------------------------===//

void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
                            GRExprEngine& Eng,
                            GRStmtNodeBuilder<ValueState>& Builder,
                            CallExpr* CE, LVal L,
                            ExplodedNode<ValueState>* Pred) {

  ValueStateManager& StateMgr = Eng.getStateManager();
  ValueState* St = Builder.GetState(Pred);

  // Invalidate all arguments passed in by reference (LVals).

  for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
        I != E; ++I) {

    RVal V = StateMgr.GetRVal(St, *I);

    if (isa<LVal>(V))
      St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
  }

  // Make up a symbol for the return value of this function.

  if (CE->getType() != Eng.getContext().VoidTy) {
    unsigned Count = Builder.getCurrentBlockCount();
    SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);

    RVal X = CE->getType()->isPointerType()
             ? cast<RVal>(lval::SymbolVal(Sym))
             : cast<RVal>(nonlval::SymbolVal(Sym));

    St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
  }

  Builder.MakeNode(Dst, CE, Pred, St);
}
<commit_msg>When reporting "bad receiver" warnings, highlight the receiver.<commit_after>// GRSimpleVals.cpp - Transfer functions for tracking simple values -*- C++ -*--
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines GRSimpleVals, a sub-class of GRTransferFuncs that
//  provides transfer functions for performing simple value tracking with
//  limited support for symbolics.
//
//===----------------------------------------------------------------------===//

#include "GRSimpleVals.h"
#include "BasicObjCFoundationChecks.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Analysis/PathDiagnostic.h"
#include "clang/Analysis/PathSensitive/ValueState.h"
#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "llvm/Support/Compiler.h"
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Bug Descriptions.
//===----------------------------------------------------------------------===//

namespace {

class VISIBILITY_HIDDEN NullDeref : public BugDescription {
public:
  virtual const char* getName() const {
    return "null dereference";
  }
  virtual const char* getDescription() const {
    return "Dereference of null pointer.";
  }
};

class VISIBILITY_HIDDEN UndefDeref : public BugDescription {
public:
  virtual const char* getName() const {
    return "bad dereference";
  }
  virtual const char* getDescription() const {
    return "Dereference of undefined value.";
  }
};

class VISIBILITY_HIDDEN UndefBranch : public BugDescription {
public:
  virtual const char* getName() const {
    return "uninitialized value";
  }
  virtual const char* getDescription() const {
    return "Branch condition evaluates to an uninitialized value.";
  }
};

class VISIBILITY_HIDDEN DivZero : public BugDescription {
public:
  virtual const char* getName() const {
    return "divide-by-zero";
  }
  virtual const char* getDescription() const {
    return "Division by zero/undefined value.";
  }
};

class VISIBILITY_HIDDEN UndefResult : public BugDescription {
public:
  virtual const char* getName() const {
    return "undefined result";
  }
  virtual const char* getDescription() const {
    return "Result of operation is undefined.";
  }
};

class VISIBILITY_HIDDEN BadCall : public BugDescription {
public:
  virtual const char* getName() const {
    return "invalid function call";
  }
  virtual const char* getDescription() const {
    return "Called function is a NULL or undefined function pointer value.";
  }
};

class VISIBILITY_HIDDEN BadArg : public BugDescription {
public:
  virtual const char* getName() const {
    return "bad argument";
  }
  virtual const char* getDescription() const {
    return "Pass-by-value argument in function is undefined.";
  }
};

class VISIBILITY_HIDDEN BadMsgExprArg : public BugDescription {
public:
  virtual const char* getName() const {
    return "bad receiver";
  }
  virtual const char* getDescription() const {
    return "Pass-by-value argument in message expression is undefined.";
  }
};

class VISIBILITY_HIDDEN BadReceiver : public BugDescription {
  SourceRange R;
public:
  BadReceiver(ExplodedNode<ValueState>* N) {
    Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
    Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
    assert (E && "Receiver cannot be NULL");
    R = E->getSourceRange();
  }

  virtual const char* getName() const {
    return "invalid message expression";
  }
  virtual const char* getDescription() const {
    return "Receiver in message expression is an uninitialized value.";
  }

  virtual void getRanges(const SourceRange*& B, const SourceRange*& E) const {
    B = &R;
    E = B+1;
  }
};

class VISIBILITY_HIDDEN RetStack : public BugDescription {
public:
  virtual const char* getName() const {
    return "return of stack address";
  }
  virtual const char* getDescription() const {
    return "Address of stack-allocated variable returned.";
  }
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//

template <typename ITERATOR> static inline
ExplodedNode<ValueState>* GetNode(ITERATOR I) {
  return *I;
}

template <> static inline
ExplodedNode<ValueState>* GetNode(GRExprEngine::undef_arg_iterator I) {
  return I->first;
}

//===----------------------------------------------------------------------===//
// Analysis Driver.
//===----------------------------------------------------------------------===//

template <typename ITERATOR>
static void EmitWarning(Diagnostic& Diag, PathDiagnosticClient* PD,
                        ASTContext& Ctx, BugReporter& BR,
                        const BugDescription& Desc,
                        ExplodedGraph<GRExprEngine>& G,
                        ITERATOR I, ITERATOR E) {

  for (; I != E; ++I)
    BR.EmitPathWarning(Diag, PD, Ctx, Desc, G, GetNode(I));
}

namespace clang {

unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
                         Diagnostic& Diag, PathDiagnosticClient* PD,
                         bool Visualize, bool TrimGraph) {

  GRCoreEngine<GRExprEngine> Eng(cfg, CD, Ctx);
  GRExprEngine* CS = &Eng.getCheckerState();

  // Set base transfer functions.
  GRSimpleVals GRSV;
  CS->setTransferFunctions(GRSV);

  // Add extra checkers.
  llvm::OwningPtr<GRSimpleAPICheck> FoundationCheck(
    CreateBasicObjCFoundationChecks(Ctx, &CS->getStateManager()));

  CS->AddObjCMessageExprCheck(FoundationCheck.get());

  // Execute the worklist algorithm.
  Eng.ExecuteWorkList(120000);

  BugReporter BR;
  ExplodedGraph<GRExprEngine>& G = Eng.getGraph();

  EmitWarning(Diag, PD, Ctx, BR, NullDeref(), G,
              CS->null_derefs_begin(), CS->null_derefs_end());

  EmitWarning(Diag, PD, Ctx, BR, UndefDeref(), G,
              CS->undef_derefs_begin(), CS->undef_derefs_end());

  EmitWarning(Diag, PD, Ctx, BR, UndefBranch(), G,
              CS->undef_branches_begin(), CS->undef_branches_end());

  EmitWarning(Diag, PD, Ctx, BR, DivZero(), G,
              CS->explicit_bad_divides_begin(), CS->explicit_bad_divides_end());

  EmitWarning(Diag, PD, Ctx, BR, UndefResult(), G,
              CS->undef_results_begin(), CS->undef_results_end());

  EmitWarning(Diag, PD, Ctx, BR, BadCall(), G,
              CS->bad_calls_begin(), CS->bad_calls_end());

  EmitWarning(Diag, PD, Ctx, BR, BadArg(), G,
              CS->undef_arg_begin(), CS->undef_arg_end());

  EmitWarning(Diag, PD, Ctx, BR, BadMsgExprArg(), G,
              CS->msg_expr_undef_arg_begin(), CS->msg_expr_undef_arg_end());

  for (GRExprEngine::UndefReceiversTy::iterator I = CS->undef_receivers_begin(),
                                  E = CS->undef_receivers_end(); I!=E; ++I) {

    BadReceiver Desc(*I);
    BR.EmitPathWarning(Diag, PD, Ctx, Desc, G, *I);
  }

  EmitWarning(Diag, PD, Ctx, BR, RetStack(), G,
              CS->ret_stackaddr_begin(), CS->ret_stackaddr_end());

  FoundationCheck.get()->ReportResults(Diag, PD, Ctx, BR, G);
#ifndef NDEBUG
  if (Visualize) CS->ViewGraph(TrimGraph);
#endif

  return Eng.getGraph().size();
}

} // end clang namespace

//===----------------------------------------------------------------------===//
// Transfer function for Casts.
//===----------------------------------------------------------------------===//

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, NonLVal X, QualType T) {

  if (!isa<nonlval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType()
                  || T->isObjCQualifiedIdType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  if (T->isPointerType())
    return lval::ConcreteInt(BasicVals.getValue(V));
  else
    return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Casts.

RVal GRSimpleVals::EvalCast(GRExprEngine& Eng, LVal X, QualType T) {

  if (T->isPointerLikeType() || T->isObjCQualifiedIdType())
    return X;

  assert (T->isIntegerType());

  if (!isa<lval::ConcreteInt>(X))
    return UnknownVal();

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
  V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
  V.extOrTrunc(Eng.getContext().getTypeSize(T));

  return nonlval::ConcreteInt(BasicVals.getValue(V));
}

// Unary operators.

RVal GRSimpleVals::EvalMinus(GRExprEngine& Eng, UnaryOperator* U, NonLVal X){

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalMinus(Eng.getBasicVals(), U);

    default:
      return UnknownVal();
  }
}

RVal GRSimpleVals::EvalComplement(GRExprEngine& Eng, NonLVal X) {

  switch (X.getSubKind()) {

    case nonlval::ConcreteIntKind:
      return cast<nonlval::ConcreteInt>(X).EvalComplement(Eng.getBasicVals());

    default:
      return UnknownVal();
  }
}

// Binary operators.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             NonLVal L, NonLVal R)  {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  while (1) {

    switch (L.getSubKind()) {
      default:
        return UnknownVal();

      case nonlval::ConcreteIntKind:

        if (isa<nonlval::ConcreteInt>(R)) {
          const nonlval::ConcreteInt& L_CI = cast<nonlval::ConcreteInt>(L);
          const nonlval::ConcreteInt& R_CI = cast<nonlval::ConcreteInt>(R);
          return L_CI.EvalBinOp(BasicVals, Op, R_CI);
        }
        else {
          NonLVal tmp = R;
          R = L;
          L = tmp;
          continue;
        }

      case nonlval::SymbolValKind: {

        if (isa<nonlval::ConcreteInt>(R)) {
          const SymIntConstraint& C =
            BasicVals.getConstraint(cast<nonlval::SymbolVal>(L).getSymbol(), Op,
                                    cast<nonlval::ConcreteInt>(R).getValue());

          return nonlval::SymIntConstraintVal(C);
        }
        else
          return UnknownVal();
      }
    }
  }
}

// Binary Operators (except assignments and comma).

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, LVal R) {

  switch (Op) {

    default:
      return UnknownVal();

    case BinaryOperator::EQ:
      return EvalEQ(Eng, L, R);

    case BinaryOperator::NE:
      return EvalNE(Eng, L, R);
  }
}

// Pointer arithmetic.

RVal GRSimpleVals::EvalBinOp(GRExprEngine& Eng, BinaryOperator::Opcode Op,
                             LVal L, NonLVal R) {
  return UnknownVal();
}

// Equality operators for LVals.

RVal GRSimpleVals::EvalEQ(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "EQ not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() ==
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {

        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {

      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                               BinaryOperator::EQ,
                               cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement == for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L == R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, false);
}

RVal GRSimpleVals::EvalNE(GRExprEngine& Eng, LVal L, LVal R) {

  BasicValueFactory& BasicVals = Eng.getBasicVals();

  switch (L.getSubKind()) {

    default:
      assert(false && "NE not implemented for this LVal.");
      return UnknownVal();

    case lval::ConcreteIntKind:

      if (isa<lval::ConcreteInt>(R)) {
        bool b = cast<lval::ConcreteInt>(L).getValue() !=
                 cast<lval::ConcreteInt>(R).getValue();

        return NonLVal::MakeIntTruthVal(BasicVals, b);
      }
      else if (isa<lval::SymbolVal>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(R).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(L).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      break;

    case lval::SymbolValKind: {
      if (isa<lval::ConcreteInt>(R)) {
        const SymIntConstraint& C =
          BasicVals.getConstraint(cast<lval::SymbolVal>(L).getSymbol(),
                                  BinaryOperator::NE,
                                  cast<lval::ConcreteInt>(R).getValue());

        return nonlval::SymIntConstraintVal(C);
      }

      // FIXME: Implement != for lval Symbols.  This is mainly useful
      //  in iterator loops when traversing a buffer, e.g. while(z != zTerm).
      //  Since this is not useful for many checkers we'll punt on this for
      //  now.

      return UnknownVal();

      break;
    }

    case lval::DeclValKind:
    case lval::FuncValKind:
    case lval::GotoLabelKind:
      return NonLVal::MakeIntTruthVal(BasicVals, L != R);
  }

  return NonLVal::MakeIntTruthVal(BasicVals, true);
}

//===----------------------------------------------------------------------===//
// Transfer function for Function Calls.
//===----------------------------------------------------------------------===//

void GRSimpleVals::EvalCall(ExplodedNodeSet<ValueState>& Dst,
                            GRExprEngine& Eng,
                            GRStmtNodeBuilder<ValueState>& Builder,
                            CallExpr* CE, LVal L,
                            ExplodedNode<ValueState>* Pred) {

  ValueStateManager& StateMgr = Eng.getStateManager();
  ValueState* St = Builder.GetState(Pred);

  // Invalidate all arguments passed in by reference (LVals).

  for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
        I != E; ++I) {

    RVal V = StateMgr.GetRVal(St, *I);

    if (isa<LVal>(V))
      St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
  }

  // Make up a symbol for the return value of this function.

  if (CE->getType() != Eng.getContext().VoidTy) {
    unsigned Count = Builder.getCurrentBlockCount();
    SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);

    RVal X = CE->getType()->isPointerType()
             ? cast<RVal>(lval::SymbolVal(Sym))
             : cast<RVal>(nonlval::SymbolVal(Sym));

    St = StateMgr.SetRVal(St, CE, X, Eng.getCFG().isBlkExpr(CE), false);
  }

  Builder.MakeNode(Dst, CE, Pred, St);
}
<|endoftext|>