New content are available at http://tis-method.org/. All articles from this site will be moved to the new location.

понедельник, 29 ноября 2010 г.

WIX include file generation

When you create an installation of the product you should list all of its components.
This process not only tedious, but also can generate synchronization errors of the project output components and the installation package.

For some products, the composition of components may changing significantly during development.
In such cases, automating the process of creating installation is a must.

WIX installation file description can include additional files using the <?include ?> instruction.
Such mechanism would create the main installation file once, and localize all changes into external files.
So, we need two external files. One to describe the included files, the second to define the components to install.

Installation files sample
Main installation file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  ...
  <Product Id="$(var.ProductGUID)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.CompanyName)" UpgradeCode="$(var.UpgradeCode)">
    ...
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" Name="PFiles">
        <Directory Id="COMPANYDIR" Name="$(var.CompanyName)">
          <Directory Id="ProductDir" Name="$(var.ProductName)">
            <Directory Id="IncDir" Name="z3d">
              <?include inc1.wxs ?>
            </Directory>
            ...
          </Directory>
        </Directory>
      </Directory>
    </Directory>
    ...
    <Feature Id="ProductFeatures" Title="$(var.ProductName)" Level="1" ConfigurableDirectory="COMPANYDIR">
      <?include inc2.wxs ?>
      ...
    </Feature>
    ...
  </Product>
</Wix>

Enumeration for installing files (inc1.wxs):
<Include>
 <Directory Id="inc_dir1" Name="boost">
  <Component Id="inc_comp1" Guid="{B2B874BA-6480-4F20-9B5A-49F6DB83E830}">
   <File Id="inc_comp1_0" Name="cast.hpp" DiskId="1" Source="b:\prjs\z3d\z3d\boost\cast.hpp"/>
  </Component>
 </Directory>
 ...
</Include>

Enumeration for installing components (inc2.wxs):
<Include>
 <ComponentRef Id="inc_comp1"/>
 ...
</Include>

scan4wix command line parameters
Console utility scan4wix.exe is used for generating wix include files.
--help                    Show this help
  --root arg                Scan root path
  --prefix arg              ID's prefix string
  --regex arg               Regular expression for file content scanning
  --include_dirs arg (=.*)  Include dirs regular expression
  --exclude_dirs arg        Exclude dirs regular expression
  --include_files arg (=.*) Include files regular expression
  --exclude_files arg       Exclude files regular expression
  --out1 arg                Output file name for WIX dir&files list
  --out2 arg                Output file name for WIX features list

Usage example
scan4wix.exe --root="с:\project\bin" --prefix="prj" --exclude_dirs=".svn" --out1="prj1.wxs" --out2="prj2.wxs"

Utility will scan directory structure beginning from "с:\project\bin". Scan will exclude any ".svn" directories.
Output file prj1.wxs will contain all files from the selected directories. Output file prj2.wxs will contain corresponding components list.

Additionally, you can specify regular expression for files content. If you set --regex command line argument, utility will evaluate this regular expression for each input file content. If result of evaluation is true, the file will add into install package, otherwise will skip.

Links
You can find scan4wix utility in the tools folder in the z3d.

пятница, 5 ноября 2010 г.

Gateway

The basis of this template is a Pimpl and combination (composition, aggregation) technique.
Template add a new layer of indirection to reduce the coupling of interface and implementation and providing a controlled subset of the interface of the aggregated object. In both cases the "external" object - the interface contains the "inner" object - implementation.
So, gateway provide static/dynamic call forwarding from the interface level to the level of implementation.

Structure
The template consists of two parts. The first part - a pointers to class methods list. This types list defines a subset of the available interfaces to the "hidden" object. The second part - a function object, its purpose - return a reference to the object for which we will be directly implemented method calls.

Implementation
Structurally, Gateway is similar to the Chain of responsibility. Most part of interface is designed to routing method calls from 0 to 10 parameters. But if the "chain of responsibility" works with "arbitrary" function object, the Gateway is working with pointers to class methods.

Example
As an example, consider the following task: route method call from interface to the object, which is located on top of the stack.
///
class base
{
public:
 virtual void update( int const i ) = 0;
};
///
class A : public base
{
public:
 virtual void update( int const i )
 { std::cout << "A::update(" << i << ");" << std::endl; }
};
///
class B : public base
{
public:
 virtual void update( int const i )
 { std::cout << "B::update(" << i << ");" << std::endl; }
};
///
typedef void ( base::* base_update_t )( int const );
///
class manager : public z3d::gateway< manager&, LOKI_TYPELIST_1( base_update_t ) >,
 protected std::stack< boost::reference_wrapper< base > >,
 public boost::noncopyable
{
public:
 ///
 manager() : z3d::gateway< manager&, LOKI_TYPELIST_1( base_update_t ) >( boost::ref( *this ), INITLIST_1( &base::update ) )
 {}
 ///
 base& operator()()
 { return stack< boost::reference_wrapper< base > >::top(); }
 ///
 void push( base& p )
 { stack< boost::reference_wrapper< base > >::push( boost::ref( p ) ); }
 ///
 void pop()
 { stack< boost::reference_wrapper< base > >::pop(); }
};

void main()
{
 A a1;
 A a2;
 B b1;
 manager man;
 man.push( b1 );
 man.push( a1 );
 man.call< base_update_t, void >( 0 );
 man.pop();
 man.call< base_update_t, void >( 1 );
 man.push( a2 );
 man.call< base_update_t, void >( 2 );
}

Program output:
A::update(0);
B::update(1);
A::update(2);


Links
File z3d/gateway.hpp from z3d contains template code.


суббота, 23 октября 2010 г.

Chain of responsibility

"Chain of responsibility" - the well-known pattern, exhaustively described in GoF. Of course, in most cases, boost::signal and boost::signal2 possible to realize almost any design. We can assume that the pattern of "chain of responsibility" is "observer" pattern with N = 1.
Nevertheless, there are rare situations where pattern "chain of responsibility" is a reasonable choice. This may be cases in which the channel signal is always single, when the signal transmission should go with a minimum of overhead, when the channel is already running in a secure multi-threaded environment or connects composite parts of one whole component.

Front-end
For example, consider the schematic design of a system built on layers of processing. Target class should allow the dynamic creation of a one-way communication between an arbitrary number of objects and provide an interface for signal propagation.
/// chain function
typedef boost::function< voidint const ) >
  chain_t;
///
class layer : protected z3d::chain_of_resp< LOKI_TYPELIST_1( chain_t ) >,
  public boost::enable_shared_from_this< layer >,
  public boost::noncopyable
{
  typedef z3d::chain_of_resp< LOKI_TYPELIST_1( chain_t ) >
    base_t;
  ///
  std::string
    name;

protected:
  /// init cons
  layer( std::string const& n ) : name( n )
  {}

public:
  ///
  typedef boost::shared_ptr< layer >
    layer_ptr_t;
  /// working function
  void chain( int const arg )
  {
    std::cout << name << "::chain(" << arg << ")" << std::endl;
    if ( !( base_t::empty< chain_t >() ) )
      base_t::call< chain_t, void >( arg + 1 );
  }
  /// making chain between layers
  layer_ptr_t attach( layer_ptr_t l )
  {
    base_t::bind( boost::bind( &layer::chain, l, _1 ) );
    return ( shared_from_this() );
  }
  ///
  static layer_ptr_t create( std::string const& name )
  { return layer_ptr_t( new layer( name ) ); }
};

void main()
{
  layer::layer_ptr_t lA2 = layer::create( "A2" );
  layer::layer_ptr_t lA1 = layer::create( "A1" )->attach( lA2->attach( layer::create( "A3" ) ) );
  std::cout << std::endl << "A1 -> A2 -> A3 chain" << std::endl;   lA1->chain( 0 );
  ///
  layer::layer_ptr_t lB1 = layer::create( "B1" );
  lB1->attach( lA2 );
  std::cout << std::endl << "B1 -> A2 -> A3 chain" << std::endl;   lB1->chain( 0 );
}
layer class contains a single channel - layer::chain. The method layer::attach allows you to associate two objects with communication channel. The example creates two channels, the output shows the processing and transmission of signals over a channel between the layers.

Output:
A1 -> A2 -> A3 chain
A1::chain(0)
A2::chain(1)
A3::chain(2)

B1 -> A2 -> A3 chain
B1::chain(0)
A2::chain(1)
A3::chain(2)

Sources
z3d::chain_of_resp.hpp

Use cases:
z3d::utests::chain_of_resp_ut01.hpp
z3d::utests::chain_of_resp_ut02.hpp
z3d::utests::chain_of_resp_ut03.hpp

суббота, 9 октября 2010 г.

Classes linear hierarchy

Getting to the problem, I'm always analyzing it by checklist.
One of point is to determine how to use compile-time and run-time opportunities. This topic is about one compile-time tool, which allows me to use a flexible layout of objects.

It is based on the possibility to manipulate C++ types at compile-time and use a partial specialization of templates for generating linear hierarchies of classes. This technique is used in the Loki and Boost libraries.

template < class, size_t >
struct slot;

template < size_t I >
struct slot< Loki::NullType, I >
{
 ///
 typedef Loki::NullType
  value_type;
 ///
 value_type
  value;
};

template < typename T, typename U, size_t I >
struct slot< Loki::Typelist< T, U >, I > : public slot< U, I + 1 >
{
 ///
 typedef T
  value_type;
 ///
 value_type
  value;
};

Template appointment - generate a classes linear hierarchy. Number of inherited classes equal to the number of types in the types list template parameter plus one.
Next design:
class С1 : public z3d::slot< LOKI_TYPELIST_4(int, char, float, long) >{};

will generate the following schematic nested structure:
class С1
{
  {
    {
      {
        {
          {
            Loki::NullType value;
          }
          long value;
        };
        float value;
      };
      char value;
    };
    int value;
  };
};

Access to elements of the structure can be as an index, so by specifying the type:
С1 с1;
c1.set_value( boost::mpl::int_< 0 >(), 1 );
c1.set_value( boost::mpl::int_< 1 >(), 'A' );
std::cout << c1.get_value( boost::mpl::identity< float >() );

Class z3d::slot also provides a mechanism to initialize the values in the constructor:
С1 с1( INITLIST_1( 1, Loki::NullType(), 1.f, Loki::NullType() );

Template class z3d::scope openly inherited from z3d::slot and adds the ability to initialize the value using a class method:
class S1 : public z3d::scope< LOKI_TYPELIST_4(int, char, float, long) >
{};

S1 s1;
s1.assign( INITLIST_1( 1, Loki::NullType(), 1.f, Loki::NullType() );


Results
Template classes z3d::slot and z3d::scope are the basic elements to build more complex structures: implementation of patterns "Chain of responsibility", "State", to reflect the dynamic relationships between objects.

Sources
z3d::slot
z3d::scope

среда, 29 сентября 2010 г.

Scanning file using boost::regex [windows specific]

Task statement
Make light wrapper around file on disk to work with boost::regex.

"Brute force"
Open file, read all data into a string, use boost::regex.

File mapping
Represent file as byte-array, using file mapping into a memory.
Below, possible solution.
template < class charT >
class basic_regex_file< charT, z3d::platform::windows >
{
public:
 ///
 typedef charT
  char_t;
 ///
 typedef std::basic_string< char_t >
  string_t;
 ///
 typedef char_t*
  iterator;
 ///
 typedef char_t const*
  const_iterator;
 ///
 typedef char_t*
  view_t;
 ///
 explicit basic_regex_file( string_t const& sname ) : 
 mapping( 0 )
  , view( 0 )
  , size_lo( 0 )
  , size_hi( 0 )
 {
  HANDLE file = open_file( sname, boost::mpl::identity< char_t >() );
  this->mapping = CreateFileMapping( file, NULL, PAGE_READONLY, 0, 0, NULL );
  this->view  = reinterpret_cast< view_t >( MapViewOfFile( this->mapping, FILE_MAP_READ, 0, 0, 0 ) );
  //
  if ( ( file != INVALID_HANDLE_VALUE ) && ( this->mapping != NULL ) && ( this->view != NULL ) )
  {
   this->size_lo = GetFileSize( file, &(this->size_hi) );
  }
  CloseHandle( file );
 }
 ~basic_regex_file()
 {
  if ( this->view != NULL )
  {
   ::UnmapViewOfFile( this->view );
  }
  if ( this->mapping != NULL )
  {
   ::CloseHandle( this->mapping );
  }
 }
 ///
 const_iterator begin() const
 { return ( &( this->view[0] ) ); }
 ///
 const_iterator end() const
 { return ( &( this->view[ this->size_lo / sizeof( char_t ) ] ) ); }
 ///
 operator bool() const
 { return ( ( this->view != 0 ) && ( this->size_lo || this->size_hi ) ); }

private:
 ///
 HANDLE
  mapping;
 ///
 view_t
  view;
 ///
 DWORD
  size_lo;
 ///
 DWORD
  size_hi;
 ///
 HANDLE open_file( string_t const& sname, boost::mpl::identity< wchar_t > )
 { return CreateFileW( sname.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); }
 ///
 HANDLE open_file( string_t const& sname, boost::mpl::identity< char > )
 { return CreateFileA( sname.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); }
};
typedef basic_regex_file< char, z3d::platform::windows > win_regex_file;
typedef basic_regex_file< wchar_t, z3d::platform::windows > wwin_regex_file;

How to use
z3d::util::win_regex_file wrf( "file.txt" );
if ( wrf && boost::regex_match( wrf.begin(), wrf.end(), boost::regex( ".*ABC.*" ) ) )
{
 // found
}

Where to find
Use classes located in z3d/util/regex-file.hpp from z3d.



четверг, 23 сентября 2010 г.

C++ type string representation


During integration CInt & C++ i found very interesting task. I saw it before in "C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond, By David Abrahams, Aleksey Gurtovoy" as exercises to chapter 2.

Task statement
Generation full function call signature string representation, including type description and parameters value.
When i call CInt script function from C++ code, like this
call< void >( "func10", 0, 'A', 1.f, 1, 'B', 2.f, 3, 'C', 3.f, true );

i have to build string
"func10((int)0,(char)'A',(float)1,(int)1,(char)'B',(float)2,(int)3,(char)'C',(float)3,(bool)1);"
and then exec it in CInt sandbox, using G__calc (CInt API function).

For each function argument i have to generate type string representation and argument value in the valid form.
call<void>( "f1", 1 ); -> "f1( (int)1 );"
int i = 1;
call<void>( "f2",  &i ); -> "f2( (int*)0x00FC0632 );"

Additionally, will be great, if i can process user defined types too.
struct my_struct {} v;
call<int>( "f3", &v ); -> "f3( (my_struct*)0x00DFCC02 );"

Step by step
The basis of the solution is set of template partial specializations
template < typename > struct term_;

 This define is used for quick setup types recognition partial specialization
#define Z3D_TYPE_NAME_DEF_TERM( t ) \
 template <>\
 struct term_< t >\
 {\
  enum { length = sizeof( #t ) - 1 };\
  std::ostream& name( std::ostream& os ) const { return( os << #t ); }\
 };

This done for all basic types: void, bool, char, signed char, unsigned char, wchar_t, short int, unsigned short int, int, unsigned int, long int, unsigned long int, long long int, unsigned long long int, float, double, long double.
Z3D_TYPE_NAME_DEF_TERM( void );
...
Z3D_TYPE_NAME_DEF_TERM( long double );

Next define should be use to add user defined type into types recognition scope:
Z3D_TYPE_NAME_DEF_TERM_USER( my_struct );

The same mechanic used to recognizing
  • const, volatile, &, *, [], [N]
  • function from R(*)() to R(*)(P1, ..., P10)
  • pointer to the member T C::*
  • pointer to the member function from R(C::*)() to R(C::*)(P1, ..., P10)
Template class type_ is intended for collect whole type information. Template function format_ should be use for getting string represent of pair "type description" & "value"

How to use
It's very simple.
std::cout << z3d::type_name::type_< unsigned char(*)( void*(*)(int&) ) >::name() << std::endl;

will output
unsigned char(*)(void *(*)(int &))

and
std::cout << z3d::type_name::param_( L"abcdef" ) << std::endl;

will print something like that
(wchar_t const *)0x01180EF8

Sources
z3d::type_name.hpp

Use cases:
z3d/utests/type_name_ut01.hpp


вторник, 21 сентября 2010 г.

HOWTO build CInt under Windows using cygwin and msvc9(msvc8, msvc7)

CInt site
 

Assume that:
CInt installed into "C:\cint\"
MSVC9 installed into "C:\Program Files"
Cygwin installed into "C:\cygwin"

1. Install cygwin. You may use cygwin default packages, but additionally, add /Devel/make package.

2. Get CInt sources from site or from project repository.

3. Add to file "C:\cygwin\Cygwin.bat" two lines «call "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat"» and 
«SET CINTSYSDIR = "C:\cint"» befor line "bash --login -i"

4. Replace in file
"C:\cygwin\etc\profile" line «PATH=/usr/local/bin:/usr/bin:/bin:$PATH» to «PATH=/cygdrive/c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/VC/bin/:/usr/local/bin:/usr/bin:/bin:$PATH»

5. Launch cygwin.bat. At the command line set current folder to CInt sources. Exec command «./configure --arch=msvc9 && make»

6. After compiling & linking, folder "C:\cint\bin" will contain dll modile – libCint.dll, folder
"C:\cint\libexport" library – libCint.lib

Current CInt version (5.18.00) depends from msvc CRT, so you need to have both debug and release builds of library to use in you application. Just exec «./configure --arch=msvc9 --debug && make» and you will have debug CInt build.
Issue is that the library names will stay the same (libCint.dll, libCint.lib). It's little awkward during library linking.
I built libCintD.dll, libCintD.lib, by changing output names in the makefiles. But it looks like workaround. When i will find legally work-flow, i will post it.