Main Contents

Php: meta-programming and self-modifying program

January 11, 2010

What is meta-programming about? Here is what wikipedia says:

“Meta-programming is the writing of computer programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at compile time that would otherwise be done at runtime.”

Following this definition, it’s impossible to write meta-programming code in an interpreted language such as PHP, too bad :(

However, we can approach this by writing a program that modify it’s own sources, this is called a self-modifying program.

Here is an example of a self modifying code in PHP (meta.php)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
 
$i = 0;
$pattern = '/\$i = [0-9]+;/';
$current_code = file_get_contents("meta.php");
 
echo "Hello world -> $i\n";
 
if ($i < 5)
  {
    $new_i = $i + 1;
    $replace = "\$i = $new_i;";
    $new_code = preg_replace($pattern, $replace, $current_code);
    file_put_contents("meta.php", $new_code);
 
    require('meta.php');
  }
else 
 {
    $new_i = 0;
    $replace = "\$i = $new_i;";
    $new_code = preg_replace($pattern, $replace, $current_code);
    file_put_contents("meta.php", $new_code);
  }

What is concretely happening?

$pattern is a regexp matching with the line “$i = 0″
$i is an integer that we will change each time
$current_code is a string of the current running code
$new_code is a string of the next code to be run

When the code is first run, $i is set to 0, the $new_code is a modified version of the $current code with one difference: the line “$i = 0;” becomes “$i = 1;”. $new_code is written to ‘meta.php’, then the script re-includes itself, existing variables are crushed and the code is executed again with $i = 1. The line “$i = 1;” becomes “$i = 2″, and so on… until $i reaches 5. This way, we have a simple loop with a self-modifying program (yeah, all that stuff for a stupid loop).

Once we have reached 5, we stop this kind of weird recursion, and reset $i to 0, and we are back to square one.

For those who had the courage to read me until this line but don’t want to try executing this code, here is a quick summary of what it does:

   > l
   total 2
   -rw-r--r--  1 rannou_s  rannou_s  504 Jan  8 19:45 meta.php
   > cp meta.php backup.php
   > php meta.php
   Hello world -> 0
   Hello world -> 1
   Hello world -> 2
   Hello world -> 3
   Hello world -> 4
   Hello world -> 5
   > diff meta.php backup.php
   >

One advantage of classic meta-programming is that the code is generated
at the compilation time. Obviously in PHP, this is done at execution, so
writing such code is useless if you are looking for optimisation.

On the other side, one problem with it is that you are limited to what is available at compilation time, that means you can’t play with non-constant value, this rule is broken with dynamic language and self-modifying code.

If we look further, we can imagine writing an intelligent algorithm able to reproduce itself in a better way … Who which could lead us to something like:

  • First execution: Yes SIR! (with the voice of a wacraft’s peon)
  • Second execution: I’m sorry, Dave. I’m afraid I can’t do that.
  • Third execution: Sarah Connor ?

More information about this on What is Technological singularity all about.

Filed under: bricolage, php | Comments (0)

Introduction to Boost Test

November 12, 2009

Introduction

Boost provides a unit test framework which ensures that a class works well now, and for its all life, even if someone decides to change it later. This is a real saving of time when the code is likely to be changed.

Here is a little class we want to test: Parameter, at that moment, it stores an association of two string, a key and a value, and provides different ways to retrieve its data:

ParameterTest.hh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
  class                 Parameter
  {
 
  private:
 
    std::string         mKey;
    std::string         mValue;
 
  public:
 
    Parameter(void);
    Parameter(const Parameter & aCopy);
    Parameter &         operator=(const Parameter & aCopy);
    ~Parameter();
 
    Parameter(const std::string & aKey);
    Parameter(const std::string & aKey, const std::string & aValue);
    bool                operator==(const Parameter & aValue) const;
 
    const std::string & getKey(void) const;
    const std::string & getValue(void) const;
    void                setKey(const std::string & aKey);
    void                setValue(const std::string & aValue);
  };

Writing tests

First thing we have to do is creating a main that will run our tests :

Runner.cpp

1
2
#define BOOST_TEST_MAIN
#include <boost/test/included/unit_test.hpp>

This main will launch the test suites we write. Each test suite is defined by a list of tests applied to a class. Here, we have one class, so we have one test suite. Let’s write a main frame where we will write Parameter’s test suite :

ParameterTest.cpp

1
2
3
4
5
6
7
8
9
#include <boost/test/unit_test.hpp>
 
#include "Parameter.hh"
 
BOOST_AUTO_TEST_SUITE(parameter_tests)
 
// Here we will write our tests
 
BOOST_AUTO_TEST_SUITE_END()

This declares a test suite called parameter_tests, we now have to write our tests in it, this is done with the macro BOOST_AUTO_TEST_CASE :

ParameterTest.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <boost/test/unit_test.hpp>
 
#include "Parameter.hh"
 
BOOST_AUTO_TEST_SUITE(parameter_tests)
 
BOOST_AUTO_TEST_CASE(constructors_test)
{
       // Here we write tests related to constructors
}
 
BOOST_AUTO_TEST_CASE(operators_test)
{
       // Here we write tests related to operators
}
 
BOOST_AUTO_TEST_SUITE_END()

Here we declare two tests, one for the construction of a Parameter, one for the operators, let’s write their content, here again, boost provides some macros :

ParameterTest.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "Parameter.hh"
 
#include <boost/test/unit_test.hpp>
#include <string>
 
BOOST_AUTO_TEST_SUITE(ini_parameter_tests)
 
BOOST_AUTO_TEST_CASE(constructors_test)
{
  BOOST_MESSAGE("testing ini::parameter constructor/setters/getters");
 
  std::string           empty("");
 
  Parameter        a;
  BOOST_CHECK_EQUAL(a.getValue(), empty);
  BOOST_CHECK_EQUAL(a.getKey(), empty);
 
  // etc...
}
 
BOOST_AUTO_TEST_CASE(operators_test)
{
  BOOST_MESSAGE("testing ini::parameter operators");
 
  Parameter        a;
  Parameter        b;
  Parameter        c("key");
 
  BOOST_CHECK(a == b);
  BOOST_CHECK(!(a == c));
  BOOST_CHECK(c == c);
}
 
BOOST_AUTO_TEST_SUITE_END()

Running tests

That’s it, let’s compile it and link it with boost_test_exec_monitor :

1
2
3
4
5
6
7
8
9
> make
c++ -I../ -I/usr/local/include/ -I../../ -c Runner.cpp
c++ -I../ -I/usr/local/include/ -I../../ -c ../Parameter.cpp
c++ -I../ -I/usr/local/include/ -I../../ -c ParameterTest.cpp
g++ -Wall *.o -o run_tests -L/usr/local/lib -lboost_test_exec_monitor
>
> ./run_tests 
Running 2 test cases...
*** No errors detected

By default, the BOOST_MESSAGE macros doesn’t print anything, this is because there are several levels of logging in boost test, it can be customized through the environment:

1
2
3
4
5
6
> export BOOST_TEST_LOG_LEVEL=message
> ./run_tests 
Running 2 test cases...
testing parameter constructor/setters/getters
testing parameter operators
*** No errors detected

Now let’s see what happens when a test fails :

1
2
3
4
5
6
7
8
> ./run_tests 
Running 2 test cases...
testing ini::parameter constructor/setters/getters
ParameterTest.cpp(43): error in "constructors_test": check a.getKey() == d.getKey() failed [ != key]
ParameterTest.cpp(44): error in "constructors_test": check a.getValue() == d.getValue() failed [ != value]
testing ini::parameter operators
 
*** 2 failures detected in test suite "Master Test Suite"

Fxitures

What if we have another class called X that contains several instances of Parameter? How to test it? We need to create an instance of X and feed it with Parameters each time we need to make a test, this is boring. Fortunately, fixtures are here to simplify this task: let’s write a XFixture class, that contains a public instance of X called mX;

Fixtures.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct XFixture
{
      XFixture()
      {
              mX.addNewParam(new Parameter("a"));
              mX.addNewParam(new Parameter("b", "val1"));
              mX.addNewParam(new Parameter("c", "val2"));
      }
 
     ~XFixture()
     {
          ;
     }
 
     X      mX;
};

Now, each time we need to write a test that requires the initialized instance of X, we only have to declare the test with the help of the macro BOOST_FIXTURE_TEST_CASE:

1
2
3
4
5
6
7
8
BOOST_AUTO_TEST_SUITE(x_tests)
 
BOOST_FIXTURE_TEST_CASE(xTest, XFixture)
{
     // here mX is available directly (public instance from XFixture)
}
 
BOOST_AUTO_TEST_SUITE_END()

Fixtures are reinitialized for each test, so it’s ok not to restore it in its initial state.

Conclusion

Boost test provides a way to quickly write test with a few macros, taking over repetitive tasks. Unfortunately, the documentation is quite hard to begin with, (this is why I’ve written this article). I haven’t tested yet other unit testing frameworks (cpptest? cppunit? …), and I hope I will have time to try it.

Filed under: CPP | Comments (0)

C++ : Know the level of a class in an inheritance list

October 21, 2009

I’ve been looking for a way to know the level of a class in an inheritance tree list (see comments for my mistake), here is a quick and dirty solution using a template class which increments it’s level value when invoked.

template        <typename T>
struct          Inc: public T
{
  enum { level = 1 + Inc<T>::level };
};

Unfortunately this is heavy to use, and I have no doubt there exists a better way to do this (I would be thankful to know it). It requires to add a public enum in the root class, and make inherit children to the template specialized in the parent class. Here is an example of code using it :

class           Root
{
public:
  enum { level = 0 };
};
 
class           One: public Inc<Root>
{
};
 
class           Second: public Inc<One>
{
};
 
class           Third: public Inc<Second>
{
};
 
int             main(void)
{
  Root          root;
  One           first;
  Second        second;
  Third         third;
 
  std::cout << "My level is " << root.level << std::endl;
  std::cout << "My level is " << first.level << std::endl;
  std::cout << "My level is " << second.level << std::endl;
  std::cout << "My level is " << third.level << std::endl;
}

The output:

> ./a.out
My level is 0
My level is 1
My level is 2
My level is 3
>

Filed under: CPP, Snippet, bricolage | Comments (3)

Cast the uncastable in an ugly way (C++)

September 30, 2009

I went through this problem recently: I wanted to cast a void * into a function pointer in C++ (as I needed to load a dynamic library with the help of dlsym, which returns a void *).

Unfortunately, C++ forbids that bad practice and a nice warning appears when compiling.

1
2
3
4
5
6
7
8
#include <dlfcn.h>
 
int             main(int, char **)
{
  void          (*f)(void) = (void (*)(void)) dlsym(0, "SomeFunction");
 
  return 0;
}

Will output something like:

ISO C++ forbids casting between pointer-to-function and pointer-to-object

An ugly trick to avoid this is to do it the C way with a memcpy:

1
2
3
4
5
6
7
8
9
10
11
#include <string.h>
#include <dlfcn.h>
 
int             main(int, char **)
{
  void          (*f)(void);
  void          *ptr = dlsym(0, "SomeFunction");
 
  memcpy(&f, &ptr, sizeof(void *));
  return 0;
}

Filed under: CPP, Snippet, bricolage | Comments (5)

What? Graoom is evolving!

September 28, 2009

It’s been quite a long time I haven’t blog about what I was doing, partly because I was very busy last weeks (I learned how to make pancakes !), mostly because I’m lazy.

This summer I started to code something I’ve called graoom, a multiplayer game without any specific guideline, in order to have something generic enough to be forked easily. The server is quite ready as I can’t really continue it without defining how the game will look like, yet the client still requires a lot of work but it’s hard to continue without taking decisions that break genericity.

So to get things going faster, I’ve decided to fork it in something more concrete called BattleTrantor and to merge it with a previous project I’ve taken part in last year (Zappy), where we developped our own game engine. I’ll also use graphics from this past project (Antoine had made very nice models that perfectly fit with the project), therefore I hope to get something playable quickly.

futurama

It will be a kind-of multiplayer hack and slash game taking place on a little planet, where strange creatures will fight for glory (I don’t know yet with what, but I doubt it will be difficult to find them weapons).

Some stuff about the project:

Filed under: Jeux vidéos, Pics, Programmation C, bricolage | Comments (0)