<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Coder-Studio</title>
	<atom:link href="http://www.coder-studio.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coder-studio.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 10 Jan 2010 14:32:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Tutoriel Boost Graph Library</title>
		<link>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/</link>
		<comments>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 01:06:58 +0000</pubDate>
		<dc:creator>Calvin1602</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[boost]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[graphes]]></category>
		<category><![CDATA[tutoriel]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=429</guid>
		<description><![CDATA[Boost, c'est le bien, et la BGL ne fait pas exception à la règle. BGL permet d'utiliser des algorithmes de graphes précodés en l'adaptant à nos besoins via les templates, et économise beaucoup de temps de développement et de debug.
C'est bien beau, mais encore faut-il que les puissants concepts utilisés pour faire fonctionner la librairie soient bien documentés. Or, la documentation de la BGL est tout simplement ignoble [...]
Ce tuto ci se veut simple. Il présente une des milliers de façons de procéder, que je considère comme simple, lisible et maintenable.]]></description>
			<content:encoded><![CDATA[<p>Boost, c&#8217;est le bien, et la BGL ne fait pas exception à la règle. BGL permet d&#8217;utiliser des algorithmes de graphes précodés en l&#8217;adaptant à nos besoins via les templates, et économise beaucoup de temps de développement et de debug.<br />
C&#8217;est bien beau, mais encore faut-il que les puissants concepts utilisés pour faire fonctionner la librairie soient bien documentés. Or, la documentation de la BGL est tout simplement ignoble :<br />
<span id="more-429"></span></p>
<ul>
<li>Elle est très peu connexe. Par exemple, il y a un unique lien vers la table des matières.</li>
<li>Elle est peu explicite. Par exemple, dans l&#8217;interface de l&#8217;algorithme de dijkstra, on peut trouver un bgl_named_parameters. Il faut se lever de bonne heure pour trouver ce que c&#8217;est.</li>
<li>Les exemples sont rares et peu explicites. Le seul exemple de l&#8217;algorithme A* est peu commenté (et encore moins aux parties les plus dures), démontre deux autres features qui n&#8217;ont rien à voir, utilise l&#8217;interface obsolète et non recommandée de la lib, et complique le tout avec une autre couche de templates totalement inutile pour un tuto qui se veut simple.</li>
</ul>
<p>Ce tuto ci se veut simple. Il présente une des milliers de façons de procéder, que je considère comme simple, lisible et maintenable. Tous les membres du namespace boost seront préfixés par boost:: afin de savoir qu&#8217;est-ce qui est à nous et qu&#8217;est-ce qui est à Boost.</p>
<p>Il est basé sur le cas suivant : on a un graphe de waypoints, et on veut utiliser l&#8217;algorithme A* (qui utilise une bonne partie des concepts importants de la lib). Dans un premier temps, dans un souci de simplicité, on va utiliser une heuristique par défaut, qui rend toujours zéro. On verra par la suite comment l&#8217;adapter.</p>
<p>On va avoir besoin de deux headers boost:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code1'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4291"><td class="code" id="p429code1"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;boost/graph/adjacency_list.hpp&gt;</span>
<span style="color: #339900;">#include &lt;boost/graph/astar_search.hpp&gt;</span></pre></td></tr></table></div>

<p>On va maintenant définir les structures nécessaires à définir notre graphe :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code2'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4292"><td class="code" id="p429code2"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Un waypoint</span>
<span style="color: #0000ff;">struct</span> WayPoint<span style="color: #008000;">&#123;</span>
    Vector3f pos<span style="color: #008080;">;</span>
    <span style="color: #666666;">// et éventuellement d'autres informations (crouch, hide, camp, ...)</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #666666;">// Une liaison entre deux waypoints</span>
<span style="color: #0000ff;">struct</span> WayPointConnection<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">float</span> dist<span style="color: #008080;">;</span>
    <span style="color: #666666;">// idem</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On va maintenant déclarer le type de notre graphe. On va utiliser une adjacency_list, qui est un peu un graphe à tout faire. Ce n&#8217;est pas le plus optimisé dans tous les cas, mais il est très versatile et convient très bien ici.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code3'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4293"><td class="code" id="p429code3"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">adjacency_list</span><span style="color: #000080;">&lt;</span>  <span style="color: #666666;">// adjacency_list est un template qui dépend de :</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">listS</span>,               <span style="color: #666666;">//  le conteneur utilisé pour les arcs partant d'un sommet. Ici, std::list.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">vecS</span>,                <span style="color: #666666;">//  le conteneur utilisé pour contenir tous les sommets du graphe. Ici, std::vector.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">undirectedS</span>,         <span style="color: #666666;">//  le type des arcs. Pourrait être boost::directedS.</span>
    WayPoint,                   <span style="color: #666666;">//  le type qui décrit un sommet.</span>
    WayPointConnection          <span style="color: #666666;">//  le type qui décrit un arc.</span>
<span style="color: #000080;">&gt;</span> WayPointGraph<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Les deux premiers paramètres influent grandement sur l&#8217;organisation mémoire et les performances de graphe. Selon les applications, une liste, un vecteur, un set, une map, &#8230; sera plus approprié. Pour plus d&#8217;information, voir <a href="http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/using_adjacency_list.html#sec:choosing-graph-type">la doc</a>.</p>
<p>On déclare aussi des raccourcis pour les IDs de sommets et d&#8217;arcs (en fait, ce sont des unsigned int)</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code4'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4294"><td class="code" id="p429code4"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">typedef</span> WayPointGraph<span style="color: #008080;">::</span><span style="color: #007788;">vertex_descriptor</span> WayPointID<span style="color: #008080;">;</span>
<span style="color: #0000ff;">typedef</span> WayPointGraph<span style="color: #008080;">::</span><span style="color: #007788;">edge_descriptor</span>   WayPointConnectionID<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On va pouvoir instancier notre graphe.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code5'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4295"><td class="code" id="p429code5"><pre class="cpp" style="font-family:monospace;">WayPointGraph graphe<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On commence par rajouter tous les sommets :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code6'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4296"><td class="code" id="p429code6"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous nos sommets S<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    WayPointID wpID <span style="color: #000080;">=</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">add_vertex</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// wp est l'indice d'un nouveau sommet qui a été ajouté dans graphe</span>
    graphe<span style="color: #008000;">&#91;</span>wpID<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span> <span style="color: #000080;">=</span> la position du sommet S    <span style="color: #666666;">// graphe[ un WayPointID ] est un WayPoint. On peut donc régler sa position de cette manière.</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Maintenant, on peut les relier par des arcs. Là, c&#8217;est à vous de savoir où vont les arcs, boost ne va pas le deviner tout seul&#8230;</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code7'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4297"><td class="code" id="p429code7"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous nos sommets U<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// petit changement de notation, dans boost un arc est souvent décrit entre deux sommets u et v.</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span>tous les voisins V de U<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// C'est à vous de savoir quels sont les voisins de U.</span>
&nbsp;
        WayPointID u <span style="color: #000080;">=</span> indice de U<span style="color: #008080;">;</span> <span style="color: #666666;">// soit c'est le int du for(), soit il faut y accéder via un autre vector. Cf les notes plus bas.</span>
        WayPointID v <span style="color: #000080;">=</span> indice de V<span style="color: #008080;">;</span>
&nbsp;
        WayPointConnectionID edge<span style="color: #008080;">;</span>
        <span style="color: #0000ff;">bool</span> ok<span style="color: #008080;">;</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">tie</span><span style="color: #008000;">&#40;</span>edge, ok<span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">add_edge</span><span style="color: #008000;">&#40;</span>u,v, graphe<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// boost::add_edge renvoie une std::pai&gt;WayPointConnectionID,bool&gt;. C'est compliqué à écrire, alors on laisse boost::tie le faire pour nous.</span>
&nbsp;
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>ok<span style="color: #008000;">&#41;</span>  <span style="color: #666666;">// Si le graphe a bel et bien été ajouté ( pas de doublon, par exemple, sauf si spécifié dans le typedef de WayPointGraph )</span>
        graphe<span style="color: #008000;">&#91;</span>edge<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">dist</span> <span style="color: #000080;">=</span> Distance<span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#91;</span>u<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span>, graphe<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span>.<span style="color: #007788;">pos</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Longueur d'un arc = distance euclidienne entre les deux sommets u et v.</span>
&nbsp;
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Plusieurs choses sont à remarquer :</p>
<ul>
<li>Personnellement, j&#8217;ai utilisé le fait que WayPointID est en fait un int et que dans mon double for(), j&#8217;utilise un int pour accéder au waypoint. C&#8217;est pas très propre, mais ça évite l&#8217;utilisation d&#8217;un vector en plus.</li>
<li>graphe[edge] ( edge étant un WayPointConnectionID ) est un WayPointConnection, alors que graphe[u] (u étant un WaypointID) est un WayPoint. On peut donc accéder directement à leurs membres.</li>
<li>Cette dernière remarque est très importante. Cette syntaxe est très appréciable, elle évite d&#8217;utiliser les incompréhensibles boost::property_map, elle oblige seulement à avoir un compilateur récent. GCC et Visual s&#8217;en sortent très bien.</li>
</ul>
<p>Pour information, mon code à moi ressemble à ça :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code8'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4298"><td class="code" id="p429code8"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i<span style="color: #000080;">&lt;</span>indices.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">/</span><span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
    ConnectiviteTriangle connectivity<span style="color: #008080;">;</span>
    fillconnectivityinfo<span style="color: #008000;">&#40;</span>i, connectivity, indices<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> c<span style="color: #000080;">=</span><span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> c<span style="color: #000040;">!</span><span style="color: #000080;">=</span><span style="color: #0000dd;">3</span><span style="color: #008080;">;</span> c<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>connectivity.<span style="color: #007788;">connexe</span><span style="color: #008000;">&#91;</span>c<span style="color: #008000;">&#93;</span><span style="color: #000040;">!</span><span style="color: #000080;">=</span><span style="color: #000040;">-</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
        TriangleDescriptor u <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span>
        TriangleDescriptor v <span style="color: #000080;">=</span> connectivity.<span style="color: #007788;">connexe</span><span style="color: #008000;">&#91;</span>c<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>La syntaxe est moyennement cool, mais j&#8217;espère que ça vous aidera à mieux comprendre.</p>
<p>Ok, donc maintenant notre graphe a des sommets et des arcs. On va pouvoir faire du pathfinding !</p>
<p>Pour ça, on va avoir besoin de quelques structures :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code9'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p4299"><td class="code" id="p429code9"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Une instance de cette structure sera lancée en exception quand on aura trouvé un chemin</span>
<span style="color: #0000ff;">struct</span> found_goal <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #666666;">// Le visiteur, dont le but est de définir une fonction examine_vertex qui dit si on est arrivé au but.</span>
<span style="color: #666666;">// Le but est spécifié via le constructeur.</span>
<span style="color: #0000ff;">class</span> astar_goal_visitor <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">default_astar_visitor</span><span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    astar_goal_visitor<span style="color: #008000;">&#40;</span>WayPointID goal<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> m_goal<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">void</span> examine_vertex<span style="color: #008000;">&#40;</span>WayPointID u, <span style="color: #0000ff;">const</span> Graph <span style="color: #000040;">&amp;</span>amp<span style="color: #008080;">;</span> g<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #666666;">// Le const est important.</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>u <span style="color: #000080;">==</span> m_goal<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">throw</span> found_goal<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// On sort en lancant une exception. C'est moche mais c'est comme ça.</span>
        <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    WayPointID m_goal<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Il faut maintenant trouver notre point de départ et notre point d&#8217;arrivée. C&#8217;est votre problème, mais il faut arriver à quelque chose du style :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code10'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42910"><td class="code" id="p429code10"><pre class="cpp" style="font-family:monospace;">TriangleDescriptor goal <span style="color: #000080;">=</span> ...
<span style="color: #007788;">TriangleDescriptor</span> start <span style="color: #000080;">=</span> ...</pre></td></tr></table></div>

<p>Ok, on y va :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code11'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42911"><td class="code" id="p429code11"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Deux vecteurs qui vont servir à sauvegarder le résultat de la recherche</span>
vector<span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span> p<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">num_vertices</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Les prédécesseurs</span>
vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span>      d<span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">num_vertices</span><span style="color: #008000;">&#40;</span>graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">// Les distances</span>
&nbsp;
<span style="color: #0000ff;">try</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// Encore une fois, la découverte d'un chemin est signalée par une exception, donc il faut un try/catch.</span>
    boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_search</span>
    <span style="color: #008000;">&#40;</span>
        graphe, <span style="color: #666666;">// notre graphe</span>
        start,  <span style="color: #666666;">// notre point de départ</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_heuristic</span><span style="color: #000080;">&lt;</span>NavMeshGraph, <span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #666666;">// Une heuristique bidon qui renvoie toujours 0</span>
        boost<span style="color: #008080;">::</span><span style="color: #007788;">predecessor_map</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>p<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">distance_map</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>d<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">visitor</span><span style="color: #008000;">&#40;</span>astar_goal_visitor<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">weight_map</span><span style="color: #008000;">&#40;</span>boost<span style="color: #008080;">::</span><span style="color: #007788;">get</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>WayPointConnection<span style="color: #008080;">::</span><span style="color: #007788;">dist</span>, graphe<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #666666;">// Voir plus bas</span>
    <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span>found_goal fg<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #666666;">// On a trouvé un chemin</span>
    <span style="color: #666666;">// On suit le chemin trouvé dans le sens inverse</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">list</span><span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span> shortest_path<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>WayPointID v <span style="color: #000080;">=</span> goal<span style="color: #008080;">;;</span> v <span style="color: #000080;">=</span> p<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        shortest_path.<span style="color: #007788;">push_front</span><span style="color: #008000;">&#40;</span>v<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>p<span style="color: #008000;">&#91;</span>v<span style="color: #008000;">&#93;</span> <span style="color: #000080;">==</span> v<span style="color: #008000;">&#41;</span>
            <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #666666;">// et on l'affiche.</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">list</span><span style="color: #000080;">&lt;</span>WayPointID<span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> spi <span style="color: #000080;">=</span> shortest_path.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">++</span>spi<span style="color: #008080;">;</span> spi <span style="color: #000040;">!</span><span style="color: #000080;">=</span> shortest_path.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>spi<span style="color: #008000;">&#41;</span>
        <span style="color: #0000dd;">Log</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>spi<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">Log</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Total travel time: &quot;</span> , d<span style="color: #008000;">&#91;</span>goal<span style="color: #008000;">&#93;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Remarque sur la ligne bizarre:</p>
<ul>
- Ce ne sont pas des virgules, ce sont des points ! Il s&#8217;agit d&#8217;un seul objet auquel on rajoute plein de propriétés. Cette syntaxe est par exemple utilisée dans la création d&#8217;interfaces graphiques : monmenu.addoption(&nbsp;&raquo;option1&#8243;).addoption(&nbsp;&raquo;option2&#8243;) etc<br />
- A* a besoin de ces quatre propriétés : une map de prédécesseurs, une map de distances, une map de poids, et un visiteur.<br />
- La map de poids est intrisèque au graphe : elle est stockée dans le champ dist des arcs. Mais Boost ne peut pas deviner tout seul que c&#8217;est cette variable qu&#8217;il faut lire, donc on le lui dit avec boost::get(&amp;WayPointConnection::dist, graphe)</p>
<li>Le visiteur est initialisé avec le goal pour pouvoir lancer son exception si il y a réussite.</li>
</ul>
<p>Vous avez économisé 4 heures de prise de tête avec la doc de BGL, autant d&#8217;implémentation de l&#8217;A* si vous l&#8217;aviez codé vous même, et autant de débug que vous n&#8217;aurez jamais à faire : un des grands intérêts des templates, c&#8217;est que comme en OCaml, quand ça compile, ça marche (souvent) ^^.</p>
<p>Voyons maintenant comment améliorer un peu notre heuristique : pour l&#8217;instant, on n&#8217;a fait qu&#8217;un parcours brutal de l&#8217;arbre, ça ne valait pas trop le coup.<br />
Cela va bien sûr passer par une nouvelle structure :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p429code12'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42912"><td class="code" id="p429code12"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> distance_heuristic <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> boost<span style="color: #008080;">::</span><span style="color: #007788;">astar_heuristic</span> <span style="color: #000080;">&lt;</span>WayPointGraph, <span style="color: #0000ff;">float</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #666666;">// De la même manière que tout à l'heure, on passe les données dont il aura besoin dans son foncteur à la construction.</span>
    distance_heuristic<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> WayPointGraph <span style="color: #000040;">&amp;</span> l, WayPointID goal<span style="color: #008000;">&#41;</span>
    <span style="color: #008080;">:</span> m_graph<span style="color: #008000;">&#40;</span>l<span style="color: #008000;">&#41;</span>, m_goal<span style="color: #008000;">&#40;</span>goal<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
    <span style="color: #0000ff;">float</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span>WayPointID u<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">const</span> WayPoint <span style="color: #000040;">&amp;</span> U <span style="color: #000080;">=</span> m_graph<span style="color: #008000;">&#91;</span>u<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">const</span> WayPoint <span style="color: #000040;">&amp;</span> V <span style="color: #000080;">=</span> m_graph<span style="color: #008000;">&#91;</span>m_goal<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">float</span> dx <span style="color: #000080;">=</span> U.<span style="color: #007788;">pos</span>.<span style="color: #007788;">x</span> <span style="color: #000040;">-</span> V.<span style="color: #007788;">pos</span>.<span style="color: #007788;">x</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">float</span> dy <span style="color: #000080;">=</span> U.<span style="color: #007788;">pos</span>.<span style="color: #007788;">y</span> <span style="color: #000040;">-</span> V.<span style="color: #007788;">pos</span>.<span style="color: #007788;">y</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">sqrt</span><span style="color: #008000;">&#40;</span>dx <span style="color: #000040;">*</span> dx <span style="color: #000040;">+</span> dy <span style="color: #000040;">*</span> dy<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">const</span> WayPointGraph <span style="color: #000040;">&amp;</span> m_graph<span style="color: #008080;">;</span>
    TriangleDescriptor m_goal<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>m_graph peut être remplacé ( en changeant le constructeur et l&#8217;opérateur ) par n&#8217;importe quoi qui vous permette d&#8217;obtenir la position d&#8217;un vertex à partir de son identifiant. Cela peut être comme ici le graphe lui-même, mais aussi les données à partir duquel il a été construit, etc.</p>
<p>Il suffit maintenant de remplacer boost::astar_heuristic<WayPointGraph, float>() par distance_heuristic(graphe, goal) dans l&#8217;appel au A*.</p>
<p>Oh, et au fait : les waypoints ça pue, utilisez des navmeshes.</p>
<p><a href="http://www.coder-studio.com/forum2/viewtopic.php?id=1392">Discussion sur le forum</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/tutoriel-boost-graph-library/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>(Petit) Clône de client telnet en Haskell</title>
		<link>http://www.coder-studio.com/blog/petit-clone-de-client-telnet-en-haskell/</link>
		<comments>http://www.coder-studio.com/blog/petit-clone-de-client-telnet-en-haskell/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 11:19:08 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[fonctionnel]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[telnet]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=421</guid>
		<description><![CDATA[Bonjour,
L&#8217;autre nuit, muni de café, j&#8217;ai souhaité m&#8217;amuser avec Haskell. J&#8217;ai alors consulté le chapitre sur le réseau en Haskell de Real World Haskell et&#8230; j&#8217;ai écrit un (très petit) clône de client telnet&#8230; qui fait 41 lignes. Le seul soucis étant que dans toute application de ce genre, on doit partager habilement la lecture [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour,</p>
<p>L&#8217;autre nuit, muni de café, j&#8217;ai souhaité m&#8217;amuser avec Haskell. J&#8217;ai alors consulté le chapitre sur le réseau en Haskell de <a href="http://book.realworldhaskell.org/read/">Real World Haskell</a> et&#8230; j&#8217;ai écrit un (très petit) clône de client telnet&#8230; qui fait 41 lignes. Le seul soucis étant que dans toute application de ce genre, on doit partager habilement la lecture des entrées de l&#8217;utilisateur, et l&#8217;affichage de ce que l&#8217;on nous envoie. Ceci mis à part, tout cela fonctionne très bien !</p>
<p><center><img src="http://haskell.org/logos/logos/logo7000.png" alt="Haskell" title="Haskell" /></center></p>
<p><span id="more-421"></span></p>
<p>Regardons à quoi cela ressemble. Petit détail : à chaque tour, je lance la réception de données réseau dans un autre thread, pour ne pas bloquer l&#8217;écriture de l&#8217;utilisateur.</p>
<p>On importe d&#8217;abord les modules nécessaires.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code20'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42120"><td class="code" id="p421code20"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Concurrent 
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Monad"><span style="color: #cccc00; font-weight: bold;">Monad</span></a> 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>Socket 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>BSD 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span>Environment 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a></pre></td></tr></table></div>

<p>Ensuite, j&#8217;ai écrit quelques fonctions pour rendre la connection, l&#8217;envoi etc plus faciles.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code21'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42121"><td class="code" id="p421code21"><pre class="haskell" style="font-family:monospace;"><span style="color: #5d478b; font-style: italic;">-- Ouverture d'une connexion TCP cliente </span>
<span style="color: #5d478b; font-style: italic;">-- Prend en argument l'host et le port/service (qui est une String également) </span>
<span style="color: #5d478b; font-style: italic;">-- Retourne le &quot;Handle&quot; vers le socket en question. </span>
openConnection <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> ServiceName <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> Handle 
openConnection hostname port <span style="color: #339933; font-weight: bold;">=</span> 
  <span style="color: #06c; font-weight: bold;">do</span> 
  addrInfos <span style="color: #339933; font-weight: bold;">&lt;-</span> getAddrInfo Nothing <span style="color: green;">&#40;</span>Just hostname<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Just port<span style="color: green;">&#41;</span> 
  <span style="color: #06c; font-weight: bold;">let</span> serveraddr <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:head"><span style="font-weight: bold;">head</span></a> addrInfos 
  sock <span style="color: #339933; font-weight: bold;">&lt;-</span> socket <span style="color: green;">&#40;</span>addrFamily serveraddr<span style="color: green;">&#41;</span> Stream defaultProtocol 
  setSocketOption sock KeepAlive <span style="color: red;">1</span> 
  connect sock <span style="color: green;">&#40;</span>addrAddress serveraddr<span style="color: green;">&#41;</span> 
  h <span style="color: #339933; font-weight: bold;">&lt;-</span> socketToHandle sock ReadWriteMode 
  hSetBuffering h <span style="color: green;">&#40;</span>BlockBuffering Nothing<span style="color: green;">&#41;</span> 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> h 
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Ferme la connexion dont le Handle est donné </span>
closeConnection <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
closeConnection h <span style="color: #339933; font-weight: bold;">=</span> hClose h 
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Envoie la chaîne donnée sur le Handle donné, et ensuite fait un flush sur ce handle, ce qui force l'envoi immédiat et nettoie les états </span>
sendMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
sendMsg h msg <span style="color: #339933; font-weight: bold;">=</span> hPutStrLn h msg <span style="color: #339933; font-weight: bold;">&gt;&gt;</span> hFlush h 
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Lis sur le Handle donné une chaîne et la renvoie (dans la monade IO) </span>
recvMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> 
recvMsg h <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  msg <span style="color: #339933; font-weight: bold;">&lt;-</span> hGetContents h  
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> msg</pre></td></tr></table></div>

<p>Voyons maintenant la fonction main.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code22'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42122"><td class="code" id="p421code22"><pre class="haskell" style="font-family:monospace;">main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs 
  <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>host<span style="color: #339933; font-weight: bold;">,</span> port<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">0</span><span style="color: #339933; font-weight: bold;">,</span> args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span></pre></td></tr></table></div>

<p>On récupère les arguments donnés au programme (s&#8217;il n&#8217;y en a pas assez, cela fera planter le logiciel &#8212; je ne me suis pas vraiment préoccupé de tous les cas d&#8217;erreur, mais ce n&#8217;était pas ma priorité ici) via la fonction getArgs, et l&#8217;on en récupère l&#8217;host et le port donnés.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code23'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42123"><td class="code" id="p421code23"><pre class="haskell" style="font-family:monospace;">  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="color: #339933; font-weight: bold;">$</span> <span style="background-color: #3cb371;">&quot;Opening client on &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> host <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;:&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> port <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> 
  hclient <span style="color: #339933; font-weight: bold;">&lt;-</span> openConnection host port 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="background-color: #3cb371;">&quot;Client connected&quot;</span></pre></td></tr></table></div>

<p>Ca y est, on se connecte, en affichant des messages pour tenir l&#8217;utilisateur informé. Si la connection échoue, le programme s&#8217;arrêtera avec une erreur &#8212; cf remarque ci-dessus.</p>
<p>Et maintenant, la boucle qui permet de lire depuis le réseau et lire depuis l&#8217;utilisateur, etc.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code24'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42124"><td class="code" id="p421code24"><pre class="haskell" style="font-family:monospace;">  forever <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span> 
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:getLine"><span style="font-weight: bold;">getLine</span></a> <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> sendMsg hclient 
    forkIO <span style="color: #339933; font-weight: bold;">$</span> recvMsg hclient <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a></pre></td></tr></table></div>

<p>Ici, on a une sorte de boucle &laquo;&nbsp;à la while(true)&nbsp;&raquo;, dans laquelle on va tour à tour récupérer une entrée de l&#8217;utilisateur et l&#8217;envoyer au serveur, puis, dans un thread séparé, récupérer ce qu&#8217;a envoyé le serveur et l&#8217;afficher.<br />
Enfin, on ferme la connection (ce code est inutile tant que l&#8217;on a pas de possibilité de sortir du forever&#8230; qui devra tôt ou tard se transformer en &laquo;&nbsp;until&nbsp;&raquo; ou autre).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code25'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42125"><td class="code" id="p421code25"><pre class="haskell" style="font-family:monospace;">  closeConnection hclient</pre></td></tr></table></div>

<p>Voilà le code complet :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code26'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p42126"><td class="code" id="p421code26"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Concurrent 
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Monad"><span style="color: #cccc00; font-weight: bold;">Monad</span></a> 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>Socket 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>BSD 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span>Environment 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> 
&nbsp;
openConnection <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> ServiceName <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> Handle 
openConnection hostname port <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  addrInfos <span style="color: #339933; font-weight: bold;">&lt;-</span> getAddrInfo Nothing <span style="color: green;">&#40;</span>Just hostname<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Just port<span style="color: green;">&#41;</span> 
  <span style="color: #06c; font-weight: bold;">let</span> serveraddr <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:head"><span style="font-weight: bold;">head</span></a> addrInfos 
  sock <span style="color: #339933; font-weight: bold;">&lt;-</span> socket <span style="color: green;">&#40;</span>addrFamily serveraddr<span style="color: green;">&#41;</span> Stream defaultProtocol 
  setSocketOption sock KeepAlive <span style="color: red;">1</span> 
  connect sock <span style="color: green;">&#40;</span>addrAddress serveraddr<span style="color: green;">&#41;</span> 
  h <span style="color: #339933; font-weight: bold;">&lt;-</span> socketToHandle sock ReadWriteMode 
  hSetBuffering h <span style="color: green;">&#40;</span>BlockBuffering Nothing<span style="color: green;">&#41;</span> 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> h 
&nbsp;
closeConnection <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
closeConnection h <span style="color: #339933; font-weight: bold;">=</span> hClose h 
&nbsp;
sendMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
sendMsg h msg <span style="color: #339933; font-weight: bold;">=</span> hPutStrLn h msg <span style="color: #339933; font-weight: bold;">&gt;&gt;</span> hFlush h 
&nbsp;
recvMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> 
recvMsg h <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  msg <span style="color: #339933; font-weight: bold;">&lt;-</span> hGetContents h  
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> msg 
&nbsp;
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs 
  <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>host<span style="color: #339933; font-weight: bold;">,</span> port<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">0</span><span style="color: #339933; font-weight: bold;">,</span> args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span> 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="color: #339933; font-weight: bold;">$</span> <span style="background-color: #3cb371;">&quot;Opening client on &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> host <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;:&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> port <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> 
  hclient <span style="color: #339933; font-weight: bold;">&lt;-</span> openConnection host port 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="background-color: #3cb371;">&quot;Client connected&quot;</span> 
  forever <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span> 
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:getLine"><span style="font-weight: bold;">getLine</span></a> <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> sendMsg hclient 
    forkIO <span style="color: #339933; font-weight: bold;">$</span> recvMsg hclient <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> 
  closeConnection hclient</pre></td></tr></table></div>

<p>Compilation :</p>
<blockquote><p>ghc &#8211;make -o net net.hs</p></blockquote>
<p>Puis 2 exemples d&#8217;exécution&#8230;<br />
<code>
<pre>
$ ./net google.fr 80
Opening client on google.fr:80
Client connected
GET / HTTP/1.0
HTTP/1.0 302 Found
Location: http://www.google.fr/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=30b094ad566b5532:TM=1251456529:LM=1251456529:S=94IXp5-SGiaYADWc; expires=Sun, 28-Aug-2011 10:48:49 GMT; path=/; domain=.google.com
Date: Fri, 28 Aug 2009 10:48:49 GMT
Server: gws
Content-Length: 218 

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.fr/">here</A>.
</BODY></HTML> 

^C
</pre>
<p></code><br />
(c&#8217;est moi qui ai tapé &laquo;&nbsp;GET / HTTP/1.0&#8243;)<br />
( qui vous dira que la page a été déplacée <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p>Et enfin, la surprise&#8230;</p>
<blockquote><p>$ ./net towel.blinkenlights.nl 23</p></blockquote>
<p>Qui, une version simplifiée d&#8217;un film très connu, vous permettra de voir, Jedi.</p>
<p>Enjoy !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/petit-clone-de-client-telnet-en-haskell/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>CipherSaber &#8211; Chiffrement en kit</title>
		<link>http://www.coder-studio.com/blog/ciphersaber-chiffrement-en-kit/</link>
		<comments>http://www.coder-studio.com/blog/ciphersaber-chiffrement-en-kit/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 22:07:59 +0000</pubDate>
		<dc:creator>Wett</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[ARC4]]></category>
		<category><![CDATA[ARCFOUR]]></category>
		<category><![CDATA[Chiffrement]]></category>
		<category><![CDATA[CipherSaber]]></category>
		<category><![CDATA[Cryptage]]></category>
		<category><![CDATA[RC4]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=404</guid>
		<description><![CDATA[CipherSaber, c'est la reprise du concept selon lequel il faut en savoir faire un minimum, tout seul, comme un grand. A l'instar des Jedis dans l'univers Star Wars qui vont réaliser eux-même leur sabre laser (vous comprenez maintenant le nom du projet), on nous propose de réaliser nous-même notre petit logiciel de chiffrement. ]]></description>
			<content:encoded><![CDATA[<h2>Sabre <span style="text-decoration: line-through;">laser</span> de chiffrement</h2>
<p>Au détour d&#8217;une naviguation web fortuite mais bienheureuse, je suis tombé sur <a title="CipherSaber" href="http://ciphersaber.gurus.org/">CipherSaber</a>. Vous savez, c&#8217;est ce genre de moment où on tombe sur une initiative sympa, facile à suivre et qui fait sens. Bref, j&#8217;ai accroché tout de suite, alors j&#8217;ai laissé tomber ce que j&#8217;étais en train de faire et y ai consacré mes heures suivantes.<br />
CipherSaber, c&#8217;est la reprise du concept selon lequel il faut en savoir faire un minimum, tout seul, comme un grand. A l&#8217;instar des Jedis dans l&#8217;univers Star Wars qui vont réaliser eux-même leur sabre laser (vous comprenez maintenant le nom du projet), on nous propose de réaliser nous-même notre petit logiciel de chiffrement.<span id="more-404"></span> Je vous laisse parcourir le site pour une explication plus en détail de la philosophie derrière ce petit combat pour la cryptographie, mais l&#8217;idée est là : A n&#8217;importe quel moment, nous devrions être capable de produire un logiciel de chiffrement suffisamment solide pour être utilisé sans risque, afin de s&#8217;affranchir des éventuelles lois contre l&#8217;exportation et garantir notre liberté de parole, autant que faire se peut. Joli programme !<br />
Voici les instructions que l&#8217;on nous fournit pour réaliser cet outil (directement traduites depuis le lien du début de l&#8217;article) :</p>
<ol>
<li> Utiliser l&#8217;algorithme de chiffrement ARCFOUR (ou RC4), tel que décrit par exemple <a title="ici" href="http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt">ici</a>.</li>
<li>Chaque fichier chiffré se compose d&#8217;un Vecteur d&#8217;Initialisation (IV) de 10 octets, puis du contenu chiffré. Un nouveau vecteur aléatoire devra être généré à chaque chiffrement de fichier.</li>
<li>La clé de chiffrement se compose elle de la clé que l&#8217;utilisateur nous fournit suivie de ce même Vecteur d&#8217;Initialisation.</li>
</ol>
<p>Et effectivement, ce sont les seules indications dont nous aurons besoin. Une fois le programme réalisé, nous aurons la possibilité de déchiffrer un certificat en gif, preuve de notre petite réussite. Si l&#8217;idée vous plait et que vous souhaitez vous contenter de ces informations pour vous-même construire votre CipherSaber, alors ne revenez lire la suite de cet article que quand vous aurez votre certificat !</p>
<h2>ARCFOUR ?</h2>
<p>ARCFOUR, c&#8217;est l&#8217;algorithme libre identique au RC4 qui lui est une propriété de RSA Security. Ici, pas de clé publique/privée, pas d&#8217;algorithme alambiqué, mais une solution implémentable &laquo;&nbsp;de tête&nbsp;&raquo;, pour peu qu&#8217;on fasse l&#8217;effort de la comprendre et d&#8217;en retenir les fondements.</p>
<p>Bon, ok, c&#8217;est gentil, mais le ARCFOUR moi, je ne le connais pas. Qu&#8217;à cela ne tienne, il suffira de suivre le lien donné ou de rechercher RC4 sur le web pour que l&#8217;algorithme nous tombe tout cru, ou presque. Mais j&#8217;insiste, le but ici est de pouvoir à tout moment réécrire ce logiciel de mémoire, donc on apportera un soin tout particulier à en retenir les principes de fonctionnement.</p>
<p>C&#8217;est un algorithme de chiffrement à flot, il repose sur deux phases :</p>
<ol>
<li>A partir de la clé K que nous donne l&#8217;utilisateur, on va générer un tableau d&#8217;état S que l&#8217;on va mélanger de nombreuses fois afin d&#8217;obtenir une suite de chiffres pseudo-aléatoires.</li>
<li>On va ensuite chiffrer le contenu sensible par un simple XOR entre ses octets et ceux du tableau d&#8217;état. Si c&#8217;est votre tout premier pas dans le monde de la cryptographie, sachez que l&#8217;opération XOR est &laquo;&nbsp;réversible&nbsp;&raquo; (il y a sûrement un terme mathématique approprié à cette propriété, pardon à eux pour mon ignorance), c&#8217;est à dire que si A xor B = C, alors A xor C = B. On utilise donc exactement la même procédure et la même clé pour chiffrer et déchiffrer.</li>
</ol>
<p>Maintenant qu&#8217;on saisit la généralité de la méthode, voyons comment la réaliser plus en détail :</p>
<ol>
<li>Créons notre tableau d&#8217;état :
<ol>
<li>Soit la clé K d&#8217;une taille de 256 octets (si elle fait moins, on la répète à la suite jusqu&#8217;à obtenir 256 octets pile)</li>
<li>Construisons un tableau S de 256 valeurs, chacune contenant son index basé à 0 : S[0] = 0, S[255]=255.</li>
<li>Mélangeons S, avec i allant de 0 à 255 et j démarrant à 0:
<ol>
<li>Inverser l&#8217;élément i de S <em>avec celui de rang</em> (S[i]+K[i])+j, j étant le rang du &laquo;&nbsp;mélangé&nbsp;&raquo; précédent. Autrement dit, ajouter S[i]+K[i] à j et inverser S[i] et S[j]</li>
</ol>
</li>
</ol>
</li>
<li>Chiffrons :
<ol>
<li>Boucler sur chaque octet du fichier à chiffrer, et avec i et j démarrant à 0 :
<ol>
<li>incrémenter i</li>
<li>Un peu comme précédemment, inverser l&#8217;élément i de S avec celui de rang (S[i]+j), j étant le rang du mélangé précédent. Autrement dit, ajouter S[i] à j et inverser S[i] et S[j]</li>
<li>Combiner l&#8217;octet à chiffrer avec la valeur de l&#8217;élément S[i]+S[j] par un XOR.</li>
</ol>
</li>
</ol>
</li>
</ol>
<p>J&#8217;ai conscience que ce n&#8217;est sûrement pas clair au premier abord, mais j&#8217;ai essayé ici de résumer l&#8217;algorithme par ses opérations logiques, afin que ce soit appréhendable pour l&#8217;esprit et donc plus aisé à retenir. Pour une version plus proche de l&#8217;implémentation, il vous reste votre moteur de recherche préféré. Retenez par contre un détail important : Chaque éléments de chaque tableau est un octet, il en va de même pour i et j. Par conséquent, <strong>chaque addition se fait modulo 256</strong>.</p>
<p>Une fois votre implémentation écrite, n&#8217;hésitez pas à la tester. Un petit chiffrement/dechiffrement pour s&#8217;assurer que tout va bien ne sera pas de trop, croyez-moi.</p>
<h2>IVs et tests</h2>
<p>Maintenant que votre ARC4 est implémenté et testé, reste à en faire quelque chose. Oui car utilisé tel quel, c&#8217;est un algorithme tout à fait prévisible, or nous recherchons un chiffrement suffisament fort. La règle qui semble être celle de base, c&#8217;est qu&#8217;un même chiffrement appliqué à un même fichier ne doit pas donner le même résultat. L&#8217;idée est donc d&#8217;ajouter un IV, l&#8217;Initialisation Vector dont on parlait plus haut.  Ainsi, lors du chiffrement, on va générer un IV <em>aléatoire</em> de 10 octets, qu&#8217;on va :</p>
<ul>
<li>Mettre à la suite de la clé que nous a fourni l&#8217;utilisateur pour produire une clé <em>unique</em> à fournir à l&#8217;argorithme de chiffrement</li>
<li>Ajouter en clair au début du fichier crypté, afin quand même que l&#8217;on puisse connaitre la clé à utiliser pour déchiffrer.</li>
</ul>
<p>L&#8217;IV est donc une donnée &laquo;&nbsp;publique&nbsp;&raquo; puisqu&#8217;en clair, mais cela suffit à notre besoin de non-répétition. Par contre son choix est important, crucial même, alors attention à la méthode de génération pseudo aléatoire que vous allez utiliser.</p>
<p>Et voilà ! Une fois ce dernier détail implémenté, il ne vous reste plus qu&#8217;à tester votre programme sur les fichiers chiffrés fournis sur le site. Si vos tests ne fonctionnent pas, vous trouverez dans la FAQ quelques points à vérifier dans votre code pour trouver le bug. Voici ceux qui m&#8217;ont servi :</p>
<ul>
<li> Si vous programmez en C/C++, ouvrez vos fichiers en binaire&#8230; On aurait tendance à l&#8217;oublier.</li>
<li>Double, triple-vérifiez vos index et les combinaisons de tailles, ajout, suppression, décalages.</li>
</ul>
<h2>Aller un peu plus loin</h2>
<p>Ainsi que vous avez peut-être lu quelque part, certaines faiblesses ont été décelées dans l&#8217;ARC4. Elles sont notamment à la base des attaques contre le protocole WEP maintenant si rapides qu&#8217;on peut faire tomber un réseau Wifi en 15 minutes. L&#8217;auteur recommande donc de passer à&#8230; CipherSaber 2 ! &lt;Musique épique, et là avouez, ça picote !&gt;</p>
<p>En fait ce n&#8217;est qu&#8217;une petite évolution de votre programme actuel : le moyen le plus simple de sécuriser son CipherSaber est de démultiplier le nombre de mélanges de S. Ainsi, à l&#8217;étape 3 de la création de notre tableau d&#8217;état décrite ci-dessus, on va non pas effectuer ce mélange complet de S une fois mais N fois, N étant une donnée qu&#8217;il faudra bien évidemment connaitre lors du déchiffrement. Pour être tranquille, utilisez un N de 15 ou 20.</p>
<h2>Aller vraiment au bout de son sabre</h2>
<p>Mais toute bonne votre méthode de chiffrement soit-elle, si vous utilisez une passphrase de 3 lettres ou votre date d&#8217;anniversaire, tout cela n&#8217;aura servi à rien. Ce n&#8217;est pas le but de l&#8217;article que de décrire un moyen efficace d&#8217;en générer une, mais sachez qu&#8217;il existe des méthodes comme celle décrite sur <a title="Diceware" href="http://world.std.com/~reinhold/diceware.html">Diceware</a> (c&#8217;est depuis ce site que j&#8217;ai découvert CipherSabre, ce n&#8217;est donc pas par hasard que je met ce lien ici). Retenez tout de même qu&#8217;un mot de passe n&#8217;est pas une.. hm, et bien phrase de passe. Le premier est adapté à un contexte local, lorsque vous avez besoin d&#8217;un mot court à entropie forte. La passphrase, de ce que j&#8217;en comprend, permet de s&#8217;affranchir plus ou moins du coté &laquo;&nbsp;impossible à retenir&nbsp;&raquo; d&#8217;un vrai de mot de passe fort, en augmentant la taille de la clé à 15 ou 20 caractères avec des mots courants, tout en fournissant pour peu qu&#8217;elle soit bien choisie (aléatoire) un entropie plus que satisfaisante.</p>
<h2>Et alors ?</h2>
<p>Et bien voilà, maintenant vous savez écrire un logiciel de chiffrement. Gardez bien-sûr conscience qu&#8217;il ne remplacera jamais une vraie solution comme OpenPGP, qui malgré sa puissance est deja suffisament mal diffusée pour qu&#8217;on n&#8217;en rajoute pas à vouloir utiliser notre solution personnelle moins pratique et moins sûre. Mais enfin, à votre niveau vous savez reproduire tout seul un outil basique mais potentiellement utile en situation réelle, vous avez limité votre dépendance à ceux qui savent, ceux qui dirigent, ceux en qui on vous demande d&#8217;avoir une confiance presque aveugle. Et enfin, vous en aurez un peu appris sur les fondements de la cryptographie, peut-être plus qu&#8217;en jouant avec AirCrack sur votre propre réseau ou celui du voisin&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/ciphersaber-chiffrement-en-kit/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Haskell Platform, ou comment se mettre à Haskell sans soucis !</title>
		<link>http://www.coder-studio.com/blog/haskell-platform-ou-comment-se-mettre-a-haskell-sans-soucis/</link>
		<comments>http://www.coder-studio.com/blog/haskell-platform-ou-comment-se-mettre-a-haskell-sans-soucis/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 08:19:14 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[platform]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=401</guid>
		<description><![CDATA[Bonjour à tous,
Cela fait quelques temps maintenant que la communauté Haskell a sorti Haskell Platform. Il s&#8217;agit d&#8217;un &#171;&#160;paquet&#160;&#187; qui regroupe :
- le compilateur haskell GHC, un debugger, un profiler, etc
- les bibliothèques les plus populaires et les plus utilisées, fournies d&#8217;office
- tout un tas d&#8217;outils auxiliaires, comme haddock, qui permet de générer de la [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour à tous,</p>
<p>Cela fait quelques temps maintenant que la communauté <a href="http://www.haskell.org/">Haskell</a> a sorti <strong><a href="http://hackage.haskell.org/platform/">Haskell Platform</a></strong>. Il s&#8217;agit d&#8217;un &laquo;&nbsp;paquet&nbsp;&raquo; qui regroupe :<br />
- le compilateur haskell GHC, un debugger, un profiler, etc<br />
- les bibliothèques les plus populaires et les plus utilisées, fournies d&#8217;office<br />
- tout un tas d&#8217;outils auxiliaires, comme <em>haddock</em>, qui permet de générer de la documentation depuis les commentaires du code source.</p>
<p>Il existe des paquets pour déjà quelques distributions Linux, sachant que ce sera bientôt prêt pour Debian et Ubuntu également. Les installeurs Windows et Mac sont très simples également.</p>
<p>Bref, plus aucune raison de ne pas essayer Haskell <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/haskell-platform-ou-comment-se-mettre-a-haskell-sans-soucis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Préprocesseur et énumérations : la suite.</title>
		<link>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/</link>
		<comments>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 20:34:09 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[énumération]]></category>
		<category><![CDATA[préprocesseur]]></category>
		<category><![CDATA[template]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=393</guid>
		<description><![CDATA[Cet article fait suite à mon premier article intitulé &#171;&#160;Faire un peu joujou avec le préprocesseur&#160;&#187;
(disponible ici : http://www.coder-studio.com/blog/preproc/ ).
Pour rappel, nous en sommes restés à un système de macro qui permettait d&#8217;automatiser la création
d&#8217;un opérateur &#171;&#160;]]></description>
			<content:encoded><![CDATA[<p>Cet article fait suite à mon premier article intitulé &laquo;&nbsp;Faire un peu joujou avec le préprocesseur&nbsp;&raquo;<br />
(disponible ici : http://www.coder-studio.com/blog/preproc/ ).</p>
<p>Pour rappel, nous en sommes restés à un système de macro qui permettait d&#8217;automatiser la création<br />
d&#8217;un opérateur &laquo;&nbsp;<<" pour iostream, capable d'afficher le nom d'une énumération.</p>
<p><span id="more-393"></span></p>
<p>Voici le code :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code38'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39338"><td class="code" id="p393code38"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\</span>
	<span style="color: #0000ff;">enum</span> enum_name <span style="color: #008000;">&#123;</span> __VA_ARGS__ <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\</span>
	<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>	\
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;	\</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(nb_vals, enum_name, ...)	\</span>
	<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> enum_name<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span>\
		<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>	\
			ENUM_CASE_N<span style="color: #008000;">&#40;</span>nb_vals, __VA_ARGS__<span style="color: #008000;">&#41;</span>	\
		<span style="color: #008000;">&#125;</span>	\
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>	\
	<span style="color: #008000;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(nb_vals, enum_name, ...)	\</span>
	MAKE_ENUM<span style="color: #008000;">&#40;</span>enum_name, __VA_ARGS__<span style="color: #008000;">&#41;</span>	\
	MAKE_OPERATOR<span style="color: #008000;">&#40;</span>nb_vals, enum_name, __VA_ARGS__<span style="color: #008000;">&#41;</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code39'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39339"><td class="code" id="p393code39"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">3</span>, MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Le plus gros problème de ce système est le fait que l&#8217;on soit obligés de donner le nombre de valeurs de l&#8217;énumération<br />
lors de l&#8217;utilisation de la macro ENUMERATE.</p>
<p>Ce qui nous oblige à spécifier ce numéro, c&#8217;est la nécessiter de &laquo;&nbsp;choisir&nbsp;&raquo; la bonne macro parmi ENUM_CASE_1, ENUM_CASE_2, &#8230;, ENUM_CASE_10.</p>
<p>Se passer de ce nombre, c&#8217;est effectuer l&#8217; &laquo;&nbsp;appel récursif&nbsp;&raquo; jusqu&#8217;à ce qu&#8217;il n&#8217;y ait plus d&#8217;argument à traiter dans la<br />
&laquo;&nbsp;liste&nbsp;&raquo; __VA_ARGS__.</p>
<p>Que se passe-t-il si l&#8217;on supprime ce nombre et que l&#8217;on remplace l&#8217;appel à ENUM_CASE_N par la version qui gère le plus d&#8217;arguments<br />
(ici ENUM_CASE_10, donc) ?</p>
<p>Version remaniée :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code40'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39340"><td class="code" id="p393code40"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\</span>
	<span style="color: #0000ff;">enum</span> enum_name <span style="color: #008000;">&#123;</span> __VA_ARGS__ <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\</span>
	<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>	\
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;	\</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(enum_name, ...)	\</span>
	<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> enum_name<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span>\
		<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>	\
			ENUM_CASE_10<span style="color: #008000;">&#40;</span>__VA_ARGS__<span style="color: #008000;">&#41;</span>	\
		<span style="color: #008000;">&#125;</span>	\
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>	\
	<span style="color: #008000;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(enum_name, ...)	\</span>
	MAKE_ENUM<span style="color: #008000;">&#40;</span>enum_name, __VA_ARGS__<span style="color: #008000;">&#41;</span>	\
	MAKE_OPERATOR<span style="color: #008000;">&#40;</span>enum_name, __VA_ARGS__<span style="color: #008000;">&#41;</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code41'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39341"><td class="code" id="p393code41"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// test.cpp</span>
&nbsp;
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Après un appel au préprocesseur par &laquo;&nbsp;cpp test.cpp&nbsp;&raquo;, voici ce qu&#8217;il nous affiche (remis en forme pour être lisible et<br />
en enlevant les lignes commençant par un #, sans importance) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code42'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39342"><td class="code" id="p393code42"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">enum</span> MonEnumeration <span style="color: #008000;">&#123;</span> E_VAL_1, E_VAL_2, E_VAL_3 <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> MonEnumeration<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">case</span> E_VAL_1<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_2<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_2&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_3<span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_3&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> <span style="color: #008080;">:</span> os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Vous voyez le problème : on a des &laquo;&nbsp;case :&nbsp;&raquo; à partir du stade où il n&#8217;y a plus d&#8217;argument. Il faut donc remplacer<br />
chaque ligne &laquo;&nbsp;case &#8230;&nbsp;&raquo; (correspondant à ce que génère ENUM_CASE_1) par quelque chose qui puisse faire un test d&#8217;égalité<br />
entre &laquo;&nbsp;e&nbsp;&raquo; et &laquo;&nbsp;E_VAL_1&#8243;, &laquo;&nbsp;E_VAL_2&#8243;&#8230;etc, mais qui puisse aussi compiler et ne rien faire lorsqu&#8217;en lieu et place<br />
de &laquo;&nbsp;E_VAL_XXX&nbsp;&raquo;, il n&#8217;y a rien.</p>
<p>Là, on pense à la surcharge de fonction ! En effet, si l&#8217;on a une fonction surchargée ainsi :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code43'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39343"><td class="code" id="p393code43"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// blabla</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// blublu</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>on peut obtenir un comportement différent selon que l&#8217;on passe ou pas quelque chose en argument à la fonction !<br />
Il suffirait de remplacer chaque ligne &laquo;&nbsp;case &#8230;&nbsp;&raquo; par un test d&#8217;égalité qui aurait cette forme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code44'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39344"><td class="code" id="p393code44"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #008000;">&#40;</span>e, E_VAL_1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span> <span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>et le tour est joué !</p>
<p>Mais attendez, vous ne voyez pas un problème ? Si, si : contrairement à la fonction f() de l&#8217;exemple, ce &laquo;&nbsp;TestEgalite&nbsp;&raquo;<br />
a 2 arguments. Si l&#8217;on remplace &laquo;&nbsp;E_VAL_1&#8243; par du vide, on obtient un &laquo;&nbsp;if(TestEgalite(e, )) {blabla;}&nbsp;&raquo; : ça ne marche pas !</p>
<p>Le problème reste donc entier&#8230;<br />
Oui, pour ceux qui se demandent, cette partie de l&#8217;article n&#8217;apporte rien à la solution, c&#8217;est juste la démarche que j&#8217;ai<br />
eue : vous pouvez vous dire que ça ne sert à rien, je ne vous le reprocherai pas, mais maintenant c&#8217;est trop tard, vous<br />
l&#8217;avez lu :p</p>
<p>On pourrait se poser le problème ainsi : comment, à partir d&#8217;une fonction à 2 arguments, en faire 2 fonctions à 1 argument ?<br />
En effet, si l&#8217;on arrive à en faire 2 fonctions à 1 argument, alors le problème serait réglé <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Si je ne m&#8217;abuse, il<br />
s&#8217;agit de la &laquo;&nbsp;curryfication&nbsp;&raquo;, que l&#8217;on trouve en programmation fonctionnelle et en lambda-calcul <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Peut-être est-ce possible, je n&#8217;ai pas exploré cette possibilité. Il ne m&#8217;étonnerait pas que cela soit possible grâce à des<br />
foncteurs, i.e. une classe dont un surcharge l&#8217;opérateur &laquo;&nbsp;()&nbsp;&raquo;. On peut ainsi se retrouver avec une construction de la forme<br />
&laquo;&nbsp;MaClasse(arg1)(arg2)&nbsp;&raquo;, i.e. un appel au constructeur suivi d&#8217;un appel à l&#8217;opérateur &laquo;&nbsp;()&nbsp;&raquo;.</p>
<p>En fait, à mon avis, c&#8217;est une solution possible, je garderai peut-être pour la suite, dans un hypothétique futur article <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Quoi qu&#8217;il en soit, pour en revenir au problème : on peut aussi se le poser ainsi : est-on obligés de traiter les cas où<br />
le préprocesseur ne met rien, en lieu et place de nos &laquo;&nbsp;E_VAL_1&#8243;, &laquo;&nbsp;E_VAL_2&#8243;&#8230;etc ? Dit encore autrement, ne peut-on pas mettre<br />
quelque chose d&#8217;autre à la place ? Qu&#8217;est-ce qui nous arrangerait alors ?</p>
<p>Hmm, voyons voir, remplacer le vide par quelque chose que l&#8217;on pourrait tester lors de la compilation&#8230;<br />
Il s&#8217;agit bien de méta-programmation. Or, en méta-programmation : les 2 outils principaux que le C++ met à notre disposition<br />
sont les macros et les templates.</p>
<p>Eurêka !</p>
<p>On peut &laquo;&nbsp;surcharger&nbsp;&raquo; une fonction template qui s&#8217;occupera de faire le test d&#8217;égalité !<br />
On écrit alors les tests d&#8217;égalité comme ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code45'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39345"><td class="code" id="p393code45"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span>E_VAL_1<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span>E_VAL_2<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span>
...
<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>TestEgalite<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">void</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>blabla<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>On déclare alors TestEgalite sous cette forme :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code46'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39346"><td class="code" id="p393code46"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span>MonEnumeration val<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> TestEgalite<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> EnumType<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> e <span style="color: #000080;">==</span> val<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> TestEgalite<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> EnumType<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Et le tour est joué !</p>
<p>Bon, maintenant, pour faire plus pro, en renommant ça en anglais et en préfixant par le nom de l&#8217;énumération<br />
(histoire que l&#8217;on n&#8217;ait pas de conflit s&#8217;il y a 2 énumérations différentes, au cas où), et en remettant tout<br />
ensemble, cela donne ceci :</p>
<p>Version finale :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code47'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39347"><td class="code" id="p393code47"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(EnumType, ...)	\</span>
	<span style="color: #0000ff;">enum</span> EnumType <span style="color: #008000;">&#123;</span> __VA_ARGS__ <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(EnumType, val, ...)	\</span>
	<span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>EnumType <span style="color: #339900;">## _EnumIsEqual&lt;val&gt;(e)) {os &lt;&lt; #val; break;}</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_1(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_3(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_2(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_4(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_3(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_5(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_4(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_6(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_5(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_7(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_6(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_8(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_7(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_9(EnumType, val, ...)		ENUM_CASE_1(EnumType, val) ENUM_CASE_8(EnumType, __VA_ARGS__, void)</span>
<span style="color: #339900;">#define ENUM_CASE_10(EnumType, val, ...)	ENUM_CASE_1(EnumType, val) ENUM_CASE_9(EnumType, __VA_ARGS__, void)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(EnumType, ...)	\</span>
	<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span>EnumType val<span style="color: #000080;">&gt;</span>				\
	<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> EnumType <span style="color: #339900;">## _EnumIsEqual(const EnumType&amp; e) {	\</span>
		<span style="color: #0000ff;">return</span> e <span style="color: #000080;">==</span> val<span style="color: #008080;">;</span>										\
	<span style="color: #008000;">&#125;</span>															\
																\
	<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>											\
	<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">bool</span> EnumType <span style="color: #339900;">## _EnumIsEqual(const EnumType&amp; e) {	\</span>
		<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>											\
	<span style="color: #008000;">&#125;</span>															\
																\
	<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> EnumType<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>	\
		<span style="color: #0000ff;">do</span> <span style="color: #008000;">&#123;</span>																\
			ENUM_CASE_10<span style="color: #008000;">&#40;</span>EnumType, __VA_ARGS__, <span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span>								\
		<span style="color: #008000;">&#125;</span> <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>											\
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>											\
	<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #339900;">#define ENUMERATE(EnumType, ...)		\</span>
	MAKE_ENUM<span style="color: #008000;">&#40;</span>EnumType, __VA_ARGS__<span style="color: #008000;">&#41;</span>	\
	MAKE_OPERATOR<span style="color: #008000;">&#40;</span>EnumType, __VA_ARGS__<span style="color: #008000;">&#41;</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p393code48'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p39348"><td class="code" id="p393code48"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Voilà pour cette partie <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ceci dit, un problème est résolu, mais il en reste d&#8217;autres, notamment :<br />
- ça doit toujours aussi mal passer auprès des systèmes d&#8217;auto-complétion (enfin, j&#8217;ai pas testé sur Visual Assist<br />
  ou Eclipse à vrai dire&#8230;)<br />
- on ne peut toujours pas attribuer de valeur numérique manuellement à un symbole de l&#8217;énumération</p>
<p>Il pourrait aussi être intéressant d&#8217;associer une autre chaîne de caractères, voire toute autre valeur, à un symbole de<br />
l&#8217;énumération&#8230;<br />
Tout comme il serait intéressant d&#8217;explorer une solution à base de pseudo-curryfication plutôt que de templates, voire, qui<br />
sait, une solution entièrement à base de templates. A ce sujet, un article très intéressant est disponible ici pour les<br />
curieux : http://www.codeguru.com/cpp/cpp/cpp_mfc/templates/article.php/c4137</p>
<p>Ce sera tout pour cette fois !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/preprocesseur-et-enumerations-la-suite/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Faire un peu joujou avec le préprocesseur&#8230;</title>
		<link>http://www.coder-studio.com/blog/preproc/</link>
		<comments>http://www.coder-studio.com/blog/preproc/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 18:53:54 +0000</pubDate>
		<dc:creator>Funto</dc:creator>
				<category><![CDATA[C & C++]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[énumération]]></category>
		<category><![CDATA[préprocesseur]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=371</guid>
		<description><![CDATA[Ça faisait un bail que je n'écrivais pas sur Coder-Studio...
Chose réparée :)

Du 17 au 19 avril 2009, a eu lieu la finale de Cod'INSA, un concours de programmation inter-INSA,
qui s'est déroulée à l'INSA de Toulouse (plus d'infos sur http://codinsa.insa-lyon.fr pour les intéressés).
Faisant partie des organisateurs, j'ai eu à faire l'interfaçage C++/Java (oui parce qu'il y en a qui veulent
participer en Java...allez comprendre :p [/troll]). J'y ai découvert les joies de GCJ et de CNI, ce qui
pourra peut-être être l'objet d'un autre article, selon ma motivation...

Bref, tout ça pour dire qu'il m'a fallu interfacer une librairie écrite en C avec du Java, et qu'il a fallu
automatiser un peu le boulot pour la partie concernant les énumérations.

Dans cet article, je vais illustrer une méthode pour faciliter l'affichage des valeurs des énumérations.
En gros, le but, c'est que si l'on a :
<pre lang="cpp">
MonEnumeration e = E_VAL_1;
std::cout << e << std::endl;
</pre>

il s'affiche alors à l'écran "E_VAL_1".]]></description>
			<content:encoded><![CDATA[<p>Ça faisait un bail que je n&#8217;écrivais pas sur Coder-Studio&#8230;<br />
Chose réparée <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Du 17 au 19 avril 2009, a eu lieu la finale de Cod&#8217;INSA, un concours de programmation inter-INSA,<br />
qui s&#8217;est déroulée à l&#8217;INSA de Toulouse (plus d&#8217;infos sur http://codinsa.insa-lyon.fr pour les intéressés).<br />
Faisant partie des organisateurs, j&#8217;ai eu à faire l&#8217;interfaçage C++/Java (oui parce qu&#8217;il y en a qui veulent<br />
participer en Java&#8230;allez comprendre :p [/troll]). J&#8217;y ai découvert les joies de GCJ et de CNI, ce qui<br />
pourra peut-être être l&#8217;objet d&#8217;un autre article, selon ma motivation&#8230;</p>
<p>Bref, tout ça pour dire qu&#8217;il m&#8217;a fallu interfacer une librairie écrite en C avec du Java, et qu&#8217;il a fallu<br />
automatiser un peu le boulot pour la partie concernant les énumérations.</p>
<p>Dans cet article, je vais illustrer une méthode pour faciliter l&#8217;affichage des valeurs des énumérations.<br />
En gros, le but, c&#8217;est que si l&#8217;on a :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code49'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37149"><td class="code" id="p371code49"><pre class="cpp" style="font-family:monospace;">MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>il s&#8217;affiche alors à l&#8217;écran &laquo;&nbsp;E_VAL_1&#8243;.</p>
<p><span id="more-371"></span></p>
<p>La version non automatisée consiste en l&#8217;écriture d&#8217;une surcharge de l&#8217;opérateur &laquo;&nbsp;<<". Programme de démonstration :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code50'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37150"><td class="code" id="p371code50"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
<span style="color: #0000ff;">enum</span> MonEnumeration
<span style="color: #008000;">&#123;</span>
	E_VAL_1,
	E_VAL_2
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> MonEnumeration<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">case</span> E_VAL_1<span style="color: #008080;">:</span>
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_1&quot;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">case</span> E_VAL_2<span style="color: #008080;">:</span>
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #FF0000;">&quot;E_VAL_2&quot;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Ce programme affiche bien &laquo;&nbsp;E_VAL_1&#8243; à l&#8217;écran.</p>
<p>Mais c&#8217;est tout de même bien contraignant : la duplication des informations est évidente : entre la<br />
déclaration de l&#8217;énumération et l&#8217;opérateur &laquo;&nbsp;<<", "E_VAL_1" est écrit 3 fois ! C'est évidemment source<br />
d'erreurs (le copier-coller n'est pas le meilleur ami du programmeur, loin s'en faut...), particulièrement<br />
lorsque l'on veut rajouter de nouvelles valeurs à l'énumération. Et puis c'est tout simplement pénible<br />
de devoir maintenir l'énumération et l'opérateur.<br />
Bref, c'est moche, peut mieux faire.</p>
<p>C'est là qu'arrive le préprocesseur.</p>
<p>A partir de là, je suppose que vous utilisez GCC (ou MinGW/Cygwin sous Windows).</p>
<p>Nous allons en particulier nous baser sur 2 opérateurs spéciaux du préprocesseur, qui ne sont pas très<br />
connus : # et ##.</p>
<p>Commençons par # : il permet de rajouter des guillemets autour de l'argument d'une macro.</p>
<p>Démonstration :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code51'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37151"><td class="code" id="p371code51"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define STRINGIFY(val) #val</span>
&nbsp;
STRINGIFY<span style="color: #008000;">&#40;</span>pouet<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>Supposons que vous ayez enregistré cela dans &laquo;&nbsp;pouet.h&nbsp;&raquo; : passez un coup de préprocesseur : &laquo;&nbsp;cpp pouet.h&nbsp;&raquo;<br />
(ou bien &laquo;&nbsp;g++ -E pouet.h&nbsp;&raquo;, ça revient au même).</p>
<p>Résultat affiché :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code52'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37152"><td class="code" id="p371code52"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
&nbsp;
&quot;pouet&quot;</pre></td></tr></table></div>

<p>Bon, déjà, ça c&#8217;est intéressant <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  On remarque que cpp écrit des lignes commençant par un #, que le compilateur<br />
qui passe derrière doit probablement interpréter pour les messages d&#8217;erreurs afin d&#8217;indiquer la ligne de l&#8217;erreur.</p>
<p>Passons à la suite : on voudrait une macro qui permette d&#8217;automatiser la création de l&#8217;opérateur &laquo;&nbsp;<<" pour<br />
l'affichage de la valeur de notre énumération.<br />
Essayons d'abord en supposant que notre énumération ne puisse contenir qu'une seule valeur :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code53'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37153"><td class="code" id="p371code53"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MAKE_ENUM(enum_name, val)	\</span>
	<span style="color: #0000ff;">enum</span> enum_name <span style="color: #008000;">&#123;</span>	\
		val			\
	<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(enum_name, val)	\</span>
	<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> enum_name<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span>\
		<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>	\
			<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>	\
				os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;	\</span>
				<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>	\
		<span style="color: #008000;">&#125;</span>	\
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>	\
	<span style="color: #008000;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(enum_name, val)	\</span>
	MAKE_ENUM<span style="color: #008000;">&#40;</span>enum_name, val<span style="color: #008000;">&#41;</span>	\
	MAKE_OPERATOR<span style="color: #008000;">&#40;</span>enum_name, val<span style="color: #008000;">&#41;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span>MonEnumeration,
	E_VAL_1<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>On a donc une macro MAKE_ENUM qui s&#8217;occupe de déclarer l&#8217;énumération et une macro MAKE_OPERATOR qui s&#8217;occupe<br />
de définir l&#8217;operateur &laquo;&nbsp;<<". Notez le "inline" qui sert à éviter tout problème de linkage (si le même fichier .h,<br />
qui décrit l'énumération et l'opérateur, est inclus dans 2 .cpp différents, on se retrouve avec l'opérateur défini 2<br />
fois, et couic !).</p>
<p>Cool, ça marche ! (en même temps c'est un tuto...)</p>
<p>Maintenant, on peut arrêter de contourner la difficulté et s'attaquer au vrai problème : comment gérer le fait<br />
qu'une énumération n'ai pas 1, 2, ou 3 valeurs, mais un nombre variable ??</p>
<p>C'est là qu'arrive une autre astuce du préprocesseur : la macro __VA_ARGS__.</p>
<p>Démonstration, dans notre pouet.h :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code54'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37154"><td class="code" id="p371code54"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MA_MACRO(...) __VA_ARGS__</span>
MA_MACRO<span style="color: #008000;">&#40;</span>a, b, c<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>cpp pouet.h donne :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code55'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37155"><td class="code" id="p371code55"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
a, b, c</pre></td></tr></table></div>

<p>Pratique, quand on veut des macros avec un nombre variable d&#8217;arguments&#8230;</p>
<p>On peut dores et déjà remplacer MAKE_ENUM par une version capable de gérer un nombre variable d&#8217;arguments :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code56'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37156"><td class="code" id="p371code56"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\</span>
	<span style="color: #0000ff;">enum</span> enum_name <span style="color: #008000;">&#123;</span> __VA_ARGS__ <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Ça, c&#8217;est fait. Maintenant, reste le problème de MAKE_OPERATOR&#8230;</p>
<p>Si l&#8217;on analyse le problème, on voit que l&#8217;on a 3 parties :</p>
<p>- une introduction :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code57'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37157"><td class="code" id="p371code57"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> enum_name<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span>
		<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span></pre></td></tr></table></div>

<p>- une partie qui se répète :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code58'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37158"><td class="code" id="p371code58"><pre class="cpp" style="font-family:monospace;">		<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>
			os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;</span>
			<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>- une conclusion :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code59'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37159"><td class="code" id="p371code59"><pre class="cpp" style="font-family:monospace;">		<span style="color: #008000;">&#125;</span>
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>Il s&#8217;agit donc, à partir d&#8217;une liste variable d&#8217;arguments, de répéter plusieurs fois la partie centrale pour<br />
chaque argument &laquo;&nbsp;val&nbsp;&raquo;. C&#8217;est là que j&#8217;ai pensé à ces vieux cours de Caml, où pour traiter une liste, on écrivait<br />
une fonction récursive, qui décomposait la liste en t::q (pour tête et queue), la tête étant le 1er élément, et la<br />
queue tout le reste. Désolé pour ceux qui n&#8217;ont pas fait de Caml :p</p>
<p>Pour revenir à notre préprocesseur, cela se traduirait par une macro qui prend en argument quelque chose de la forme :<br />
#define MACRO(a, &#8230;) et qui ensuite s&#8217;appellerait récursivement jusqu&#8217;à ce qu&#8217;il n&#8217;y ait plus d&#8217;argument.</p>
<p>Malheureusement, la récursivité, en préprocesseur ça n&#8217;existe pas, ou alors j&#8217;ai pas trouvé comment&#8230;</p>
<p>Il va donc falloir trouver une parade : il s&#8217;agira d&#8217;écrire une version de la macro pour chaque appel récursif, i.e.<br />
pour chaque nombre d&#8217;arguments :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code60'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37160"><td class="code" id="p371code60"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define ENUM_CASE_1(val)	\</span>
	<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>	\
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;	\</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span></pre></td></tr></table></div>

<p>Le problème n&#8217;est toujours pas totalement résolu : encore faut-il choisir la bonne macro à utiliser&#8230;</p>
<p>C&#8217;est là qu&#8217;arrive l&#8217;opérateur ## du préprocesseur <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Celui-ci permet de concaténer des symboles.</p>
<p>Exemple (dans pouet.h) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code61'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37161"><td class="code" id="p371code61"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define CONCAT(a, b) a ## b</span>
CONCAT<span style="color: #008000;">&#40;</span>foo, bar<span style="color: #008000;">&#41;</span></pre></td></tr></table></div>

<p>&laquo;&nbsp;cpp pouet.h&nbsp;&raquo; affiche cette fois :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code62'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37162"><td class="code" id="p371code62"><pre class="text" style="font-family:monospace;"># 1 &quot;pouet.h&quot;
# 1 &quot;&lt;interne&gt;&quot;
# 1 &quot;&lt;command-line&gt;&quot;
# 1 &quot;pouet.h&quot;
&nbsp;
foobar</pre></td></tr></table></div>

<p>Cela va nous servir à choisir la bonne macro à utiliser :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code63'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37163"><td class="code" id="p371code63"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span></pre></td></tr></table></div>

<p>Le gros inconvénient est bien sûr qu&#8217;il nous faut préciser le nombre de valeurs de l&#8217;énumération :/</p>
<p>Il semble que l&#8217;on ait fait le tour. Voici donc la version finale de tout ça, séparée dans un .h générique<br />
et un .cpp d&#8217;exemple :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code64'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37164"><td class="code" id="p371code64"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// Enumerate.h</span>
&nbsp;
<span style="color: #339900;">#ifndef ENUMERATE_H</span>
<span style="color: #339900;">#define ENUMERATE_H</span>
&nbsp;
<span style="color: #339900;">#define MAKE_ENUM(enum_name, ...)	\</span>
	<span style="color: #0000ff;">enum</span> enum_name <span style="color: #008000;">&#123;</span> __VA_ARGS__ <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_1(val)	\</span>
	<span style="color: #0000ff;">case</span> val<span style="color: #008080;">:</span>	\
		os <span style="color: #000080;">&lt;&lt;</span> <span style="color: #339900;">#val;	\</span>
		<span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_2(val, ...)	ENUM_CASE_1(val) ENUM_CASE_1(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_3(val, ...)	ENUM_CASE_1(val) ENUM_CASE_2(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_4(val, ...)	ENUM_CASE_1(val) ENUM_CASE_3(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_5(val, ...)	ENUM_CASE_1(val) ENUM_CASE_4(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_6(val, ...)	ENUM_CASE_1(val) ENUM_CASE_5(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_7(val, ...)	ENUM_CASE_1(val) ENUM_CASE_6(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_8(val, ...)	ENUM_CASE_1(val) ENUM_CASE_7(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_9(val, ...)	ENUM_CASE_1(val) ENUM_CASE_8(__VA_ARGS__)</span>
<span style="color: #339900;">#define ENUM_CASE_10(val, ...)	ENUM_CASE_1(val) ENUM_CASE_9(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define ENUM_CASE_N(nb_vals, ...) ENUM_CASE_ ## nb_vals(__VA_ARGS__)</span>
&nbsp;
<span style="color: #339900;">#define MAKE_OPERATOR(nb_vals, enum_name, ...)	\</span>
	<span style="color: #0000ff;">inline</span> std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> operator<span style="color: #000080;">&lt;&lt;</span><span style="color: #008000;">&#40;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">ostream</span><span style="color: #000040;">&amp;</span> os, <span style="color: #0000ff;">const</span> enum_name<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>	<span style="color: #008000;">&#123;</span>\
		<span style="color: #0000ff;">switch</span><span style="color: #008000;">&#40;</span>e<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>	\
			ENUM_CASE_N<span style="color: #008000;">&#40;</span>nb_vals, __VA_ARGS__<span style="color: #008000;">&#41;</span>	\
		<span style="color: #008000;">&#125;</span>	\
		<span style="color: #0000ff;">return</span> os<span style="color: #008080;">;</span>	\
	<span style="color: #008000;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #339900;">#define ENUMERATE(nb_vals, enum_name, ...)	\</span>
	MAKE_ENUM<span style="color: #008000;">&#40;</span>enum_name, __VA_ARGS__<span style="color: #008000;">&#41;</span>	\
	MAKE_OPERATOR<span style="color: #008000;">&#40;</span>nb_vals, enum_name, __VA_ARGS__<span style="color: #008000;">&#41;</span>
&nbsp;
<span style="color: #339900;">#endif // ENUMERATE_H</span></pre></td></tr></table></div>


<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p371code65'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p37165"><td class="code" id="p371code65"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// main.cpp</span>
&nbsp;
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &quot;Enumerate.h&quot;</span>
&nbsp;
ENUMERATE<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">3</span>, MonEnumeration,
	E_VAL_1,
	E_VAL_2,
	E_VAL_3<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	MonEnumeration e <span style="color: #000080;">=</span> E_VAL_1<span style="color: #008080;">;</span>
	std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span> <span style="color: #000080;">&lt;&lt;</span> e <span style="color: #000080;">&lt;&lt;</span> std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p><strong>Conclusion</strong></p>
<p>Au final, cette méthode présente l&#8217;avantage d&#8217;éviter la duplication de code, et tous les ennuis qui vont avec.<br />
Il reste cependant plusieurs inconvénients non négligeables :<br />
- On est obligés de préciser le nombre de valeurs de l&#8217;énumération<br />
- On est limités dans le nombre de valeurs que l&#8217;on peut définir par le nombre de macros que l&#8217;on a définis dans Enumerate.h<br />
  A la limite, si l&#8217;on a besoin de plus de valeurs, il suffit de les rajouter, c&#8217;est pas bien grave ^^<br />
- Pour la plupart des IDE, je pense qu&#8217;un tel système aboutit à un type &laquo;&nbsp;MonEnumeration&nbsp;&raquo;, ainsi que les valeurs définies,<br />
  qui sont inconnus. Ça peut être un problème&#8230;<br />
- En déclarant ses énumérations de la sorte, on ne peut pas préciser de valeur numérique pour chaque valeur possible de<br />
  l&#8217;énumération.</p>
<p>La méthode a ses limites, et je me demande s&#8217;il n&#8217;y aurait pas moyen d&#8217;aller au-delà en utilisant des templates&#8230;<br />
Par ailleurs, ce petit article sur le préprocesseur ne fait aucune mention de Boost::Preprocessor, qui, selon Arnaud,<br />
est incroyable à voir&#8230;<br />
Je serais curieux de voir s&#8217;il pourrait apporter un élément de réponse au problème ^^</p>
<p>Ce sera tout !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/preproc/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>GTK+ en Haskell</title>
		<link>http://www.coder-studio.com/blog/gtk-en-haskell/</link>
		<comments>http://www.coder-studio.com/blog/gtk-en-haskell/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 02:37:15 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[glade]]></category>
		<category><![CDATA[gtk]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=342</guid>
		<description><![CDATA[Bonjour,
M&#8217;étant mis à Haskell depuis quelques temps (principalement grâce au désormais fameux Real World Haskell), je me suis dis qu&#8217;il était temps que je regarde un peu du côté des bibliothèques pour interfaces utilisateurs. Hé bien, je n&#8217;ai pas été déçu. Il y a notamment Gtk2Hs qui fournit un bon binding de GTK+, compatible avec [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour,</p>
<p>M&#8217;étant mis à Haskell depuis quelques temps (principalement grâce au désormais fameux <a href="http://general.developpez.com/livres/general/?page=prog-fonctionnelle#L9780596514983">Real World Haskell</a>), je me suis dis qu&#8217;il était temps que je regarde un peu du côté des bibliothèques pour interfaces utilisateurs. Hé bien, je n&#8217;ai pas été déçu. Il y a notamment <strong>Gtk2Hs</strong> qui fournit un bon binding de GTK+, compatible avec Glade (le designer) et qui permet donc de charger des interfaces depuis du XML.</p>
<p><center><img src="http://blog.developpez.com/media/gtk2hs.png" width="409" height="297" alt="Gtk2Hs en action" /></center></p>
<p><span id="more-342"></span></p>
<p>Allez-y, devinez combien de lignes il a fallu ?<br />
Initialiser le GUI, créer les widgets, &#8230; Hmm beaucoup ?</p>
<p>Hé bien non ! Le designer, Glade, exporte le &laquo;&nbsp;projet&nbsp;&raquo; suivant dans un XML.</p>
<p><center><img src="http://blog.developpez.com/media/glade.png" width="700" height="370" alt="Designer de fenêtres de GTK+" /></center></p>
<p>XML généré :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p342code68'); return false;">View Code</a> XML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p34268"><td class="code" id="p342code68"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span> 
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;glade-interface<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #808080; font-style: italic;">&lt;!-- interface-requires gtk+ 2.16 --&gt;</span> 
  <span style="color: #808080; font-style: italic;">&lt;!-- interface-naming-policy project-wide --&gt;</span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;widget</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;GtkWindow&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;window1&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;title&quot;</span> <span style="color: #000066;">translatable</span>=<span style="color: #ff0000;">&quot;yes&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Hello, Developpez !<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;default_width&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>400<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;default_height&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>400<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;child<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;widget</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;GtkButton&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;yo&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;label&quot;</span> <span style="color: #000066;">translatable</span>=<span style="color: #ff0000;">&quot;yes&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Bonjour Developpez, comment vas-tu ? 
&nbsp;
Je suis un programme Haskell qui utilise 
Gtk2Hs, binding Haskell de GTK+. 
&nbsp;
Clique pour fermer.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;visible&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>True<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;can_focus&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>True<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;receives_default&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>True<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/property<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/widget<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/child<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/widget<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> 
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/glade-interface<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>Et voilà, l&#8217;essentiel est fait.</p>
<p>Voici donc le main.hs, qui est le programme Haskell dont vous avez vu un screenshot plus haut :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p342code69'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table width="100%" ><tr id="p34269"><td class="code" id="p342code69"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span> 
&nbsp;
<span style="color: #06c; font-weight: bold;">import</span> Graphics<span style="color: #339933; font-weight: bold;">.</span>UI<span style="color: #339933; font-weight: bold;">.</span>Gtk <span style="color: #5d478b; font-style: italic;">-- on importe le module GTK </span>
<span style="color: #06c; font-weight: bold;">import</span> Graphics<span style="color: #339933; font-weight: bold;">.</span>UI<span style="color: #339933; font-weight: bold;">.</span>Gtk<span style="color: #339933; font-weight: bold;">.</span>Glade <span style="color: #5d478b; font-style: italic;">-- et le module Glade, pour créer une IHM depuis le XML au format Glade </span>
&nbsp;
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  initGUI 
  Just xml <span style="color: #339933; font-weight: bold;">&lt;-</span> xmlNew <span style="background-color: #3cb371;">&quot;test.glade&quot;</span>  
  window <span style="color: #339933; font-weight: bold;">&lt;-</span> xmlGetWidget xml castToWindow <span style="background-color: #3cb371;">&quot;window1&quot;</span> 
  button <span style="color: #339933; font-weight: bold;">&lt;-</span> xmlGetWidget xml castToButton <span style="background-color: #3cb371;">&quot;yo&quot;</span> 
  onClicked button <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span> 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="background-color: #3cb371;">&quot;Bye&quot;</span> 
  mainQuit 
  onDestroy window mainQuit 
  widgetShowAll window 
  mainGUI</pre></td></tr></table></div>

<p>Et voilà. Assez simple non ? <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/gtk-en-haskell/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Robot wifi terminé</title>
		<link>http://www.coder-studio.com/blog/robot-wifi-termine/</link>
		<comments>http://www.coder-studio.com/blog/robot-wifi-termine/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 12:50:14 +0000</pubDate>
		<dc:creator>Aquanum</dc:creator>
				<category><![CDATA[Embarqué]]></category>
		<category><![CDATA[Robotique]]></category>
		<category><![CDATA[robot]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=339</guid>
		<description><![CDATA[Voici deux nouvelles vidéos de notre projet de robot wifi que nous venons de terminer. On peut encore l&#8217;améliorer, mais avons atteint notre but initial et développé toutes les fonctionnalités que nous souhaitions implémenter 
Vous pouvez retrouver plus d&#8217;info sur notre robot sur mon site.


]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Voici deux nouvelles vidéos de notre projet de robot wifi que nous venons de terminer. On peut encore l&#8217;améliorer, mais avons atteint notre but initial et développé toutes les fonctionnalités que nous souhaitions implémenter <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Vous pouvez retrouver plus d&#8217;info sur notre robot <a href="http://www.yoannsculo.fr/" target="_blank">sur mon site.</a></p>
<p><object class="aligncenter" width="425" height="344" data="http://www.youtube.com/v/rzsYxudxMRQ&amp;hl=fr&amp;fs=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/rzsYxudxMRQ&amp;hl=fr&amp;fs=1" /><param name="allowfullscreen" value="true" /></object></p>
<p><object class="aligncenter" width="425" height="344" data="http://www.youtube.com/v/CM0XtpQLot8&amp;hl=fr&amp;fs=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/CM0XtpQLot8&amp;hl=fr&amp;fs=1" /><param name="allowfullscreen" value="true" /></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/robot-wifi-termine/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Challenge Tower Bloxx</title>
		<link>http://www.coder-studio.com/blog/challenge-tower-bloxx/</link>
		<comments>http://www.coder-studio.com/blog/challenge-tower-bloxx/#comments</comments>
		<pubDate>Sun, 10 May 2009 02:31:42 +0000</pubDate>
		<dc:creator>nicolas66</dc:creator>
				<category><![CDATA[Optimisation combinatoire]]></category>
		<category><![CDATA[graphe]]></category>
		<category><![CDATA[programmation linéaire]]></category>
		<category><![CDATA[tower bloxx]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=309</guid>
		<description><![CDATA[Certains d&#8217;entre vous connaissent probablement le jeu Tower Bloxx sur téléphone portable. Pour résumer, le jeu consiste à construire une petite agglomération en plaçant des immeubles sur une grille carrée de taille n x n. Chaque immeuble est créé en empilant un à un les étages à l&#8217;aide d&#8217;une grue qui balance d&#8217;un bout à [...]]]></description>
			<content:encoded><![CDATA[<p>Certains d&#8217;entre vous connaissent probablement le jeu Tower Bloxx sur téléphone portable. Pour résumer, le jeu consiste à construire une petite agglomération en plaçant des immeubles sur une grille carrée de taille <em>n x n</em>. Chaque immeuble est créé en empilant un à un les étages à l&#8217;aide d&#8217;une grue qui balance d&#8217;un bout à l&#8217;autre de l&#8217;écran. A chaque fois qu&#8217;un étage est ajouté, des habitants viennent peupler l&#8217;immeuble. Plus les étages sont alignés, plus l&#8217;immeuble abrite d&#8217;habitants et moins l&#8217;immeuble balance pour placer de nouveaux étages. Il existe plusieurs types d&#8217;immeubles (<em>m</em>), avec un nombre de points et une population croissants : résidentiel (bleu), commercial (rouge), industriel (vert) et hôtel de luxe (jaune). Les règles de placement des immeubles sont les suivantes :</p>
<ul>
<li>Un immeuble bleu peut être placé partout.</li>
<li>Un immeuble rouge doit posséder au moins un immeuble bleu dans son voisinage.</li>
<li>Un immeuble vert doit posséder au moins un immeuble bleu et rouge dans son voisinage.</li>
<li>Un immeuble jaune doit posséder au moins un immeuble bleu, rouge et vert dans son voisinage.</li>
</ul>
<p>On considère ici un voisinage en 4-connexités. Dans le jeu original, il est possible de détruire des tours voisines afin de placer davantage de tours de plus grande importance (loophole). Dans un souci de simplicité, j&#8217;ignore ici cette possibilité. L&#8217;image ci-dessous donne un exemple d&#8217;agglomération qui respecte les règles énoncées précédemment.</p>
<div id="attachment_94" class="wp-caption aligncenter" style="width: 210px"><img class="size-medium wp-image-94" title="Exemple d'agglomération" src="http://nicolas.lerme.free.fr/city-block.png" alt="Exemple d'agglomération" width="200" height="200" /><p class="wp-caption-text">Exemple d'agglomération</p></div>
<p><span id="more-309"></span></p>
<p> Outre l&#8217;aspect divertissant du jeu, une question plus profonde a rapidement taraudé mon esprit : quelle est la configuration optimale des immeubles qui maximise le nombre d&#8217;immeubles de plus grande importance ?</p>
<p>Très vite, on devine que le problème d&#8217;optimisation combinatoire sous-jacent posé doit facilement pouvoir s&#8217;exprimer sous la forme d&#8217;un programme linéaire en nombres entiers (PLNE). Algorithmiquement, la résolution d&#8217;un PLNE est autrement plus difficile qu&#8217;un PL mais il existe des algorithmes (par exemple branch-and-bound) performants et éprouvés. Ces algorithmes se basent sur la relaxation continue du PLNE (sans les contraintes d&#8217;intégrité) et permettent d&#8217;éviter une énumération exhaustive des solutions.</p>
<p>Après avoir écrit sur papier la fonction objectif et les contraintes associées, je me suis donc mis en quête d&#8217;un solveur gratuit et disponible sous GNU/Linux. Ne connaissant pas en détail les différents solveurs, mon choix s&#8217;est porté sur le premier venu : GLPK. Etant novice, l&#8217;écriture du programme linéaire m&#8217;a demandé quelques refléxions préalables pour généraliser le problème pour un couple de paramètres (<em>n</em>, <em>m</em>) donné.</p>
<p>A partir de ce problème, on peut aussi imaginer diverses extensions :</p>
<ul>
<li>Transposer le problème sous la forme d&#8217;un graphe et généraliser.</li>
<li>Généraliser le problème en dimension <em>N</em> : cela implique notamment de définir précisément la notion de voisinage en dimension quelconque.</li>
<li>Utiliser d&#8217;autres règles de dépendances entre immeubles : on pourrait alors imaginer des graphes de dépendance beaucoup plus complexes.</li>
<li>Utiliser d&#8217;autres types de voisinages dans le cas de graphes à &laquo;&nbsp;grille&nbsp;&raquo;.</li>
</ul>
<p>Comme bien souvent, la question initiale en appelle plusieurs autres : est-ce que ce problème a déjà été traité dans la littérature (éventuellement présenté sous une autre forme) ? Si oui, quelle est sa complexité pour un <em>m</em> fixé ? Le parallèle sur la coloration de graphes vient presque spontanément. Néanmoins, le problème qui nous occupe est différent et a priori plus simple. On peut tout de même se poser la question pour <em>m=2</em>, <em>m=3</em> et <em>m>=4</em>. En particulier, il serait intéressant de savoir d&#8217;une part, s&#8217;il existe un algorithme polynomial pour <em>m=2</em> et d&#8217;autre part, savoir si le problème est NP-Difficile pour <em>m>=4</em>.</p>
<p>D&#8217;un point de vue plus technique, cela consiste simplement en un programme linéaire écrit en GMPL pour le solveur GLPK. Les contraintes entre immeubles sont générées à l&#8217;aide d&#8217;un simple script. Le script écrit le programme linéaire dans un fichier, lance le solveur, affiche les résultats sous la forme d&#8217;un tableau et donne le score correspondant.</p>
<p>Finalement, j&#8217;ai pu résoudre mon problème initial pour l&#8217;instance (<em>n=5</em>, <em>m=4</em>) en une à deux heures de calcul. Il est sûrement possible de diminuer le temps de calcul au niveau de l&#8217;algorithme de branch-and-bound, en passant les options adéquates au solveur. Lorsque j&#8217;aurai davantage de temps, j&#8217;aimerai aussi pouvoir résoudre le même problème avec loophole. Have fun <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/challenge-tower-bloxx/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Détournement de Nabaztag et reverse engineering</title>
		<link>http://www.coder-studio.com/blog/detournement-de-nabaztag-et-reverse-engineering/</link>
		<comments>http://www.coder-studio.com/blog/detournement-de-nabaztag-et-reverse-engineering/#comments</comments>
		<pubDate>Fri, 08 May 2009 17:57:41 +0000</pubDate>
		<dc:creator>Aquanum</dc:creator>
				<category><![CDATA[Embarqué]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[électronique]]></category>
		<category><![CDATA[JTAG]]></category>
		<category><![CDATA[Nabaztag]]></category>
		<category><![CDATA[reverse engineering]]></category>
		<category><![CDATA[violet]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=305</guid>
		<description><![CDATA[
J&#8217;ai reçu à Noël dernier une jolie petite bestiole. Un bon gadget de geek   Le Nabaztag.
Très bonne idée à la base, le concept est intéressant, c&#8217;est typiquement le genre de truc qui m&#8217;intéresse. Sauf &#8230; que ce Nabaztag est finalement un peu trop inutile à mon goût et surtout bien trop contrôlé par [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">
<div id="attachment_94" class="wp-caption alignleft" style="width: 310px"><img class="size-medium wp-image-94" title="nabaztag" src="http://www.yoannsculo.fr/wp-content/uploads/2009/05/nabaztag-300x300.jpg" alt="Nabaztag" width="300" height="300" /><p class="wp-caption-text">Nabaztag</p></div>
<p>J&#8217;ai reçu à Noël dernier une jolie petite bestiole. Un bon gadget de geek <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Le Nabaztag.</p>
<p style="text-align: justify;">Très bonne idée à la base, le concept est intéressant, c&#8217;est typiquement le genre de truc qui m&#8217;intéresse. Sauf &#8230; que ce Nabaztag est finalement un peu trop inutile à mon goût et surtout bien trop contrôlé par la société qui le vend, à savoir la société Violet. Déjà, qu&#8217;est-ce que cette petite bestiole ? Il s&#8217;agit en fait d&#8217;un terminal connecté à Internet en wifi par lui même et qui peut interagir à la fois avec du contenu sur Internet et avec l&#8217;utilisateur. Il est alors possible de lire la météo, suivre ses emails, écouter la radio, écouter des podcast, lire des flux en streaming, suivre des flux RSS, etc. Notre ami lapin clignote de partout et bouge les oreilles dans tous les sens et peut même lire des puces RFID. Bref une bonne idée dans l&#8217;absolu, mais finalement ce lapin m&#8217;a plus énervé que servi pour l&#8217;instant. J&#8217;écoute beaucoup de webradio sur Internet, on peut charger des radios sans problème &#8230; sauf que notre ami lapin lit comme un abruti les trames METADATA (titres des musiques entre autres) des flux http des radios. Du coup on a droit à des gros parasites aléatoires dans la musique, parce que le lapin essaye de faire lire du texte au lieu du flux mp3&#8230; ahah bien joué !</p>
<p style="text-align: justify;"><span id="more-305"></span>Second truc qui m&#8217;embête pas mal. Le lapin se connecte par Internet au serveur de Violet. Le système embarqué au sein du lapin n&#8217;est pas super puissant, donc tout le traitement a lieu, semblerait-il, de manière déportée, le lapin ne reçoit que des commandes.En gros si la société fait faillite ou arrête le développement du lapin &#8230; le lapin devient hors d&#8217;usage. J&#8217;ai quand même du mal à me savoir dépendant d&#8217;une société pour utiliser un objet comme celui-ci. En dehors du fait que le lapin n&#8217;est pas super fiable, dépend du serveur de violet pour fonctionner comme réveil ou lire ses mails etc, le gadget reste intéressant, mais hélas ça reste un gadget. Je n&#8217;ai pas réussi à l&#8217;intégrer dans ma vie de tous le jours. Dommage.</p>
<p style="text-align: justify;">En dehors des services de base proposés par Violet pour le nabaztag, la société a créé une API pour permettre aux propriétaires de Nabaztag de le commander eux mêmes, c&#8217;est à dire faire bouger les oreilles, lancer des flux mp3 à la demande, lancer le synthétiseur de parole, etc. Mais, même problème ce ne sont que de simples requêtes HTTP qui ne permettent pas d&#8217;aller bien loin. Et puis accessoirement, le lapin est carrément manipulable depuis n&#8217;importe quel coin de la planète, du moment qu&#8217;une personne a l&#8217;identifiant de votre lapin (sorte d&#8217;adresse MAC). Vous avez vite fait de tomber par hasard sur l&#8217;adresse d&#8217;un lapin existant.</p>
<p style="text-align: justify;">Bref, après moins de 2 semaines de tentatives d&#8217;utilisation je n&#8217;ai pas résisté à la tentation de démonter cette petite bestiole. Il s&#8217;avère qu&#8217;elle cache du matériel plutôt sympathique, et j&#8217;ai découvert avec joie qu&#8217;elle disposait d&#8217;un port JTAG, permettant de programmer le processeur directement.</p>
<div id="attachment_96" class="wp-caption aligncenter" style="width: 680px"><img class="size-full wp-image-96" title="dsc06946_small" src="http://www.yoannsculo.fr/wp-content/uploads/2009/05/dsc06946_small.jpg" alt="Nabaztag Démonté" width="670" height="503" /><p class="wp-caption-text">Nabaztag Démonté</p></div>
<div id="attachment_98" class="wp-caption aligncenter" style="width: 680px"><img class="size-full wp-image-98" title="dsc06951_small" src="http://www.yoannsculo.fr/wp-content/uploads/2009/05/dsc06951_small.jpg" alt="Carte embarquée du Nabaztag" width="670" height="503" /><p class="wp-caption-text">Carte embarquée du Nabaztag</p></div>
<p>J&#8217;ai pu donc diséquer le lapin et découvrir ce qu&#8217;il se trouvait à l&#8217;intérieur:</p>
<ul>
<li>2 moteurs continus pour faire bouger les oreilles</li>
<li>Un lecteur de puce RFID</li>
<li>Un micro</li>
<li>Une prise jack reliée à la carte son</li>
<li>Un potentiomètre pour régler le volume</li>
<li>Une carte wifi</li>
<li>Un haut parleur</li>
<li>Des DELs associées et leurs cônes de direction pour avoir de jolies petits ronds lumineux sur la coque par transparence</li>
</ul>
<div id="attachment_101" class="wp-caption alignright" style="width: 160px"><img class="size-thumbnail wp-image-101" title="mcbstm32" src="http://www.yoannsculo.fr/wp-content/uploads/2009/05/mcbstm32-150x150.jpg" alt="MCBSTM32 - Carte de développement pour processeur ARM" width="150" height="150" /><p class="wp-caption-text">MCBSTM32 - Carte de développement pour processeur ARM</p></div>
<p style="text-align: justify;">
<p>Je ne vais pas détailler minutieusement tous les composants de la carte principale. Quelqu&#8217;un s&#8217;en est déjà chargé sur <a href="http://www.petertyser.com/2007/03/11/nabaztag-nabaztagtag-dissection/" target="_blank">ce blog</a>. Je peux lire sur le processeur &laquo;&nbsp;OKI L670405I &#8211; INNN, ARM 722EBAUJ&nbsp;&raquo;. Il semblerait qu&#8217;il s&#8217;agisse d&#8217;un processeur <a href="http://www.arm.com/products/CPUs/ARM7TDMI.html" target="_blank">ARM7 TDMI</a>, ce processeur pourrait d&#8217;après mes recherches (je n&#8217;en suis pas sûr) être programmé par une <a href="http://embeddedgear.com/mcbstm32.aspx" target="_blank">carte de développement</a> qui vaut 229$. Ahah la bonne blague ! Il doit peut être y avoir moyen de trouver un moyen moins cher, mais je ne le connais pas encore.</p>
<p style="text-align: justify;">Du coup j&#8217;essaye de découvrir comment reprogrammer le processeur pour y mettre un Firmware maison et libre de surcroit. En gros dans l&#8217;idée de permettre aux gens d&#8217;utiliser leur nabaztag sur des serveurs qui ne sont pas ceux de Violet. (Free your rabits !!!) Cela impliquerait un certain travail, analyse minutieuse des specifications matérielles, reprogrammation des drivers, reprogrammation des protocoles de communication, reprogrammation d&#8217;un serveur etc. Mais c&#8217;est le genre de projet qui m&#8217;intéresserait vraiment : refaire de A à Z le firmware à des fins pédagogiques. J&#8217;essaye de contacter des gens sur Internet qui semblent intéressés par la libération des lapins, pour l&#8217;instant pas de réponse positive. Mais je cherche toujours ! Pour l&#8217;instant je ne sais pas trop par où commencer avec le peu de connaissances et de matériel que j&#8217;ai à ma disposition. Mais si par hasard, vous êtes intéressé par une telle entreprise n&#8217;hésitez pas à <a href="http://www.yoannsculo.fr/contact/" target="_blank">me contacter</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/detournement-de-nabaztag-et-reverse-engineering/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
