<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pe_file.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: kz $ $Date: 2007-10-09 15:02:36 $
 *
 *  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 <precomp.h>
#include "pe_file.hxx"

// NOT FULLY DECLARED SERVICES
#include "pe_defs.hxx"
#include "pe_enum.hxx"
#include "pe_namsp.hxx"
#include "pe_tpltp.hxx"
#include "pe_tydef.hxx"
#include "pe_vafu.hxx"
#include "pe_ignor.hxx"

// NOT FULLY DECLARED SERVICES

namespace cpp
{

PE_File::PE_File( cpp::PeEnvironment & io_rEnv)
    :   Cpp_PE(io_rEnv),
        pEnv(&io_rEnv),
        pStati( new PeStatusArray<PE_File> ),
        // pSpNamespace,
        // pSpTypedef,
        // pSpVarFunc,
        // pSpIgnore,
        // pSpuNamespace,
        // pSpuClass,
        // pSpuTypedef,
        // pSpuVarFunc,
        // pSpuTemplate,
        // pSpuUsing,
        // pSpuIgnoreFailure,
        bWithinSingleExternC(false)
{
    Setup_StatusFunctions();

    pSpNamespace = new SP_Namespace(*this);
    pSpTypedef   = new SP_Typedef(*this);
    pSpVarFunc   = new SP_VarFunc(*this);
    pSpTemplate  = new SP_Template(*this);
    pSpDefs      = new SP_Defines(*this);
    pSpIgnore    = new SP_Ignore(*this);

    pSpuNamespace   = new SPU_Namespace(*pSpNamespace, 0, 0);
    pSpuTypedef     = new SPU_Typedef(*pSpTypedef, 0, 0);
    pSpuVarFunc     = new SPU_VarFunc(*pSpVarFunc, 0, &PE_File::SpReturn_VarFunc);
    pSpuTemplate    = new SPU_Template(*pSpTemplate, 0, &PE_File::SpReturn_Template);
    pSpuDefs        = new SPU_Defines(*pSpDefs, 0, 0);
    pSpuUsing       = new SPU_Ignore(*pSpIgnore, 0, 0);
    pSpuIgnoreFailure
                    = new SPU_Ignore(*pSpIgnore, 0, 0);
}

PE_File::~PE_File()
{
}

void
PE_File::Call_Handler( const cpp::Token &   i_rTok )
{
    pStati->Cur().Call_Handler(i_rTok.TypeId(), i_rTok.Text());
}

Cpp_PE *
PE_File::Handle_ChildFailure()
{
    SetCurSPU(pSpuIgnoreFailure.Ptr());
    return &pSpuIgnoreFailure->Child();
}

ary::cpp::RwGate &
PE_File::AryGate() const
{
     return const_cast< PE_File& >(*this).access_Env().AryGate();
}

void
PE_File::Setup_StatusFunctions()
{
    typedef CallFunction<PE_File>::F_Tok    F_Tok;
    static F_Tok stateF_std[] =             { &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_ClassKey,
                                              &PE_File::On_std_ClassKey,
                                              &PE_File::On_std_ClassKey,
                                              &PE_File::On_std_enum,

                                              &PE_File::On_std_typedef,
                                              &PE_File::On_std_template,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_extern,

                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_namespace,
                                              &PE_File::On_std_using,

                                              &PE_File::On_std_SwBracketRight,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_DefineName,
                                              &PE_File::On_std_MacroName,

                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc };

    static INT16 stateT_std[] =             { Tid_Identifier,
                                              Tid_class,
                                              Tid_struct,
                                              Tid_union,
                                              Tid_enum,

                                              Tid_typedef,
                                              Tid_template,
                                              Tid_const,
                                              Tid_volatile,
                                              Tid_extern,

                                              Tid_static,
                                              Tid_register,
                                              Tid_inline,
                                              Tid_namespace,
                                              Tid_using,

                                              Tid_SwBracket_Right,
                                              Tid_DoubleColon,
                                              Tid_typename,
                                              Tid_DefineName,
                                              Tid_MacroName,

                                              Tid_BuiltInType,
                                              Tid_TypeSpecializer };

    static F_Tok stateF_in_extern[] =       { &PE_File::On_in_extern_Constant };
    static INT16 stateT_in_extern[] =       { Tid_Constant };

    static F_Tok stateF_in_externC[] =      { &PE_File::On_in_externC_SwBracket_Left };
    static INT16 stateT_in_externC[] =      { Tid_SwBracket_Left };

    SEMPARSE_CREATE_STATUS(PE_File, std, Hdl_SyntaxError);
    SEMPARSE_CREATE_STATUS(PE_File, in_extern, On_in_extern_Ignore);
    SEMPARSE_CREATE_STATUS(PE_File, in_externC, On_in_externC_NoBlock);
}

void
PE_File::InitData()
{
    pStati->SetCur(std);
}

void
PE_File::TransferData()
{
    pStati->SetCur(size_of_states);
}

void
PE_File::Hdl_SyntaxError( const char * i_sText)
{
    if ( *i_sText == ';' )
    {
         Cerr() << Env().CurFileName() << ", line "
                  << Env().LineCount()
                  << ": Sourcecode warning: ';' as a toplevel declaration is deprecated."
                  << Endl();
        SetTokenResult(done,stay);
        return;
    }

    StdHandlingOfSyntaxError(i_sText);
}

void
PE_File::SpReturn_VarFunc()
{
     if (bWithinSingleExternC)
    {
        access_Env().CloseBlock();
         bWithinSingleExternC = false;
    }
}

void
PE_File::SpReturn_Template()
{
    access_Env().OpenTemplate( pSpuTemplate->Child().Result_Parameters() );
}

void
PE_File::On_std_namespace(const char * )
{
    pSpuNamespace->Push(done);
}

void
PE_File::On_std_ClassKey(const char * )
{
    pSpuVarFunc->Push(not_done);        // This is correct,
                                        //   classes are parsed via PE_Type.
}

void
PE_File::On_std_typedef(const char * )
{
    pSpuTypedef->Push(not_done);
}

void
PE_File::On_std_enum(const char * )
{
    pSpuVarFunc->Push(not_done);        // This is correct,
                                        //   enums are parsed via PE_Type.
}

void
PE_File::On_std_VarFunc(const char * )
{
    pSpuVarFunc->Push(not_done);
}

void
PE_File::On_std_template(const char * )
{
    pSpuTemplate->Push(done);
}

void
PE_File::On_std_extern(const char * )
{
    SetTokenResult(done, stay);
    pStati->SetCur(in_extern);
}

void
PE_File::On_std_using(const char * )
{
    pSpuUsing->Push(done);
}

void
PE_File::On_std_SwBracketRight(const char * )
{
    SetTokenResult(done,stay);
    access_Env().CloseBlock();
}

void
PE_File::On_std_DefineName(const char * )
{
    pSpuDefs->Push(not_done);
}

void
PE_File::On_std_MacroName(const char * )
{
    pSpuDefs->Push(not_done);
}

void
PE_File::On_in_extern_Constant(const char * )
{
    SetTokenResult(done,stay);
    pStati->SetCur(in_externC);

    access_Env().OpenExternC();
}

void
PE_File::On_in_extern_Ignore(const char * )
{
    SetTokenResult(not_done, stay);
    pStati->SetCur(std);
}

void
PE_File::On_in_externC_SwBracket_Left(const char * )
{
    SetTokenResult(done, stay);
    pStati->SetCur(std);
}

void
PE_File::On_in_externC_NoBlock(const char * )
{
    SetTokenResult(not_done, stay);
    pStati->SetCur(std);

    bWithinSingleExternC = true;
}

}   // namespace cpp
<commit_msg>INTEGRATION: CWS adc18 (1.10.2); FILE MERGED 2007/10/18 15:23:17 np 1.10.2.1: #i81775#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pe_file.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-02 16:54:54 $
 *
 *  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 <precomp.h>
#include "pe_file.hxx"

// NOT FULLY DECLARED SERVICES
#include "pe_defs.hxx"
#include "pe_enum.hxx"
#include "pe_namsp.hxx"
#include "pe_tpltp.hxx"
#include "pe_tydef.hxx"
#include "pe_vafu.hxx"
#include "pe_ignor.hxx"

// NOT FULLY DECLARED SERVICES

namespace cpp
{

PE_File::PE_File( cpp::PeEnvironment & io_rEnv)
    :   Cpp_PE(io_rEnv),
        pEnv(&io_rEnv),
        pStati( new PeStatusArray<PE_File> ),
        // pSpNamespace,
        // pSpTypedef,
        // pSpVarFunc,
        // pSpIgnore,
        // pSpuNamespace,
        // pSpuClass,
        // pSpuTypedef,
        // pSpuVarFunc,
        // pSpuTemplate,
        // pSpuUsing,
        // pSpuIgnoreFailure,
        bWithinSingleExternC(false)
{
    Setup_StatusFunctions();

    pSpNamespace = new SP_Namespace(*this);
    pSpTypedef   = new SP_Typedef(*this);
    pSpVarFunc   = new SP_VarFunc(*this);
    pSpTemplate  = new SP_Template(*this);
    pSpDefs      = new SP_Defines(*this);
    pSpIgnore    = new SP_Ignore(*this);

    pSpuNamespace   = new SPU_Namespace(*pSpNamespace, 0, 0);
    pSpuTypedef     = new SPU_Typedef(*pSpTypedef, 0, 0);
    pSpuVarFunc     = new SPU_VarFunc(*pSpVarFunc, 0, &PE_File::SpReturn_VarFunc);
    pSpuTemplate    = new SPU_Template(*pSpTemplate, 0, &PE_File::SpReturn_Template);
    pSpuDefs        = new SPU_Defines(*pSpDefs, 0, 0);
    pSpuUsing       = new SPU_Ignore(*pSpIgnore, 0, 0);
    pSpuIgnoreFailure
                    = new SPU_Ignore(*pSpIgnore, 0, 0);
}

PE_File::~PE_File()
{
}

void
PE_File::Call_Handler( const cpp::Token &   i_rTok )
{
    pStati->Cur().Call_Handler(i_rTok.TypeId(), i_rTok.Text());
}

Cpp_PE *
PE_File::Handle_ChildFailure()
{
    SetCurSPU(pSpuIgnoreFailure.Ptr());
    return &pSpuIgnoreFailure->Child();
}

ary::cpp::Gate &
PE_File::AryGate() const
{
     return const_cast< PE_File& >(*this).access_Env().AryGate();
}

void
PE_File::Setup_StatusFunctions()
{
    typedef CallFunction<PE_File>::F_Tok    F_Tok;
    static F_Tok stateF_std[] =             { &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_ClassKey,
                                              &PE_File::On_std_ClassKey,
                                              &PE_File::On_std_ClassKey,
                                              &PE_File::On_std_enum,

                                              &PE_File::On_std_typedef,
                                              &PE_File::On_std_template,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_extern,

                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_namespace,
                                              &PE_File::On_std_using,

                                              &PE_File::On_std_SwBracketRight,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_DefineName,
                                              &PE_File::On_std_MacroName,

                                              &PE_File::On_std_VarFunc,
                                              &PE_File::On_std_VarFunc };

    static INT16 stateT_std[] =             { Tid_Identifier,
                                              Tid_class,
                                              Tid_struct,
                                              Tid_union,
                                              Tid_enum,

                                              Tid_typedef,
                                              Tid_template,
                                              Tid_const,
                                              Tid_volatile,
                                              Tid_extern,

                                              Tid_static,
                                              Tid_register,
                                              Tid_inline,
                                              Tid_namespace,
                                              Tid_using,

                                              Tid_SwBracket_Right,
                                              Tid_DoubleColon,
                                              Tid_typename,
                                              Tid_DefineName,
                                              Tid_MacroName,

                                              Tid_BuiltInType,
                                              Tid_TypeSpecializer };

    static F_Tok stateF_in_extern[] =       { &PE_File::On_in_extern_Constant };
    static INT16 stateT_in_extern[] =       { Tid_Constant };

    static F_Tok stateF_in_externC[] =      { &PE_File::On_in_externC_SwBracket_Left };
    static INT16 stateT_in_externC[] =      { Tid_SwBracket_Left };

    SEMPARSE_CREATE_STATUS(PE_File, std, Hdl_SyntaxError);
    SEMPARSE_CREATE_STATUS(PE_File, in_extern, On_in_extern_Ignore);
    SEMPARSE_CREATE_STATUS(PE_File, in_externC, On_in_externC_NoBlock);
}

void
PE_File::InitData()
{
    pStati->SetCur(std);
}

void
PE_File::TransferData()
{
    pStati->SetCur(size_of_states);
}

void
PE_File::Hdl_SyntaxError( const char * i_sText)
{
    if ( *i_sText == ';' )
    {
         Cerr() << Env().CurFileName() << ", line "
                  << Env().LineCount()
                  << ": Sourcecode warning: ';' as a toplevel declaration is deprecated."
                  << Endl();
        SetTokenResult(done,stay);
        return;
    }

    StdHandlingOfSyntaxError(i_sText);
}

void
PE_File::SpReturn_VarFunc()
{
     if (bWithinSingleExternC)
    {
        access_Env().CloseBlock();
         bWithinSingleExternC = false;
    }
}

void
PE_File::SpReturn_Template()
{
    access_Env().OpenTemplate( pSpuTemplate->Child().Result_Parameters() );
}

void
PE_File::On_std_namespace(const char * )
{
    pSpuNamespace->Push(done);
}

void
PE_File::On_std_ClassKey(const char * )
{
    pSpuVarFunc->Push(not_done);        // This is correct,
                                        //   classes are parsed via PE_Type.
}

void
PE_File::On_std_typedef(const char * )
{
    pSpuTypedef->Push(not_done);
}

void
PE_File::On_std_enum(const char * )
{
    pSpuVarFunc->Push(not_done);        // This is correct,
                                        //   enums are parsed via PE_Type.
}

void
PE_File::On_std_VarFunc(const char * )
{
    pSpuVarFunc->Push(not_done);
}

void
PE_File::On_std_template(const char * )
{
    pSpuTemplate->Push(done);
}

void
PE_File::On_std_extern(const char * )
{
    SetTokenResult(done, stay);
    pStati->SetCur(in_extern);
}

void
PE_File::On_std_using(const char * )
{
    pSpuUsing->Push(done);
}

void
PE_File::On_std_SwBracketRight(const char * )
{
    SetTokenResult(done,stay);
    access_Env().CloseBlock();
}

void
PE_File::On_std_DefineName(const char * )
{
    pSpuDefs->Push(not_done);
}

void
PE_File::On_std_MacroName(const char * )
{
    pSpuDefs->Push(not_done);
}

void
PE_File::On_in_extern_Constant(const char * )
{
    SetTokenResult(done,stay);
    pStati->SetCur(in_externC);

    access_Env().OpenExternC();
}

void
PE_File::On_in_extern_Ignore(const char * )
{
    SetTokenResult(not_done, stay);
    pStati->SetCur(std);
}

void
PE_File::On_in_externC_SwBracket_Left(const char * )
{
    SetTokenResult(done, stay);
    pStati->SetCur(std);
}

void
PE_File::On_in_externC_NoBlock(const char * )
{
    SetTokenResult(not_done, stay);
    pStati->SetCur(std);

    bWithinSingleExternC = true;
}

}   // namespace cpp
<|endoftext|>


<commit_before>///
/// @file  print.cpp
///
/// Copyright (C) 2015 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <print.hpp>
#include <primecount-internal.hpp>
#include <int128.hpp>
#include <stdint.h>

#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

namespace {

bool print_status_ = false;

bool print_variables_ = false;

}

namespace primecount {

void set_print_status(bool print_status)
{
  print_status_ = print_status;
}

void set_print_variables(bool print_variables)
{
  print_variables_ = print_variables;
}

bool print_result()
{
  return !print_variables();
}

bool print_status()
{
  return print_status_;
}

bool print_variables()
{
  return print_variables_;
}

void print(const string& str)
{
  if (print_status())
    cout << str << endl;
}

void print(maxint_t x, int64_t y, int64_t z, int64_t c, double alpha, int threads)
{
  if (print_status())
  {
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
    cout << "z = " << z << endl;
    cout << "c = " << c << endl;
    cout << "alpha = " << fixed << setprecision(3) << alpha << endl;
    cout << "threads = " << validate_threads(threads) << endl;
  }
}

void print(maxint_t x, int64_t y, int threads)
{
  if (print_variables())
  {
    maxint_t z = x / y;
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
    cout << "z = " << z << endl;
    cout << "alpha = " << fixed << setprecision(3) << get_alpha(x, y) << endl;
    cout << "threads = " << validate_threads(threads) << endl;
    cout << endl;
  }
}

void print(maxint_t x, int64_t y, int64_t c, int threads)
{
  if (print_variables())
  {
    maxint_t z = x / y;
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
    cout << "z = " << z << endl;
    cout << "c = " << c << endl;
    cout << "alpha = " << fixed << setprecision(3) << get_alpha(x, y) << endl;
    cout << "threads = " << validate_threads(threads) << endl;
    cout << endl;
  }
}

void print(const string& res_name, maxint_t res, double time)
{
  if (print_status())
  {
    cout << "\r" << string(40,' ') << "\r";
    cout << "Status: 100%" << endl;
    cout << res_name << " = " << res << endl;
    print_seconds(get_wtime() - time);
  }
}

void print_seconds(double seconds)
{
  if (print_status())
    cout << "Seconds: " << fixed << setprecision(3) << seconds << endl;
}

} // namespace
<commit_msg>Fix --time option<commit_after>///
/// @file  print.cpp
///
/// Copyright (C) 2015 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <print.hpp>
#include <primecount-internal.hpp>
#include <int128.hpp>
#include <stdint.h>

#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

namespace {

bool print_status_ = false;

bool print_variables_ = false;

}

namespace primecount {

void set_print_status(bool print_status)
{
  print_status_ = print_status;
}

void set_print_variables(bool print_variables)
{
  print_variables_ = print_variables;
}

bool print_result()
{
  return !print_variables();
}

bool print_status()
{
  return print_status_;
}

bool print_variables()
{
  return print_variables_;
}

void print(const string& str)
{
  if (print_status())
    cout << str << endl;
}

void print(maxint_t x, int64_t y, int64_t z, int64_t c, double alpha, int threads)
{
  if (print_status())
  {
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
    cout << "z = " << z << endl;
    cout << "c = " << c << endl;
    cout << "alpha = " << fixed << setprecision(3) << alpha << endl;
    cout << "threads = " << validate_threads(threads) << endl;
  }
}

void print(maxint_t x, int64_t y, int threads)
{
  if (print_variables())
  {
    maxint_t z = x / y;
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
    cout << "z = " << z << endl;
    cout << "alpha = " << fixed << setprecision(3) << get_alpha(x, y) << endl;
    cout << "threads = " << validate_threads(threads) << endl;
    cout << endl;
  }
}

void print(maxint_t x, int64_t y, int64_t c, int threads)
{
  if (print_variables())
  {
    maxint_t z = x / y;
    cout << "x = " << x << endl;
    cout << "y = " << y << endl;
    cout << "z = " << z << endl;
    cout << "c = " << c << endl;
    cout << "alpha = " << fixed << setprecision(3) << get_alpha(x, y) << endl;
    cout << "threads = " << validate_threads(threads) << endl;
    cout << endl;
  }
}

void print(const string& res_name, maxint_t res, double time)
{
  if (print_status())
  {
    cout << "\r" << string(40,' ') << "\r";
    cout << "Status: 100%" << endl;
    cout << res_name << " = " << res << endl;
    print_seconds(get_wtime() - time);
  }
}

void print_seconds(double seconds)
{
  cout << "Seconds: " << fixed << setprecision(3) << seconds << endl;
}

} // namespace
<|endoftext|>


<commit_before>#include <ptrace.hh>
#include <utils.hh>

#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sched.h>
#include <map>
#include <list>

using namespace coincident;

class Ptrace : public IPtrace
{
public:
	Ptrace()
	{
		m_breakpointId = 0;
	}

	bool readMemory(uint8_t *dst, void *start, size_t bytes)
	{
		memcpy(dst, start, bytes);

		return true;
	}

	bool readProcessMemory(uint8_t *dst, void *start, size_t bytes)
	{
		panic_if (bytes != sizeof(unsigned long),
				"Can only read a word at a time now");

		panic_if ((unsigned long)start & (sizeof(unsigned long) - 1),
				"Address must be aligned");

		unsigned long data = ptrace(PTRACE_PEEKTEXT, m_child, start, 0);
		memcpy(dst, &data, bytes);

		return true;
	}

	int forkAndAttach()
	{
		pid_t child, who;
		int status;
		int myCpu = coin_get_current_cpu();

		m_breakpointToAddrMap.clear();
		m_addrToBreakpointMap.clear();
		m_instructionMap.clear();

		child = fork();
		if (child < 0) {
			error("fork failed!\n");
			return -1;
		}

		if (child == 0) {
			int res;

			coin_set_cpu(getpid(), myCpu);

			/* We're in the child, set me as traced */
			res = ptrace(PTRACE_TRACEME, 0, 0, 0);
			if (res < 0) {
				error("Can't set me as ptraced");
				return -1;
			}
			::kill(getpid(), SIGSTOP);

			return 0;
		}

		coin_debug(INFO_MSG, "INFO: Forked child %d\n", child);

		/* Wait for the initial stop */
		who = waitpid(child, &status, 0);
		if (who < 0) {
			error("waitpid failed");
			return -1;
		}
		if (!WIFSTOPPED(status)) {
			error("Child hasn't stopped: %x\n", status);
			return -1;
		}
		ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK);

		m_child = child;

		return child;
	}

	int setBreakpoint(void *addr)
	{
		uint8_t data;
		int id;

		// There already?
		if (m_addrToBreakpointMap.find(addr) != m_addrToBreakpointMap.end())
			return m_addrToBreakpointMap[addr];

		if (readMemory(&data, addr, 1) == false)
			return -1;

		id = m_breakpointId++;

		m_breakpointToAddrMap[id] = addr;
		m_addrToBreakpointMap[addr] = id;
		m_instructionMap[addr] = data;

		// Set the breakpoint
		writeByte(m_child, addr, 0xcc);

		return id;
	}

	void clearAllBreakpoints()
	{
		for (breakpointToAddrMap_t::iterator it = m_breakpointToAddrMap.begin();
				it != m_breakpointToAddrMap.end(); it++)
			clearBreakpoint(it->first);

		m_addrToBreakpointMap.clear();
		m_addrToBreakpointMap.clear();
		m_instructionMap.clear();
	}

	bool clearBreakpoint(int id)
	{
		if (m_breakpointToAddrMap.find(id) == m_breakpointToAddrMap.end())
			return false;

		void *addr = m_breakpointToAddrMap[id];

		panic_if(m_addrToBreakpointMap.find(addr) == m_addrToBreakpointMap.end(),
				"Breakpoint id, but no addr-to-id map!");

		panic_if(m_instructionMap.find(addr) == m_instructionMap.end(),
				"Breakpoint found, but no instruction data at that point!");

		m_breakpointToAddrMap.erase(id);
		m_addrToBreakpointMap.erase(addr);

		// Clear the actual breakpoint instruction
		writeByte(m_child, addr, m_instructionMap[addr]);

		return true;
	}

	void saveRegisters(void *regs)
	{
		ptrace(PTRACE_GETREGS, m_child, 0, regs);
	}

	void loadRegisters(void *regs)
	{
		ptrace(PTRACE_SETREGS, m_child, 0, regs);
	}

	void saveFpRegisters(void *regs)
	{
		ptrace(PTRACE_GETFPXREGS, m_child, 0, regs);
	}

	void loadFpRegisters(void *regs)
	{
		ptrace(PTRACE_SETFPXREGS, m_child, 0, regs);
	}

	void singleStep()
	{
		struct user_regs_struct regs;
		void *pc;

		ptrace(PTRACE_GETREGS, m_child, 0, &regs);
		pc = getPcFromRegs(&regs);

		panic_if(m_instructionMap.find(pc) == m_instructionMap.end(),
				"Single-step over no breakpoint at %p", pc);

		writeByte(m_child, pc, m_instructionMap[pc]);

		// Step back one instruction
		regs.eip--;
		ptrace(PTRACE_SETREGS, m_child, 0, &regs);

		long res = ptrace(PTRACE_SINGLESTEP, m_child, 0, NULL);
		panic_if(res < 0,
				"ptrace singlestep failed!\n");
		writeByte(m_child, pc, 0xcc);
	}

	const PtraceEvent continueExecution()
	{
		PtraceEvent out;
		int status;
		int who;
		int res;

		// Assume error
		out.type = ptrace_error;
		out.eventId = -1;

		res = ptrace(PTRACE_CONT, m_child, 0, 0);
		if (res < 0)
			return out;

		who = waitpid(m_child, &status, __WALL);
		if (who == -1)
			return out;

		out.addr = getPc(m_child);

		// A signal?
		if (WIFSTOPPED(status)) {
			// A trap?
			if (WSTOPSIG(status) == SIGTRAP) {
				out.type = ptrace_breakpoint;
				out.eventId = -1;

				// Breakpoint id
				addrToBreakpointMap_t::iterator it = m_addrToBreakpointMap.find(out.addr);
				if (it != m_addrToBreakpointMap.end())
					out.eventId = it->second;

				return out;
			}
			// No, deliver it directly
			ptrace(PTRACE_CONT, who, 0, WSTOPSIG(status));
		}
		// Thread died?
		if (WIFSIGNALED(status) || WIFEXITED(status)) {
			if (who == m_child) {
				out.type = ptrace_exit;
				out.eventId = -1;
				return out;
			}
		}

		return out;
	}

	void kill()
	{
		ptrace(PTRACE_KILL, m_child, 0, 0);
		ptrace(PTRACE_DETACH, m_child, 0, 0);
	}

private:
	void *getPcFromRegs(struct user_regs_struct *regs)
	{
		return (void *)(regs->eip - 1);
	}

	void *getPc(int pid)
	{
		struct user_regs_struct regs;

		memset(&regs, 0, sizeof(regs));
		ptrace(PTRACE_GETREGS, pid, 0, &regs);

		return getPcFromRegs(&regs);
	}

	// Assume x86 with single-byte breakpoint instructions for now...
	void writeByte(int pid, void *addr, uint8_t byte)
	{
		unsigned long aligned = getAligned((unsigned long)addr);
		unsigned long offs = (unsigned long)addr - aligned;
		unsigned long shift = 8 * offs;
		unsigned long data = byte;
		unsigned long old_data;
		unsigned long val;

		old_data = ptrace(PTRACE_PEEKTEXT, pid, aligned, 0);
		val = (old_data & ~(0xffULL << shift)) | (data << shift);
		ptrace(PTRACE_POKETEXT, pid, aligned, val);
	}

	unsigned long getAligned(unsigned long addr)
	{
		return (addr / sizeof(unsigned long)) * sizeof(unsigned long);
	}

	typedef std::map<int, void *> breakpointToAddrMap_t;
	typedef std::map<void *, int> addrToBreakpointMap_t;
	typedef std::map<void *, uint8_t> instructionMap_t;

	int m_breakpointId;

	instructionMap_t m_instructionMap;
	breakpointToAddrMap_t m_breakpointToAddrMap;
	addrToBreakpointMap_t m_addrToBreakpointMap;

	pid_t m_child;
};

IPtrace &IPtrace::getInstance()
{
	static Ptrace *instance;

	if (!instance)
		instance = new Ptrace();

	return *instance;
}
<commit_msg>ptrace: Trace signals to the process<commit_after>#include <ptrace.hh>
#include <utils.hh>

#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sched.h>
#include <map>
#include <list>

using namespace coincident;

class Ptrace : public IPtrace
{
public:
	Ptrace()
	{
		m_breakpointId = 0;
	}

	bool readMemory(uint8_t *dst, void *start, size_t bytes)
	{
		memcpy(dst, start, bytes);

		return true;
	}

	bool readProcessMemory(uint8_t *dst, void *start, size_t bytes)
	{
		panic_if (bytes != sizeof(unsigned long),
				"Can only read a word at a time now");

		panic_if ((unsigned long)start & (sizeof(unsigned long) - 1),
				"Address must be aligned");

		unsigned long data = ptrace(PTRACE_PEEKTEXT, m_child, start, 0);
		memcpy(dst, &data, bytes);

		return true;
	}

	int forkAndAttach()
	{
		pid_t child, who;
		int status;
		int myCpu = coin_get_current_cpu();

		m_breakpointToAddrMap.clear();
		m_addrToBreakpointMap.clear();
		m_instructionMap.clear();

		child = fork();
		if (child < 0) {
			error("fork failed!\n");
			return -1;
		}

		if (child == 0) {
			int res;

			coin_set_cpu(getpid(), myCpu);

			/* We're in the child, set me as traced */
			res = ptrace(PTRACE_TRACEME, 0, 0, 0);
			if (res < 0) {
				error("Can't set me as ptraced");
				return -1;
			}
			::kill(getpid(), SIGSTOP);

			return 0;
		}

		coin_debug(INFO_MSG, "INFO: Forked child %d\n", child);

		/* Wait for the initial stop */
		who = waitpid(child, &status, 0);
		if (who < 0) {
			error("waitpid failed");
			return -1;
		}
		if (!WIFSTOPPED(status)) {
			error("Child hasn't stopped: %x\n", status);
			return -1;
		}
		ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK);

		m_child = child;

		return child;
	}

	int setBreakpoint(void *addr)
	{
		uint8_t data;
		int id;

		// There already?
		if (m_addrToBreakpointMap.find(addr) != m_addrToBreakpointMap.end())
			return m_addrToBreakpointMap[addr];

		if (readMemory(&data, addr, 1) == false)
			return -1;

		id = m_breakpointId++;

		m_breakpointToAddrMap[id] = addr;
		m_addrToBreakpointMap[addr] = id;
		m_instructionMap[addr] = data;

		// Set the breakpoint
		writeByte(m_child, addr, 0xcc);

		return id;
	}

	void clearAllBreakpoints()
	{
		for (breakpointToAddrMap_t::iterator it = m_breakpointToAddrMap.begin();
				it != m_breakpointToAddrMap.end(); it++)
			clearBreakpoint(it->first);

		m_addrToBreakpointMap.clear();
		m_addrToBreakpointMap.clear();
		m_instructionMap.clear();
	}

	bool clearBreakpoint(int id)
	{
		if (m_breakpointToAddrMap.find(id) == m_breakpointToAddrMap.end())
			return false;

		void *addr = m_breakpointToAddrMap[id];

		panic_if(m_addrToBreakpointMap.find(addr) == m_addrToBreakpointMap.end(),
				"Breakpoint id, but no addr-to-id map!");

		panic_if(m_instructionMap.find(addr) == m_instructionMap.end(),
				"Breakpoint found, but no instruction data at that point!");

		m_breakpointToAddrMap.erase(id);
		m_addrToBreakpointMap.erase(addr);

		// Clear the actual breakpoint instruction
		writeByte(m_child, addr, m_instructionMap[addr]);

		return true;
	}

	void saveRegisters(void *regs)
	{
		ptrace(PTRACE_GETREGS, m_child, 0, regs);
	}

	void loadRegisters(void *regs)
	{
		ptrace(PTRACE_SETREGS, m_child, 0, regs);
	}

	void saveFpRegisters(void *regs)
	{
		ptrace(PTRACE_GETFPXREGS, m_child, 0, regs);
	}

	void loadFpRegisters(void *regs)
	{
		ptrace(PTRACE_SETFPXREGS, m_child, 0, regs);
	}

	void singleStep()
	{
		struct user_regs_struct regs;
		void *pc;

		ptrace(PTRACE_GETREGS, m_child, 0, &regs);
		pc = getPcFromRegs(&regs);

		panic_if(m_instructionMap.find(pc) == m_instructionMap.end(),
				"Single-step over no breakpoint at %p", pc);

		writeByte(m_child, pc, m_instructionMap[pc]);

		// Step back one instruction
		regs.eip--;
		ptrace(PTRACE_SETREGS, m_child, 0, &regs);

		long res = ptrace(PTRACE_SINGLESTEP, m_child, 0, NULL);
		panic_if(res < 0,
				"ptrace singlestep failed!\n");
		writeByte(m_child, pc, 0xcc);
	}

	const PtraceEvent continueExecution()
	{
		PtraceEvent out;
		int status;
		int who;
		int res;

		// Assume error
		out.type = ptrace_error;
		out.eventId = -1;

		res = ptrace(PTRACE_CONT, m_child, 0, 0);
		if (res < 0)
			return out;

		who = waitpid(m_child, &status, __WALL);
		if (who == -1)
			return out;

		out.addr = getPc(m_child);

		// A signal?
		if (WIFSTOPPED(status)) {
			// A trap?
			if (WSTOPSIG(status) == SIGTRAP) {
				out.type = ptrace_breakpoint;
				out.eventId = -1;

				// Breakpoint id
				addrToBreakpointMap_t::iterator it = m_addrToBreakpointMap.find(out.addr);
				if (it != m_addrToBreakpointMap.end())
					out.eventId = it->second;

				return out;
			}
			// No, deliver it directly
			coin_debug(PTRACE_MSG, "PT signal %d at %p\n",
					WSTOPSIG(status), out.addr);
			ptrace(PTRACE_CONT, who, 0, WSTOPSIG(status));
		}
		// Thread died?
		if (WIFSIGNALED(status) || WIFEXITED(status)) {
			if (who == m_child) {
				out.type = ptrace_exit;
				out.eventId = -1;
				return out;
			}
		}

		return out;
	}

	void kill()
	{
		ptrace(PTRACE_KILL, m_child, 0, 0);
		ptrace(PTRACE_DETACH, m_child, 0, 0);
	}

private:
	void *getPcFromRegs(struct user_regs_struct *regs)
	{
		return (void *)(regs->eip - 1);
	}

	void *getPc(int pid)
	{
		struct user_regs_struct regs;

		memset(&regs, 0, sizeof(regs));
		ptrace(PTRACE_GETREGS, pid, 0, &regs);

		return getPcFromRegs(&regs);
	}

	// Assume x86 with single-byte breakpoint instructions for now...
	void writeByte(int pid, void *addr, uint8_t byte)
	{
		unsigned long aligned = getAligned((unsigned long)addr);
		unsigned long offs = (unsigned long)addr - aligned;
		unsigned long shift = 8 * offs;
		unsigned long data = byte;
		unsigned long old_data;
		unsigned long val;

		old_data = ptrace(PTRACE_PEEKTEXT, pid, aligned, 0);
		val = (old_data & ~(0xffULL << shift)) | (data << shift);
		ptrace(PTRACE_POKETEXT, pid, aligned, val);
	}

	unsigned long getAligned(unsigned long addr)
	{
		return (addr / sizeof(unsigned long)) * sizeof(unsigned long);
	}

	typedef std::map<int, void *> breakpointToAddrMap_t;
	typedef std::map<void *, int> addrToBreakpointMap_t;
	typedef std::map<void *, uint8_t> instructionMap_t;

	int m_breakpointId;

	instructionMap_t m_instructionMap;
	breakpointToAddrMap_t m_breakpointToAddrMap;
	addrToBreakpointMap_t m_addrToBreakpointMap;

	pid_t m_child;
};

IPtrace &IPtrace::getInstance()
{
	static Ptrace *instance;

	if (!instance)
		instance = new Ptrace();

	return *instance;
}
<|endoftext|>


<commit_before>/*=========================================================================

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

// It is important to use OrientedImages
#include "itkOrientedImage.h"
#include "itkImageFileReader.h"
#include "itkCastImageFilter.h"
#include "itkImageFileWriter.h"

// The following three should be used in every CLI application
#include "tubeCLIFilterWatcher.h"
#include "itkTimeProbesCollectorBase.h"
#include "tubeCLIProgressReporter.h"

// Includes specific to this CLI application
#include "itkRecursiveGaussianImageFilter.h"

// Must do a forward declaraction of DoIt before including
// tubeCLIHelperFunctions
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] );

// Must include CLP before including tubeCLIHleperFunctions
#include "SampleCLIApplicationCLP.h"

// Includes tube::ParseArgsAndCallDoIt function
#include "tubeCLIHelperFunctions.h"

// Your code should be within the DoIt function...
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] )
  {
  PARSE_ARGS;

  // The timeCollector is used to perform basic profiling of the components
  //   of your algorithm.
  itk::TimeProbesCollectorBase timeCollector;

  // CLIProgressReporter is used to communicate progress with the Slicer GUI
  tube::CLIProgressReporter    progressReporter( "SampleCLIApplication",
                                                 CLPProcessInformation );
  progressReporter.Start();

  typedef float                                         PixelType;
  typedef itk::Image< PixelType,  dimensionT >          ImageType;
  typedef itk::ImageFileReader< ImageType >             ReaderType;

  timeCollector.Start("Load data");
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputVolume.c_str() );
  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Load data");
  double progress = 0.1;
  progressReporter.Report( progress );

  typename ImageType::Pointer curImage = reader->GetOutput();

  if( gaussianBlurStdDev > 0 )
    {
    timeCollector.Start("Gaussian Blur");

    typedef itk::RecursiveGaussianImageFilter< ImageType, ImageType > FilterType;
    typename FilterType::Pointer filter = FilterType::New();

    // Progress per iteration
    double progressFraction = 0.8/dimensionT;

    for(unsigned int i=0; i<dimensionT; i++)
      {
      filter = FilterType::New();
      filter->SetInput( curImage );
      filter->SetNormalizeAcrossScale( true );
      filter->SetSigma( gaussianBlurStdDev );

      filter->SetOrder(
               itk::RecursiveGaussianImageFilter<ImageType>::ZeroOrder );
      filter->SetDirection( i );
      tube::CLIFilterWatcher( filter,
                              "Blur Filter 1D",
                              CLPProcessInformation,
                              progressFraction,
                              progress );

      filter->Update();
      curImage = filter->GetOutput();
      }

    timeCollector.Stop("Gaussian Blur");
    }

  typedef itk::ImageFileWriter< ImageType  >   ImageWriterType;

  timeCollector.Start("Save data");
  typename ImageWriterType::Pointer writer = ImageWriterType::New();
  writer->SetFileName( outputVolume.c_str() );
  writer->SetInput( curImage );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "Exception caught: " << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Save data");
  progress = 1.0;
  progressReporter.Report( progress );

  return EXIT_SUCCESS;
  }

// Main
int main( int argc, char **argv )
  {
  PARSE_ARGS;

  // You may need to update this line if, in the project's .xml CLI file,
  //   you change the variable name for the inputVolume.
  return tube::ParseArgsAndCallDoIt( inputVolume, argc, argv );
  }

<commit_msg>STYLE: Removed unused filters that had been included.  Added call to timeProbe.Report() at end.<commit_after>/*=========================================================================

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

// It is important to use OrientedImages
#include "itkOrientedImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

// The following three should be used in every CLI application
#include "tubeCLIFilterWatcher.h"
#include "tubeCLIProgressReporter.h"
#include "itkTimeProbesCollectorBase.h"

// Includes specific to this CLI application
#include "itkRecursiveGaussianImageFilter.h"

// Must do a forward declaraction of DoIt before including
// tubeCLIHelperFunctions
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] );

// Must include CLP before including tubeCLIHleperFunctions
#include "SampleCLIApplicationCLP.h"

// Includes tube::ParseArgsAndCallDoIt function
#include "tubeCLIHelperFunctions.h"

// Your code should be within the DoIt function...
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] )
  {
  PARSE_ARGS;

  // The timeCollector is used to perform basic profiling of the components
  //   of your algorithm.
  itk::TimeProbesCollectorBase timeCollector;

  // CLIProgressReporter is used to communicate progress with the Slicer GUI
  tube::CLIProgressReporter    progressReporter( "SampleCLIApplication",
                                                 CLPProcessInformation );
  progressReporter.Start();

  typedef float                                         PixelType;
  typedef itk::Image< PixelType,  dimensionT >          ImageType;
  typedef itk::ImageFileReader< ImageType >             ReaderType;

  timeCollector.Start("Load data");
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputVolume.c_str() );
  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Load data");
  double progress = 0.1;
  progressReporter.Report( progress );

  typename ImageType::Pointer curImage = reader->GetOutput();

  if( gaussianBlurStdDev > 0 )
    {
    timeCollector.Start("Gaussian Blur");

    typedef itk::RecursiveGaussianImageFilter< ImageType, ImageType > FilterType;
    typename FilterType::Pointer filter;

    // Progress per iteration
    double progressFraction = 0.8/dimensionT;

    for(unsigned int i=0; i<dimensionT; i++)
      {
      filter = FilterType::New();
      filter->SetInput( curImage );
      filter->SetNormalizeAcrossScale( true );
      filter->SetSigma( gaussianBlurStdDev );

      filter->SetOrder(
               itk::RecursiveGaussianImageFilter<ImageType>::ZeroOrder );
      filter->SetDirection( i );
      tube::CLIFilterWatcher( filter,
                              "Blur Filter 1D",
                              CLPProcessInformation,
                              progressFraction,
                              progress );

      filter->Update();
      curImage = filter->GetOutput();
      }

    timeCollector.Stop("Gaussian Blur");
    }

  typedef itk::ImageFileWriter< ImageType  >   ImageWriterType;

  timeCollector.Start("Save data");
  typename ImageWriterType::Pointer writer = ImageWriterType::New();
  writer->SetFileName( outputVolume.c_str() );
  writer->SetInput( curImage );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "Exception caught: " << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Save data");
  progress = 1.0;
  progressReporter.Report( progress );

  timeCollector.Report();

  return EXIT_SUCCESS;
  }

// Main
int main( int argc, char **argv )
  {
  PARSE_ARGS;

  // You may need to update this line if, in the project's .xml CLI file,
  //   you change the variable name for the inputVolume.
  return tube::ParseArgsAndCallDoIt( inputVolume, argc, argv );
  }

<|endoftext|>


<commit_before>/*=========================================================================

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

// It is important to use OrientedImages
#include "itkOrientedImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

// The following three should be used in every CLI application
#include "tubeCLIFilterWatcher.h"
#include "tubeCLIProgressReporter.h"
#include "itkTimeProbesCollectorBase.h"

// Includes specific to this CLI application
#include "itkRecursiveGaussianImageFilter.h"

// Must do a forward declaraction of DoIt before including
// tubeCLIHelperFunctions
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] );

// Must include CLP before including tubeCLIHleperFunctions
#include "SampleCLIApplicationCLP.h"

// Includes tube::ParseArgsAndCallDoIt function
#include "tubeCLIHelperFunctions.h"

// Your code should be within the DoIt function...
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] )
  {
  PARSE_ARGS;

  // The timeCollector is used to perform basic profiling of the components
  //   of your algorithm.
  itk::TimeProbesCollectorBase timeCollector;

  // CLIProgressReporter is used to communicate progress with the Slicer GUI
  tube::CLIProgressReporter    progressReporter( "SampleCLIApplication",
                                                 CLPProcessInformation );
  progressReporter.Start();

  typedef float                                         PixelType;
  typedef itk::Image< PixelType,  dimensionT >          ImageType;
  typedef itk::ImageFileReader< ImageType >             ReaderType;

  timeCollector.Start("Load data");
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputVolume.c_str() );
  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Load data");
  double progress = 0.1;
  progressReporter.Report( progress );

  typename ImageType::Pointer curImage = reader->GetOutput();

  if( gaussianBlurStdDev > 0 )
    {
    timeCollector.Start("Gaussian Blur");

    typedef itk::RecursiveGaussianImageFilter< ImageType, ImageType > FilterType;
    typename FilterType::Pointer filter;

    // Progress per iteration
    double progressFraction = 0.8/dimensionT;

    for(unsigned int i=0; i<dimensionT; i++)
      {
      filter = FilterType::New();
      filter->SetInput( curImage );
      filter->SetNormalizeAcrossScale( true );
      filter->SetSigma( gaussianBlurStdDev );

      filter->SetOrder(
               itk::RecursiveGaussianImageFilter<ImageType>::ZeroOrder );
      filter->SetDirection( i );
      tube::CLIFilterWatcher( filter,
                              "Blur Filter 1D",
                              CLPProcessInformation,
                              progressFraction,
                              progress );

      filter->Update();
      curImage = filter->GetOutput();
      }

    timeCollector.Stop("Gaussian Blur");
    }

  typedef itk::ImageFileWriter< ImageType  >   ImageWriterType;

  timeCollector.Start("Save data");
  typename ImageWriterType::Pointer writer = ImageWriterType::New();
  writer->SetFileName( outputVolume.c_str() );
  writer->SetInput( curImage );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "Exception caught: " << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Save data");
  progress = 1.0;
  progressReporter.Report( progress );

  timeCollector.Report();

  return EXIT_SUCCESS;
  }

// Main
int main( int argc, char **argv )
  {
  PARSE_ARGS;

  // You may need to update this line if, in the project's .xml CLI file,
  //   you change the variable name for the inputVolume.
  return tube::ParseArgsAndCallDoIt( inputVolume, argc, argv );
  }

<commit_msg>STYLE: Fixed style issues.<commit_after>/*=========================================================================

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

=========================================================================*/

#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

// It is important to use OrientedImages
#include "itkOrientedImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

// The following three should be used in every CLI application
#include "tubeCLIFilterWatcher.h"
#include "tubeCLIProgressReporter.h"
#include "itkTimeProbesCollectorBase.h"

// Includes specific to this CLI application
#include "itkRecursiveGaussianImageFilter.h"

// Must do a forward declaraction of DoIt before including
// tubeCLIHelperFunctions
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] );

// Must include CLP before including tubeCLIHleperFunctions
#include "SampleCLIApplicationCLP.h"

// Includes tube::ParseArgsAndCallDoIt function
#include "tubeCLIHelperFunctions.h"

// Your code should be within the DoIt function...
template< class pixelT, unsigned int dimensionT >
int DoIt( int argc, char * argv[] )
{
  PARSE_ARGS;

  // The timeCollector is used to perform basic profiling of the components
  //   of your algorithm.
  itk::TimeProbesCollectorBase timeCollector;

  // CLIProgressReporter is used to communicate progress with the Slicer GUI
  tube::CLIProgressReporter    progressReporter( "SampleCLIApplication",
                                                 CLPProcessInformation );
  progressReporter.Start();

  typedef float                                         PixelType;
  typedef itk::Image< PixelType,  dimensionT >          ImageType;
  typedef itk::ImageFileReader< ImageType >             ReaderType;

  timeCollector.Start("Load data");
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( inputVolume.c_str() );
  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "ExceptionObject caught !" << std::endl;
    std::cerr << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Load data");
  double progress = 0.1;
  progressReporter.Report( progress );

  typename ImageType::Pointer curImage = reader->GetOutput();

  if( gaussianBlurStdDev > 0 )
    {
    timeCollector.Start("Gaussian Blur");

    typedef itk::RecursiveGaussianImageFilter< ImageType, ImageType > FilterType;
    typename FilterType::Pointer filter;

    // Progress per iteration
    double progressFraction = 0.8/dimensionT;

    for(unsigned int i=0; i<dimensionT; i++)
      {
      filter = FilterType::New();
      filter->SetInput( curImage );
      filter->SetNormalizeAcrossScale( true );
      filter->SetSigma( gaussianBlurStdDev );

      filter->SetOrder(
               itk::RecursiveGaussianImageFilter<ImageType>::ZeroOrder );
      filter->SetDirection( i );
      tube::CLIFilterWatcher( filter,
                              "Blur Filter 1D",
                              CLPProcessInformation,
                              progressFraction,
                              progress );

      filter->Update();
      curImage = filter->GetOutput();
      }

    timeCollector.Stop("Gaussian Blur");
    }

  typedef itk::ImageFileWriter< ImageType  >   ImageWriterType;

  timeCollector.Start("Save data");
  typename ImageWriterType::Pointer writer = ImageWriterType::New();
  writer->SetFileName( outputVolume.c_str() );
  writer->SetInput( curImage );
  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    std::cerr << "Exception caught: " << err << std::endl;
    return EXIT_FAILURE;
    }
  timeCollector.Stop("Save data");
  progress = 1.0;
  progressReporter.Report( progress );

  timeCollector.Report();

  return EXIT_SUCCESS;
}

// Main
int main( int argc, char **argv )
{
  PARSE_ARGS;

  // You may need to update this line if, in the project's .xml CLI file,
  //   you change the variable name for the inputVolume.
  return tube::ParseArgsAndCallDoIt( inputVolume, argc, argv );
}

<|endoftext|>


<commit_before>//Copyright (c) 2019 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <gtest/gtest.h>

#include "../src/infill.h"
#include "ReadTestPolygons.h"

namespace cura
{
    template<typename ... Ts>
    std::string makeName(const std::string& format_string, Ts ... args)
    {
        constexpr int buff_size = 1024;
        char buff[buff_size];
        std::snprintf(buff, buff_size, format_string.c_str(), args...);
        return std::string(buff);
    }

    coord_t getPatternMultiplier(const EFillMethod& pattern)
    {
        switch (pattern)
        {
        case EFillMethod::GRID: // fallthrough
        case EFillMethod::TETRAHEDRAL: // fallthrough
        case EFillMethod::QUARTER_CUBIC:
            return 2;
        case EFillMethod::TRIANGLES: // fallthrough
        case EFillMethod::TRIHEXAGON: // fallthrough
        case EFillMethod::CUBIC: // fallthrough
        case EFillMethod::CUBICSUBDIV:
            return 3;
        default:
            return 1;
        }
    }

    struct InfillParameters
    {
    public:
        // Actual infill parameters:
        EFillMethod pattern;
        bool zig_zagify;
        bool connect_polygons;
        coord_t line_distance;

        std::string name;

        InfillParameters(const EFillMethod& pattern, const bool& zig_zagify, const bool& connect_polygons, const coord_t& line_distance) :
            pattern(pattern),
            zig_zagify(zig_zagify),
            connect_polygons(connect_polygons),
            line_distance(line_distance)
        {
            name = makeName("InfillParameters_%d_%d_%d_%lld", (int)pattern, (int)zig_zagify, (int)connect_polygons, line_distance);
        }
    };

    class InfillTestParameters
    {
    public:
        bool valid;  // <-- if the file isn't read (or anything else goes wrong with the setup) we can communicate it to the tests
        std::string fail_reason;
        size_t test_polygon_id;

        // Parameters used to generate the infill:
        InfillParameters params;
        Polygons outline_polygons;

        // Resulting infill:
        Polygons result_lines;
        Polygons result_polygons;

        std::string name;

        InfillTestParameters() :
            valid(false),
            fail_reason("Read of file with test polygons failed (see generateInfillTests), can't continue tests."),
            test_polygon_id(-1),
            params(InfillParameters(EFillMethod::NONE, false, false, 0)),
            outline_polygons(Polygons()),
            result_lines(Polygons()),
            result_polygons(Polygons()),
            name("UNNAMED")
        {
        }

        InfillTestParameters(const InfillParameters& params, const size_t& test_polygon_id, const Polygons& outline_polygons, const Polygons& result_lines, const Polygons& result_polygons) :
            valid(true),
            fail_reason("__"),
            test_polygon_id(test_polygon_id),
            params(params),
            outline_polygons(outline_polygons),
            result_lines(result_lines),
            result_polygons(result_polygons)
        {
            name = makeName("InfillTestParameters_P%d_Z%d_C%d_L%lld__%lld", (int)params.pattern, (int)params.zig_zagify, (int)params.connect_polygons, params.line_distance, test_polygon_id);
        }

        friend std::ostream& operator<<(std::ostream& os, const InfillTestParameters& params)
        {
            return os << params.name << "(" << (params.valid ? std::string("input OK") : params.fail_reason) << ")";
        }
    };

    constexpr coord_t outline_offset = 0;
    constexpr coord_t infill_line_width = 350;
    constexpr coord_t infill_overlap = 0;
    constexpr size_t infill_multiplier = 1;
    const AngleDegrees fill_angle = 0.;
    constexpr coord_t z = 100; // Future improvement: Also take an uneven layer, so we get the alternate.
    constexpr coord_t shift = 0;
	const std::vector<std::string> polygon_filenames =
		{
			"../tests/resources/polygon_concave.txt",
			"../tests/resources/polygon_concave_hole.txt",
			"../tests/resources/polygon_square.txt",
			"../tests/resources/polygon_square_hole.txt",
			"../tests/resources/polygon_triangle.txt",
			"../tests/resources/polygon_two_squares.txt",
		};

    InfillTestParameters generateInfillToTest(const InfillParameters& params, const size_t& test_polygon_id, const Polygons& outline_polygons)
    {
        const EFillMethod pattern = params.pattern;
        const bool zig_zagify = params.zig_zagify;
        const bool connect_polygons = params.connect_polygons;
        const coord_t line_distance = params.line_distance;

        Infill infill
        (
            pattern,
            zig_zagify,
            connect_polygons,
            outline_polygons,
            outline_offset,
            infill_line_width,
            line_distance,
            infill_overlap,
            infill_multiplier,
            fill_angle,
            z,
            shift
        ); // There are some optional parameters, but these will do for now (future improvement?).

        Polygons result_polygons;
        Polygons result_lines;
        infill.generate(result_polygons, result_lines, nullptr, nullptr);

        InfillTestParameters result = InfillTestParameters(params, test_polygon_id, outline_polygons, result_lines, result_polygons);
        return result;
    }

    std::vector<InfillTestParameters> generateInfillTests()
    {
        std::vector<Polygons> shapes;
        if (!readTestPolygons(polygon_filenames, shapes))
        {
            return { InfillTestParameters() };  // return an invalid singleton, that'll trip up the 'file read' assertion in the TEST_P's
        }

        std::vector<EFillMethod> methods;
        std::vector<EFillMethod> skip_methods = { EFillMethod::CROSS, EFillMethod::CROSS_3D, EFillMethod::CUBICSUBDIV }; //TODO: Support for testing infill that needs the sierpinski-provider!
        for (int i_method = 0; i_method < static_cast<int>(EFillMethod::NONE); ++i_method)
        {
            const EFillMethod method = static_cast<EFillMethod>(i_method);
            if (std::find(skip_methods.begin(), skip_methods.end(), method) == skip_methods.end()) // Only use if not in skipped.
            {
                methods.push_back(method);
            }
        }

        std::vector<coord_t> line_distances = { 400, 600, 800, 1200 }; // TODO?: Gyroid fails the 'fill less than 100% of area available' with values close to the line width, like 350.

        std::vector<InfillTestParameters> parameters_list;
        size_t test_polygon_id = 0;
        for (const Polygons& polygons : shapes)
        {
            for (const EFillMethod& method : methods)
            {
                for (const coord_t& line_distance : line_distances)
                {
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, false, false, line_distance), test_polygon_id, polygons));
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, false, true, line_distance), test_polygon_id, polygons));
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, true, false, line_distance), test_polygon_id, polygons));
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, true, true, line_distance), test_polygon_id, polygons));
                }
            }
            ++test_polygon_id;
        }

        return parameters_list;
    }

    class InfillTest : public testing::TestWithParam<InfillTestParameters> {};

    INSTANTIATE_TEST_CASE_P(InfillTestcases, InfillTest, testing::ValuesIn(generateInfillTests()), [](testing::TestParamInfo<InfillTestParameters> info) { return info.param.name; });

    TEST_P(InfillTest, TestInfillSanity)
    {
        InfillTestParameters params = GetParam();
        ASSERT_TRUE(params.valid) << params.fail_reason;
        ASSERT_FALSE(params.result_polygons.empty() && params.result_lines.empty()) << "Infill should have been generated.";

        const double available_area = std::abs(params.outline_polygons.area());
        const double expected_infill_area = (available_area * infill_line_width) / params.params.line_distance;
        const double total_infill_area = (params.result_polygons.polygonLength() + params.result_lines.polyLineLength()) * infill_line_width / getPatternMultiplier(params.params.pattern);
        ASSERT_GT((coord_t)available_area, (coord_t)total_infill_area) << "Infill area should allways be less than the total area available.";
        ASSERT_NEAR((coord_t)total_infill_area, (coord_t)expected_infill_area, (coord_t)(total_infill_area * 0.15)) << "Infill area should be within 15% of expected size."; // TODO: 10 ~ 20% is actually quite bad?

        const Polygons padded_shape_outline = params.outline_polygons.offset(infill_line_width / 2);
        ASSERT_EQ(padded_shape_outline.intersectionPolyLines(params.result_lines).polyLineLength(), params.result_lines.polyLineLength()) << "Infill (lines) should not be outside target polygon.";
        ASSERT_EQ(params.result_polygons.difference(padded_shape_outline).area(), 0) << "Infill (polys) should not be outside target polygon.";
    }

} //namespace cura
<commit_msg>Make infill test code more self-documenting.<commit_after>//Copyright (c) 2019 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <gtest/gtest.h>

#include "../src/infill.h"
#include "ReadTestPolygons.h"

namespace cura
{
    template<typename ... Ts>
    std::string makeName(const std::string& format_string, Ts ... args)
    {
        constexpr int buff_size = 1024;
        char buff[buff_size];
        std::snprintf(buff, buff_size, format_string.c_str(), args...);
        return std::string(buff);
    }

    coord_t getPatternMultiplier(const EFillMethod& pattern)
    {
        switch (pattern)
        {
        case EFillMethod::GRID: // fallthrough
        case EFillMethod::TETRAHEDRAL: // fallthrough
        case EFillMethod::QUARTER_CUBIC:
            return 2;
        case EFillMethod::TRIANGLES: // fallthrough
        case EFillMethod::TRIHEXAGON: // fallthrough
        case EFillMethod::CUBIC: // fallthrough
        case EFillMethod::CUBICSUBDIV:
            return 3;
        default:
            return 1;
        }
    }

    struct InfillParameters
    {
    public:
        // Actual infill parameters:
        EFillMethod pattern;
        bool zig_zagify;
        bool connect_polygons;
        coord_t line_distance;

        std::string name;

        InfillParameters(const EFillMethod& pattern, const bool& zig_zagify, const bool& connect_polygons, const coord_t& line_distance) :
            pattern(pattern),
            zig_zagify(zig_zagify),
            connect_polygons(connect_polygons),
            line_distance(line_distance)
        {
            name = makeName("InfillParameters_%d_%d_%d_%lld", (int)pattern, (int)zig_zagify, (int)connect_polygons, line_distance);
        }
    };

    class InfillTestParameters
    {
    public:
        bool valid;  // <-- if the file isn't read (or anything else goes wrong with the setup) we can communicate it to the tests
        std::string fail_reason;
        size_t test_polygon_id;

        // Parameters used to generate the infill:
        InfillParameters params;
        Polygons outline_polygons;

        // Resulting infill:
        Polygons result_lines;
        Polygons result_polygons;

        std::string name;

        InfillTestParameters() :
            valid(false),
            fail_reason("Read of file with test polygons failed (see generateInfillTests), can't continue tests."),
            test_polygon_id(-1),
            params(InfillParameters(EFillMethod::NONE, false, false, 0)),
            outline_polygons(Polygons()),
            result_lines(Polygons()),
            result_polygons(Polygons()),
            name("UNNAMED")
        {
        }

        InfillTestParameters(const InfillParameters& params, const size_t& test_polygon_id, const Polygons& outline_polygons, const Polygons& result_lines, const Polygons& result_polygons) :
            valid(true),
            fail_reason("__"),
            test_polygon_id(test_polygon_id),
            params(params),
            outline_polygons(outline_polygons),
            result_lines(result_lines),
            result_polygons(result_polygons)
        {
            name = makeName("InfillTestParameters_P%d_Z%d_C%d_L%lld__%lld", (int)params.pattern, (int)params.zig_zagify, (int)params.connect_polygons, params.line_distance, test_polygon_id);
        }

        friend std::ostream& operator<<(std::ostream& os, const InfillTestParameters& params)
        {
            return os << params.name << "(" << (params.valid ? std::string("input OK") : params.fail_reason) << ")";
        }
    };

    constexpr coord_t outline_offset = 0;
    constexpr coord_t infill_line_width = 350;
    constexpr coord_t infill_overlap = 0;
    constexpr size_t infill_multiplier = 1;
    const AngleDegrees fill_angle = 0.;
    constexpr coord_t z = 100; // Future improvement: Also take an uneven layer, so we get the alternate.
    constexpr coord_t shift = 0;
	const std::vector<std::string> polygon_filenames =
		{
			"../tests/resources/polygon_concave.txt",
			"../tests/resources/polygon_concave_hole.txt",
			"../tests/resources/polygon_square.txt",
			"../tests/resources/polygon_square_hole.txt",
			"../tests/resources/polygon_triangle.txt",
			"../tests/resources/polygon_two_squares.txt",
		};

    InfillTestParameters generateInfillToTest(const InfillParameters& params, const size_t& test_polygon_id, const Polygons& outline_polygons)
    {
        const EFillMethod pattern = params.pattern;
        const bool zig_zagify = params.zig_zagify;
        const bool connect_polygons = params.connect_polygons;
        const coord_t line_distance = params.line_distance;

        Infill infill
        (
            pattern,
            zig_zagify,
            connect_polygons,
            outline_polygons,
            outline_offset,
            infill_line_width,
            line_distance,
            infill_overlap,
            infill_multiplier,
            fill_angle,
            z,
            shift
        ); // There are some optional parameters, but these will do for now (future improvement?).

        Polygons result_polygons;
        Polygons result_lines;
        infill.generate(result_polygons, result_lines, nullptr, nullptr);

        InfillTestParameters result = InfillTestParameters(params, test_polygon_id, outline_polygons, result_lines, result_polygons);
        return result;
    }

    std::vector<InfillTestParameters> generateInfillTests()
    {
		constexpr bool do_zig_zaggify = true;
		constexpr bool dont_zig_zaggify = false;
		constexpr bool do_connect_polygons = true;
		constexpr bool dont_connect_polygons = false;

        std::vector<Polygons> shapes;
        if (!readTestPolygons(polygon_filenames, shapes))
        {
            return { InfillTestParameters() };  // return an invalid singleton, that'll trip up the 'file read' assertion in the TEST_P's
        }

        std::vector<EFillMethod> methods;
        std::vector<EFillMethod> skip_methods = { EFillMethod::CROSS, EFillMethod::CROSS_3D, EFillMethod::CUBICSUBDIV }; //TODO: Support for testing infill that needs the sierpinski-provider!
        for (int i_method = 0; i_method < static_cast<int>(EFillMethod::NONE); ++i_method)
        {
            const EFillMethod method = static_cast<EFillMethod>(i_method);
            if (std::find(skip_methods.begin(), skip_methods.end(), method) == skip_methods.end()) // Only use if not in skipped.
            {
                methods.push_back(method);
            }
        }

        std::vector<coord_t> line_distances = { 400, 600, 800, 1200 }; // TODO?: Gyroid fails the 'fill less than 100% of area available' with values close to the line width, like 350.

        std::vector<InfillTestParameters> parameters_list;
        size_t test_polygon_id = 0;
        for (const Polygons& polygons : shapes)
        {
            for (const EFillMethod& method : methods)
            {
                for (const coord_t& line_distance : line_distances)
                {
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, dont_zig_zaggify, dont_connect_polygons, line_distance), test_polygon_id, polygons));
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, dont_zig_zaggify, do_connect_polygons, line_distance), test_polygon_id, polygons));
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, do_zig_zaggify, dont_connect_polygons, line_distance), test_polygon_id, polygons));
                    parameters_list.push_back(generateInfillToTest(InfillParameters(method, do_zig_zaggify, do_connect_polygons, line_distance), test_polygon_id, polygons));
                }
            }
            ++test_polygon_id;
        }

        return parameters_list;
    }

    class InfillTest : public testing::TestWithParam<InfillTestParameters> {};

    INSTANTIATE_TEST_CASE_P(InfillTestcases, InfillTest, testing::ValuesIn(generateInfillTests()), [](testing::TestParamInfo<InfillTestParameters> info) { return info.param.name; });

    TEST_P(InfillTest, TestInfillSanity)
    {
        InfillTestParameters params = GetParam();
        ASSERT_TRUE(params.valid) << params.fail_reason;
        ASSERT_FALSE(params.result_polygons.empty() && params.result_lines.empty()) << "Infill should have been generated.";

        const double available_area = std::abs(params.outline_polygons.area());
        const double expected_infill_area = (available_area * infill_line_width) / params.params.line_distance;
        const double total_infill_area = (params.result_polygons.polygonLength() + params.result_lines.polyLineLength()) * infill_line_width / getPatternMultiplier(params.params.pattern);
        ASSERT_GT((coord_t)available_area, (coord_t)total_infill_area) << "Infill area should allways be less than the total area available.";
        ASSERT_NEAR((coord_t)total_infill_area, (coord_t)expected_infill_area, (coord_t)(total_infill_area * 0.15)) << "Infill area should be within 15% of expected size."; // TODO: 10 ~ 20% is actually quite bad?

        const Polygons padded_shape_outline = params.outline_polygons.offset(infill_line_width / 2);
        ASSERT_EQ(padded_shape_outline.intersectionPolyLines(params.result_lines).polyLineLength(), params.result_lines.polyLineLength()) << "Infill (lines) should not be outside target polygon.";
        ASSERT_EQ(params.result_polygons.difference(padded_shape_outline).area(), 0) << "Infill (polys) should not be outside target polygon.";
    }

} //namespace cura
<|endoftext|>


<commit_before>#ifndef SIMULATION_OBJECT_HPP
#define SIMULATION_OBJECT_HPP

#include <string>
#include <vector>
#include <memory>
#include <list>

#include "FileStream.hpp"
#include "utility/memory.hpp"
#include "RandomNumberGenerator.hpp"

namespace warped {

class Event;
struct ObjectState;
class FileStream;
class EventDispatcher;

// SimulationObjects are the core of the simulation. All models must define at
// least one class implementing this interface. Each SimulationObject has a
// name_ that is used to identify the object. It must be unique across all
// SimulationObjects.
class SimulationObject {
public:
    SimulationObject(const std::string& name);
    virtual ~SimulationObject() {}

    // Return the state of this object.
    //
    // Any state that is mutable once the simulation has begun must be stored
    // in an ObjectState class. This object is saved and restored repeatedly
    // during the course of the simulation.
    virtual ObjectState& getState() = 0;

    // This is the main function of the SimulationObject which processes incoming events.
    //
    // It is called when an object is sent an event. The receive time of the
    // event is the current simulation time. The object may create new events
    // and return then as a vector, or return an empty vector if no events are
    // created. Events must not be created with a timestamp less than the
    // current simulation time.
    virtual std::vector<std::shared_ptr<Event>> receiveEvent(const Event& event) = 0;

    // Create events before the simulation starts.
    //
    // This is an optional method that is called before the simulation begins.
    virtual std::vector<std::shared_ptr<Event>> createInitialEvents();

    FileStream& getInputFileStream(const std::string& filename);

    FileStream& getOutputFileStream(const std::string& filename, std::shared_ptr<Event> this_event);

    const std::string name_;

    unsigned int last_fossil_collect_gvt_ = 0;

    template<class RNGType>
    void registerRNG(std::shared_ptr<RNGType>);

    std::list<std::shared_ptr<RandomNumberGenerator>> rng_list_;

};

template<class RNGType>
void SimulationObject::registerRNG(std::shared_ptr<RNGType> new_rng) {
    auto rng = std::make_shared<RNGDerived<RNGType>>(new_rng);
    rng_list_.push_back(std::move(rng));
}

} // namespace warped

#endif
<commit_msg>Remove unused header file which fixes build problem<commit_after>#ifndef SIMULATION_OBJECT_HPP
#define SIMULATION_OBJECT_HPP

#include <string>
#include <vector>
#include <memory>
#include <list>

#include "FileStream.hpp"
#include "RandomNumberGenerator.hpp"

namespace warped {

class Event;
struct ObjectState;
class FileStream;
class EventDispatcher;

// SimulationObjects are the core of the simulation. All models must define at
// least one class implementing this interface. Each SimulationObject has a
// name_ that is used to identify the object. It must be unique across all
// SimulationObjects.
class SimulationObject {
public:
    SimulationObject(const std::string& name);
    virtual ~SimulationObject() {}

    // Return the state of this object.
    //
    // Any state that is mutable once the simulation has begun must be stored
    // in an ObjectState class. This object is saved and restored repeatedly
    // during the course of the simulation.
    virtual ObjectState& getState() = 0;

    // This is the main function of the SimulationObject which processes incoming events.
    //
    // It is called when an object is sent an event. The receive time of the
    // event is the current simulation time. The object may create new events
    // and return then as a vector, or return an empty vector if no events are
    // created. Events must not be created with a timestamp less than the
    // current simulation time.
    virtual std::vector<std::shared_ptr<Event>> receiveEvent(const Event& event) = 0;

    // Create events before the simulation starts.
    //
    // This is an optional method that is called before the simulation begins.
    virtual std::vector<std::shared_ptr<Event>> createInitialEvents();

    FileStream& getInputFileStream(const std::string& filename);

    FileStream& getOutputFileStream(const std::string& filename, std::shared_ptr<Event> this_event);

    const std::string name_;

    unsigned int last_fossil_collect_gvt_ = 0;

    template<class RNGType>
    void registerRNG(std::shared_ptr<RNGType>);

    std::list<std::shared_ptr<RandomNumberGenerator>> rng_list_;

};

template<class RNGType>
void SimulationObject::registerRNG(std::shared_ptr<RNGType> new_rng) {
    auto rng = std::make_shared<RNGDerived<RNGType>>(new_rng);
    rng_list_.push_back(std::move(rng));
}

} // namespace warped

#endif
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE SMT2Parser
#include <iostream>

#include <metaSMT/support/default_visitation_unrolling_limit.hpp>
#include <metaSMT/DirectSolver_Context.hpp>
#include <metaSMT/API/Stack.hpp>
#include <metaSMT/API/Options.hpp>
#include <metaSMT/backend/SMT2.hpp>

using namespace std;
using namespace metaSMT;
using namespace metaSMT::solver;
struct Solver_Fixture
{
public:
  typedef DirectSolver_Context< SMT2 > ContextType;
  Solver_Fixture()
  {
    set_option(ctx,"solver_executable","toolbox/smt2Input_evaluator/metaSMT-smt2Input_Evaluator_z3");
    set_option(ctx,"solver_arguments","");
  }
  ContextType ctx;
};

#include "test_solver.cpp"
#include "test_QF_BV.cpp"
//#include "test_QF_UF.cpp"
//#include "test_annotate.cpp"
//#include "test_stack.cpp"
//#include "test_Array.cpp"
//#include "test_Types.cpp"
//#include "test_cardinality.cpp"
//#include "test_optimization.cpp"
//#include "test_expression.cpp"
//#include "test_simplify.cpp"
<commit_msg>removed unnecessary iostreams header from SMT2Parser.cpp<commit_after>#define BOOST_TEST_MODULE SMT2Parser
#include <metaSMT/support/default_visitation_unrolling_limit.hpp>
#include <metaSMT/DirectSolver_Context.hpp>
#include <metaSMT/API/Stack.hpp>
#include <metaSMT/API/Options.hpp>
#include <metaSMT/backend/SMT2.hpp>

using namespace std;
using namespace metaSMT;
using namespace metaSMT::solver;
struct Solver_Fixture
{
public:
  typedef DirectSolver_Context< SMT2 > ContextType;
  Solver_Fixture()
  {
    set_option(ctx,"solver_executable","toolbox/smt2Input_evaluator/metaSMT-smt2Input_Evaluator_z3");
    set_option(ctx,"solver_arguments","");
  }
  ContextType ctx;
};

#include "test_solver.cpp"
#include "test_QF_BV.cpp"
//#include "test_QF_UF.cpp"
//#include "test_annotate.cpp"
//#include "test_stack.cpp"
//#include "test_Array.cpp"
//#include "test_Types.cpp"
//#include "test_cardinality.cpp"
//#include "test_optimization.cpp"
//#include "test_expression.cpp"
//#include "test_simplify.cpp"
<|endoftext|>