// Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. #include "CoinFinite.hpp" #include "CoinMessageHandler.hpp" #include "CoinHelperFunctions.hpp" #include #include /* Default constructor. */ CoinOneMessage::CoinOneMessage() { externalNumber_=-1; message_[0]='\0'; severity_='I'; detail_=0; } /* Destructor */ CoinOneMessage::~CoinOneMessage() { } /* The copy constructor */ CoinOneMessage::CoinOneMessage(const CoinOneMessage & rhs) { externalNumber_=rhs.externalNumber_; strcpy(message_,rhs.message_); severity_=rhs.severity_; detail_=rhs.detail_; } /* assignment operator. */ CoinOneMessage& CoinOneMessage::operator=(const CoinOneMessage & rhs) { if (this != &rhs) { externalNumber_=rhs.externalNumber_; strcpy(message_,rhs.message_); severity_=rhs.severity_; detail_=rhs.detail_; } return *this; } /* Normal constructor */ CoinOneMessage::CoinOneMessage(int externalNumber, char detail, const char * message) { externalNumber_=externalNumber; strcpy(message_,message); if (externalNumber<3000) severity_='I'; else if (externalNumber<6000) severity_='W'; else if (externalNumber<9000) severity_='E'; else severity_='S'; detail_=detail; } // Replaces messages (i.e. a different language) void CoinOneMessage::replaceMessage( const char * message) { strcpy(message_,message); } /* Constructor with number of messages. */ CoinMessages::CoinMessages(int numberMessages) { numberMessages_=numberMessages; language_=us_en; strcpy(source_,"Unk"); class_=1; lengthMessages_=-1; if (numberMessages_) { message_ = new CoinOneMessage * [numberMessages_]; int i; for (i=0;imessage()); //printf("message %d at %x wass %s\n",i,rhs.message_[i],rhs.message_[i]->message()); } } } } /* assignment operator. */ CoinMessages& CoinMessages::operator=(const CoinMessages & rhs) { if (this != &rhs) { language_=rhs.language_; strcpy(source_,rhs.source_); class_=rhs.class_; if (lengthMessages_<0) { int i; for (i=0;imessage()); //printf("message %d at %x wass %s\n",i,rhs.message_[i],rhs.message_[i]->message()); } } } } return *this; } // Puts message in correct place void CoinMessages::addMessage(int messageNumber, const CoinOneMessage & message) { if (messageNumber>=numberMessages_) { // should not happen but allow for it CoinOneMessage ** temp = new CoinOneMessage * [messageNumber+1]; int i; for (i=0;i=0) fromCompact(); delete message_[messageNumber]; message_[messageNumber]=new CoinOneMessage(message); } // Replaces messages (i.e. a different language) void CoinMessages::replaceMessage(int messageNumber, const char * message) { if (lengthMessages_>=0) fromCompact(); assert(messageNumberreplaceMessage(message); } // Changes detail level for one message void CoinMessages::setDetailMessage(int newLevel, int messageNumber) { int i; // Last message is null (corresponds to DUMMY) for (i=0;iexternalNumber()==messageNumber) { message_[i]->setDetail(newLevel); break; } } } // Changes detail level for several messages void CoinMessages::setDetailMessages(int newLevel, int numberMessages, int * messageNumbers) { int i; if (numberMessages<3&&messageNumbers) { // do one by one int j; for (j=0;jexternalNumber()==messageNumber) { message_[i]->setDetail(newLevel); break; } } } } else if (numberMessages<10000&&messageNumbers) { // do backward mapping int backward[10000]; for (i=0;i<10000;i++) backward[i]=-1; for (i=0;iexternalNumber()]=i; for (i=0;i=0) message_[iback]->setDetail(newLevel); } } else { // do all (except for dummy end) for (i=0;isetDetail(newLevel); } } } // Changes detail level for all messages >= low and < high void CoinMessages::setDetailMessages(int newLevel, int low, int high) { // do all (except for dummy end) if in range for (int i=0;iexternalNumber(); if (iNumber>=low&&iNumbersetDetail(newLevel); } } /* Moves to compact format Compact format is an initial array of CoinOneMessage pointers, followed by a bulk store that holds compressed CoinOneMessage objects, where the message_ array is truncated to be just as large as necessary. */ void CoinMessages::toCompact() { if (numberMessages_&&lengthMessages_<0) { lengthMessages_=numberMessages_*sizeof(CoinOneMessage *); int i; for (i=0;imessage()); length = (message_[i]->message()+length+1)- (char *) message_[i]; assert (length<1000); int leftOver = length %8; if (leftOver) length += 8-leftOver; lengthMessages_+=length; } } // space char * temp = new char [lengthMessages_]; CoinOneMessage ** newMessage = (CoinOneMessage **) temp; temp += numberMessages_*sizeof(CoinOneMessage *); CoinOneMessage message; //printf("new address %x(%x) - length %d\n",newMessage,temp,lengthMessages_); lengthMessages_=numberMessages_*sizeof(CoinOneMessage *); for (i=0;imessage()); if (leftOver) length += 8-leftOver; temp += length; lengthMessages_+=length; } else { // null message newMessage[i]=NULL; } } for (i=0;i=0) { CoinOneMessage ** temp = new CoinOneMessage * [numberMessages_]; int i; for (i=0;imessageBuffer_) { *messageOut_=0; //take off trailing spaces and commas messageOut_--; while (messageOut_>=messageBuffer_) { if (*messageOut_==' '||*messageOut_==',') { *messageOut_=0; messageOut_--; } else { break; } } // Now do print which can be overridden returnCode=print(); // See what to do on error checkSeverity(); } return returnCode; } // Print message, return 0 normally int CoinMessageHandler::print() { fprintf(fp_,"%s\n",messageBuffer_); return 0; } // Check severity void CoinMessageHandler::checkSeverity() { if (currentMessage_.severity_=='S') { fprintf(fp_,"Stopping due to previous errors.\n"); //Should do walkback abort(); } } /* Amount of print out: 0 - none 1 - minimal 2 - normal low 3 - normal high 4 - verbose above that 8,16,32 etc just for selective debug and are for printf messages in code */ void CoinMessageHandler::setLogLevel(int value) { if (value>=-1) logLevel_=value; } void CoinMessageHandler::setLogLevel(int which,int value) { if (which>=0&&which=-1) logLevel_=value; } } void CoinMessageHandler::setPrefix(bool value) { if (value) prefix_ = 255; else prefix_ =0; } bool CoinMessageHandler::prefix() const { return (prefix_!=0); } // Constructor CoinMessageHandler::CoinMessageHandler() : logLevel_(1), prefix_(255), currentMessage_(), internalNumber_(0), format_(NULL), printStatus_(0), highestNumber_(-1), fp_(stdout) { for (int i=0;i=8&&logLevel_>=0) { // bit setting - debug if ((detail&logLevel_)==0) printStatus_ = 3; } else if (logLevel_