<?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>Autour de Linux &#187; C++</title>
	<atom:link href="http://linux.leunen.com/?feed=rss2&#038;cat=4" rel="self" type="application/rss+xml" />
	<link>http://linux.leunen.com</link>
	<description>Ubuntu, linux, C++, audio, python, ...</description>
	<lastBuildDate>Tue, 17 Aug 2010 11:50:29 +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>Compiler xvidcap-1.1.7 sous Lucid</title>
		<link>http://linux.leunen.com/?p=920</link>
		<comments>http://linux.leunen.com/?p=920#comments</comments>
		<pubDate>Sun, 23 May 2010 20:27:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Vidéo]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=920</guid>
		<description><![CDATA[Dans les forums d&#8217;Ubuntu-fr, quelqu&#8217;un demandait comment compiler xvidcap-1.1.7 sous Lucid afin de résoudre des problèmes de son qu&#8217;il avait avec la version des dépôts et manifestement avait un peu de mal a s&#8217;en sortir avec les messages d&#8217;erreurs.
Xvidcap est un programme de capture d&#8217;écran, dans un fichier vidéo AVI ou mpeg, destinée à la [...]]]></description>
			<content:encoded><![CDATA[<p>Dans les <a href="http://forum.ubuntu-fr.org/viewtopic.php?id=393570">forums d&#8217;Ubuntu-fr</a>, quelqu&#8217;un demandait comment compiler <em>xvidcap-1.1.7</em> sous Lucid afin de résoudre des problèmes de son qu&#8217;il avait avec la version des dépôts et manifestement avait un peu de mal a s&#8217;en sortir avec les messages d&#8217;erreurs.</p>
<p><em>Xvidcap</em> est un programme de capture d&#8217;écran, dans un fichier vidéo AVI ou mpeg, destinée à la réalisation de screencast.<br />
Pour compiler le programme, il faut le télécharger <a href="http://sourceforge.net/projects/xvidcap/">ici</a>, installer les paquets suivants qui sont nécessaires:</p>
<pre class="codesource">
$ sudo aptitude install libxmu-dev
$ sudo aptitude libxmu-headers
$ sudo aptitude libxt-dev
</pre>
<p>Ensuite, il faut décompresser l&#8217;archive puis compiler le programme de manière habituelle:</p>
<pre class="codesource">
$ tar  -zxvf xvidcap-1.1.7.tar.gz
$ cd xvidcap-1.1.7
$ ./configure
$ make
</pre>
<p>Mais durant le make, une erreur apparaît qui peut être incompréhensible pour quelqu&#8217;un qui n&#8217;a pas l&#8217;habitude:</p>
<pre class="codesource">
capture.c: In function ‘XGetZPixmapSHM’:
capture.c:668: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
capture.c:668: error: ‘req’ undeclared (first use in this function)
capture.c:668: error: (Each undeclared identifier is reported only once
capture.c:668: error: for each function it appears in.)
capture.c:669: error: ‘xShmGetImageReply’ undeclared (first use in this function)
capture.c:669: error: expected ‘;’ before ‘rep’
capture.c:675: error: ‘sz_xShmGetImageReq’ undeclared (first use in this function)
capture.c:675: error: ‘xShmGetImageReq’ undeclared (first use in this function)
capture.c:675: error: expected expression before ‘)’ token
capture.c:675: error: ‘X_ShmGetImage’ undeclared (first use in this function)
capture.c:693: error: ‘rep’ undeclared (first use in this function)
</pre>
<p>En bref, cela signifie que dans le fichier capture.c, à la ligne 668, dans la fonction XGetZPixmapSHM, il y a un type non-déclaré: <em>xShmGetImageReq</em>.<br />
Après une petite recherche dans les fichiers d&#8217;entête (.h), il apparaît que ce type est  déclaré dans Lucid dans le fichier <em>X11/extensions/shmproto.h</em>. Or celui-ci n&#8217;est pas inclus dans capture.c. A la place, on trouve un fichier <em>X11/extensions/shmstr.h</em> qui lui n&#8217;existe plus. Donc il semblerait bien que le premier remplace le second dans les dernières versions. Il suffit donc dans le fichier capture.c de trouver la ligne contenant:</p>
<pre class="codesource">
#include &lt;X11/extensions/shmstr.h&gt;
</pre>
<p>et de la remplacer par:</p>
<pre class="codesource">
#include &lt;X11/extensions/shmproto.h&gt;
</pre>
<p>Relancez la compilation puis l&#8217;installation et vous obtiendrez une version compilée de xvidcap fonctionnelle et avec le son en plus:</p>
<pre class="codesource">
$ make
$ sudo make install
</pre>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=920</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Parasite</title>
		<link>http://linux.leunen.com/?p=673</link>
		<comments>http://linux.leunen.com/?p=673#comments</comments>
		<pubDate>Tue, 29 Sep 2009 15:33:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=673</guid>
		<description><![CDATA[Parasite est un outil qui peut être très utile à toute personne qui développe de petites ou de grosses applications en utilisant GTK pour la partie interface graphique. Ce module qui s&#8217;intercale dans votre application de façon très simple, vous permet de débugger votre interface graphique (GUI en anglais ou IHM en français) en vous [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://chipx86.github.com/gtkparasite/">Parasite</a> est un outil qui peut être très utile à toute personne qui développe de petites ou de grosses applications en utilisant <em>GTK</em> pour la partie interface graphique. Ce module qui s&#8217;intercale dans votre application de façon très simple, vous permet de débugger votre interface graphique (<em>GUI</em> en anglais ou <em>IHM</em> en français) en vous donnant la hiérarchie des widgets utilisés ainsi que leurs propriétés. <em>Parasite</em> vous permet aussi d&#8217;agir sur ces propriétés et de les modifier et ainsi de voir immédiatement l&#8217;effet de vos modifications sur votre interface graphique.<br />
Ceux d&#8217;entre-vous qui utilisent firebug sous Firefox ne seront pas dépaysés. L&#8217;interface y ressemble avec son bouton &#8216;Inspect&#8217; qui permet de voyager dans les widgets de l&#8217;interface graphique.<br />
Voici un screenshot vous montrant à quoi ressemble <em>Parasite</em>. Dans l&#8217;exemple, <em>Parasite</em> est utilisé pour inspecter l&#8217;interface graphique de la calculatrice <em>Gnome</em> (gcalctool). Je me suis amusé à y changer certains labels de boutons et à en rendre un invisible. Mais ce n&#8217;est évidemment pas tout ce que peu faire <em>Parasite</em>; ça ne se limite bien sûr pas à changer le label des boutons!<br />
<center><br />
<a href="http://linux.leunen.com/wp-content/uploads/2009/09/Capture-Parasite.png"><img src="http://linux.leunen.com/wp-content/uploads/2009/09/Capture-Parasite-small.png" alt="Capture-Parasite" title="Capture-Parasite" width="304" height="387" class="center" /></a><br />
</center><br />
Pour installer <em>Parasite</em>, downloadez le fichier .tar.gz à cette adresse et décompressez l&#8217;archive:<br />
<a href="http://github.com/chipx86/gtkparasite/tarball/master">http://github.com/chipx86/gtkparasite/tarball/master</a></p>
<p>Il va falloir compiler le programme mais rassurez-vous, cela se passe sans problème.<br />
En regardant dans le répertoire où l&#8217;archive est décompressée, on remarque qu&#8217;il n&#8217;y a pas de fichier <em>configure</em>. Heureusement, le script <em>autogen.sh</em> va nous le créer. ensuite, la compilation se fait &#8220;as usual&#8221; en utilisant <em>configure/make/make install</em>:</p>
<pre class="codesource">
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
</pre>
<p>Vérifiez que toutes ces étapes se soient bien passées et qu&#8217;aucun message d&#8217;erreur ne soit affiché dans le terminal.<br />
il reste ensuite à créer un lien symbolique dans <em>/usr/lib</em> pointant vers <em>/usr/local/lib/gtk-2.0/modules/libgtkparasite.so</em>.</p>
<pre class="codesource">
$ cd /usr/lib
$ sudo ln -s /usr/local/lib/gtk-2.0/modules/libgtkparasite.so libgtkparasite.so
</pre>
<p>Pour attacher <em>Parasite</em> à une application, il suffit d&#8217;intercaler <em>Parasite</em> de cette manière:</p>
<pre class="codesource">
$ GTK_MODULES=gtkparasite gcalctool
</pre>
<p>Vous devez bien évidemment, dans la ligne ci-dessus, remplacer gcalctool<em>gcalctool</em> par le nom de l&#8217;application dont vous voulez débugger l&#8217;interface graphique.</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=673</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Colorisation syntaxique avec pygments</title>
		<link>http://linux.leunen.com/?p=652</link>
		<comments>http://linux.leunen.com/?p=652#comments</comments>
		<pubDate>Tue, 15 Sep 2009 17:28:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=652</guid>
		<description><![CDATA[Elle consiste à donner à chaque élément d&#8217;un texte un style particulier. En programmation, cela consiste à donner une couleur et un style (gras, italique&#8230;) à chaque élément constituant le code source. La colorisation syntaxique rend le code plus lisible donc plus facilement compréhensible.
La plupart des éditeurs de texte le font automatiquement mais si vous [...]]]></description>
			<content:encoded><![CDATA[<p>Elle consiste à donner à chaque élément d&#8217;un texte un style particulier. En programmation, cela consiste à donner une couleur et un style (gras, italique&#8230;) à chaque élément constituant le code source. La colorisation syntaxique rend le code plus lisible donc plus facilement compréhensible.</p>
<p>La plupart des éditeurs de texte le font automatiquement mais si vous devez formater le texte vous même pour l&#8217;afficher dans un wiki, une page web ou un blog, c&#8217;est une autre paire de manche.<br />
J&#8217;utilise par exemple deux scripts qui me permettent de faire la colorisation syntaxique de code <em>C++</em> ou <em>python</em> et me donnent un fichier <em>html</em> que je peux inclure dans une page web. Le problème est que si je veux documenter du code <em>PHP</em>, <em>javascript</em> ou des requètes <em>SQL</em> et faire la colorisation syntaxique moi-même, il faudra que je réécrive un nouveau script pour chaque langage. Heureusement pour moi, j&#8217;ai découvert une application écrite en python et trouvable sur <a href="http://pygments.org">http://pygments.org</a>.</p>
<p><em>Pygments</em> permet la colorisation syntaxique d&#8217;un très grand nombre de langages dont par exemple bash, C,C++, C#, Lisp, Lua, Delphi, PHP, Perl Python, Ruby, Tcl, Java, Javascript &#8230; Et je n&#8217;ai mis ici que les langages les plus connus. Il ye en a plein d&#8217;autres. <em>Pygments</em> permet aussi la colorisation syntaxique de fichiers de configuration, ini, css, html, sql, xml, latex,&#8230; De surcroît, on peut choisir le format de sortie: html, latex, rtf&#8230;</p>
<p><em>Pygments</em> peut être utilisé en ligne de commande ou en tant que librairie dans un projet.</p>
<p>Pour l&#8217;installer, downloadez le fichier <em>Pygments-1.1.tar.gz</em> depuis <a href="http://pypi.python.org/pypi/Pygments">http://pypi.python.org/pypi/Pygments</a><br />
Ensuite tapez les commandes suivantes dans un terminal pour extraire de l&#8217;archive les fichiers et exécuter le fichier d&#8217;installation.</p>
<pre class="codesource">
$ tar -zxvf Pygments-1.1.tar.gz
$ cd Pygments-1.1
$ sudo python setup.py install
</pre>
<p>Exemple d&#8217;utilisation en ligne de commande pour générer du code html:</p>
<p>Disons que nous voulons coloriser le bout de code <em>python</em> suivant:</p>
<pre class="codesource">
# Returns the factorial of a number
def factorial(x):
    if x < 0:
        raise ValueError("Factorial is only defined for x >= 0")
    y = 1
    while x >= 2:
        y *= x
        x -= 1
    return y
</pre>
<p>Ce bout de code, plaçons-le dans un fichier appelé <em>test.py</em> et tapons la ligne suivante dans notre terminal:</p>
<pre class="codesource">
$ pygmentize -f html -l python -o test.html test.py
</pre>
<p><em>-l</em> choix du lexer, c&#8217;est à dire le module chargé de parser le code donné dans le langage spécifié et le séparer en ses composants (keywords, comments, chaînes de caractères&#8230;)</p>
<p><em>-f</em> choix du formateur, c&#8217;est à dire le format sous lequel vous désirez le fichier de sortie (html, latex, rtf&#8230;).</p>
<p>Le résultat obtenu est le fichier html <em>test.html</em> ci-dessous:</p>
<pre class="codesource">
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Returns the factorial of a number&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&lt;&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&quot;Factorial is only defined for x &gt;= 0&quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</pre>
<p>Vous remarquerez que chaque constituant du code a son propre style avec sa classe propre. A vous de déterminer ce style en donnant au navigateur une feuille de style (<em>css</em>) compatible. Vous pouvez vous aider en utilisant la commande suivante qui liste les différents styles utilisés sous forme de css:</p>
<pre class="codesource">
$ pygmentize -f html -S colorful 

.hll { background-color: #ffffcc }
.c { color: #808080 } /* Comment */
.err { color: #F00000; background-color: #F0A0A0 } /* Error */
.k { color: #008000; font-weight: bold } /* Keyword */
.o { color: #303030 } /* Operator */
.cm { color: #808080 } /* Comment.Multiline */
.cp { color: #507090 } /* Comment.Preproc */
.c1 { color: #808080 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #00A000 } /* Generic.Inserted */
.go { color: #808080 } /* Generic.Output */
.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #0040D0 } /* Generic.Traceback */
.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.kp { color: #003080; font-weight: bold } /* Keyword.Pseudo */
.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.kt { color: #303090; font-weight: bold } /* Keyword.Type */
.m { color: #6000E0; font-weight: bold } /* Literal.Number */
.s { background-color: #fff0f0 } /* Literal.String */
.na { color: #0000C0 } /* Name.Attribute */
.nb { color: #007020 } /* Name.Builtin */
.nc { color: #B00060; font-weight: bold } /* Name.Class */
.no { color: #003060; font-weight: bold } /* Name.Constant */
.nd { color: #505050; font-weight: bold } /* Name.Decorator */
.ni { color: #800000; font-weight: bold } /* Name.Entity */
.ne { color: #F00000; font-weight: bold } /* Name.Exception */
.nf { color: #0060B0; font-weight: bold } /* Name.Function */
.nl { color: #907000; font-weight: bold } /* Name.Label */
.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.nt { color: #007000 } /* Name.Tag */
.nv { color: #906030 } /* Name.Variable */
.ow { color: #000000; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #6000E0; font-weight: bold } /* Literal.Number.Float */
.mh { color: #005080; font-weight: bold } /* Literal.Number.Hex */
.mi { color: #0000D0; font-weight: bold } /* Literal.Number.Integer */
.mo { color: #4000E0; font-weight: bold } /* Literal.Number.Oct */
.sb { background-color: #fff0f0 } /* Literal.String.Backtick */
.sc { color: #0040D0 } /* Literal.String.Char */
.sd { color: #D04020 } /* Literal.String.Doc */
.s2 { background-color: #fff0f0 } $ pygmentize -O full -o test.html test.py/* Literal.String.Double */
.se { color: #606060; font-weight: bold; background-color: #fff0f0 } /* Literal.String.Escape */
.sh { background-color: #fff0f0 } /* Literal.String.Heredoc */
.si { background-color: #e0e0e0 } /* Literal.String.Interpol */
.sx { color: #D02000; background-color: #fff0f0 } /* Literal.String.Other */
.sr { color: #000000; background-color: #fff0ff } /* Literal.String.Regex */
.s1 { background-color: #fff0f0 } /* Literal.String.Single */
.ss { color: #A06000 } /* Literal.String.Symbol */
.bp { color: #007020 } /* Name.Builtin.Pseudo */
.vc { color: #306090 } /* Name.Variable.Class */
.vg { color: #d07000; font-weight: bold } /* Name.Variable.Global */
.vi { color: #3030B0 } /* Name.Variable.Instance */
.il { color: #0000D0; font-weight: bold } /* Literal.Number.Integer.Long */
</pre>
<p>Il vous est aussi possible d&#8217;ajouter des numéros de lignes. Ceci crée en fait un tableau html dont la première colonne est le numéro de la ligne:</p>
<pre class="codesource">
$ pygmentize -f html -l python -O style=colorful,linenos=1 -o test.html test.py
</pre>
<p>Si vous préférez un fichier html complet représentant une page complète avec entête et style utilisable directement avec le navigateur:</p>
<pre class="codesource">
$ pygmentize -O full -o test.html test.py
</pre>
<p>Le résultat est ci-dessous. Notez l&#8217;entête, les <em>CSS</em> inclus dans le fichier et finalement votre code source formaté:</p>
<pre class="codesource">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd"&gt;

&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;&lt;/title&gt;
  &lt;meta http-equiv="content-type" content="text/html; charset=latin1"&gt;
  &lt;style type="text/css"&gt;
td.linenos { background-color: #f0f0f0; padding-right: 10px; }
span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }
pre { line-height: 125%; }
body .hll { background-color: #ffffcc }
body  { background: #f8f8f8; }
body .c { color: #408080; font-style: italic } /* Comment */
body .err { border: 1px solid #FF0000 } /* Error */
body .k { color: #008000; font-weight: bold } /* Keyword */
body .o { color: #666666 } /* Operator */
body .cm { color: #408080; font-style: italic } /* Comment.Multiline */
body .cp { color: #BC7A00 } /* Comment.Preproc */
body .c1 { color: #408080; font-style: italic } /* Comment.Single */
body .cs { color: #408080; font-style: italic } /* Comment.Special */
body .gd { color: #A00000 } /* Generic.Deleted */
body .ge { font-style: italic } /* Generic.Emph */
body .gr { color: #FF0000 } /* Generic.Error */
body .gh { color: #000080; font-weight: bold } /* Generic.Heading */
body .gi { color: #00A000 } /* Generic.Inserted */
body .go { color: #808080 } /* Generic.Output */
body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
body .gs { font-weight: bold } /* Generic.Strong */
body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
body .gt { color: #0040D0 } /* Generic.Traceback */
body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
body .kp { color: #008000 } /* Keyword.Pseudo */
body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
body .kt { color: #B00040 } /* Keyword.Type */
body .m { color: #666666 } /* Literal.Number */
body .s { color: #BA2121 } /* Literal.String */
body .na { color: #7D9029 } /* Name.Attribute */
body .nb { color: #008000 } /* Name.Builtin */
body .nc { color: #0000FF; font-weight: bold } /* Name.Class */
body .no { color: #880000 } /* Name.Constant */
body .nd { color: #AA22FF } /* Name.Decorator */
body .ni { color: #999999; font-weight: bold } /* Name.Entity */
body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
body .nf { color: #0000FF } /* Name.Function */
body .nl { color: #A0A000 } /* Name.Label */
body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
body .nt { color: #008000; font-weight: bold } /* Name.Tag */
body .nv { color: #19177C } /* Name.Variable */
body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
body .w { color: #bbbbbb } /* Text.Whitespace */
body .mf { color: #666666 } /* Literal.Number.Float */
body .mh { color: #666666 } /* Literal.Number.Hex */
body .mi { color: #666666 } /* Literal.Number.Integer */
body .mo { color: #666666 } /* Literal.Number.Oct */
body .sb { color: #BA2121 } /* Literal.String.Backtick */
body .sc { color: #BA2121 } /* Literal.String.Char */
body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
body .s2 { color: #BA2121 } /* Literal.String.Double */
body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
body .sh { color: #BA2121 } /* Literal.String.Heredoc */
body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
body .sx { Colorisation syntaxique avec pygmentscolor: #008000 } /* Literal.String.Other */
body .sr { color: #BB6688 } /* Literal.String.Regex */
body .s1 { color: #BA2121 } /* Literal.String.Single */
body .ss { color: #19177C } /* Literal.String.Symbol */
body .bp { color: #008000 } /* Name.Builtin.Pseudo */
body .vc { color: #19177C } /* Name.Variable.Class */
body .vg { color: #19177C } /* Name.Variable.Global */
body .vi { color: #19177C } /* Name.Variable.Instance */
body .il { color: #666666 } /* Literal.Number.Integer.Long */

  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h2&gt;&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Returns the factorial of a number&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;factorial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&lt;&lt;/span&gt; &lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&quot;Factorial is only defined for x &gt;= 0&quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html>
</pre>
<p>Et vous pouvez voir <a href="http://linux.leunen.com/wp-content/uploads/2009/09/test.html">ici</a> le résultat de tous vos efforts.</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=652</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ &#8211; le compilateur est-il installé?</title>
		<link>http://linux.leunen.com/?p=618</link>
		<comments>http://linux.leunen.com/?p=618#comments</comments>
		<pubDate>Sat, 01 Aug 2009 08:39:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=618</guid>
		<description><![CDATA[J&#8217;avais une application que je devais absolument compiler sur une machine. L&#8217;application était écrite en C et en C++. Je lance la compilation avec make et gcc me donne tout à coup une erreur:

gcc: error trying to exec 'cc1plus': execvp: Aucun fichier ou dossier de ce type

Il faut savoir que cc1 est le compilateur C [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;avais une application que je devais absolument compiler sur une machine. L&#8217;application était écrite en <em>C</em> et en <em>C++</em>. Je lance la compilation avec <em>make</em> et <em>gcc</em> me donne tout à coup une erreur:</p>
<pre class="codesource">
gcc: error trying to exec 'cc1plus': execvp: Aucun fichier ou dossier de ce type
</pre>
<p>Il faut savoir que <em>cc1</em> est le compilateur <em>C</em> et <em>cc1plus</em>, le compilateur <em>C++</em>.<br />
Je me suis gratté la tête pendant un quart d&#8217;heure à me demander pourquoi le compilateur <em>C++</em> ne pouvait être lancé avant de réaliser qu&#8217;en fait, ce message d&#8217;erreur signale simplement que le compilateur n&#8217;est pas installé. Donc, avant de faire comme moi et de fouiller tout votre système à la recherche du compilateur g++, vérifiez si vous n&#8217;avez pas tout simplement oublié de l&#8217;installer.</p>
<pre class="codesource">
$ sudo aptitude install g++
</pre>
<p>Ceci suffit à l&#8217;installer et à faire disparaître l&#8217;erreur de compilation.</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=618</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ &#8211; Qt Creator un IDE complet</title>
		<link>http://linux.leunen.com/?p=418</link>
		<comments>http://linux.leunen.com/?p=418#comments</comments>
		<pubDate>Sat, 07 Mar 2009 14:34:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=418</guid>
		<description><![CDATA[Le 3 mars est sorti Qt 4.5, la nouvelle version du framework Qt ex-Trolltech et maintenant devenu Nokia. Comme chacun sait, KDE est construit sur Qt et si j&#8217;en parle ici, c&#8217;est parce que cette nouvelle version est accompagnée de tout un SDK (Software Development Kit) qui intégre un IDE (Integrated Development Environment) complet qui [...]]]></description>
			<content:encoded><![CDATA[<p>Le 3 mars est sorti Qt 4.5, la nouvelle version du framework Qt ex-Trolltech et maintenant devenu Nokia. Comme chacun sait, KDE est construit sur Qt et si j&#8217;en parle ici, c&#8217;est parce que cette nouvelle version est accompagnée de tout un SDK (Software Development Kit) qui intégre un <em>IDE</em> (Integrated Development Environment) complet qui est assez extraordinaire et qui fait rêver. A quand un <em>IDE</em> basé sur GTK pour Gnome et qui soit de la qualité de <em>Qt Creator</em> puisque c&#8217;est le nom de cet <em>IDE</em>. Un <em>IDE</em> est un environement complet qui permet le design (pour la partie GUI), l&#8217;écriture, la gestion, la compilation et le débuggage d&#8217;une application. Et ce <em>Qt Creator</em> est de la qualité de Visual C++ de Microsoft ou de C++Builder de CodeGear (ex-Borland) pour citer deux autres IDE. Assez étonnamment, il est assez léger à l&#8217;usage même sur mon vieux P4 2.8GHz avec 1Gb de RAM.</p>
<p><em>Qt Creator</em> est bien sûr utilisable sous Ubuntu même si vous êtes sous Gnome. A l&#8217;installation, les librairies nécessaires sont installées automatiquement.<br />
Pour l&#8217;installer, rendez-vous sur le site de <a href="http://www.qtsoftware.com/downloads/sdk-linux-x11-32bit-cpp">qtsoftware</a> pour y télécharger la version pour Linux. Le nom du fichier est qt-sdk-linux-x86-opensource-2009.01.bin. Après l&#8217;avoir téléchargé, rendez-ce fichier exécutable et lancez-le:</p>
<pre class="codesource">
$ chmod +x qt-sdk-linux-x86-opensource-2009.01.bin
$ sudo ./qt-sdk-linux-x86-opensource-2009.01.bin
</pre>
<p>L&#8217;installation est assez rapide et automatique. Il ne vous demandera que d&#8217;accepter la licence. Ensuite, une nouvelle entrée dans votre menu <em>Applications/Programmation</em> sera ajoutée. Il ne vous reste plus qu&#8217;à lancer l&#8217;<em>IDE</em> et à l&#8217;utiliser.<br />
Ci-dessous quelques screenshots de <em>Qt Creator</em>, juste pour vous mettre l&#8217;eau à la bouche:</p>
<p>Qt Creator &#8211; fenêtre principale </p>
<p><a href="http://linux.leunen.com/wp-content/uploads/2009/03/qtcreator_main.png"><img src="http://linux.leunen.com/wp-content/uploads/2009/03/qtcreator_main.png" alt="main window" title="QtCreator - main window" width="425" height="297" class="center" /></a></p>
<p>Qt Creator &#8211; l&#8217;éditeur</p>
<p><a href="http://linux.leunen.com/wp-content/uploads/2009/03/qtcreator_editor.png"><img src="http://linux.leunen.com/wp-content/uploads/2009/03/qtcreator_editor.png" alt="editor window" title="QtCreator - editor window" width="425" height="297" class="center" /></a></p>
<p>Qt Creator &#8211; le designer</p>
<p><a href="http://linux.leunen.com/wp-content/uploads/2009/03/qtcreator_designer.png"><img src="http://linux.leunen.com/wp-content/uploads/2009/03/qtcreator_designer.png" alt="editor window" title="QtCreator - designer window" width="425" height="287" class="center" /></a></p>
<p>Espérons qu&#8217;on ait un jour un <em>IDE</em> de qualité semblable mais sous GTK. Ca me &#8216;gêne&#8217; toujours un peu d&#8217;utiliser des librairies KDE sous Gnome et je n&#8217;ai pas envie, pour l&#8217;instant du moins, de migrer vers KDE.</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=418</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>C++ &#8211; Alignement des structures</title>
		<link>http://linux.leunen.com/?p=371</link>
		<comments>http://linux.leunen.com/?p=371#comments</comments>
		<pubDate>Tue, 03 Feb 2009 20:38:59 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=371</guid>
		<description><![CDATA[Vous devez toujours garder à l&#8217;esprit cette notion d&#8217;alignement parce que la taille réelle d&#8217;une structure ou d&#8217;une classe n&#8217;est pas toujours celle que vous imaginez.
Prenons l&#8217;exemple de cette structure:

struct A
{
  int i;
  char c;
}a;

Le résultat de sizeof(a) donnera 8 octets alors que seulement 5 octets sont utilisés. Le reste, c&#8217;est l&#8217;alignement (padding [...]]]></description>
			<content:encoded><![CDATA[<p>Vous devez toujours garder à l&#8217;esprit cette notion d&#8217;alignement parce que la taille réelle d&#8217;une structure ou d&#8217;une classe n&#8217;est pas toujours celle que vous imaginez.<br />
Prenons l&#8217;exemple de cette structure:</p>
<pre class="codesource">
<span class="reservedname">struct</span> A
{
  <span class="reservedname">int</span> i;
  <span class="reservedname">char</span> c;
}a;
</pre>
<p>Le résultat de <em>sizeof(a)</em> donnera 8 octets alors que seulement 5 octets sont utilisés. Le reste, c&#8217;est l&#8217;alignement (padding en anglais). Le compilateur essaie toujours de garder l&#8217;alignement sur un multiple de <em>quad-word</em> (quatre mots, un mot étant égal à deux octets). Ceci est en tout cas valable pour les PC avec un OS 32 bits et dépend de l&#8217;implémentation.</p>
<pre class="codesource">
<span class="reservedname">struct</span> A
{
  <span class="reservedname">int</span> i;
  <span class="reservedname">char</span> c1;
  <span class="reservedname">char</span> c2;
  <span class="reservedname">char</span> c3;
  <span class="reservedname">char</span> c4;
}a;
</pre>
<p>Dans ce cas, la réponse de <em>sizeof(a)</em> est aussi 8 octets et nous avons effectivement 8 octets d&#8217;utilisés. </p>
<p>Il est possible, lorsque la structure des données doit impérativement être alignée sur sa valeur réelle ou sur une autre valeur que des multiples de quatre mots, de dire au compilateur de changer ce comportement par défaut. Mais il est important de savoir que si le compilateur utilise ce type d&#8217;alignement sur des mots de quatre mots (8 octets), c&#8217;est parce que le processeur a plus de facilité à traiter cette taille de données. Le processeur dispose de registres et d&#8217;instructions rapides pour traiter les données alignées de cette façon. Si vous modifiez l&#8217;alignement, ceci aura un impact non-négligeable sur les performances de votre application. Autrement dit celle-ci sera notablement plus lente si vous traitez un grand nombre de structures de données.</p>
<pre class="codesource">
<span class="reservedname">struct</span> A
{
    <span class="reservedname">int</span> i;
    <span class="reservedname">char</span> c1;
}<span class="reservedname">__attribute__</span>((<span class="reservedname">packed</span>));
</pre>
<p>L&#8217;attribut <em>packed</em> donné à la structure donne injonction au compilateur d&#8217;aligner la structure sur sa taille réelle. Ici, la réponse de <em>sizeof(a)</em> donnerait 5 octets.</p>
<pre class="codesource">
<span class="reservedname">struct</span> A
{
    <span class="reservedname">int</span> i;
    <span class="reservedname">char</span> c1;
}<span class="reservedname">__attribute__</span>((<span class="reservedname">aligned</span>(x)));
</pre>
<p>Remplacez <em>x</em> par la valeur que vous souhaitez et le compilateur alignera la structure sur la valeur que vous avez spécifiée.</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=371</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ &#8211; le problème des variables temporaires</title>
		<link>http://linux.leunen.com/?p=246</link>
		<comments>http://linux.leunen.com/?p=246#comments</comments>
		<pubDate>Mon, 17 Nov 2008 16:15:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=246</guid>
		<description><![CDATA[Imaginons une fonction retournant un std::string par valeur:

std::string foo()
{
  return std::string();
}

Lors du return, le compilateur crée une variable temporaire et celle-ci existe jusqu&#8217;à ce que la fonction se termine. Cela ne pose pas de problème si vous utilisez cette variable temporaire de cette manière:

std::string str = foo();

Une copie de la variable temporaire est assignée [...]]]></description>
			<content:encoded><![CDATA[<p>Imaginons une fonction retournant un std::string par valeur:</p>
<pre class="codesource">
std::string foo()
{
  <span class="reservedname">return</span> std::string();
}
</pre>
<p>Lors du return, le compilateur crée une variable temporaire et celle-ci existe jusqu&#8217;à ce que la fonction se termine. Cela ne pose pas de problème si vous utilisez cette variable temporaire de cette manière:</p>
<pre class="codesource">
std::string str = foo();
</pre>
<p>Une copie de la variable temporaire est assignée à <em>str</em> et lorsque la fonction se termine, la variable temporaire est détruite. Sa valeur a été transmise par copie à <em>str</em>. Tout va bien.</p>
<p>Un problème peut se présenter si vous assignez cette variable temporaire à une référence non constante:</p>
<pre class="codesource">
<span class="reservedname">const</span> std::string&amp; str = foo();
</pre>
<p>Le type de retour de <em>foo()</em> spécifie qu&#8217;un string est retourné par valeur. C&#8217;est à dire qu&#8217;une copie de la variable temporaire est créée et liée à votre référence et sa durée de vie est égale à celle de la référence. Il faut bien comprendre que la variable temporaire créée lors du return n&#8217;est pas la même que celle créée par copie et liée à la référence.</p>
<p>Par contre, lier une variable temporaire à une référence non constante n&#8217;est pas permis par la norme:</p>
<pre class="codesource">
std::string&amp; str = foo();   <span class="codecomment">//illégal</span>
</pre>
<p>La norme précise qu&#8217;une variable temporaire liée à une référence est une <em>rvalue</em> (expression à droite du signe =) et donc on ne peut pas lui assigner une valeur ni la modifier. En conséquence lier une variable temporaire à une référence non constante viole cette règle. Et ce n&#8217;est donc pas permis.</p>
<p>Le code de bonne pratique veut donc que vos références soient constantes par défaut. Ne les rendez non constantes que si c&#8217;est absolument nécessaire. Et si vraiment vous devez modifier une référence, pourquoi ne pas utiliser un pointeur?</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=246</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ &#8211; Comprendre les structures</title>
		<link>http://linux.leunen.com/?p=146</link>
		<comments>http://linux.leunen.com/?p=146#comments</comments>
		<pubDate>Fri, 19 Sep 2008 10:21:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=146</guid>
		<description><![CDATA[Bien souvent, on me demande d&#8217;expiquer la notation des structures telles que celle utilisées dans l&#8217;API Windows. Je sais, cela n&#8217;a rien à voir avec Linux sauf que Microsoft ayant tendance a rendre son code illisible parfois (ou disons plus compliqué pour le débutant), je vais tenter d&#8217;expliquer cette construction même si on d&#8217;éloigne un [...]]]></description>
			<content:encoded><![CDATA[<p>Bien souvent, on me demande d&#8217;expiquer la notation des structures telles que celle utilisées dans l&#8217;API Windows. Je sais, cela n&#8217;a rien à voir avec Linux sauf que Microsoft ayant tendance a rendre son code illisible parfois (ou disons plus compliqué pour le débutant), je vais tenter d&#8217;expliquer cette construction même si on d&#8217;éloigne un peu du C++ (les structures en C n&#8217;ayant que peu à voir avec celles du C++). Voici un exemple typique d&#8217;une structure en C:</p>
<pre class="codesource">
typedef struct type1
{
  int i;
  char *c;
}var1, *var2;
</pre>
<p>Commençons par simplifier cette structure afin d&#8217;y voir plus clair:</p>
<pre class="codesource">
struct type1
{
  int i;
  char *c;
};
</pre>
<p>Ceci définit une structure de type type1 contenant un entier i et un pointeur vers un caractère c. Ok, jusque là, c&#8217;est assez simple. </p>
<pre class="codesource">
struct type1
{
  int i;
  char *c;
}var1;
</pre>
<p>Cette fois-ci nous avons défini une structure de type type1 et une variable var1 de type type1.</p>
<p>Si vous mettez le mot-clé typedef devant une variable, vous changez la déclaration de la variable en une déclaration de type. Le nom de ce qui devrait être le nom de la variable devient, à cause du typedef, un nom de type.</p>
<pre class="codesource">
typedef int i;
</pre>
<p><em>i</em> devient un type équivalent à un <em>int</em>.<br />
Revenons-en à notre problème et voyons en quoi le typedef en modifie le sens.</p>
<pre class="codesource">
typedef struct type1
{
  int i;
  char *c;
}var1;
</pre>
<p>Ceci déclare un type type1 et var1 qui est aussi un type mais équivalent à type1.</p>
<pre class="codesource">
struct type1
{
  int i;
  char *c;
}var1, *var2;
</pre>
<p>Ici, on définit une structure de type type1, une variable de type type1 corespondant à la structure et une variable de type pointeur vers un type type1.<br />
Ajoutons le typedef:</p>
<pre class="codesource">
typedef struct type1
{
  int i;
  char *c;
}var1, *var2;
</pre>
<p>Avec le typedef, on en arrive finalement à notre structure telle que rencontrée fréquemment dans l&#8217;API Windows.<br />
Cette structure, précédée de typedef, définit trois types. D&#8217;abord un type type1 et un type var1 qui sont équivalents. Ensuite on définit le type var2 comme étant un pointeur vers le type type1. Remarquez qu&#8217;on ne définit donc pas de variables mais bien trois types. </p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=146</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Utiliser ses propres journaux d&#8217;événements</title>
		<link>http://linux.leunen.com/?p=120</link>
		<comments>http://linux.leunen.com/?p=120#comments</comments>
		<pubDate>Sat, 13 Sep 2008 10:24:28 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=120</guid>
		<description><![CDATA[Sous Linux, les journaux d&#8217;événements (log en anglais) sont centralisés. il y a un daemon syslogd qui implémente le protocole syslog et gère les différents fichiers de log du système.
Ces fichiers sont très important pour résoudre des problèmes de fonctionnement ou de plantage.
Ma question du jour est: est-il possible d&#8217;utiliser cette facilité pour ses propres [...]]]></description>
			<content:encoded><![CDATA[<p>Sous Linux, les journaux d&#8217;événements (log en anglais) sont centralisés. il y a un daemon <em>syslogd</em> qui implémente le protocole <em>syslog</em> et gère les différents fichiers de log du système.<br />
Ces fichiers sont très important pour résoudre des problèmes de fonctionnement ou de plantage.<br />
Ma question du jour est: est-il possible d&#8217;utiliser cette facilité pour ses propres scripts ou programmes? Ce que je veux c&#8217;est un fichier .log qui ne soit utilisé que par mes programmes et qui soit situé, comme tous les autres fichiers de log du système, dans le répertoire <em>/var/log</em>.</p>
<p>Sans entrer dans les détails du fichier <em>/etc/syslog.conf</em>, il existe un certain nombre de fichiers standards comme par exemple (extrait du fichier <em>/etc/syslog.conf</em>):</p>
<pre class="codesource">
kern.*				-/var/log/kern.log
mail.info			-/var/log/mail.info
news.crit			/var/log/news/news.crit
</pre>
<p>On peut voir par exemple que les événements concernant le mail sont écrits dans le fichier <em>/var/log/mail.log</em>. Le protocole <em>syslog</em> définit un certain nombres de facilités (facility). vous en voyez des exemples ici: mail, kern, lpr, user,news,&#8230; et huit priorités (priority) différentes:</p>
<ul>
<li> Emerg (emergency)
<li> Alert
<li> Crit (critical)</li>
<li> Err (error)</li>
<li> Warning</li>
<li> Notice</li>
<li> Info</li>
<li> Debug</li>
</ul>
<p>l&#8217;astérisque dans le couple <em>facility.priority</em> signifie que le fichier utilisé doit être celui qui est spécifié peu importe le niveau de priorité.</p>
<p>Ce qui nous intéresse, c&#8217;est qu&#8217;il existe huit facilités définissables par l&#8217;utilisateur ou par tout programme pour lequel il n&#8217;existerait pas de facilité par défaut dans syslog. Il s&#8217;agit des facilités <em>local0</em> à <em>local7</em>. Autrement dit, il nous suffit d&#8217;ajouter dans le fichier <em>/etc/syslog.conf</em> une ligne du genre:</p>
<pre class="codesource">
local0.*			-/var/log/michel.log
</pre>
<p>Je ne spécifie pas de priorité et le fichier dans lequel les événements sont écrits doit être <em>/var/log/michel.log</em>. le <em>-</em> devant signifie que les messages ne doivent pas nécessairement être écrits directement dans le fichier mais que leur écriture peut être différée. Ceci n&#8217;a d&#8217;importance que pour des messages vraiment critiques qui en cas de plantage pourraient ne pas être écrits dans le fichier de log.</p>
<p>Ok, il reste une petite chose à faire: relancer le daemon <em>syslogd</em> pour que nos changements dans le fichier <em>/etc/syslog.conf</em> soit pris en compte:</p>
<pre class="codesource">
$ sudo /etc/init.d/sysklogd restart
</pre>
<p>Maintenant nous sommes prêts à écrire nos messages dans le fichier de log <em>/var/log/michel.log</em> comme nous le voulions. Mais comment faire?</p>
<p>Dans un script shell, c&#8217;est facile, il existe une commande qui permet d&#8217;écrire dans un fichier de log:</p>
<pre class="codesource">
$ logger -p local0.notice -t TEST Test de log
</pre>
<p>le switch <em>-p</em> spécifie le couple facilité.priorité. La priorité n&#8217;a pas d&#8217;importance pour nous.<br />
le <em>-t</em> spécifie un tag que l&#8217;on peut afficher au début du message, le nom du programme qui a généré le message par exemple.<br />
Le résultat de la commande se trouve donc dans le fichier <em>/var/log/michel.log</em> comme voulu:</p>
<pre class="codesource">
$ more /var/log/michel.log
Sep 13 09:48:26 LinuxPC TEST: Test de log
</pre>
<p>Faire la même chose dans un programme écrit en python est à peine plus compliqué:</p>
<pre class="codesource">
#!/usr/bin/env python

import syslog

syslog.openlog('TEST', 0, syslog.LOG_LOCAL0)
syslog.syslog(syslog.LOG_INFO,'Test de log en python')
syslog.closelog()
</pre>
<p>Je vous invite à jeter un oeil à la documentation du module syslog pour connaître les différentes constantes utilisables.</p>
<p>Voici la même chose en C++:</p>
<pre class="codesource">
# include &lt;string&gt;
# include &lt;syslog.h&gt;

int main()
{
  std::string message = "TEST";
  openlog(message.c_str(), 0, LOG_LOCAL0);
  syslog(LOG_INFO,"Test de log en C++");
  closelog();
  return EXIT_SUCCESS;
}
</pre>
<p>Un conseil, abusez des fichiers de log dans vos scripts et vos programmes. Je vous assure que cela rend de grand services en cas de problème. C&#8217;est d&#8217;autant plus vrai si vous distribuez vos programmes parce que c&#8217;est toujours sur une autre machine que la vôtre que les plantages arrivent et vous serez content que votre client puisse vous envoyer le fichier de log de votre programme.</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=120</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ &#8211; Classes et fonctions amies</title>
		<link>http://linux.leunen.com/?p=85</link>
		<comments>http://linux.leunen.com/?p=85#comments</comments>
		<pubDate>Tue, 12 Aug 2008 19:07:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://linux.leunen.com/?p=85</guid>
		<description><![CDATA[On utilise la notion d&#8217;ami lorsque l&#8217;on a deux classes dont l&#8217;une doit avoir accès aux données membres privées de l&#8217;autre.
Cette façon de faire permet de limiter à une seule classe l&#8217;accès à des données privées et de ne pas devoir rendre celles-ci publiques ce qui les rendrait disponibles pour tout objet ou classe.

class A
{
 [...]]]></description>
			<content:encoded><![CDATA[<p>On utilise la notion d&#8217;ami lorsque l&#8217;on a deux classes dont l&#8217;une doit avoir accès aux données membres privées de l&#8217;autre.<br />
Cette façon de faire permet de limiter à une seule classe l&#8217;accès à des données privées et de ne pas devoir rendre celles-ci publiques ce qui les rendrait disponibles pour tout objet ou classe.</p>
<pre class="codesource">
<span class="reservedname">class</span> A
{
  <span class="reservedname">public</span>:
    <span class="reservedname">void</span> f();
};

<span class="reservedname">class</span> B
{
  <span class="reservedname">private</span>:
    <span class="reservedname">friend</span> <span class="reservedname">class</span> A;
    <span class="reservedname">int</span> g(){<span class="reservedname">return</span> x;}
    <span class="reservedname">int</span> x;
};
</pre>
<p>Il est important de remarquer que c&#8217;est la classe qui veut partager ses données privées avec une autre qui donne l&#8217;accès à celles-ci en spécifiant que l&#8217;autre classe est une amie.<br />
Cela se fait avec le mot-clé <em>friend</em> suivi de la classe qui reçoit l&#8217;accès aux données privées.<br />
Les bonnes pratiques de la programmation veulent que même si dans ce cas-ci, A a accès à <em>x</em> dans B, A n&#8217;y fasse appel que via une fonction privée <em>g()</em>, qui sert d&#8217;interface, et non directement. Rien ne l&#8217;empêche néanmoins si ce n&#8217;est le code de bonne pratique.</p>
<p>En réalité, cette notion de classe amie est une généralisation des fonctions amies. On peut très bien avoir une fonction membre d&#8217;une classe ou une fonction globale à laquelle une classe accorderait l&#8217;accès à ses données privées. Le principe est le même que pour une classe.</p>
<pre class="codesource">
<span class="reservedname">class</span> A
{
  <span class="reservedname">public</span>:
    <span class="reservedname">int</span> f();

<span class="reservedname">class</span> B
{
  <span class="reservedname">private</span>:
    <span class="reservedname">friend</span> <span class="reservedname">int</span> global_func();
    <span class="reservedname">friend</span> <span class="reservedname">void</span> A::f();
    <span class="reservedname">int</span> x;
};

<span class="reservedname">int</span> A::f()
{
  B b;
  <span class="reservedname">return</span> b.x;
}

<span class="reservedname">int</span> global_func()
{
  B b;
  <span class="reservedname">return</span> b.x;
}
</pre>
<p>Notez également que les déclarations d&#8217;amis peuvent être faites tant dans la partie privée que publique de la classe. Il n&#8217;y a aucune différence entre les deux.</p>
]]></content:encoded>
			<wfw:commentRss>http://linux.leunen.com/?feed=rss2&amp;p=85</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
