<commit_before>/*************************************************************************
 *
 *  $RCSfile: formlayerexport.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: vg $ $Date: 2005-03-23 11:25:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>

#ifndef _XMLOFF_FORMLAYEREXPORT_HXX_
#include "formlayerexport.hxx"
#endif
#ifndef _XMLOFF_FORMS_STRINGS_HXX_
#include "strings.hxx"
#endif
#ifndef _XMLOFF_ELEMENTEXPORT_HXX_
#include "elementexport.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _XMLOFF_FORMS_LAYEREXPORT_HXX_
#include "layerexport.hxx"
#endif
#ifndef _XMLOFF_FORMS_PROPERTYEXPORT_HXX_
#include "propertyexport.hxx"
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _XMLOFF_FORMS_OFFICEFORMS_HXX_
#include "officeforms.hxx"
#endif

//.........................................................................
namespace xmloff
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::drawing;
    using namespace ::com::sun::star::frame;

    //=====================================================================
    //= OFormLayerXMLExport
    //=====================================================================

    //---------------------------------------------------------------------
    OFormLayerXMLExport::OFormLayerXMLExport(SvXMLExport& _rContext)
        :m_rContext(_rContext)
        ,m_pImpl(new OFormLayerXMLExport_Impl(_rContext))
    {
    }

    //---------------------------------------------------------------------
    OFormLayerXMLExport::~OFormLayerXMLExport()
    {
        delete m_pImpl;
        m_pImpl = NULL;
    }

    //---------------------------------------------------------------------
    sal_Bool OFormLayerXMLExport::seekPage(const Reference< XDrawPage >& _rxDrawPage)
    {
        return m_pImpl->seekPage(_rxDrawPage);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString OFormLayerXMLExport::getControlId(const Reference< XPropertySet >& _rxControl)
    {
        return m_pImpl->getControlId(_rxControl);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString OFormLayerXMLExport::getControlNumberStyle( const Reference< XPropertySet >& _rxControl )
    {
        return m_pImpl->getControlNumberStyle(_rxControl);
    }

    //---------------------------------------------------------------------
    ::vos::ORef< SvXMLExportPropertyMapper > OFormLayerXMLExport::getStylePropertyMapper()
    {
        return m_pImpl->getStylePropertyMapper();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::initialize()
    {
        m_pImpl->clear();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::examineForms(const Reference< XDrawPage >& _rxDrawPage)
    {
        try
        {
            m_pImpl->examineForms(_rxDrawPage);
        }
        catch(Exception&)
        {
            OSL_ENSURE(sal_False, "OFormLayerXMLExport::examine: could not examine the draw page!");
        }
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportForms(const Reference< XDrawPage >& _rxDrawPage)
    {
        m_pImpl->exportForms(_rxDrawPage);
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportXForms() const
    {
        m_pImpl->exportXForms();
    }

    //---------------------------------------------------------------------
    bool OFormLayerXMLExport::pageContainsForms( const Reference< XDrawPage >& _rxDrawPage ) const
    {
        return m_pImpl->pageContainsForms( _rxDrawPage );
    }

    //---------------------------------------------------------------------
    bool OFormLayerXMLExport::documentContainsXForms() const
    {
        return m_pImpl->documentContainsXForms();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportControlNumberStyles()
    {
        m_pImpl->exportControlNumberStyles();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportAutoControlNumberStyles()
    {
        m_pImpl->exportAutoControlNumberStyles();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportAutoStyles()
    {
        m_pImpl->exportAutoStyles();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::excludeFromExport( const Reference< XControlModel > _rxControl )
    {
        m_pImpl->excludeFromExport( _rxControl );
    }

    //=========================================================================
    //= OOfficeFormsExport
    //=========================================================================
    //-------------------------------------------------------------------------
    OOfficeFormsExport::OOfficeFormsExport( SvXMLExport& _rExp )
        :m_pImpl(NULL)
    {
        m_pImpl = new OFormsRootExport(_rExp);
    }

    //-------------------------------------------------------------------------
    OOfficeFormsExport::~OOfficeFormsExport()
    {
        delete m_pImpl;
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.13.430.1  2004/12/13 17:27:32  fs
 *  #i36597# +exportXForms/pageContainsForms/documentContainsXForms
 *
 *  Revision 1.13  2002/10/25 07:58:00  fs
 *  #104402# re-introduced exportAutoStyles
 *
 *  Revision 1.12  2002/09/25 12:02:38  fs
 *  #103597# +excludeFromExport
 *
 *  Revision 1.11  2001/05/28 14:59:18  fs
 *  #86712# added control number style related functionality
 *
 *  Revision 1.10  2001/03/20 13:35:38  fs
 *  #83970# +OOfficeFormsExport
 *
 *  Revision 1.9  2001/03/20 08:04:08  fs
 *  removed exportAutoStyles (was obsolete)
 *
 *  Revision 1.8  2001/03/16 14:36:39  sab
 *  did the required change (move of extract.hxx form cppuhelper to comphelper)
 *
 *  Revision 1.7  2001/02/01 09:46:47  fs
 *  no own style handling anymore - the shape exporter is responsible for our styles now
 *
 *  Revision 1.6  2000/12/18 16:22:35  fs
 *  forgot an & on the getControlId parameter
 *
 *  Revision 1.5  2000/12/18 15:14:35  fs
 *  some changes ... now exporting/importing styles
 *
 *  Revision 1.4  2000/12/06 17:28:05  fs
 *  changes for the formlayer import - still under construction
 *
 *  Revision 1.3  2000/12/03 10:57:06  fs
 *  some changes to support more than one page to be examined/exported
 *
 *  Revision 1.2  2000/11/29 10:32:13  mh
 *  add: header for Solaris8
 *
 *  Revision 1.1  2000/11/17 19:02:16  fs
 *  initial checkin - export and/or import the applications form layer
 *
 *
 *  Revision 1.0 13.11.00 14:58:17  fs
 ************************************************************************/

<commit_msg>INTEGRATION: CWS ooo19126 (1.14.94); FILE MERGED 2005/09/05 14:38:59 rt 1.14.94.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: formlayerexport.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 14:10:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <stdio.h>

#ifndef _XMLOFF_FORMLAYEREXPORT_HXX_
#include "formlayerexport.hxx"
#endif
#ifndef _XMLOFF_FORMS_STRINGS_HXX_
#include "strings.hxx"
#endif
#ifndef _XMLOFF_ELEMENTEXPORT_HXX_
#include "elementexport.hxx"
#endif
#ifndef _XMLOFF_XMLNMSPE_HXX
#include "xmlnmspe.hxx"
#endif
#ifndef _XMLOFF_XMLEXP_HXX
#include "xmlexp.hxx"
#endif
#ifndef _XMLOFF_FORMS_LAYEREXPORT_HXX_
#include "layerexport.hxx"
#endif
#ifndef _XMLOFF_FORMS_PROPERTYEXPORT_HXX_
#include "propertyexport.hxx"
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _COMPHELPER_EXTRACT_HXX_
#include <comphelper/extract.hxx>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _XMLOFF_FORMS_OFFICEFORMS_HXX_
#include "officeforms.hxx"
#endif

//.........................................................................
namespace xmloff
{
//.........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::drawing;
    using namespace ::com::sun::star::frame;

    //=====================================================================
    //= OFormLayerXMLExport
    //=====================================================================

    //---------------------------------------------------------------------
    OFormLayerXMLExport::OFormLayerXMLExport(SvXMLExport& _rContext)
        :m_rContext(_rContext)
        ,m_pImpl(new OFormLayerXMLExport_Impl(_rContext))
    {
    }

    //---------------------------------------------------------------------
    OFormLayerXMLExport::~OFormLayerXMLExport()
    {
        delete m_pImpl;
        m_pImpl = NULL;
    }

    //---------------------------------------------------------------------
    sal_Bool OFormLayerXMLExport::seekPage(const Reference< XDrawPage >& _rxDrawPage)
    {
        return m_pImpl->seekPage(_rxDrawPage);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString OFormLayerXMLExport::getControlId(const Reference< XPropertySet >& _rxControl)
    {
        return m_pImpl->getControlId(_rxControl);
    }

    //---------------------------------------------------------------------
    ::rtl::OUString OFormLayerXMLExport::getControlNumberStyle( const Reference< XPropertySet >& _rxControl )
    {
        return m_pImpl->getControlNumberStyle(_rxControl);
    }

    //---------------------------------------------------------------------
    ::vos::ORef< SvXMLExportPropertyMapper > OFormLayerXMLExport::getStylePropertyMapper()
    {
        return m_pImpl->getStylePropertyMapper();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::initialize()
    {
        m_pImpl->clear();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::examineForms(const Reference< XDrawPage >& _rxDrawPage)
    {
        try
        {
            m_pImpl->examineForms(_rxDrawPage);
        }
        catch(Exception&)
        {
            OSL_ENSURE(sal_False, "OFormLayerXMLExport::examine: could not examine the draw page!");
        }
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportForms(const Reference< XDrawPage >& _rxDrawPage)
    {
        m_pImpl->exportForms(_rxDrawPage);
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportXForms() const
    {
        m_pImpl->exportXForms();
    }

    //---------------------------------------------------------------------
    bool OFormLayerXMLExport::pageContainsForms( const Reference< XDrawPage >& _rxDrawPage ) const
    {
        return m_pImpl->pageContainsForms( _rxDrawPage );
    }

    //---------------------------------------------------------------------
    bool OFormLayerXMLExport::documentContainsXForms() const
    {
        return m_pImpl->documentContainsXForms();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportControlNumberStyles()
    {
        m_pImpl->exportControlNumberStyles();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportAutoControlNumberStyles()
    {
        m_pImpl->exportAutoControlNumberStyles();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::exportAutoStyles()
    {
        m_pImpl->exportAutoStyles();
    }

    //---------------------------------------------------------------------
    void OFormLayerXMLExport::excludeFromExport( const Reference< XControlModel > _rxControl )
    {
        m_pImpl->excludeFromExport( _rxControl );
    }

    //=========================================================================
    //= OOfficeFormsExport
    //=========================================================================
    //-------------------------------------------------------------------------
    OOfficeFormsExport::OOfficeFormsExport( SvXMLExport& _rExp )
        :m_pImpl(NULL)
    {
        m_pImpl = new OFormsRootExport(_rExp);
    }

    //-------------------------------------------------------------------------
    OOfficeFormsExport::~OOfficeFormsExport()
    {
        delete m_pImpl;
    }

//.........................................................................
}   // namespace xmloff
//.........................................................................

/*************************************************************************
 * history:
 *  $Log: not supported by cvs2svn $
 *  Revision 1.14.94.1  2005/09/05 14:38:59  rt
 *  #i54170# Change license header: remove SISSL
 *
 *  Revision 1.14  2005/03/23 11:25:13  vg
 *  INTEGRATION: CWS eforms4 (1.13.430); FILE MERGED
 *  2004/12/13 17:27:32 fs 1.13.430.1: #i36597# +exportXForms/pageContainsForms/documentContainsXForms
 *
 *  Revision 1.13.430.1  2004/12/13 17:27:32  fs
 *  #i36597# +exportXForms/pageContainsForms/documentContainsXForms
 *
 *  Revision 1.13  2002/10/25 07:58:00  fs
 *  #104402# re-introduced exportAutoStyles
 *
 *  Revision 1.12  2002/09/25 12:02:38  fs
 *  #103597# +excludeFromExport
 *
 *  Revision 1.11  2001/05/28 14:59:18  fs
 *  #86712# added control number style related functionality
 *
 *  Revision 1.10  2001/03/20 13:35:38  fs
 *  #83970# +OOfficeFormsExport
 *
 *  Revision 1.9  2001/03/20 08:04:08  fs
 *  removed exportAutoStyles (was obsolete)
 *
 *  Revision 1.8  2001/03/16 14:36:39  sab
 *  did the required change (move of extract.hxx form cppuhelper to comphelper)
 *
 *  Revision 1.7  2001/02/01 09:46:47  fs
 *  no own style handling anymore - the shape exporter is responsible for our styles now
 *
 *  Revision 1.6  2000/12/18 16:22:35  fs
 *  forgot an & on the getControlId parameter
 *
 *  Revision 1.5  2000/12/18 15:14:35  fs
 *  some changes ... now exporting/importing styles
 *
 *  Revision 1.4  2000/12/06 17:28:05  fs
 *  changes for the formlayer import - still under construction
 *
 *  Revision 1.3  2000/12/03 10:57:06  fs
 *  some changes to support more than one page to be examined/exported
 *
 *  Revision 1.2  2000/11/29 10:32:13  mh
 *  add: header for Solaris8
 *
 *  Revision 1.1  2000/11/17 19:02:16  fs
 *  initial checkin - export and/or import the applications form layer
 *
 *
 *  Revision 1.0 13.11.00 14:58:17  fs
 ************************************************************************/

<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<commit_msg>--allow-empty_message<commit_after>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<|endoftext|>


<commit_before>#include "cppbencode.h"
#include <sstream>
#include <stdio.h>

void verify(const ben::Value &value, const char *encoded)
{
	/* verify that the encoder produces the expected output */
	std::ostringstream ss;
	value.write(ss);
	assert(ss.str() == encoded);

	/* try to load the bencoded string, and check that it is equal */
	std::istringstream parser(ss.str());
	ben::Value value2;
	value2.load_all(parser);
	assert(value == value2);
}

void verify_error(const char *s, const char *error)
{
	ben::Value val;
	std::istringstream ss(s);
	try {
		val.load(ss);
		/* should always raise an exception */
		assert(0);
	} catch (const ben::decode_error &e) {
		assert(e.what() == std::string(error));
	}
}

int main()
{
	verify(0, "i0e");
	verify(1234, "i1234e");
	verify(-1234, "i-1234e");
	verify(std::string("foobar"), "6:foobar");
	verify(std::string(""), "0:");
	verify(true, "b1");
	verify(false, "b0");

	std::vector<ben::Value> arr;
	arr.push_back(std::string("foo"));
	arr.push_back(1234);
	arr.push_back(true);
	verify(arr, "l3:fooi1234eb1e");

	ben::dict_map_t dict;
	dict.insert(std::make_pair("bar", arr));
	dict.insert(std::make_pair("foo", std::string("test")));
	verify(dict, "d3:barl3:fooi1234eb1e3:foo4:teste");

	verify_error("i1234", "Expected 'e'");
	verify_error("dx", "Expected a digit");
	verify_error("d-5", "Expected a digit");
	verify_error("d123", "Expected ':'");
	verify_error("i", "Unexpected end of input");
	verify_error("i 1e", "Expected a digit or '-'");
	verify_error("i1111111111111111111111e", "Invalid integer");
	verify_error("i- 1e", "Invalid integer");
	verify_error("i-0e", "Zero with a minus sign");
	verify_error("i05e", "Integer has leading zeroes");
	verify_error("06:foobar", "String length has leading zeroes");
	verify_error("123", "Expected ':'");
	verify_error("5:foo", "Unexpected end of input");
	verify_error("l", "Unexpected end of input");

	try {
		ben::Value val;
		std::istringstream ss("d3:bari123ee");
		val.load_all(ss);
		int i = val.get("foo").as_integer();
		(void) i;
	} catch (const ben::type_error &e) {
		assert(e.what() == std::string("Expected type integer, but got null"));
	}

	try {
		ben::Value val;
		std::istringstream ss("d3:bari123e3:foob1e");
		val.load_all(ss);
		int i = val.get("foo").as_integer();
		(void) i;
	} catch (const ben::type_error &e) {
		assert(e.what() == std::string("Expected type integer, but got boolean"));
	}

	printf("ok\n");
	return 0;
}
<commit_msg>test: Use simplier method to insert to std::map [CLEANUP]<commit_after>#include "cppbencode.h"
#include <sstream>
#include <stdio.h>

void verify(const ben::Value &value, const char *encoded)
{
	/* verify that the encoder produces the expected output */
	std::ostringstream ss;
	value.write(ss);
	assert(ss.str() == encoded);

	/* try to load the bencoded string, and check that it is equal */
	std::istringstream parser(ss.str());
	ben::Value value2;
	value2.load_all(parser);
	assert(value == value2);
}

void verify_error(const char *s, const char *error)
{
	ben::Value val;
	std::istringstream ss(s);
	try {
		val.load(ss);
		/* should always raise an exception */
		assert(0);
	} catch (const ben::decode_error &e) {
		assert(e.what() == std::string(error));
	}
}

int main()
{
	verify(0, "i0e");
	verify(1234, "i1234e");
	verify(-1234, "i-1234e");
	verify(std::string("foobar"), "6:foobar");
	verify(std::string(""), "0:");
	verify(true, "b1");
	verify(false, "b0");

	std::vector<ben::Value> arr;
	arr.push_back(std::string("foo"));
	arr.push_back(1234);
	arr.push_back(true);
	verify(arr, "l3:fooi1234eb1e");

	ben::dict_map_t dict;
	dict["bar"] = arr;
	dict["foo"] = std::string("test");
	verify(dict, "d3:barl3:fooi1234eb1e3:foo4:teste");

	verify_error("i1234", "Expected 'e'");
	verify_error("dx", "Expected a digit");
	verify_error("d-5", "Expected a digit");
	verify_error("d123", "Expected ':'");
	verify_error("i", "Unexpected end of input");
	verify_error("i 1e", "Expected a digit or '-'");
	verify_error("i1111111111111111111111e", "Invalid integer");
	verify_error("i- 1e", "Invalid integer");
	verify_error("i-0e", "Zero with a minus sign");
	verify_error("i05e", "Integer has leading zeroes");
	verify_error("06:foobar", "String length has leading zeroes");
	verify_error("123", "Expected ':'");
	verify_error("5:foo", "Unexpected end of input");
	verify_error("l", "Unexpected end of input");

	try {
		ben::Value val;
		std::istringstream ss("d3:bari123ee");
		val.load_all(ss);
		int i = val.get("foo").as_integer();
		(void) i;
	} catch (const ben::type_error &e) {
		assert(e.what() == std::string("Expected type integer, but got null"));
	}

	try {
		ben::Value val;
		std::istringstream ss("d3:bari123e3:foob1e");
		val.load_all(ss);
		int i = val.get("foo").as_integer();
		(void) i;
	} catch (const ben::type_error &e) {
		assert(e.what() == std::string("Expected type integer, but got boolean"));
	}

	printf("ok\n");
	return 0;
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "test.hpp"
#include "date.hpp"

using namespace std::string_literals;

TEST_CASE("date/to_string") {
    budget::date a(1988, 4, 9);

    FAST_CHECK_EQ(budget::date_to_string(a), "1988-04-09"s);
    FAST_CHECK_EQ(budget::to_string(a), "1988-04-09"s);

    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(budget::date_to_string(b), "2111-10-10"s);
    FAST_CHECK_EQ(budget::to_string(b), "2111-10-10"s);
}

TEST_CASE("date/from_string") {
    auto as = budget::from_string("1988-04-09");
    auto bs = budget::from_string("2111-10-10");

    budget::date a(1988, 4, 9);
    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(a, as);
    FAST_CHECK_EQ(b, bs);
}

TEST_CASE("date/minus/days") {
    budget::date a(2010, 5, 6);
    a -= budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 5);

    a -= budget::days(10);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 25);
}

TEST_CASE("date/minus/month") {
    budget::date a(2010, 5, 6);
    a -= budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::months(10);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/minus/years") {
    budget::date a(2010, 5, 6);
    a -= budget::years(1);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::years(10);

    FAST_CHECK_EQ(a.year(), 1999);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/days") {
    budget::date a(2010, 5, 6);
    a += budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 7);

    a += budget::days(30);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/month") {
    budget::date a(2010, 5, 6);
    a += budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::months(10);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/years") {
    budget::date a(2010, 5, 6);
    a += budget::years(1);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::years(10);

    FAST_CHECK_EQ(a.year(), 2021);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/is_leap") {
    FAST_CHECK_UNARY(budget::date(1804, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(1944, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2000, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2212, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2400, 1, 1).is_leap());

    FAST_CHECK_UNARY(!budget::date(1805, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(1943, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(2001, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(2399, 1, 1).is_leap());
}

TEST_CASE("date/day_of_the_week") {
    // A leap year
    FAST_CHECK_EQ(budget::date(2000, 3, 3).day_of_the_week(), 5);
    FAST_CHECK_EQ(budget::date(2000, 3, 4).day_of_the_week(), 6);
    FAST_CHECK_EQ(budget::date(2000, 3, 5).day_of_the_week(), 7);
    FAST_CHECK_EQ(budget::date(2000, 3, 6).day_of_the_week(), 1);

    // A non-leap year
    FAST_CHECK_EQ(budget::date(2019, 3, 3).day_of_the_week(), 7);
    FAST_CHECK_EQ(budget::date(2019, 3, 4).day_of_the_week(), 1);
    FAST_CHECK_EQ(budget::date(2019, 3, 5).day_of_the_week(), 2);
    FAST_CHECK_EQ(budget::date(2019, 3, 6).day_of_the_week(), 3);
    FAST_CHECK_EQ(budget::date(2019, 3, 7).day_of_the_week(), 4);
}

// TODO Test for leap years
// TODO Test for start_of_week
// TODO Test for start_of_month
// TODO Test for end_of_month
// TODO Test for week()
// TODO Test for year_days()
// TODO Test for comparisons
// TODO Test for date differences
<commit_msg>Complete the unit test<commit_after>//=======================================================================
// Copyright (c) 2013-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "test.hpp"
#include "date.hpp"

using namespace std::string_literals;

TEST_CASE("date/to_string") {
    budget::date a(1988, 4, 9);

    FAST_CHECK_EQ(budget::date_to_string(a), "1988-04-09"s);
    FAST_CHECK_EQ(budget::to_string(a), "1988-04-09"s);

    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(budget::date_to_string(b), "2111-10-10"s);
    FAST_CHECK_EQ(budget::to_string(b), "2111-10-10"s);
}

TEST_CASE("date/from_string/1") {
    auto as = budget::from_string("1988-04-09");
    auto bs = budget::from_string("2111-10-10");

    budget::date a(1988, 4, 9);
    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(a, as);
    FAST_CHECK_EQ(b, bs);
}

TEST_CASE("date/from_string/1") {
    // Size must be 10 exactly
    REQUIRE_THROWS_AS(budget::from_string("1988-4-9"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("1988-04-9"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("88-04-09"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("1988 -04-9"), budget::date_exception);
}

TEST_CASE("date/from_string/2") {
    // Each of the parts must be exactly a number
    REQUIRE_THROWS_AS(budget::from_string("abcd-4-9"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("1988-AB-9"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("88-04-9a"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("1988--4-9"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("19o8--4-9"), budget::date_exception);
    REQUIRE_THROWS_AS(budget::from_string("198 -04-09"), budget::date_exception);
}

TEST_CASE("date/minus/days") {
    budget::date a(2010, 5, 6);
    a -= budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 5);

    a -= budget::days(10);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 25);
}

TEST_CASE("date/minus/month") {
    budget::date a(2010, 5, 6);
    a -= budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::months(10);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/minus/years") {
    budget::date a(2010, 5, 6);
    a -= budget::years(1);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::years(10);

    FAST_CHECK_EQ(a.year(), 1999);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/days") {
    budget::date a(2010, 5, 6);
    a += budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 7);

    a += budget::days(30);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/month") {
    budget::date a(2010, 5, 6);
    a += budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::months(10);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/years") {
    budget::date a(2010, 5, 6);
    a += budget::years(1);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::years(10);

    FAST_CHECK_EQ(a.year(), 2021);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/is_leap") {
    FAST_CHECK_UNARY(budget::date(1804, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(1944, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2000, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2212, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2400, 1, 1).is_leap());

    FAST_CHECK_UNARY(!budget::date(1805, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(1943, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(2001, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(2399, 1, 1).is_leap());
}

TEST_CASE("date/day_of_the_week") {
    // A leap year
    FAST_CHECK_EQ(budget::date(2000, 3, 3).day_of_the_week(), 5);
    FAST_CHECK_EQ(budget::date(2000, 3, 4).day_of_the_week(), 6);
    FAST_CHECK_EQ(budget::date(2000, 3, 5).day_of_the_week(), 7);
    FAST_CHECK_EQ(budget::date(2000, 3, 6).day_of_the_week(), 1);

    // A non-leap year
    FAST_CHECK_EQ(budget::date(2019, 3, 3).day_of_the_week(), 7);
    FAST_CHECK_EQ(budget::date(2019, 3, 4).day_of_the_week(), 1);
    FAST_CHECK_EQ(budget::date(2019, 3, 5).day_of_the_week(), 2);
    FAST_CHECK_EQ(budget::date(2019, 3, 6).day_of_the_week(), 3);
    FAST_CHECK_EQ(budget::date(2019, 3, 7).day_of_the_week(), 4);
}

// TODO Test for leap years
// TODO Test for start_of_week
// TODO Test for start_of_month
// TODO Test for end_of_month
// TODO Test for week()
// TODO Test for year_days()
// TODO Test for comparisons
// TODO Test for date differences
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2013-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "test.hpp"
#include "date.hpp"

using namespace std::string_literals;

TEST_CASE("date/to_string") {
    budget::date a(1988, 4, 9);

    FAST_CHECK_EQ(budget::date_to_string(a), "1988-04-09"s);
    FAST_CHECK_EQ(budget::to_string(a), "1988-04-09"s);

    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(budget::date_to_string(b), "2111-10-10"s);
    FAST_CHECK_EQ(budget::to_string(b), "2111-10-10"s);
}

TEST_CASE("date/from_string") {
    auto as = budget::from_string("1988-04-09");
    auto bs = budget::from_string("2111-10-10");

    budget::date a(1988, 4, 9);
    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(a, as);
    FAST_CHECK_EQ(b, bs);
}

TEST_CASE("date/minus/days") {
    budget::date a(2010, 5, 6);
    a -= budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 5);

    a -= budget::days(10);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 25);
}

TEST_CASE("date/minus/month") {
    budget::date a(2010, 5, 6);
    a -= budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::months(10);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/minus/years") {
    budget::date a(2010, 5, 6);
    a -= budget::years(1);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::years(10);

    FAST_CHECK_EQ(a.year(), 1999);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/days") {
    budget::date a(2010, 5, 6);
    a += budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 7);

    a += budget::days(30);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/month") {
    budget::date a(2010, 5, 6);
    a += budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::months(10);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/years") {
    budget::date a(2010, 5, 6);
    a += budget::years(1);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::years(10);

    FAST_CHECK_EQ(a.year(), 2021);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

// TODO Test for leap years
// TODO Test for start_of_week
// TODO Test for start_of_month
// TODO Test for week()
// TODO Test for year_days()
// TODO Test for day_of_the_week
// TODO Test for comparisons
// TODO Test for date differences
<commit_msg>Unit tests for is_leap<commit_after>//=======================================================================
// Copyright (c) 2013-2020 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "test.hpp"
#include "date.hpp"

using namespace std::string_literals;

TEST_CASE("date/to_string") {
    budget::date a(1988, 4, 9);

    FAST_CHECK_EQ(budget::date_to_string(a), "1988-04-09"s);
    FAST_CHECK_EQ(budget::to_string(a), "1988-04-09"s);

    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(budget::date_to_string(b), "2111-10-10"s);
    FAST_CHECK_EQ(budget::to_string(b), "2111-10-10"s);
}

TEST_CASE("date/from_string") {
    auto as = budget::from_string("1988-04-09");
    auto bs = budget::from_string("2111-10-10");

    budget::date a(1988, 4, 9);
    budget::date b(2111, 10, 10);

    FAST_CHECK_EQ(a, as);
    FAST_CHECK_EQ(b, bs);
}

TEST_CASE("date/minus/days") {
    budget::date a(2010, 5, 6);
    a -= budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 5);

    a -= budget::days(10);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 25);
}

TEST_CASE("date/minus/month") {
    budget::date a(2010, 5, 6);
    a -= budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::months(10);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/minus/years") {
    budget::date a(2010, 5, 6);
    a -= budget::years(1);

    FAST_CHECK_EQ(a.year(), 2009);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a -= budget::years(10);

    FAST_CHECK_EQ(a.year(), 1999);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/days") {
    budget::date a(2010, 5, 6);
    a += budget::days(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 7);

    a += budget::days(30);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/month") {
    budget::date a(2010, 5, 6);
    a += budget::months(1);

    FAST_CHECK_EQ(a.year(), 2010);
    FAST_CHECK_EQ(a.month(), 6);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::months(10);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 4);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/plus/years") {
    budget::date a(2010, 5, 6);
    a += budget::years(1);

    FAST_CHECK_EQ(a.year(), 2011);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);

    a += budget::years(10);

    FAST_CHECK_EQ(a.year(), 2021);
    FAST_CHECK_EQ(a.month(), 5);
    FAST_CHECK_EQ(a.day(), 6);
}

TEST_CASE("date/is_leap") {
    FAST_CHECK_UNARY(budget::date(1804, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(1944, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2000, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2212, 1, 1).is_leap());
    FAST_CHECK_UNARY(budget::date(2400, 1, 1).is_leap());

    FAST_CHECK_UNARY(!budget::date(1805, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(1943, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(2001, 1, 1).is_leap());
    FAST_CHECK_UNARY(!budget::date(2399, 1, 1).is_leap());
}

// TODO Test for leap years
// TODO Test for start_of_week
// TODO Test for start_of_month
// TODO Test for week()
// TODO Test for year_days()
// TODO Test for day_of_the_week
// TODO Test for comparisons
// TODO Test for date differences
<|endoftext|>


<commit_before>// csastil_uppernames.cpp                                             -*-C++-*-

#include <clang/AST/ASTContext.h>
#include <clang/AST/Decl.h>
#include <clang/AST/DeclBase.h>
#include <clang/AST/DeclTemplate.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/ASTMatchers/ASTMatchersInternal.h>
#include <clang/Basic/IdentifierTable.h>
#include <clang/Basic/SourceLocation.h>
#include <csabase_analyser.h>
#include <csabase_registercheck.h>
#include <csabase_util.h>
#include <llvm/ADT/Optional.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/ADT/VariadicFunction.h>
#include <llvm/Support/Casting.h>
#include <utils/event.hpp>
#include <utils/function.hpp>
#include <set>
#include <string>
#include <utility>

namespace csabase { class PPObserver; }
namespace csabase { class Visitor; }

using namespace clang;
using namespace clang::ast_matchers;
using namespace csabase;

// ----------------------------------------------------------------------------

static std::string const check_name("upper-case-names");

// ----------------------------------------------------------------------------

namespace
{

struct data
{
    data();

    std::set<NamedDecl const*> d_decls;
};

data::data()
{
}

struct report
    // Complain about upper-case only variables and constants.
{
    report(Analyser& analyser);
        // Create an object of this type using the specified analyser.

    void match_has_name(const BoundNodes& nodes);
        // Find named declarations.

    void operator()();
        // Callback invoked at end of translation unit.

    Analyser& d_analyser;
    data& d_data;
};

report::report(Analyser& analyser)
: d_analyser(analyser)
, d_data(analyser.attachment<data>())
{
}

internal::DynTypedMatcher has_name_matcher()
    // Return an AST matcher which looks for named declarations.
{
    return decl(forEachDescendant(namedDecl().bind("decl")));
}

void report::match_has_name(const BoundNodes& nodes)
{
    NamedDecl const* decl = nodes.getNodeAs<NamedDecl>("decl");
    if (!d_data.d_decls.insert(decl).second) {
        return;                                                       // RETURN
    }
    if (decl->getLocation().isMacroID()) {
        return;                                                       // RETURN
    }
    if (!d_analyser.is_component(decl)) {
        return;                                                       // RETURN
    }
    if (llvm::dyn_cast<TemplateTypeParmDecl>(decl) ||
        llvm::dyn_cast<TemplateTemplateParmDecl>(decl) ||
        llvm::dyn_cast<NonTypeTemplateParmDecl>(decl)) {
        return;                                                       // RETURN
    }
    if (FunctionDecl const* func = llvm::dyn_cast<FunctionDecl>(decl)) {
        if (func->isDefaulted()) {
            return;                                                   // RETURN
        }
    }
    if (RecordDecl const* record = llvm::dyn_cast<RecordDecl>(decl)) {
        if (record->isInjectedClassName()) {
            return;                                                   // RETURN
        }
    }

    IdentifierInfo const* ii = decl->getIdentifier();
    if (ii) {
        llvm::StringRef name = ii->getName();
        if (name.find_first_of("abcdefghijklmnopqrstuvwxyz") == name.npos &&
            name.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ") != name.npos &&
            name.find(llvm::StringRef(d_analyser.component()).upper()) ==
                name.npos) {
            d_analyser.report(decl, check_name, "UC01",
                              "Name should not be all upper-case");
        }
    }

    if (TemplateDecl const* tplt = llvm::dyn_cast<TemplateDecl>(decl)) {
        d_data.d_decls.insert(tplt->getTemplatedDecl());
    }
}

void report::operator()()
{
    if (!d_analyser.is_test_driver()) {
        MatchFinder mf;
        OnMatch<report, &report::match_has_name> m1(this);
        mf.addDynamicMatcher(has_name_matcher(), &m1);
        mf.match(*d_analyser.context()->getTranslationUnitDecl(),
                 *d_analyser.context());
    }
}

void subscribe(Analyser& analyser, Visitor&, PPObserver&)
{
    analyser.onTranslationUnitDone += report(analyser);
}

}

// ----------------------------------------------------------------------------

static RegisterCheck c1(check_name, &subscribe);

// ----------------------------------------------------------------------------
// Copyright (C) 2014 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<commit_msg>Don't warn inside #ifndef BDE_OMIT_INTERNAL_DEPRECATED.<commit_after>// csastil_uppernames.cpp                                             -*-C++-*-

#include <clang/AST/ASTContext.h>
#include <clang/AST/Decl.h>
#include <clang/AST/DeclBase.h>
#include <clang/AST/DeclTemplate.h>
#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/ASTMatchers/ASTMatchers.h>
#include <clang/ASTMatchers/ASTMatchersInternal.h>
#include <clang/Basic/IdentifierTable.h>
#include <clang/Basic/SourceLocation.h>
#include <clang/Lex/Preprocessor.h>
#include <csabase_analyser.h>
#include <csabase_debug.h>
#include <csabase_registercheck.h>
#include <csabase_report.h>
#include <csabase_util.h>
#include <llvm/ADT/Optional.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/ADT/VariadicFunction.h>
#include <llvm/Support/Casting.h>
#include <utils/event.hpp>
#include <utils/function.hpp>
#include <set>
#include <string>
#include <utility>

namespace csabase { class PPObserver; }
namespace csabase { class Visitor; }

using namespace clang;
using namespace clang::ast_matchers;
using namespace csabase;

// ----------------------------------------------------------------------------

static std::string const check_name("upper-case-names");

// ----------------------------------------------------------------------------

namespace
{

struct data
{
    std::set<NamedDecl const*> d_decls;
    std::vector<SourceRange> d_omit_internal_deprecated;
};

struct report :  Report<data>
    // Complain about upper-case only variables and constants.
{
    INHERIT_REPORT_CTOR(report, Report, data);

    void match_has_name(const BoundNodes& nodes);
        // Find named declarations.

    void operator()();
        // Callback invoked at end of translation unit.

    void operator()(SourceLocation,
                    SourceRange,
                    PPCallbacks::ConditionValueKind,
                    SourceLocation);
        // Callback for #elif.

    void operator()(SourceLocation, const Token &, const MacroDefinition &);
        // Callback for #ifndef.

    void operator()(SourceLocation, SourceLocation);
        // Callback for #else/#endif.
};

internal::DynTypedMatcher has_name_matcher()
    // Return an AST matcher which looks for named declarations.
{
    return decl(forEachDescendant(namedDecl().bind("decl")));
}

void report::match_has_name(const BoundNodes& nodes)
{
    NamedDecl const* decl = nodes.getNodeAs<NamedDecl>("decl");
    if (!d_data.d_decls.insert(decl).second) {
        return;                                                       // RETURN
    }
    if (decl->getLocation().isMacroID()) {
        return;                                                       // RETURN
    }
    if (!d_analyser.is_component(decl)) {
        return;                                                       // RETURN
    }
    if (llvm::dyn_cast<TemplateTypeParmDecl>(decl) ||
        llvm::dyn_cast<TemplateTemplateParmDecl>(decl) ||
        llvm::dyn_cast<NonTypeTemplateParmDecl>(decl)) {
        return;                                                       // RETURN
    }
    if (FunctionDecl const* func = llvm::dyn_cast<FunctionDecl>(decl)) {
        if (func->isDefaulted()) {
            return;                                                   // RETURN
        }
    }
    if (RecordDecl const* record = llvm::dyn_cast<RecordDecl>(decl)) {
        if (record->isInjectedClassName()) {
            return;                                                   // RETURN
        }
    }

    IdentifierInfo const* ii = decl->getIdentifier();
    if (ii) {
        llvm::StringRef name = ii->getName();
        if (name.find_first_of("abcdefghijklmnopqrstuvwxyz") == name.npos &&
            name.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ") != name.npos &&
            name.find(llvm::StringRef(d_analyser.component()).upper()) ==
                name.npos) {
            bool omit = false;
            for (auto i : d.d_omit_internal_deprecated) {
                if (m.isBeforeInTranslationUnit(i.getBegin(),
                                                decl->getLocation()) &&
                    m.isBeforeInTranslationUnit(decl->getLocation(),
                                                i.getEnd())) {
                    omit = true;
                    break;
                }
            }
            if (!omit) {
                d_analyser.report(decl, check_name, "UC01",
                                  "Name should not be all upper-case");
            }
        }
    }

    if (TemplateDecl const* tplt = llvm::dyn_cast<TemplateDecl>(decl)) {
        d_data.d_decls.insert(tplt->getTemplatedDecl());
    }
}

void report::operator()()
{
    if (!d_analyser.is_test_driver()) {
        MatchFinder mf;
        OnMatch<report, &report::match_has_name> m1(this);
        mf.addDynamicMatcher(has_name_matcher(), &m1);
        mf.match(*d_analyser.context()->getTranslationUnitDecl(),
                 *d_analyser.context());
    }
}

// Ifndef
void report::operator()(SourceLocation         loc,
                        const Token&           macro,
                        const MacroDefinition& md)
{
    if (macro.getIdentifierInfo()->getName() ==
        "BDE_OMIT_INTERNAL_DEPRECATED") {
        d.d_omit_internal_deprecated.emplace_back(loc);
    }
}

// Else
// Endif
void report::operator()(SourceLocation loc, SourceLocation ifloc)
    // Callback for #else/#endif.
{
    for (auto &i : d.d_omit_internal_deprecated) {
        if (i.getBegin() == ifloc && i.getEnd() == ifloc) {
            i.setEnd(loc);
        }
    }
}

// Elif
void report::operator()(SourceLocation                  loc,
                        SourceRange                     condition,
                        PPCallbacks::ConditionValueKind kind,
                        SourceLocation                  ifloc)
{
    (*this)(loc, ifloc);
}

void subscribe(Analyser& analyser, Visitor&, PPObserver& observer)
{
    analyser.onTranslationUnitDone += report(analyser);

    observer.onPPIfndef += report(analyser, observer.e_Ifndef);
    observer.onPPElif   += report(analyser, observer.e_Elif);
    observer.onPPElse   += report(analyser, observer.e_Else);
    observer.onPPEndif  += report(analyser, observer.e_Endif);
}

}

// ----------------------------------------------------------------------------

static RegisterCheck c1(check_name, &subscribe);

// ----------------------------------------------------------------------------
// Copyright (C) 2014 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

#include <lac/compressed_simple_sparsity_pattern.h>

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <numeric>
#include <functional>

DEAL_II_NAMESPACE_OPEN

template <typename ForwardIterator>
void
CompressedSimpleSparsityPattern::Line::add_entries (ForwardIterator begin,
						    ForwardIterator end,
						    const bool      indices_are_sorted)
{
  const int n_elements = end - begin;
  if (n_elements <= 0)
    return;

  const unsigned int stop_size = entries.size() + n_elements;

  if (indices_are_sorted == true && n_elements > 3)
    {
				   // in debug mode, check whether the
				   // indices really are sorted.
#ifdef DEBUG
      {
	ForwardIterator test = begin, test1 = begin;
	++test1;
	for ( ; test1 != end; ++test, ++test1)
	  {
	    if (*test1 <= *test)
	      std::cout << end-begin << " " << test1-begin << " " << *test1 << " " << *test << "  " << std::flush;
	  Assert (*test1 > *test, ExcInternalError());
	  }
      }
#endif

      if (entries.size() == 0 || entries.back() < *begin)
	{
	  entries.insert(entries.end(), begin, end);
	  return;
	}

				   // find a possible insertion point for
				   // the first entry. check whether the
				   // first entry is a duplicate before
				   // actually doing something.
      ForwardIterator my_it = begin;
      unsigned int col = *my_it;
      std::vector<unsigned int>::iterator it =
	std::lower_bound(entries.begin(), entries.end(), col);
      while (*it == col)
	{
	  ++my_it;
	  if (my_it == end)
	    break;
	  col = *my_it;
				   // check the very next entry in the
				   // current array
	  ++it;
	  if (it == entries.end())
	    break;
	  if (*it > col)
	    break;
	  if (*it == col)
	    continue;
				   // ok, it wasn't the very next one, do a
				   // binary search to find the insert point
	  it = std::lower_bound(it, entries.end(), col);
	  if (it == entries.end())
	    break;
	}
				   // all input entries were duplicates.
      if (my_it == end)
	return;

				   // resize vector by just inserting the
				   // list
      const unsigned int pos1 = it - entries.begin();
      Assert (pos1 <= entries.size(), ExcInternalError());
      entries.insert (it, my_it, end);
      it = entries.begin() + pos1;
      Assert (entries.size() >= (unsigned int)(it-entries.begin()), ExcInternalError());

				   // now merge the two lists.
      std::vector<unsigned int>::iterator it2 = it + (end-my_it);

				   // as long as there are indices both in
				   // the end of the entries list and in the
				   // input list
      while (my_it != end && it2 != entries.end())
	{
	  if (*my_it < *it2)
	    *it++ = *my_it++;
	  else if (*my_it == *it2)
	    {
	      *it++ = *it2++;
	      ++my_it;
	    }
	  else
	    *it++ = *it2++;
	}
				   // in case there are indices left in the
				   // input list
      while (my_it != end)
	*it++ = *my_it++;

				   // in case there are indices left in the
				   // end of entries
      while (it2 != entries.end())
	*it++ = *it2++;

				   // resize and return
      const unsigned int new_size = it - entries.begin();
      Assert (new_size <= stop_size, ExcInternalError());
      entries.resize (new_size);
      return;
    }

				   // unsorted case or case with too few
				   // elements
  ForwardIterator my_it = begin;

				   // If necessary, increase the size of the
				   // array.
  if (stop_size > entries.capacity())
    entries.reserve (stop_size);

  unsigned int col = *my_it;
  std::vector<unsigned int>::iterator it, it2;
				   // insert the first element as for one
				   // entry only first check the last
				   // element (or if line is still empty)
  if ( (entries.size()==0) || ( entries.back() < col) ) {
    entries.push_back(col);
    it = entries.end()-1;
  }
  else {
				   // do a binary search to find the place
				   // where to insert:
    it2 = std::lower_bound(entries.begin(), entries.end(), col);

				   // If this entry is a duplicate, continue
				   // immediately Insert at the right place
				   // in the vector. Vector grows
				   // automatically to fit elements. Always
				   // doubles its size.
    if (*it2 != col)
      it = entries.insert(it2, col);
    else
      it = it2;
  }

  ++my_it;
				   // Now try to be smart and insert with
				   // bias in the direction we are
				   // walking. This has the advantage that
				   // for sorted lists, we always search in
				   // the right direction, what should
				   // decrease the work needed in here.
  for ( ; my_it != end; ++my_it)
    {
      col = *my_it;
				   // need a special insertion command when
				   // we're at the end of the list
      if (col > entries.back()) {
	entries.push_back(col);
	it = entries.end()-1;
      }
				   // search to the right (preferred search
				   // direction)
      else if (col > *it) {
      	it2 = std::lower_bound(it++, entries.end(), col);
	if (*it2 != col)
	  it = entries.insert(it2, col);
      }
				   // search to the left
      else if (col < *it) {
	it2 = std::lower_bound(entries.begin(), it, col);
	if (*it2 != col)
	  it = entries.insert(it2, col);
      }
				   // if we're neither larger nor smaller,
				   // then this was a duplicate and we can
				   // just continue.
    }
}

CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern ()
                :
		rows(0),
		cols(0)
{}

CompressedSimpleSparsityPattern::
CompressedSimpleSparsityPattern (const CompressedSimpleSparsityPattern &s)
                :
		Subscriptor(),
		rows(0),
		cols(0)
{
  Assert (s.rows == 0, ExcInvalidConstructorCall());
  Assert (s.cols == 0, ExcInvalidConstructorCall());
}

CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern (const unsigned int m,
						      const unsigned int n)
		:
                rows(0),
                cols(0)
{
  reinit (m,n);
}

CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern (const unsigned int n)
		:
                rows(0),
                cols(0)
{
  reinit (n,n);
}

CompressedSimpleSparsityPattern &
CompressedSimpleSparsityPattern::operator = (const CompressedSimpleSparsityPattern &s)
{
  Assert (s.rows == 0, ExcInvalidConstructorCall());
  Assert (s.cols == 0, ExcInvalidConstructorCall());

  Assert (rows == 0, ExcInvalidConstructorCall());
  Assert (cols == 0, ExcInvalidConstructorCall());

  return *this;
}

void
CompressedSimpleSparsityPattern::reinit (const unsigned int m,
				   const unsigned int n)
{
  rows = m;
  cols = n;

  std::vector<Line> new_lines (rows);
  lines.swap (new_lines);
}

void
CompressedSimpleSparsityPattern::compress ()
{}

bool
CompressedSimpleSparsityPattern::empty () const
{
  return ((rows==0) && (cols==0));
}

unsigned int
CompressedSimpleSparsityPattern::max_entries_per_row () const
{
  unsigned int m = 0;
  for (unsigned int i=0; i<rows; ++i)
    {
      m = std::max (m, static_cast<unsigned int>(lines[i].entries.size()));
    }

  return m;
}

bool
CompressedSimpleSparsityPattern::exists (const unsigned int i,
				   const unsigned int j) const
{
  Assert (i<rows, ExcIndexRange(i, 0, rows));
  Assert (j<cols, ExcIndexRange(j, 0, cols));

  return std::binary_search (lines[i].entries.begin(),
                             lines[i].entries.end(),
                             j);
}

void
CompressedSimpleSparsityPattern::symmetrize ()
{
  Assert (rows==cols, ExcNotQuadratic());

				   // loop over all elements presently
				   // in the sparsity pattern and add
				   // the transpose element. note:
				   //
				   // 1. that the sparsity pattern
				   // changes which we work on, but
				   // not the present row
				   //
				   // 2. that the @p{add} function can
				   // be called on elements that
				   // already exist without any harm
  for (unsigned int row=0; row<rows; ++row)
    {
      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end();
           ++j)
				       // add the transpose entry if
				       // this is not the diagonal
        if (row != *j)
          add (*j, row);
    }
}

void
CompressedSimpleSparsityPattern::print (std::ostream &out) const
{
  for (unsigned int row=0; row<rows; ++row)
    {
      out << '[' << row;

      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end(); ++j)
        out << ',' << *j;

      out << ']' << std::endl;
    }

  AssertThrow (out, ExcIO());
}

void
CompressedSimpleSparsityPattern::print_gnuplot (std::ostream &out) const
{
  for (unsigned int row=0; row<rows; ++row)
    {
      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end(); ++j)
                                         // while matrix entries are usually
                                         // written (i,j), with i vertical and
                                         // j horizontal, gnuplot output is
                                         // x-y, that is we have to exchange
                                         // the order of output
        out << *j << " " << -static_cast<signed int>(row) << std::endl;
    }

  AssertThrow (out, ExcIO());
}

unsigned int
CompressedSimpleSparsityPattern::bandwidth () const
{
  unsigned int b=0;
  for (unsigned int row=0; row<rows; ++row)
    {
      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end(); ++j)
        if (static_cast<unsigned int>(std::abs(static_cast<int>(row-*j))) > b)
          b = std::abs(static_cast<signed int>(row-*j));
    }

  return b;
}

unsigned int
CompressedSimpleSparsityPattern::n_nonzero_elements () const
{
  unsigned int n=0;
  for (unsigned int i=0; i<rows; ++i)
    {
      n += lines[i].entries.size();
    }

  return n;
}

// explicit instantiations
template void CompressedSimpleSparsityPattern::Line::add_entries(unsigned int *,
								 unsigned int *,
								 const bool);
template void CompressedSimpleSparsityPattern::Line::
add_entries(std::vector<unsigned int>::iterator,
	    std::vector<unsigned int>::iterator,
	    const bool);

DEAL_II_NAMESPACE_CLOSE
<commit_msg>I committed some nonsense.<commit_after>//---------------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

#include <lac/compressed_simple_sparsity_pattern.h>

#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <numeric>
#include <functional>

DEAL_II_NAMESPACE_OPEN

template <typename ForwardIterator>
void
CompressedSimpleSparsityPattern::Line::add_entries (ForwardIterator begin,
						    ForwardIterator end,
						    const bool      indices_are_sorted)
{
  const int n_elements = end - begin;
  if (n_elements <= 0)
    return;

  const unsigned int stop_size = entries.size() + n_elements;

  if (indices_are_sorted == true && n_elements > 3)
    {
				   // in debug mode, check whether the
				   // indices really are sorted.
#ifdef DEBUG
      {
	ForwardIterator test = begin, test1 = begin;
	++test1;
	for ( ; test1 != end; ++test, ++test1)
	  Assert (*test1 > *test, ExcInternalError());
      }
#endif

      if (entries.size() == 0 || entries.back() < *begin)
	{
	  entries.insert(entries.end(), begin, end);
	  return;
	}

				   // find a possible insertion point for
				   // the first entry. check whether the
				   // first entry is a duplicate before
				   // actually doing something.
      ForwardIterator my_it = begin;
      unsigned int col = *my_it;
      std::vector<unsigned int>::iterator it =
	std::lower_bound(entries.begin(), entries.end(), col);
      while (*it == col)
	{
	  ++my_it;
	  if (my_it == end)
	    break;
	  col = *my_it;
				   // check the very next entry in the
				   // current array
	  ++it;
	  if (it == entries.end())
	    break;
	  if (*it > col)
	    break;
	  if (*it == col)
	    continue;
				   // ok, it wasn't the very next one, do a
				   // binary search to find the insert point
	  it = std::lower_bound(it, entries.end(), col);
	  if (it == entries.end())
	    break;
	}
				   // all input entries were duplicates.
      if (my_it == end)
	return;

				   // resize vector by just inserting the
				   // list
      const unsigned int pos1 = it - entries.begin();
      Assert (pos1 <= entries.size(), ExcInternalError());
      entries.insert (it, my_it, end);
      it = entries.begin() + pos1;
      Assert (entries.size() >= (unsigned int)(it-entries.begin()), ExcInternalError());

				   // now merge the two lists.
      std::vector<unsigned int>::iterator it2 = it + (end-my_it);

				   // as long as there are indices both in
				   // the end of the entries list and in the
				   // input list
      while (my_it != end && it2 != entries.end())
	{
	  if (*my_it < *it2)
	    *it++ = *my_it++;
	  else if (*my_it == *it2)
	    {
	      *it++ = *it2++;
	      ++my_it;
	    }
	  else
	    *it++ = *it2++;
	}
				   // in case there are indices left in the
				   // input list
      while (my_it != end)
	*it++ = *my_it++;

				   // in case there are indices left in the
				   // end of entries
      while (it2 != entries.end())
	*it++ = *it2++;

				   // resize and return
      const unsigned int new_size = it - entries.begin();
      Assert (new_size <= stop_size, ExcInternalError());
      entries.resize (new_size);
      return;
    }

				   // unsorted case or case with too few
				   // elements
  ForwardIterator my_it = begin;

				   // If necessary, increase the size of the
				   // array.
  if (stop_size > entries.capacity())
    entries.reserve (stop_size);

  unsigned int col = *my_it;
  std::vector<unsigned int>::iterator it, it2;
				   // insert the first element as for one
				   // entry only first check the last
				   // element (or if line is still empty)
  if ( (entries.size()==0) || ( entries.back() < col) ) {
    entries.push_back(col);
    it = entries.end()-1;
  }
  else {
				   // do a binary search to find the place
				   // where to insert:
    it2 = std::lower_bound(entries.begin(), entries.end(), col);

				   // If this entry is a duplicate, continue
				   // immediately Insert at the right place
				   // in the vector. Vector grows
				   // automatically to fit elements. Always
				   // doubles its size.
    if (*it2 != col)
      it = entries.insert(it2, col);
    else
      it = it2;
  }

  ++my_it;
				   // Now try to be smart and insert with
				   // bias in the direction we are
				   // walking. This has the advantage that
				   // for sorted lists, we always search in
				   // the right direction, what should
				   // decrease the work needed in here.
  for ( ; my_it != end; ++my_it)
    {
      col = *my_it;
				   // need a special insertion command when
				   // we're at the end of the list
      if (col > entries.back()) {
	entries.push_back(col);
	it = entries.end()-1;
      }
				   // search to the right (preferred search
				   // direction)
      else if (col > *it) {
      	it2 = std::lower_bound(it++, entries.end(), col);
	if (*it2 != col)
	  it = entries.insert(it2, col);
      }
				   // search to the left
      else if (col < *it) {
	it2 = std::lower_bound(entries.begin(), it, col);
	if (*it2 != col)
	  it = entries.insert(it2, col);
      }
				   // if we're neither larger nor smaller,
				   // then this was a duplicate and we can
				   // just continue.
    }
}

CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern ()
                :
		rows(0),
		cols(0)
{}

CompressedSimpleSparsityPattern::
CompressedSimpleSparsityPattern (const CompressedSimpleSparsityPattern &s)
                :
		Subscriptor(),
		rows(0),
		cols(0)
{
  Assert (s.rows == 0, ExcInvalidConstructorCall());
  Assert (s.cols == 0, ExcInvalidConstructorCall());
}

CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern (const unsigned int m,
						      const unsigned int n)
		:
                rows(0),
                cols(0)
{
  reinit (m,n);
}

CompressedSimpleSparsityPattern::CompressedSimpleSparsityPattern (const unsigned int n)
		:
                rows(0),
                cols(0)
{
  reinit (n,n);
}

CompressedSimpleSparsityPattern &
CompressedSimpleSparsityPattern::operator = (const CompressedSimpleSparsityPattern &s)
{
  Assert (s.rows == 0, ExcInvalidConstructorCall());
  Assert (s.cols == 0, ExcInvalidConstructorCall());

  Assert (rows == 0, ExcInvalidConstructorCall());
  Assert (cols == 0, ExcInvalidConstructorCall());

  return *this;
}

void
CompressedSimpleSparsityPattern::reinit (const unsigned int m,
				   const unsigned int n)
{
  rows = m;
  cols = n;

  std::vector<Line> new_lines (rows);
  lines.swap (new_lines);
}

void
CompressedSimpleSparsityPattern::compress ()
{}

bool
CompressedSimpleSparsityPattern::empty () const
{
  return ((rows==0) && (cols==0));
}

unsigned int
CompressedSimpleSparsityPattern::max_entries_per_row () const
{
  unsigned int m = 0;
  for (unsigned int i=0; i<rows; ++i)
    {
      m = std::max (m, static_cast<unsigned int>(lines[i].entries.size()));
    }

  return m;
}

bool
CompressedSimpleSparsityPattern::exists (const unsigned int i,
				   const unsigned int j) const
{
  Assert (i<rows, ExcIndexRange(i, 0, rows));
  Assert (j<cols, ExcIndexRange(j, 0, cols));

  return std::binary_search (lines[i].entries.begin(),
                             lines[i].entries.end(),
                             j);
}

void
CompressedSimpleSparsityPattern::symmetrize ()
{
  Assert (rows==cols, ExcNotQuadratic());

				   // loop over all elements presently
				   // in the sparsity pattern and add
				   // the transpose element. note:
				   //
				   // 1. that the sparsity pattern
				   // changes which we work on, but
				   // not the present row
				   //
				   // 2. that the @p{add} function can
				   // be called on elements that
				   // already exist without any harm
  for (unsigned int row=0; row<rows; ++row)
    {
      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end();
           ++j)
				       // add the transpose entry if
				       // this is not the diagonal
        if (row != *j)
          add (*j, row);
    }
}

void
CompressedSimpleSparsityPattern::print (std::ostream &out) const
{
  for (unsigned int row=0; row<rows; ++row)
    {
      out << '[' << row;

      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end(); ++j)
        out << ',' << *j;

      out << ']' << std::endl;
    }

  AssertThrow (out, ExcIO());
}

void
CompressedSimpleSparsityPattern::print_gnuplot (std::ostream &out) const
{
  for (unsigned int row=0; row<rows; ++row)
    {
      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end(); ++j)
                                         // while matrix entries are usually
                                         // written (i,j), with i vertical and
                                         // j horizontal, gnuplot output is
                                         // x-y, that is we have to exchange
                                         // the order of output
        out << *j << " " << -static_cast<signed int>(row) << std::endl;
    }

  AssertThrow (out, ExcIO());
}

unsigned int
CompressedSimpleSparsityPattern::bandwidth () const
{
  unsigned int b=0;
  for (unsigned int row=0; row<rows; ++row)
    {
      for (std::vector<unsigned int>::const_iterator
             j=lines[row].entries.begin();
           j != lines[row].entries.end(); ++j)
        if (static_cast<unsigned int>(std::abs(static_cast<int>(row-*j))) > b)
          b = std::abs(static_cast<signed int>(row-*j));
    }

  return b;
}

unsigned int
CompressedSimpleSparsityPattern::n_nonzero_elements () const
{
  unsigned int n=0;
  for (unsigned int i=0; i<rows; ++i)
    {
      n += lines[i].entries.size();
    }

  return n;
}

// explicit instantiations
template void CompressedSimpleSparsityPattern::Line::add_entries(unsigned int *,
								 unsigned int *,
								 const bool);
template void CompressedSimpleSparsityPattern::Line::
add_entries(std::vector<unsigned int>::iterator,
	    std::vector<unsigned int>::iterator,
	    const bool);

DEAL_II_NAMESPACE_CLOSE
<|endoftext|>


<commit_before>/**
 * computeDifferenceImage
 *
 * This program computes the difference between images.
 *
 *
 * authors:       Marius Staring
 *
 */

#include <iostream>
#include "itkImageFileReader.h"

/** In order to determine if argv[1] is a directory or a file,
 * so that we can distinguish between dicom and other files.
 */
#include <itksys/SystemTools.hxx>

// extern int ComputeScalarDifferenceImage( const std::string &inputPixelComponentType1,
//   const std::string &inputPixelComponentType2, const std::string &outputPixelComponentType,
//   const std::string &image1FileName, const std::string &image2FileName,
//   const std::string &outputFileName, int inputDimension);

extern int ComputeVectorDifferenceImage( const std::string &inputPixelComponentType1,
  const std::string &inputPixelComponentType2, const std::string &outputPixelComponentType,
  const std::string &image1FileName, const std::string &image2FileName,
  const std::string &outputFileName, int inputDimension, int vectorDimension);

//-------------------------------------------------------------------------------------

int  main(  int  argc,  char *argv[] )
{
  /** TASK 1:
   * Check arguments.
   * *******************************************************************
   */
  if ( argc  < 3 || argv[ 1 ] == "--help" )
  {
    std::cout  << "Usage:"  << std::endl;
    std::cout  << "\tpxcomputedifferenceimage inputimage1filename inputimage2filename [outputimagefilename] [outputPixelComponentType]" << std::endl;
    std::cout  << "\twhere outputPixelComponentType is one of:" << std::endl;
    std::cout  << "\t\t- unsigned_char" << std::endl;
    std::cout  << "\t\t- char" << std::endl;
    std::cout  << "\t\t- unsigned_short" << std::endl;
    std::cout  << "\t\t- short" << std::endl;
    std::cout  << "\t\t- unsigned_int" << std::endl;
    std::cout  << "\t\t- int" << std::endl;
    std::cout  << "\t\t- unsigned_long" << std::endl;
    std::cout  << "\t\t- long" << std::endl;
    std::cout  << "\t\t- float" << std::endl;
    std::cout  << "\t\t- double" << std::endl;
    std::cout  << "\tprovided that the outputPixelComponentType is supported by the output file format." << std::endl;
    std::cout  << "\tBy default the outputPixelComponentType is set to the inputPixelComponentType of image1." << std::endl;
    return 1;
  }

  /** Print arguments. */
  std::cout << "pxcomputedifferenceimage ";
  for ( unsigned int i = 1; i < argc; i++ )
  {
    std::cout << argv[ i ] << " ";
  }
  std::cout << std::endl;

  /** Get the image names. */
  std::string image1FileName = argv[ 1 ];
  std::string image2FileName = argv[ 2 ];
  std::string outputFileName = "";
  std::string outputPixelComponentType = "";
  if ( argc == 3 )
  {
    std::string::size_type slash = image2FileName.find_last_of( "/" ) + 1;
    outputFileName = image1FileName.substr( 0, image1FileName.rfind( "." ) );
    outputFileName += "MINUS";
    outputFileName += image2FileName.substr( slash, image2FileName.rfind( "." ) - slash );
    outputFileName += ".mhd";
  }
  else if ( argc == 4 )
  {
    outputFileName = argv[ 3 ];
  }
  else if ( argc == 5 )
  {
    outputFileName = argv[ 3 ];
    outputPixelComponentType = argv[ 4 ];
  }

  /** Check if image1FileName and image2FileName exist. */
  bool exists1 = itksys::SystemTools::FileExists( image1FileName.c_str() );
  bool exists2 = itksys::SystemTools::FileExists( image2FileName.c_str() );

  if ( !exists1 || !exists2 )
  {
    /** Something is wrong. */
    std::cerr << "ERROR: first input argument does not exist!" << std::endl;
    return 1;
  }

  /** Check outputPixelType. */
  if ( outputPixelComponentType != ""
    && outputPixelComponentType != "unsigned_char"
    && outputPixelComponentType != "char"
    && outputPixelComponentType != "unsigned_short"
    && outputPixelComponentType != "short"
    && outputPixelComponentType != "unsigned_int"
    && outputPixelComponentType != "int"
    && outputPixelComponentType != "unsigned_long"
    && outputPixelComponentType != "long"
    && outputPixelComponentType != "float"
    && outputPixelComponentType != "double" )
  {
    /** In this case an illegal outputPixelComponentType is given. */
    std::cerr << "The given outputPixelComponentType is \"" << outputPixelComponentType
      << "\", which is not supported." << std::endl;
    return 1;
  }

  /** TASK 2:
   * Typedefs and test reading to determine correct image types.
   * *******************************************************************
   */

  /** Initial image type. */
  const unsigned int    Dimension  =  3;
  typedef short         PixelType;

  /** Some typedef's. */
  typedef itk::Image< PixelType, Dimension >      ImageType;
  typedef itk::ImageFileReader< ImageType >       ReaderType;
  typedef itk::ImageIOBase                        ImageIOBaseType;

  /** Create testReaders. */
  ReaderType::Pointer testReader1 = ReaderType::New();
  ReaderType::Pointer testReader2 = ReaderType::New();

  /** Setup the testReaders. */
  testReader1->SetFileName( image1FileName.c_str() );
  testReader2->SetFileName( image2FileName.c_str() );

  /** Generate all information. */
  testReader1->GenerateOutputInformation();
  testReader2->GenerateOutputInformation();

  /** Extract the ImageIO from the testReaders. */
  ImageIOBaseType::Pointer testImageIOBase1 = testReader1->GetImageIO();
  ImageIOBaseType::Pointer testImageIOBase2 = testReader2->GetImageIO();

  /** Get the component type, number of components, dimension and pixel type of image1. */
  unsigned int inputDimension1 = testImageIOBase1->GetNumberOfDimensions();
  unsigned int numberOfComponents1 = testImageIOBase1->GetNumberOfComponents();
  std::string inputPixelComponentType1 = testImageIOBase1->GetComponentTypeAsString(
    testImageIOBase1->GetComponentType() );
  std::string pixelType1 = testImageIOBase1->GetPixelTypeAsString(
    testImageIOBase1->GetPixelType() );

  /** Get the component type, number of components, dimension and pixel type of image2. */
  unsigned int inputDimension2 = testImageIOBase2->GetNumberOfDimensions();
  unsigned int numberOfComponents2 = testImageIOBase2->GetNumberOfComponents();
  std::string inputPixelComponentType2 = testImageIOBase2->GetComponentTypeAsString(
    testImageIOBase2->GetComponentType() );
  std::string pixelType2 = testImageIOBase2->GetPixelTypeAsString(
    testImageIOBase2->GetPixelType() );

  /** TASK 3:
   * Do some preparations and checks.
   * *******************************************************************
   */

  /** Check dimension equality. */
  if ( inputDimension1 != inputDimension2 )
  {
    std::cerr << "The dimensions of the input images are "
      << inputDimension1 << " and "
      << inputDimension2 << "." << std::endl;
    std::cerr << "They should match!" << std::endl;
    return 1;
  }

  /** Check equality of the pixel type. */
  if ( pixelType1 != pixelType2 )
  {
    std::cerr << "The pixel type of the input images are "
      << pixelType1 << " and "
      << pixelType2 << "." << std::endl;
    std::cerr << "They should match!" << std::endl;
    return 1;
  }

  /** Check equality of the number of components. */
  if ( numberOfComponents1 != numberOfComponents2 )
  {
    std::cerr << "The number of components of the input images are "
      << numberOfComponents1 << " and "
      << numberOfComponents2 << "." << std::endl;
    std::cerr << "They should match!" << std::endl;
    return 1;
  }

  /** Check inputPixelComponentType1. */
  if ( inputPixelComponentType1 != "unsigned_char"
    && inputPixelComponentType1 != "char"
    && inputPixelComponentType1 != "unsigned_short"
    && inputPixelComponentType1 != "short"
    && inputPixelComponentType1 != "unsigned_int"
    && inputPixelComponentType1 != "int"
    && inputPixelComponentType1 != "unsigned_long"
    && inputPixelComponentType1 != "long"
    && inputPixelComponentType1 != "float"
    && inputPixelComponentType1 != "double" )
  {
    /** In this case an illegal inputPixelComponentType is found. */
    std::cerr << "The found inputPixelComponentType of image1 is \"" << inputPixelComponentType1
      << "\", which is not supported." << std::endl;
    return 1;
  }

  /** Check inputPixelType2. */
  if ( inputPixelComponentType2 != "unsigned_char"
    && inputPixelComponentType2 != "char"
    && inputPixelComponentType2 != "unsigned_short"
    && inputPixelComponentType2 != "short"
    && inputPixelComponentType2 != "unsigned_int"
    && inputPixelComponentType2 != "int"
    && inputPixelComponentType2 != "unsigned_long"
    && inputPixelComponentType2 != "long"
    && inputPixelComponentType2 != "float"
    && inputPixelComponentType2 != "double" )
  {
    /** In this case an illegal inputPixelComponentType is found. */
    std::cerr << "The found inputPixelComponentType of image2 is \"" << inputPixelComponentType2
      << "\", which is not supported." << std::endl;
    return 1;
  }

  /** Check outputPixelType. */
  if ( outputPixelComponentType == "" )
  {
    /** In this case this option is not given, and by default
    * we set it to the inputPixelComponentType.
    */
    outputPixelComponentType = inputPixelComponentType1;
  }

  /** Get rid of the "_" in inputPixelComponentTypes and outputPixelComponentType. */
  std::basic_string<char>::size_type pos = inputPixelComponentType1.find( "_" );
  static const std::basic_string<char>::size_type npos = std::basic_string<char>::npos;
  if ( pos != npos )
  {
    inputPixelComponentType1.replace( pos, 1, " " );
  }
  pos = inputPixelComponentType2.find( "_" );
  if ( pos != npos )
  {
    inputPixelComponentType2.replace( pos, 1, " " );
  }
  pos = outputPixelComponentType.find( "_" );
  if ( pos != npos )
  {
    outputPixelComponentType.replace( pos, 1, " " );
  }

  /** TASK 4:
   * Now we are ready to check on image type and subsequently call the
   * correct ComputeDifference-function.
   * *******************************************************************
   */

  try
  {
    /**
     * ****************** Support for SCALAR pixel types. **********************************
     *
    if ( strcmp( pixelType1.c_str(), "scalar" ) == 0 && numberOfComponents1 == 1 )
    {
      const int ret_value = ComputeScalarDifferenceImage(
        inputPixelComponentType1, inputPixelComponentType2,
        outputPixelComponentType, image1FileName, image2FileName,
        outputFileName, inputDimension1 );
      if ( ret_value != 0 )
      {
        return ret_value;
      }
    } // end scalar support */
    /**
     * ****************** Support for VECTOR pixel types. **********************************
     */
    //else if ( strcmp( pixelType1.c_str(), "vector" ) == 0 )
    if ( numberOfComponents1 > 1 )
    {
      const int ret_value = ComputeVectorDifferenceImage(
        inputPixelComponentType1, inputPixelComponentType2,
        outputPixelComponentType, image1FileName, image2FileName,
        outputFileName, inputDimension1, numberOfComponents1 );
      if ( ret_value != 0 )
      {
        return ret_value;
      }
    } // end vector support
    else
    {
      std::cerr << "Pixel types are " << pixelType1
        << ", component types are " << inputPixelComponentType1
        << " and number of components equals " << numberOfComponents1 << "." << std::endl;
      std::cerr << "ERROR: This image type is not supported." << std::endl;
      return 1;
    }
  } // end try

  /** If any errors have occurred, catch and print the exception and return false. */
  catch( itk::ExceptionObject  &  err  )
  {
    std::cerr  << "ExceptionObject caught !"  << std::endl;
    std::cerr  << err <<  std::endl;
    return 1;
  }

  /** End  program. Return success. */
  return 0;

}  // end main
<commit_msg>Fix comparison with string literal results in unspecified behavior warning<commit_after>/**
 * computeDifferenceImage
 *
 * This program computes the difference between images.
 *
 *
 * authors:       Marius Staring
 *
 */

#include <iostream>
#include "itkImageFileReader.h"

/** In order to determine if argv[1] is a directory or a file,
 * so that we can distinguish between dicom and other files.
 */
#include <itksys/SystemTools.hxx>

// extern int ComputeScalarDifferenceImage( const std::string &inputPixelComponentType1,
//   const std::string &inputPixelComponentType2, const std::string &outputPixelComponentType,
//   const std::string &image1FileName, const std::string &image2FileName,
//   const std::string &outputFileName, int inputDimension);

extern int ComputeVectorDifferenceImage( const std::string &inputPixelComponentType1,
  const std::string &inputPixelComponentType2, const std::string &outputPixelComponentType,
  const std::string &image1FileName, const std::string &image2FileName,
  const std::string &outputFileName, int inputDimension, int vectorDimension);

//-------------------------------------------------------------------------------------

int  main(  int  argc,  char *argv[] )
{
  /** TASK 1:
   * Check arguments.
   * *******************************************************************
   */
  if ( argc  < 3 || strcmp(argv[ 1 ], "--help") == 0 )
  {
    std::cout  << "Usage:"  << std::endl;
    std::cout  << "\tpxcomputedifferenceimage inputimage1filename inputimage2filename [outputimagefilename] [outputPixelComponentType]" << std::endl;
    std::cout  << "\twhere outputPixelComponentType is one of:" << std::endl;
    std::cout  << "\t\t- unsigned_char" << std::endl;
    std::cout  << "\t\t- char" << std::endl;
    std::cout  << "\t\t- unsigned_short" << std::endl;
    std::cout  << "\t\t- short" << std::endl;
    std::cout  << "\t\t- unsigned_int" << std::endl;
    std::cout  << "\t\t- int" << std::endl;
    std::cout  << "\t\t- unsigned_long" << std::endl;
    std::cout  << "\t\t- long" << std::endl;
    std::cout  << "\t\t- float" << std::endl;
    std::cout  << "\t\t- double" << std::endl;
    std::cout  << "\tprovided that the outputPixelComponentType is supported by the output file format." << std::endl;
    std::cout  << "\tBy default the outputPixelComponentType is set to the inputPixelComponentType of image1." << std::endl;
    return 1;
  }

  /** Print arguments. */
  std::cout << "pxcomputedifferenceimage ";
  for ( unsigned int i = 1; i < argc; i++ )
  {
    std::cout << argv[ i ] << " ";
  }
  std::cout << std::endl;

  /** Get the image names. */
  std::string image1FileName = argv[ 1 ];
  std::string image2FileName = argv[ 2 ];
  std::string outputFileName = "";
  std::string outputPixelComponentType = "";
  if ( argc == 3 )
  {
    std::string::size_type slash = image2FileName.find_last_of( "/" ) + 1;
    outputFileName = image1FileName.substr( 0, image1FileName.rfind( "." ) );
    outputFileName += "MINUS";
    outputFileName += image2FileName.substr( slash, image2FileName.rfind( "." ) - slash );
    outputFileName += ".mhd";
  }
  else if ( argc == 4 )
  {
    outputFileName = argv[ 3 ];
  }
  else if ( argc == 5 )
  {
    outputFileName = argv[ 3 ];
    outputPixelComponentType = argv[ 4 ];
  }

  /** Check if image1FileName and image2FileName exist. */
  bool exists1 = itksys::SystemTools::FileExists( image1FileName.c_str() );
  bool exists2 = itksys::SystemTools::FileExists( image2FileName.c_str() );

  if ( !exists1 || !exists2 )
  {
    /** Something is wrong. */
    std::cerr << "ERROR: first input argument does not exist!" << std::endl;
    return 1;
  }

  /** Check outputPixelType. */
  if ( outputPixelComponentType != ""
    && outputPixelComponentType != "unsigned_char"
    && outputPixelComponentType != "char"
    && outputPixelComponentType != "unsigned_short"
    && outputPixelComponentType != "short"
    && outputPixelComponentType != "unsigned_int"
    && outputPixelComponentType != "int"
    && outputPixelComponentType != "unsigned_long"
    && outputPixelComponentType != "long"
    && outputPixelComponentType != "float"
    && outputPixelComponentType != "double" )
  {
    /** In this case an illegal outputPixelComponentType is given. */
    std::cerr << "The given outputPixelComponentType is \"" << outputPixelComponentType
      << "\", which is not supported." << std::endl;
    return 1;
  }

  /** TASK 2:
   * Typedefs and test reading to determine correct image types.
   * *******************************************************************
   */

  /** Initial image type. */
  const unsigned int    Dimension  =  3;
  typedef short         PixelType;

  /** Some typedef's. */
  typedef itk::Image< PixelType, Dimension >      ImageType;
  typedef itk::ImageFileReader< ImageType >       ReaderType;
  typedef itk::ImageIOBase                        ImageIOBaseType;

  /** Create testReaders. */
  ReaderType::Pointer testReader1 = ReaderType::New();
  ReaderType::Pointer testReader2 = ReaderType::New();

  /** Setup the testReaders. */
  testReader1->SetFileName( image1FileName.c_str() );
  testReader2->SetFileName( image2FileName.c_str() );

  /** Generate all information. */
  testReader1->GenerateOutputInformation();
  testReader2->GenerateOutputInformation();

  /** Extract the ImageIO from the testReaders. */
  ImageIOBaseType::Pointer testImageIOBase1 = testReader1->GetImageIO();
  ImageIOBaseType::Pointer testImageIOBase2 = testReader2->GetImageIO();

  /** Get the component type, number of components, dimension and pixel type of image1. */
  unsigned int inputDimension1 = testImageIOBase1->GetNumberOfDimensions();
  unsigned int numberOfComponents1 = testImageIOBase1->GetNumberOfComponents();
  std::string inputPixelComponentType1 = testImageIOBase1->GetComponentTypeAsString(
    testImageIOBase1->GetComponentType() );
  std::string pixelType1 = testImageIOBase1->GetPixelTypeAsString(
    testImageIOBase1->GetPixelType() );

  /** Get the component type, number of components, dimension and pixel type of image2. */
  unsigned int inputDimension2 = testImageIOBase2->GetNumberOfDimensions();
  unsigned int numberOfComponents2 = testImageIOBase2->GetNumberOfComponents();
  std::string inputPixelComponentType2 = testImageIOBase2->GetComponentTypeAsString(
    testImageIOBase2->GetComponentType() );
  std::string pixelType2 = testImageIOBase2->GetPixelTypeAsString(
    testImageIOBase2->GetPixelType() );

  /** TASK 3:
   * Do some preparations and checks.
   * *******************************************************************
   */

  /** Check dimension equality. */
  if ( inputDimension1 != inputDimension2 )
  {
    std::cerr << "The dimensions of the input images are "
      << inputDimension1 << " and "
      << inputDimension2 << "." << std::endl;
    std::cerr << "They should match!" << std::endl;
    return 1;
  }

  /** Check equality of the pixel type. */
  if ( pixelType1 != pixelType2 )
  {
    std::cerr << "The pixel type of the input images are "
      << pixelType1 << " and "
      << pixelType2 << "." << std::endl;
    std::cerr << "They should match!" << std::endl;
    return 1;
  }

  /** Check equality of the number of components. */
  if ( numberOfComponents1 != numberOfComponents2 )
  {
    std::cerr << "The number of components of the input images are "
      << numberOfComponents1 << " and "
      << numberOfComponents2 << "." << std::endl;
    std::cerr << "They should match!" << std::endl;
    return 1;
  }

  /** Check inputPixelComponentType1. */
  if ( inputPixelComponentType1 != "unsigned_char"
    && inputPixelComponentType1 != "char"
    && inputPixelComponentType1 != "unsigned_short"
    && inputPixelComponentType1 != "short"
    && inputPixelComponentType1 != "unsigned_int"
    && inputPixelComponentType1 != "int"
    && inputPixelComponentType1 != "unsigned_long"
    && inputPixelComponentType1 != "long"
    && inputPixelComponentType1 != "float"
    && inputPixelComponentType1 != "double" )
  {
    /** In this case an illegal inputPixelComponentType is found. */
    std::cerr << "The found inputPixelComponentType of image1 is \"" << inputPixelComponentType1
      << "\", which is not supported." << std::endl;
    return 1;
  }

  /** Check inputPixelType2. */
  if ( inputPixelComponentType2 != "unsigned_char"
    && inputPixelComponentType2 != "char"
    && inputPixelComponentType2 != "unsigned_short"
    && inputPixelComponentType2 != "short"
    && inputPixelComponentType2 != "unsigned_int"
    && inputPixelComponentType2 != "int"
    && inputPixelComponentType2 != "unsigned_long"
    && inputPixelComponentType2 != "long"
    && inputPixelComponentType2 != "float"
    && inputPixelComponentType2 != "double" )
  {
    /** In this case an illegal inputPixelComponentType is found. */
    std::cerr << "The found inputPixelComponentType of image2 is \"" << inputPixelComponentType2
      << "\", which is not supported." << std::endl;
    return 1;
  }

  /** Check outputPixelType. */
  if ( outputPixelComponentType == "" )
  {
    /** In this case this option is not given, and by default
    * we set it to the inputPixelComponentType.
    */
    outputPixelComponentType = inputPixelComponentType1;
  }

  /** Get rid of the "_" in inputPixelComponentTypes and outputPixelComponentType. */
  std::basic_string<char>::size_type pos = inputPixelComponentType1.find( "_" );
  static const std::basic_string<char>::size_type npos = std::basic_string<char>::npos;
  if ( pos != npos )
  {
    inputPixelComponentType1.replace( pos, 1, " " );
  }
  pos = inputPixelComponentType2.find( "_" );
  if ( pos != npos )
  {
    inputPixelComponentType2.replace( pos, 1, " " );
  }
  pos = outputPixelComponentType.find( "_" );
  if ( pos != npos )
  {
    outputPixelComponentType.replace( pos, 1, " " );
  }

  /** TASK 4:
   * Now we are ready to check on image type and subsequently call the
   * correct ComputeDifference-function.
   * *******************************************************************
   */

  try
  {
    /**
     * ****************** Support for SCALAR pixel types. **********************************
     *
    if ( strcmp( pixelType1.c_str(), "scalar" ) == 0 && numberOfComponents1 == 1 )
    {
      const int ret_value = ComputeScalarDifferenceImage(
        inputPixelComponentType1, inputPixelComponentType2,
        outputPixelComponentType, image1FileName, image2FileName,
        outputFileName, inputDimension1 );
      if ( ret_value != 0 )
      {
        return ret_value;
      }
    } // end scalar support */
    /**
     * ****************** Support for VECTOR pixel types. **********************************
     */
    //else if ( strcmp( pixelType1.c_str(), "vector" ) == 0 )
    if ( numberOfComponents1 > 1 )
    {
      const int ret_value = ComputeVectorDifferenceImage(
        inputPixelComponentType1, inputPixelComponentType2,
        outputPixelComponentType, image1FileName, image2FileName,
        outputFileName, inputDimension1, numberOfComponents1 );
      if ( ret_value != 0 )
      {
        return ret_value;
      }
    } // end vector support
    else
    {
      std::cerr << "Pixel types are " << pixelType1
        << ", component types are " << inputPixelComponentType1
        << " and number of components equals " << numberOfComponents1 << "." << std::endl;
      std::cerr << "ERROR: This image type is not supported." << std::endl;
      return 1;
    }
  } // end try

  /** If any errors have occurred, catch and print the exception and return false. */
  catch( itk::ExceptionObject  &  err  )
  {
    std::cerr  << "ExceptionObject caught !"  << std::endl;
    std::cerr  << err <<  std::endl;
    return 1;
  }

  /** End  program. Return success. */
  return 0;

}  // end main
<|endoftext|>