text: /**
   * @file    SBMLErrorLog.cpp
   * @brief   Stores errors (and messages) encountered while processing SBML.
   * @author  Ben Bornstein
   *
   * $Id: SBMLErrorLog.cpp 10129 2009-08-28 12:23:22Z sarahkeating $
   * $HeadURL: https://sbml.svn.sourceforge.net/svnroot/sbml/trunk/libsbml/src/sbml/SBMLErrorLog.cpp $
   *
   *<!---------------------------------------------------------------------------
   * This file is part of libSBML.  Please visit http://sbml.org for more
   * information about SBML, and the latest version of libSBML.
   *
   * Copyright 2005-2009 California Institute of Technology.
   * Copyright 2002-2005 California Institute of Technology and
   *                     Japan Science and Technology Corporation.
   *
   * This library is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation.  A copy of the license agreement is provided
   * in the file named "LICENSE.txt" included with this software distribution
   * and also available online as http://sbml.org/software/libsbml/license.html
   *----------------------------------------------------------------------- -->*/
  
  #include <algorithm>
  #include <functional>
  #include <string>
  #include <list>
  
  #include <sbml/xml/XMLToken.h>
  #include <sbml/xml/XMLParser.h>
  #include <sbml/SBMLError.h>
  #include <sbml/SBMLErrorLog.h>
  
  
  /** @cond doxygen-ignored */
  
  using namespace std;
  
  /** @endcond doxygen-ignored */
  
  LIBSBML_CPP_NAMESPACE_BEGIN
  
  /** @cond doxygen-libsbml-internal */
  /** Most of the methods are internal.  A few visible ones are at the end. */
  
  
  /*
   * Creates a new empty SBMLErrorLog.
   */
  SBMLErrorLog::SBMLErrorLog ()
  {
  }
  
  
  /**
   * Used by the Destructor to delete each item in mErrors.
   */
  struct Delete : public unary_function<XMLError*, void>
  {
    void operator() (XMLError* error) { delete error; }
  };
  
  
  /*
   * Destroys this SBMLErrorLog.
   */
  SBMLErrorLog::~SBMLErrorLog ()
  {
  /*
    //
    // debug code for SBMLErrorLog::remove(const unsigned int)
    //
    vector<XMLError*>::iterator iter;
  
    int count = 0;
    iter = mErrors.begin();
    while(iter != mErrors.end() )
    {
      ++count;
      unsigned int errid  = (*iter)->getErrorId();
      unsigned int column = (*iter)->getColumn();
      cout << "(" << count << ") ErrorId " << errid << " column " << column << endl;
      remove (errid);
      cout << "Size of mErrors " << mErrors.size() << endl;
      iter = mErrors.begin();
    }
  */
  }
  
  
  /*
   * See SBMLError for a list of SBML error codes and XMLError
   * for a list of system and XML-level error codes.
   */
  void
  SBMLErrorLog::logError ( const unsigned int errorId
                         , const unsigned int level
                         , const unsigned int version
                         , const std::string& details
                         , const unsigned int line
                         , const unsigned int column
                         , const unsigned int severity
                         , const unsigned int category )
  {
    add( SBMLError( errorId, level, version, details, line, column,
                    severity, category ));
  }
  
  
  /*
   * Adds the given SBMLError to the log.
   *
   * @param error SBMLError, the error to be logged.
   */
  void
  SBMLErrorLog::add (const SBMLError& error)
  {
    if (error.getSeverity() != LIBSBML_SEV_NOT_APPLICABLE)
      XMLErrorLog::add(error);
  }
  
  
  /*
   * Logs (copies) the SBMLErrors in the given SBMLError list to this
   * SBMLErrorLog.
   *
   * @param errors list, a list of SBMLError to be added to the log.
   */
  void
  SBMLErrorLog::add (const std::list<SBMLError>& errors)
  {
    list<SBMLError>::const_iterator end = errors.end();
    list<SBMLError>::const_iterator iter;
  
    for (iter = errors.begin(); iter != end; ++iter)
      XMLErrorLog::add( *iter );
  }
  
  
  /*
   * Helper class used by SBMLErrorLog::remove.
   */
  class MatchErrorId
  {
  public:
    MatchErrorId(const unsigned int theId) : idToFind(theId) {};
  
    bool operator() (XMLError* e) const
    {
      return e->getErrorId() == idToFind;
    };
  
  private:
    unsigned int idToFind;
  };
  
  
  /*
   * Removes an error having errorId from the SBMLError list.
   *
   * Only the first item will be removed if there are multiple errors
   * with the given errorId.
   *
   * @param errorId the error identifier of the error to be removed.
   */
  void
  SBMLErrorLog::remove (const unsigned int errorId)
  {
    //
    // "mErrors.erase( remove_if( ...))" can't be used for removing
    // the matched items from the list, because the type of the vector container is pointer
    // of XMLError object.
    //
    // (Effective STL 50 Specific Ways to Improve Your Use of the Standard Template Library
    //  Scott Meyers
    //  Item 33: Be wary of remove-like algorithms on containers of pointers. 143)
    //
    //
    vector<XMLError*>::iterator delIter;
  
    // finds an item with the given errorId (the first item will be found if
    // there are two or more items with the same Id)
    delIter = find_if(mErrors.begin(), mErrors.end(), MatchErrorId(errorId));
  
    if ( delIter != mErrors.end() )
    {
      // deletes (invoke delete operator for the matched item) and erases (removes
      // the pointer from mErrors) the matched item (if any)
      delete *delIter;
      mErrors.erase(delIter);
    }
  }
  
  
  /*
   * Helper class used by
   * SBMLErrorLog::getNumFailsWithSeverity(SBMLErrorSeverity_t).
   */
  class MatchSeverity
  {
  public:
    MatchSeverity(const unsigned int s) : severity(s) {};
  
    bool operator() (XMLError* e) const
    {
      return e->getSeverity() == severity;
    };
  
  private:
    unsigned int severity;
  };
  
  
  
  /** @endcond doxygen-libsbml-internal */
  
  
  /**
    * Returns number of errors that are logged with severity Error
    */
  unsigned int
  SBMLErrorLog::getNumFailsWithSeverity(unsigned int severity)
  {
    int n = 0;
  
  #if defined(__SUNPRO_CC)
    // Workaround for Sun cc which is missing:
    count_if(mErrors.begin(), mErrors.end(), MatchSeverity(severity), n);
  #else
    n = count_if(mErrors.begin(), mErrors.end(), MatchSeverity(severity));
  #endif
  
    return n;
  }
  
  
  /*
   * Returns the nth SBMLError in this log.
   *
   * @param n unsigned int number of the error to retrieve.
   *
   * @return the nth SBMLError in this log.
   */
  const SBMLError*
  SBMLErrorLog::getError (unsigned int n) const
  {
    return static_cast<const SBMLError*>(XMLErrorLog::getError(n));
  }
  
  LIBSBML_CPP_NAMESPACE_END
  
  