Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Dev Mag 2012

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 70

Developpez

Le Mag

dition de octobre - novembre 2012. Numro 42. Magazine en ligne gratuit. Diffusion de copies conformes loriginal autorise. Ralisation : Alexandre Pottiez Rdaction : la rdaction de Developpez Contact : magazine@redaction-developpez.com

Sommaire
JavaScript (X)HTML CSS Lazarus SAS Access C++ Qt 2D/3D/Jeux Java NetBeans Eclipse Android Liens Page 2 Page 4 Page 10 Page 16 Page 23 Page 28 Page 37 Page 47 Page 52 Page 55 Page 63 Page 64 Page 67 Page 69

Article (X)HTML

Raliser une application offline en HTML5


Cet article vous permettra de faire rapidement une application HTML5 qui grera le mode offline de votre navigateur.
par Franck Lefevre Page 4

Article Qt ditorial
Ce mois-ci, profitez de deux nouvelles rubriques totalement indites dans le magazine, Lazarus et SAS. Et bien entendu, retrouvez le meilleur des ressources de vos rubriques prfres. Profitez-en bien ! La rdaction

Les modules de Qt 5
Qt 5 rorganise vos modules, retrouvez-les rapidement et facilement grce cet article.
par Guillaume Belz Page 47

JavaScript
Les blogs JavaScript HTML5 : quelques nouveauts de lAPI DOM pour JavaScript
La spcification HTML5 dfinit diffrents modules indpendants. Cette modularit a pour avantage de permettre de travailler sur certains aspects du standard sans avoir besoin de se soucier de ltat davancement des autres. Parmi ces modules, lAPI DOM est celui qui permet de dfinir les proprits et mthodes disponibles en JavaScript pour manipuler le DOM. Nous allons voir les diffrentes nouveauts particulirement utiles de cette API. Standardisation de innerHTML Introduite par Internet Explorer 4 (de mmoire), la proprit innerHTML permet de dfinir le contenu dun lment en lui affectant sous forme de chaine une portion de code HTML.
HTMLElement.innerHTML = '<p>chaine HTML</p>'

querySelector() / querySelectorAll() Ces deux nouvelles mthodes font leur apparition avec un fonctionnement un peu diffrent des prcdentes. Les mthodes du type getElement[s]By prennent comme argument une chaine correspondant au type dlment recherch (un id, un nom de balise, de classe ou un name). Les mthodes querySelector() et querySelectorAll() prennent quant elles en argument une chaine qui correspond un slecteur CSS. Normalement, toute chaine pouvant servir de slecteur en CSS est accepte, y compris les plus complexes. Nous ne listerons pas ici les diffrents slecteurs possibles, je vous laisse faire vos propres tests. Ces mthodes sappliquent soit lobjet document, soit un objet HTMLElement. querySelector() renvoie un lment HTML qui correspond au premier lment trouv dans le DOM correspondant au slecteur, son rsultat peut donc tre exploit directement. querySelectorAll() renvoie une collection dlments HTML correspondant tous les lments correspondants au slecteur. Pour traiter son rsultat, il faudra donc faire une boucle sur chacun de ses membres.

Notez quil sagit dune proprit et non dune mthode, var complexSelection = on lutilise donc sous forme dune affectation et non document.querySelector('.aChoisir ul[title="Liste comme un appel de fonction. puce"], li &gt; a[href^=www]); Bien que propritaire IE, cette proprit (sic) sest var allImportantDivInMyParagraph = largement rpandue sur les autres navigateurs et est depuis document.getElementById('My').querySelectorAll('d iv.important'); longtemps largement compatible. Elle est dsormais standardise (innerHTML : Lien 01) et Ces mthodes sont disponibles sur tous les navigateurs fait pleinement partie de la spcification HTML5. modernes y compris Internet Explorer depuis la version 9. getElementsByClassName() matchesSelector() Nous connaissions dj les classiques getElementById(), getElementsByName() et getElementsByTagName(), mais Cette mthode permet de vrifier si un lment correspond beaucoup de dveloppeurs ont longtemps regrett un slecteur CSS. Tout comme les prcdentes, elle labsence de possibilit de recherche dlments partir prend en argument une chaine correspondant un dun nom de classe (ce qui amenait souvent utiliser une slecteur. Elle renvoie un boolen. bibliothque JavaScript pour pallier ce manque). Cest dsormais rectifi avec lapparition de la mthode var el1 = document.getElementById('elem1'); var el2 = document.getElementsByTagName('div') getElementsByClassName(). [0]; Cette mthode peut tre applique lobjet document ou if(el1.matchesSelector('h1')){ un objet HTMLElement. Comme le s de elements le // traitement si l'lment est un titre de laisse supposer, elle retourne une collection dlments (il niveau 1 est donc ncessaire de faire une boucle sur la collection } if(el2.matchesSelector('#toto')){ pour traiter individuellement chaque lment). // traitement si la premire div du document Il est possible de spcifier plusieurs noms de classe pour un lment spars par des espaces, la mthode prend bien possde l'id "toto" } entendu en compte cette subtilit.
var coll = document.getElementsByClassName('classe'); var coll = document.getElementById('un_id').getElementsByCla ssName('classe');

Cette mthode est disponible sur tous les navigateurs rcents y compris Internet Explorer depuis la version 9, cependant, seules les versions prfixes sont reconnues : mozMatchesSelector(), webkitMatchesSelector(), oMatchesSelector() et msMatchesSelector().

Cette mthode est accessible sur tous les navigateurs rcents, y compris Internet Explorer depuis sa version 8.
Numro 42 octobre - novembre 2012 Page 2

Developpez Magazine est une publication de developpez.com

L'interface classList Jusqu prsent, pour manipuler les classes CSS dun lment, il tait ncessaire dutiliser des mthodes assez complexes, que ce soit pour vrifier la prsence dun nom de classe, pour en ajouter ou en retirer. Il fallait utiliser le plus souvent des expressions rgulires et se mfier des erreurs possibles (typiquement, quune recherche sur classe ne renvoie pas vrai si llment possde la classe classeN ). Linterface classList permet de simplifier tout cela. Elle sapplique un lment HTML et renvoie une collection de ses noms de classe.

llment ne la possde pas, le retirer sinon ; contains() permet de vrifier lexistence dun nom de classe parmi celles de llment.

Cette interface est disponible sur tous les navigateurs modernes lexception dInternet Explorer avant la version 10. Conclusion

Ces diffrentes proprits et mthodes apportent beaucoup aux dveloppeurs pour ce qui est de la manipulation du DOM. Cependant, il me semble que de nombreuses mthodes utiles ont t oublies, que ce soit en rapport var allClasses = HTMLElement.classList; linsertion dlments dans le DOM, la possibilit de faire des recherches en remontant larborescence Elle dispose aussi de plusieurs mthodes permettant de (retrouver facilement un lment partir dun de ses manipuler cette liste de classes : descendants). Esprons que les futures implmentations add() permet dajouter un nom de classe combleront ces manques en sinspirant, par exemple, des diffrentes bibliothques JavaScript. llment ; remove() permet de retirer un nom de classe Retrouvez ce billet blog de Didier Mouonval en ligne : llment ; toggle() permet dajouter un nom de classe si Lien 02

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 3

(X)HTML
Les derniers tutoriels et articles
Raliser une application offline en HTML5 Cet article vous permettra de faire rapidement une application HTML5 qui grera le mode offline de votre navigateur.
1. Traduction Code CSS : Cet article va vous apprendre grer trois technologies : HTML5 grant le mode offline, le cache du navigateur et style.css le stockage local. Notre exemple est une gestion de to-do body{ list qui utilise trois technologies : HTML5 et background-color: #E0E0E0; JavaScript/jQuery pour le ct client et PHP pour le ct color: #556677; serveur. font-family: Arial; 2. Prrequis Le code est simple. La page HTML contient une liste non numrote contenant les tches, ainsi qu'un formulaire. Ds que celui-ci est activ, le JavaScript intercepte le formulaire et l'envoie au fichier PHP pour qu'il l'enregistre dans un fichier texte. Code HTML : index.html
<!DOCTYPE html> <html lang="fr"> <head> <title>Article sur HTML5 et le mode offline</title> <meta charset="utf-8"> <link href="style.css" media="screen" rel="stylesheet" type="text/css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery /1.8.1/jquery.min.js" type="text/javascript"></script> <script src="script.js" type="text/javascript"></script> </head> <body> <div class="content"> <h1>Article sur HTML5 et le mode offline</h1> <form method="post" action="index.html" id="frmTodo"> <div> <label for="txtItem">Item :</label> <input type="text" name="txtItem" id="txtItem"> </div> <input type="submit" value="Ajouter" /> </form> <ul></ul> <p>Source : <br/><a href="http://icones.pro/supprimer-15-imagepng.html" target="_blank">Image : <img src="delete.png" alt="Supprimer" /></a></p> </div> </body> </html> } .content{ margin:0 auto; text-align: center; width:300px; } form > div{ padding: 10px; } input[type="text"]{ border: 1px solid #556677; color: #556677; width: 150px; } input[type="submit"]{ border: 1px solid #556677; color: #556677; font-weight: bold; padding: 5px 26px; } ul{ padding: 0; text-align: left; } li{ background-color: #CCCCCC; list-style-type: none; margin: 5px; padding: 5px; } li:hover{ background-color: #AAAAAA; } li > img{ cursor:pointer; float: right; height: 16px; width: 16px; } p{ margin: 60px; } p > a{ color: #556677; font-weight: bold; text-decoration: none; }

Raliser une application offline en HTML5

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 4

p > a > img{ height: 16px; width: 16px; }

Code JavaScript : script.js


$(document).ready(function(){ var jqoTaskLi = $('<li><span class="lblTask"></span><img src="delete.png" alt="Supprimer" class="delTask"/></li>'); }); // Lister les tches l'initialisation de la page $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'list' }, success: function(data) { if(data.result == true){ $.each(data.data, function(key, value){ var jqoItem = jqoTaskLi.clone(); jqoItem.find('.lblTask').html(value); $('ul').append(jqoItem); }); } } }); // vnement lors de la soumission du formulaire $('#frmTodo').submit(function(){ // On rcupre le texte nettoy des espaces avant et aprs var sVal = $('#txtItem').val(); var sVal = $.trim(sVal); if(sVal != ''){ // On envoie une requte AJAX de type POST pour ajouter la tche $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'add', item:sVal }, success: function(data) { if(data.result == true){ var jqoItem = jqoTaskLi.clone(); jqoItem.find('.lblTask').html(valu e); $('ul').append(jqoItem); $('#txtItem').val(''); } } }); } return false; }); $('#ulTodo').on('click','.delTask', function(){ var jqoParent = $(this).parent(); // On envoie une requte AJAX de type POST pour supprimer la tche $.ajax({ }); }) ;

url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'del', pos:$('li').index(jqoParent) }, success: function(data) { if(data.result == true){ jqoParent.remove(); } }

Code PHP : ajax.php


<?php $arrAction = array('add', 'del', 'list'); $arrResult = array('result' => false); if(isset($_POST['type']) && in_array($_POST['type'], $arrAction)){ // Si le fichier contenant les tches n'existe pas, on le cre. if(!file_exists('db.txt')){ file_put_contents('db.txt', ''); } // On charge le fichier et dcode la chaine JSON contenant les tches. $sDbTasks = file_get_contents('db.txt'); $arrTasks = json_decode($sDbTasks); // Si l'action est un ajout if($_POST['type'] == 'add'){ // on ajoute l'lment aux tableaux des tches. $arrTasks[] = htmlentities($_POST['item'], ENT_QUOTES); $arrResult['result'] = true; } // Si l'action est une suppression elseif($_POST['type'] == 'del'){ // et qu'il existe dans le tableau, on le supprime if(is_numeric($_POST['pos'])){ if(isset($arrTasks[$_POST['pos']])){ array_splice($arrTasks,$_POST['pos'],1); $arrResult['result'] = true; } else { $arrResult['result'] = false; } } else { $arrResult['result'] = false; } } // Si l'action est un listing elseif($_POST['type'] == 'list'){ $arrResult['result'] = true; $arrResult['data'] = $arrTasks; } // On encode le tableau des tches dans une

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 5

chaine JSON et on sauvegarde. $sDbTasks = json_encode($arrTasks); file_put_contents('db.txt', $sDbTasks); } echo json_encode($arrResult); ?>

Comme vous pouvez le voir, un commentaire peut tre plac n'importe quel endroit du fichier si un dise est plac au dbut de la ligne. 3.2. Pratique Aprs la thorie, la pratique. Nous mettons donc en place le fichier manifest, le .htaccess et la modification de la balise HTML. En visitant la page sous Firefox, un message s'affiche dans le haut du navigateur (figure 3.2.1).

3. La gestion du cache 3.1. Thorie Le mode hors-ligne intervient quand votre ordinateur n'a plus de rseau ou que votre tlphone se situe dans une zone sans rseau. ce moment-l, votre application Web utilise le cache du navigateur pour stocker les fichiers dont il aura besoin pour travailler (images, JavaScript, feuilles de style et pages HTML). Ces fichiers seront dclars dans un fichier de type MANIFEST li votre fichier HTML via la balise HTML comme ci-dessous : index.html
<html manifest="filename.manifest">

Figure 3.2.1 : Mozilla Firefox propose le tlchargement du cache

Aprs autorisation, on active le travail hors connexion de Mozilla Firefox. Pour que ce fichier soit bien dclar au niveau du serveur, Actualisons la page. il nous faut dclarer son MIME-TYPE via un fichier Rsultat : la page HTML et les contenus statiques sont l. .htaccess : Maintenant, testons un ajout et une suppression de tche : cela fonctionne. .htaccess
AddType text/cache-manifest manifest

4. Le mode hors-ligne

Aprs que le fichier a bien t dclar au niveau du HTML 4.1. Test et du serveur, nous allons voir comment il est structur : manifest.manifest
CACHE MANIFEST # Comment CACHE: delete.png index.html script.js style.css # Fichier JS : jQuery https://ajax.googleapis.com/ajax/libs/jquery/1.8. 1/jquery.min.js FALLBACK: NETWORK: /ajax.php

On active le travail hors connexion de Mozilla Firefox. Comme on peut le voir dans la figure IV.1.1, la requte AJAX vers le fichier ajax.php a chou.

Figure IV.1.1 : chec de la requte AJAX 4.2. Thorie Dans ce cas, nous devons dtecter quand il n'y a plus de rseau pour empcher les requtes AJAX, et quand le rseau est de nouveau disponible, permettre les requtes vers le serveur. Pour cela, on utilise la proprit onLine de l'objet window.navigator (rfrence : Lien 03) qui retourne un boolen contenant le statut en ligne du navigateur. De plus, pour voir les changements rseaux, deux vnements existent : window.onOnline et window.onOffline. 4.3. Pratique Du ct pratique, il suffit d'interroger la variable

Ce fichier MANIFEST est divis en quatre parties : l'en-tte qui doit tre dclar comme tel : CACHE MANIFEST ; la zone de CACHE contenant les fichiers statiques mettre dans le cache du navigateur ; la zone de FALLBACK contenant la redirection mettre en place pour le cas o ils ne seraient pas accessibles en ligne ; la zone de NETWORK contenant les fichiers ncessitant une connexion internet (par exemple, les pages de connexion ou les fichiers PHP lis de l'AJAX).

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 6

navigator.onLine qui contient le statut du navigateur et de suivre via callbacks les deux vnements window.onOnline et window.onOffline. script.js
$(document).ready(function(){ var jqoTaskLi = $('<li><span class="lblTask"></span><img src="delete.png" alt="Supprimer" class="delTask"/></li>'); // Lister les tches l'initialisation de la page $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'list' }, success: function(data) { if(data.result == true){ $.each(data.data, function(key, value) { var jqoItem = jqoTaskLi.clone(); jqoItem.find('.lblTask').html(value); $('ul').append(jqoItem); }); } } }); // vnements lors de la mise on/offline du navigateur $(document).on('online', function() { }); $(document).on('online', function() { alert('Vous tes maintenant hors-ligne. Vos tches ne seront pas enregistres'); }); // vnement lors de la soumission du formulaire $('#frmTodo').submit(function(){ // On rcupre le texte nettoy des espaces avant et aprs var sVal = $('#txtItem').val(); var sVal = $.trim(sVal); // Si on est en ligne if(navigator.onLine){ if(sVal != ''){ // On envoie une requte AJAX de type POST pour ajouter la tche $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'add', item:sVal }, success: function(data) { if(data.result == true){ var jqoItem = jqoTaskLi.clone(); jqoItem.find('.lblTask').html(sVal); $('ul').append(jqoItem); $('#txtItem').val(''); } } }); } }

// Si on n'est pas en ligne else { alert('Rseau : Offline'); } return false; }); $('#ulTodo').on('click','.delTask', function(){ var jqoParent = $(this).parent(); // Si on est en ligne if(navigator.onLine == true){ // On envoie une requte AJAX de type POST pour supprimer la tche $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'del', pos:$('li').index(jqoParent) }, success: function(data) { if(data.result == true){ jqoParent.remove(); } } }); } // Si on n'est pas en ligne else { alert('Rseau : Offline'); } }); });

5. Le stockage local ce niveau, les tches ne sont envoyes uniquement que dans le cas o le navigateur est en ligne. Si le navigateur est hors ligne, un simple message d'erreur nous prvient. Mais comme la technologie HTML5 est bien conue : nous allons pouvoir stocker les actions via la technologie du stockage local, plus communment nomm localStorage. 5.1. Thorie Le stockage local permet de stocker facilement des informations de type cl-valeur. L'objet localStorage contient six mthodes : localStorage.clear() : supprime toutes les cls stockes ; localStorage.getItem(sKey) : retourne la valeur associe une cl ; localStorage.key(iIndex) : retourne la cl d'un index ; localStorage.length : retourne le nombre de cls stockes ; localStorage.removeItem(sKey) : supprime une cl et sa valeur associe ; localStorage.setItem(sKey, sValue) : stocke une cl avec une valeur associe. 5.2. Pratique Dans notre projet, nous allons avoir besoin du stockage local deux moments : en cas de navigateur hors ligne pour stocker les

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 7

script.js

actions (ajout et suppression) ; en cas de retour au mode en ligne pour lister et excuter les actions stockes prcdemment.

jQuery(function($){ var jqoTaskLi = $('<li><span class="lblTask"></span><img src="delete.png" alt="Supprimer" class="delTask"/></li>'); // Lister les tches l'initialisation de la page $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'list' }, success: function(data) { if(data.result == true){ $.each(data.data, function(key, value) { var jqoItem = jqoTaskLi.clone(); jqoItem.find('.lblTask').html(value); $('ul').append(jqoItem); }); } } }); // vnements lors de la mise on/offline du navigateur $(document).on('online', function() { if(localStorage.getItem('numActions')==null){ localStorage.setItem('numActions', 0); } var numActions = localStorage.getItem('numActions'); numActions = parseInt(numActions); if(numActions > 0){ // On parse toutes les actions for (iInc = 0; iInc < numActions; iInc++) { var sAction = localStorage.getItem('action'+iInc); // On dirige en fonction des actions if(sAction == 'add'){ // On envoie la requte AJAX d'ajout $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'add', item:localStorage.getItem('item'+iI nc) }, success: function(data) { if(data.result == false){ alert('Error') } } }); } else if(sAction == 'del'){ // On envoie la requte AJAX de suppression $.ajax({ url: 'ajax.php', dataType: 'json',

type: 'POST', data:{ type:'del', pos:localStorage.getItem('pos'+iInc) }, success: function(data) { if(data.result == false){ alert('Error') } } }); } } // On nettoie toutes les actions localStorage.clear(); } }); $(document).on('online', function() { localStorage.setItem('numActions', 0); }); // vnement lors de la soumission du formulaire $('#frmTodo').submit(function(){ var sVal = $('#txtItem').val(); var sVal = $.trim(sVal); // Si on est en ligne if(navigator.onLine){ // On rcupre le texte nettoy des espaces avant et aprs if(sVal != ''){ // On envoie une requte AJAX de type POST pour ajouter la tche $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'add', item:sVal }, success: function(data) { if(data.result == true){ var jqoItem = jqoTaskLi.clone(); jqoItem.find('.lblTask').html(sVal); $('ul').append(jqoItem); $('#txtItem').val(''); } } }); } } // Si on n'est pas en ligne else { if(localStorage.getItem('numActions') == null){ localStorage.setItem('numActions', 0); } var numActions = localStorage.getItem('numActions'); numActions = parseInt(numActions); // On enregistre en local localStorage.setItem('action'+numActions, 'add'); localStorage.setItem('item'+numActions, sVal); localStorage.setItem('numActions', numActions + 1); // On excute l'action comme si on tait en Numro 42 octobre - novembre 2012 Page 8

Developpez Magazine est une publication de developpez.com

ligne var jqoItem = jqoTaskLi.clone(); jqoItem.find('.lblTask').html(sVal); $('ul').append(jqoItem); $('#txtItem').val(''); } return false; }); $('#ulTodo').on('click', '.delTask', function() { var jqoParent = $(this).parent(); // Si on est en ligne if(navigator.onLine == true){ // On envoie une requte AJAX de type POST pour supprimer la tche $.ajax({ url: 'ajax.php', dataType: 'json', type: 'POST', data:{ type:'del', pos:$('li').index(jqoParent) }, success: function(data) { if(data.result == true){ jqoParent.remove(); } } }); } // Si on n'est pas en ligne else { if(localStorage.getItem('numActions') == null){ localStorage.setItem('numActions', 0);

} var numActions = localStorage.getItem('numActions'); numActions = parseInt(numActions); // On enregistre en local localStorage.setItem('action'+numActions, 'del'); localStorage.setItem('pos'+numActions, $ ('li').index(jqoParent)); localStorage.setItem('numActions', numActions + 1); // On excute l'action comme si on tait en ligne jqoParent.remove(); } }); });

6. Conclusion Et voil, vous savez dsormais grer la dconnexion rseau, le cache de votre application Web et mme du stockage local. Ce code est amliorable sur de nombreux points dont voici quelques pistes : scuriser la gestion des erreurs avec par exemple, la protection des failles XSS (essayer d'ajouter la tche <script>alert('Test');</script>) ; crer une image qui sera modifie chaque changement de statut rseau. Vous pouvez retrouver toutes les sources sur mon compte GitHub ddi aux articles Dveloppez.com : Lien 04 Retrouvez l'article de Franck Lefevre en ligne : Lien 05

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 9

CSS
Les derniers tutoriels et articles
Les bordures en CSS3 Il n'est peut-tre plus la peine de vous prsenter les avantages et nouveauts apportes par la troisime version du CSS (Cascading Style Sheets). L'un des grands pas dans ce langage est l'apparition de proprits de mise en forme avance des bordures.
1. Introduction Nous dfinissons une valeur pour le rayon du cercle dcrivant la forme de l'arrondi. Voici un schma Nous verrons ici comment crer des bordures aux coins d'illustration : arrondis (border-radius), des bordures partir d'image (border-image), des bordures aux couleurs dgrades (border-color) et enfin, des ombres portes aux botes (box-shadow). Et un petit bonus que je vous laisse dcouvrir par vous-mme ! 2. Il n'y a pas que les footballeurs qui russissent leurs corners 2.1. Gnralits Jusqu' prsent pour raliser des botes aux coins arrondis, nous devions utiliser une ou plusieurs images appliquer en arrire-plan dans des <div> imbriqus ou des tableaux neuf cellules. Nous passions plus de temps dcouper nos lments en un coin en haut gauche, puis droite, recoller les morceaux parce qu'on a donn un coup de ciseau de travers Eh bien tout ceci est termin ! Pour peu que le navigateur soit assez rcent pour comprendre ce que nous allons lui demander. IE - avant sa version 9 - ne prend pas en charge les proprits qui suivent. Il est bien videmment possible de spcifier des valeurs diffrentes pour chacun des coins de l'lment. Les bordures en CSS3

Pour rappel : la syntaxe de cette proprit nous permet de mettre de une quatre valeurs qui peuvent tre d'units diverses (px, em, %) : une valeur : pour les quatre cts ; deux valeurs : la premire pour le haut et le bas, la seconde pour la gauche et la droite ; trois valeurs : la premire pour le haut, la seconde pour la gauche et la droite, la troisime pour le bas ; Avec le CSS3, il nous est possible de faire un angle quatre valeurs : respectivement haut, droite, bas et arrondi via la proprit border-radius. gauche. Voici sa syntaxe : <valeur>{1,4} / <valeur>{1,4} Sa compatibilit : IE9+, Firefox 4+, Chrome, Safari 5+ et Opera 10.50+.
.corner { border-radius: 5px; } <div style="background-color: red; width: 150px; height: 150px; color: white;" class="corner">Ceci n'est pas un carton rouge !</div> .corner { -moz-border-radius: 5px 0 50px 10px; -webkit-border-radius: 5px 0 50px 10px; -khtml-border-radius: 5px 0 50px 10px; border-radius: 5px 0 50px 10px; } <div style="background-color: red; width: 200px; height: 100px;" class="corner"></div>

Heu...m'sieur l'arbitre ! C'est qui -moz, -webkit et -khtml ? Outre le fait que nous avons dfini des arrondis plus ou moins importants sur les diffrents angles de notre div, vous avez pu remarquer que des nouvelles proprits se sont invites dans la partie. Il s'agit de proprits propritaires spcifiques chaque navigateur. Cela leur permet d'implmenter et de tester des
Numro 42 octobre - novembre 2012 Page 10

Vous voyez, rien de plus simple. Ici, tous les coins ont le mme arrondi.

Developpez Magazine est une publication de developpez.com

proprits qui ne sont pas encore recommandes par le W3C.

<div style="background-color: red; width: 200px; height: 100px;" class="corner"></div>

Les avis divergent sur leurs utilisations. Certains encouragent les omettre prtextant une implmentation de border-radius largement rpandue depuis quelques versions dans certains navigateurs, d'autres prfrent les laisser pour assurer une compatibilit accrue. Dans la suite de ce tutoriel, je n'emploierai que la proprit sans prfixe pour des raisons de lisibilit. Vous l'aurez compris, seuls les angles en haut gauche et en bas droite sont paramtrs. 2.2. En dtail Voici les proprits disponibles avec les quivalents pour Maintenant que nous avons vu comment faire des arrondis, les proprits propritaires au cas o vous deviez les nous allons voir que nous pouvons pousser le bouchon de utiliser. Les standards sans prfixe (ce qui est le cas pour Maurice un peu plus loin. Opera) : border-radius ; En effet, enfin les effets de border-radius peuvent tre border-top-left-radius ; tendus en mettant des couples de valeurs. Ces couples border-top-right-radius ; dont les valeurs sont spares par un slash (/) permettent border-bottom-right-radius ; de dfinir les rayons horizontaux pour la premire valeur border-bottom-left-radius. et les rayons verticaux pour la deuxime. La diffrence ici est que ces deux rayons s'appliquent sur une ellipse et non plus un cercle. C'est pourquoi les formes peuvent tre Safari et Chrome (pour ne citer qu'eux) : -webkit-border-radius ; diverses et varies. -webkit-border-top-left-radius ; Un autre schma d'illustration pour mieux comprendre : -webkit-border-top-right-radius ; -webkit-border-bottom-right-radius ; -webkit-border-bottom-left-radius. Mozilla Firefox : -moz-border-radius ; -moz-border-radius-topleft ; -moz-border-radius-topright ; -moz-border-radius-bottomright ; -moz-border-radius-bottomleft. 2.3. S'il te plat, dessine-moi un mouton ! Voici quelques exemples d'utilisation de border-radius :
#exemple div { background-color: gray; width:200px; height: 80px; float: left; margin-left: 30px; margin-top: 30px; line-height: 80px; text-align: center; font-size: 25px; color: white; font-weight: bold; } #demo1 { border-radius: 35px; } #demo2 { border-top-left-radius: 30px 15px; } #demo3 { border-bottom-left-radius: 25px 50px; }

Reprenons notre exemple en appliquant une valeur pour l'horizontale et la verticale :


.corner { border-radius: 10px 50px / 50px; } <div style="background-color: red; width: 200px; height: 100px;" class="corner"></div>

Dans le cas prsent, les coins en haut gauche et en bas droite sont dfinis par une ellipse avec des rayons verticaux et horizontaux diffrents (respectivement 50px et 10px). Comme c'est souvent le cas en CSS, cet attribut peut tre dtaill. C'est--dire que l'on ne peut arrondir que certains angles en les prcisant spcifiquement.
.corner { border-top-left-radius: 50px 10px; border-bottom-right-radius: 25px; }

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 11

3.1.2. Border-image-slice
#demo4 { border-radius: 25px 10px / 10px 25px; } #demo5 { border-radius: 1em 4em 1em 4em; } #demo6 { border-top-left-radius: 50px; } <div id="exemple"> <div id="demo1"></div> <div id="demo2"></div> <div id="demo3"></div><p style="clear: both;"></p> <div id="demo4"></div> <div id="demo5"></div> <div id="demo6"></div> </div>

Permet de dfinir jusqu' quatre longueurs indiquant la distance partir de chaque coin de l'image afin de la couper. Un petit schma pour mieux comprendre :

Nous avons dcoup notre image en neuf parties : 1, 3, 7 et 9 : ce sont nos quatre coins. Ils ne seront pas modifis (ni tirs, ni rpts, ni mme les deux) ; 2, 4, 5, 6, 8 : ces parties-l seront tires, rpts ou les deux. Tout dpend de vos attentes. Ici, pour cet exemple, le CSS ressemblerait :
.corner-image { border-image-slice: 26 26 26 26; border-image-slice: 26 /* En version raccourcie vu que les cts sont tous de la mme longueur */ }

L'image est dcoupe en neuf carrs de 26 pixels de ct. 3. L'image vaut mille mots. - Confucius 3.1.3. Border-image-width Il est dsormais possible de dfinir une image comme Permet de dfinir la largeur de la bordure. Elle est motif de bordure en lieu et place des traits dont nous prioritaire sur border-width. Dans le cas o aucune n'est disposions jusqu' maintenant. prsente, la bordure sera celle par dfaut de border-width. Notre image de rfrence : Opera ne prend pas en charge border-image-width, il faudra donc utiliser border-width la place.
.corner-image { border-image-width: 26px; }

3.1. Une balise unique pour les gouverner toutes Border-image regroupe une liste de proprits que nous verrons brivement ci-dessous. Pourquoi brivement ? Parce qu'elles ne sont pas encore reconnues par les navigateurs, l'exception donc, de border-image dont l'exemple complet sera donn la fin de la prsentation des proprits qu'elle regroupe.

3.1.4. Border-image-outset La proprit border-image-outset indique de combien la zone de l'image peut s'tendre au-del de la dimension de la bordure sur les quatre cts.
.corner-image { 26;

Les proprits prsentes dans le point A ne sont pas border-image-outset: reconnues par nos navigateurs. Elles ne sont donnes qu' } titre d'exemple et d'explication pour la proprit raccourcie : border-image. 3.1.5. Border-image-repeat 3.1.1. Border-image-source

Permet de dfinir de quelle manire seront traits les bords en haut, droite, en bas et gauche de l'image. Cela ne Permet de dfinir l'URL de l'image utiliser. On peut concerne pas les angles, bien videmment puisqu'eux ne utiliser les mmes types d'images que pour les images de sont pas rpts. Il est possible de dfinir une ou deux fond, savoir : les jpeg, gif, png, svg, les dgrads, des valeurs, la premire s'appliquant pour le haut et le bas, images codes en base64. tandis que la deuxime sera pour la droite et la gauche. Si une seule est fournie elle s'applique sur les quatre cts.
.corner-image { border-image-source : url('fond.gif'); }

Les valeurs disponibles sont : stretch : tire l'image sur toute la longueur couvrir ; repeat : comme pour background, l'image sera
Numro 42 octobre - novembre 2012 Page 12

Developpez Magazine est une publication de developpez.com

rpte pour couvrir tout l'espace ncessaire ; round : comme repeat, la diffrence que cette fois, l'chelle de l'image sera conserve afin de ne plus avoir de coupure. Nous avons donc une bordure constitue d'une image dont les parties du milieu sont rptes sans coupures (round). 4. Sortez vos feutres, c'est atelier coloriage Grce la version trois de CSS, il est possible d'avoir des dgrads de couleurs dans nos bordures. Actuellement, seul Firefox a implment la gestion du dgrad. L'utilisation du prfixe -moz est donc obligatoire. Voici la syntaxe de -moz-border-colors : [ <color> || transparent ]+ La compatibilit de border-colors : Firefox 3.0+ Un exemple d'utilisation :
.color-border-1 { border: 6px solid black; -moz-border-bottom-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; -moz-border-top-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; -moz-border-left-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; -moz-border-right-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; } <div style="background-color: red; width: 200px; height: 100px;" class="color-border-1"></div>

Le code ci-dessous montre leur mise en application.


.corner-image-1 { border-image-repeat: stretch stretch; } .corner-image-2 { border-image-repeat: repeat repeat; } .corner-image-3 { border-image-repeat: round round; }

3.2. Enfin ! La voil ! Border-image ! Alors pour faire court, vous prenez tout ce qu'on a fait prcdemment et vous les mettez la suite. Dans l'ordre nonc.

Voici la syntaxe de border-image :<source> <slice {1,4}> / <width {1,4}> / <outset> <repeat{1,2}> On dclare une couleur par pixel. Donc si on a une bordure de six pixels, on dclare six couleurs. Sa compatibilit : Firefox avec le prfixe -moz, Opera avec le prfixe -o, Safari avec le prfixe -webkit. Internet 5. L'ombre c'est pas qu'avec les parasols ? Explorer ne prend pas encore en charge cette proprit. La dernire (ou pas) proprit que nous verrons Chrome quant lui supporte cette proprit. aujourd'hui est box-shadow. Avec cette dernire, il vous est possible d'ajouter une ombre interne ou externe sur un Exemple : lment HTML de type bloc. Pour le texte il faudra utiliser text-shadow qui est prvu cet effet. .corner-image {
border-width: 26px; /* Fix pour Opera */ border-image: url('fond.gif') 26 / 26px round; }

Voici la syntaxe de box-shadow : none | <shadow> [ , <shadow> ]* avec : <shadow> = inset? && [ <length>{2,4} && <color>? ] Sa compatibilit : IE 9+, Firefox 4+, Safari 4+, Opera 10.5+, Chrome 10+ Un petit peu d'explications ne serait pas du luxe : une valeur positive pour le dcalage horizontal dplace l'ombre vers la droite, une valeur ngative vers la gauche ;

Qui est la version abrge de :


.corner-image { border-width: 26px; /* Fix pour Opera */ border-image: url('fond.gif') 26 26 26 26 / 26px 26px 26px 26px round; /* Je vous rappelle que les quatre cts sont gaux donc pas besoin de rpter leurs valeurs */ }

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 13

une valeur positive pour le dcalage vertical dplace l'ombre vers le bas, une valeur ngative Voici d'autres exemples d'utilisation : vers le haut ; vous ne pouvez pas donner une valeur ngative #exemple div { width:200px; pour l'tendue de flou. Plus la valeur est grande, height: 80px; plus le flou s'tale ; float: left; une distance de propagation positive entrane une line-height: 80px; expansion de la zone d'ombre dans toutes les text-align: center; directions, une valeur ngative entrane une font-size: 25px; contraction ; color: black; la couleur est celle de l'ombre ; font-weight: bold; la valeur inset indique une ombre interne plutt } qu'externe. #demo1 {
background-color: yellow; box-shadow: -5px -5px 5px #888; margin-left: 30px; margin-top: 30px; } #demo2 { background-color: yellow; box-shadow: -5px -5px 0 5px #888; /* On propage la zone d'ombre de 5px */ margin-left: 30px; margin-top: 30px; } #demo3 { background-color: yellow; box-shadow: 0 0 5px #888; margin-left: 30px; margin-top: 30px; } #demo4 { background-color: yellow; box-shadow: 0 0 5px 5px #888; margin-left: 30px; margin-top: 30px; border-radius: 10px; } #demo5 { background-color: white; border: 1px solid black; border-radius: 20px; margin: 100px; box-shadow: 40px 30px 50px red, -40px -30px 50px blue, 40px -30px 50px yellow, -40px 30px green; } <div id="exemple"> <div id="demo1">1</div> <div id="demo2">2</div> <div id="demo3">3</div><p style="clear: both;"></p> <div id="demo4">4</div> <div id="demo5">5</div> </div>

Je vous assure que cela va tre plus clair avec un exemple, que voici d'ailleurs :
.shadow { box-shadow: 2px 2px 4px black; } <div style="background-color: yellow; width: 200px; height: 100px;" class="shadow"></div>

Ici, notre ombre est dcale de deux pixels horizontalement et verticalement avec un flou de quatre pixels, le tout de couleur noire. L, mme chose avec des valeurs lgrement diffrentes :
.shadow { box-shadow: 20px 20px black; } <div style="background-color: yellow; width: 200px; height: 100px;" class="shadow"></div>

Vous comprenez maintenant comment donner plus de dimension vos botes ? Un autre exemple mais avec une ombre interne :
.shadow { box-shadow: inset 0 0 5px 5px #888; } <div style="background-color: yellow; width: 200px; height: 100px;" class="shadow"></div>

Je crois que vous avez compris le principe maintenant.

Petit exemple, juste comme a, avec tout ce qui a t vu


Numro 42 octobre - novembre 2012 Page 14

Developpez Magazine est une publication de developpez.com

jusqu' maintenant :
#demo6 { background-color: yellow; box-shadow: 5px 5px 5px #888; margin-left: 30px; margin-top: 30px; border-radius: 1em 4em 1em 4em; border: 6px solid black; -moz-border-bottom-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; -moz-border-top-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; -moz-border-left-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; -moz-border-right-colors: #0682bd #198dc9 #2d99d7 #3da3e1 #51afee #62baf9; } }

background: rgba(0, 0, 255, 0.5); position: absolute; left: 75px;

<article> <div class="rgba-1"></div> <div class="rgba-2"></div> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis. </article>

Vous remarquez que la deuxime div semble d'une couleur diffrente pourtant elle est juste transparente. On peut vraiment faire des choses intressantes avec Les valeurs de la couche Alpha varient de 0 1, de la plus CSS3. claire la plus fonce. 6. Bonus Attention, le systme RGBA n'est pas confondre avec la proprit opacity. Elles n'ont pas les mmes utilisations. Allez, une dernire proprit pour la route et aprs je vous Opacity rend l'lment entier transparent, contenu laisse avec Conclusion et remerciements , ils sont compris, alors que RGBA ne s'applique qu'aux couleurs. sympa vous verrez ;) Je n'en ai pas parl jusqu' prsent mais CSS3 offre une nime faon de dclarer une couleur pour un lment : le RGBA. Ce n'est ni plus ni moins que le systme RGB traditionnel complt du canal Alpha, qui permet de jouer avec l'opacit, la transparence d'une couleur. Et a, c'est intressant ! Par exemple : dfinissons une div bleue et une deuxime, galement bleue, mais avec une transparence de 50 %.
body { background: gray; } article { background: rgb(255, 0, 0); width: 200px; height: 100px; position: relative; } .rgba-1 { width: 75px; height: 75px; background: rgba(0, 0, 255, 1); position: absolute; } .rgba-2 { width: 75px; height: 150px;

Observez la diffrence :
.rgba { background: rgba(0, 125, 0, 0.5); } .opacity { background: rgb(0, 125, 0); opacity: 0.5; } <div style="width: 200px; height: 20px; height: 20px;" class="rgba">Ceci est un avec RGBA</div> <div style="width: 200px; height: 20px; height: 20px;" class="opacity">Ceci est avec Opacity</div> linetexte lineun texte

On voit ici que dans le cas d'opacity, le texte est galement mis en transparence. 7. Conclusion Voil, c'est tout pour l'instant. J'espre que ce petit article vous aura plu et que je vous retrouverai dans la suite des aventures du CSS3. Retrouvez l'article de Torgar en ligne : Lien 06

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 15

Lazarus
Les derniers tutoriels et articles
GENSE D'UN DICTIONNAIRE - Construction d'un lexique interactif avec Lazarus Cette srie d'articles a pour objectif la construction d'un lexique interactif, chaque tape traitant les difficults rencontres dans la gestion du vocabulaire, et prsente une ou des solutions.
1. Lecture d'une liste de mots La saisie d'un vocabulaire de 300 000 mots est une tche digne des copistes du Moyen ge : raison d'un mot par seconde, il faudrait quatre jours de frappe ininterrompue 1.1. Introduction Heureusement, avec internet, l'accs ce volume de La saisie assiste de SMS, l'accs aux moteurs de donnes est facile. recherche et la correction automatique d'orthographe nous ont familiariss avec un processus remarquable : en temps 1.3. Liste de dpart rel, un robot nous propose de complter le mot que l'on a Dans votre navigateur prfr, collez l'adresse suivante, ou en tte cliquez tout simplement sur le lien : Lien 07 La prestation est d'autant plus notable qu'elle s'est insinue dans nos tches quotidiennes sans crier gare : l'assistance Sur la page qui apparat, cliquez sur est l, permanente, rassurante, quelquefois mme " liste.de.mots.francais.frgut.txt " (Lien 08). envahissante ; ceci dans des conditions techniques stockages de donnes monstrueux, flux d'changes dbits Le navigateur s'ouvre sur une nouvelle page qui prsente levs, algorithmes de tri rapide mieux gards que Fort la liste recherche. Un clic droit, dans le menu contextuel, Knox, etc. que l'on peut difficilement imaginer. choisissez Enregistrer sous ; vous pouvez conserver le Il n'est pas question ici d'aborder cet arsenal la pointe de nom propos ; choisissez comme rpertoire celui du projet, l'informatique d'aujourd'hui, mais modestement d'tudier par exemple Lexique, et sauvegardez. comment raliser une base de vocabulaire personnelle, volutive, consultable aisment, ce qui est dj une 1.4. La source approche intressante, mais, pourquoi pas, susceptible de donner un coup de main dans le cadre d'un jeu de mots : Le fichier qui vient d'tre charg est un vritable trsor : il recherche formelle avec l'utilisation d'un masque contient exactement 336 531 entres, donc beaucoup plus prcisant la longueur du mot et les lettres que les plus gros dictionnaires ou encyclopdies jamais dits sur papier ! C'est le rsultat d'un travail initi connues, recherche logique partir d'une dfinition souvent notamment par l'Universit de Lausanne (merci nos amis humoristique. Un exemple clbre est celui de suisses) et poursuivi en France au CNRS et diffrentes Tristan Bernard : Vide les baignoires et remplit universits dont Paris Descartes. les lavabos . Rponse la fin du chapitre. Christophe Pallier est un minent chercheur en sciences En quelques tapes, nous allons construire une imposante cognitives, et je ne rsiste pas la tentation de reprendre base de mots avec les outils ncessaires pour la consulter ici la prsentation qu'il fait de lui-mme, les nuls en anglais me (lui) pardonneront : et l'enrichir. Oui, a marche : mieux que Google ! I am a middle age homo-sapiens drinking too much coffee. I am also the father of 3 homo-sapiens-sapiens (2 males/1 female). During the day, I work as a scientific researcher, sponsored by the french tax-payers to try and understand the brain machinery that allows us to speak. As no one seems willing to write a Wikipedia entry about me or my accomplishments, I have decided to create this website (in 1994, long before the advent of Wikipedia, but let us not be sidetracked by this apparent paradox). GENSE D'UN DICTIONNAIRE - Construction d'un lexique interactif avec Lazarus

L'approche se veut mthodique et progressive. Didactique. Les geeks ne trouveront rien de transcendant. Les dbutants et les curieux pourront au contraire apprcier une mthode essentiellement pragmatique Et aprs tout, rien n'empchera de porter l'application sur Android, pour que l'application, une fois acheve, soit accessible sur son PDA Les passionns et les bonnes volonts pourront apporter Tout le monde a compris qu'il buvait trop de caf, qu'il leur comptence, qui sera la bienvenue. avait trois enfants, qu'il vivait aux crochets du contribuable et que Wikipedia ne parlait pas de lui ! 1.2. Prsentation La premire tape est consacre au chargement d'une liste et sa consultation. Les suivantes constituent une initiation ludique la programmation sous Lazarus, mais elles restent transposables aisment tout autre langage. Merci ce brillant chercheur pour son humour et l'autorisation qu'il nous a donne d'utiliser sa publication (Il a exploit, souligne-t-il, les travaux de Christophe Pythoud et de l'association Gutenberg ).

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 16

1.5. Lecture directe Il suffit de cliquer sur le nouveau fichier pour que le programme par dfaut de votre ordinateur affiche le texte. Le bloc-notes de Windows est lent et prsente tous les mots sans retour la ligne ; WordPad convient, mais Notepad++ est mieux adapt, car les numros de ligne sont indiqus :

moins un lien avec un autre mot C'est ce que l'on va aborder dans le prochain chapitre en utilisant Lazarus que l'on peut charger ds maintenant partir du site Developpez.com ou directement ici : Lien 09 Attention, la page affiche des boutons Tlchargez ou Download qui sont des liens publicitaires. La cible reprer s'intitule Lazarus Windows 32 bits Lazarus Windows 64 bits ou Lazarus Mac, Linux, etc. dans des versions dates du 28 ou 29 juillet 2012. Cliquez sur la ligne qui vous convient et installez Lazarus. 1.7. Conclusion Pour la langue franaise, la ressource disponible se rvle mieux que copieuse : notre projet dmarre dans de bonnes conditions. Mais il est difficile d'imaginer que des ressources homologues n'existent pas pour d'autres langues : Internet est une mine fconde o il suffit souvent de chercher

Peut-on vrifier le nombre exact d'entres ?

Il suffit de rejoindre la fin du fichier dans la fentre du programme. Notepad++ donne les informations Sans oublier la colle du dbut de chapitre : les baignoires cherches : sont (galement) des loges au thtre ; les lavabos sont (galement) des toilettes. Si on associe thtre et toilettes, avec l'aide peut-tre de quelques lettres dj identifies, on aboutit entracte ! Un essai avec Google : le moteur de recherche propose Jacob Delafon Logique purement commerciale, loin de tout humour ! Voyons si nos petits bras muscls et nos quelques neurones encore valides seront en mesure de relever le dfi Le prochain chapitre abordera diffrentes mthodes pour ouvrir le fichier texte avec Lazarus. Le dernier mot s'crit zythums (Bire de l'gypte Je ne retomberai jamais en enfance, j'y suis toujours ancienne) et il figure sur la ligne 336531. Objectif atteint. rest. Tristan Bernard 1.6. Utilisation 2. Affichage sous Lazarus L'ensemble du fichier texte et de son programme de lecture donne accs aux fonctions essentielles : 2.1. Introduction lecture d'un mot ; modification ; Le premier chapitre a conduit au chargement d'un fichier ajout ; texte. Fichier quand mme exceptionnel puisqu'il apporte recherche ; plus de 336 000 mots de la langue franaise ! sauvegarde, etc. Cette liste est consultable l'aide d'un programme courant, style bloc-notes ou WordPad, mais l'intrt de cette Donc notre projet pourrait s'arrter l, avec une belle consultation reste alors trs restreint. Un outil tel que collection de mots d'un ct, et un outil tout prt pour la Lazarus va ouvrir des possibilits intressantes. Dans ce consulter chapitre seront prsentes trois mthodes de lecture, et une technique d'valuation. Mais faisons un rve. Ne pourrait-on pas : Dans le chapitre suivant, le programme sera complt pour dessiner une interface plus accueillante ; aborder diffrentes faons d'afficher et de balayer le texte. disposer d'une petite fentre pour dialoguer avec 2.2. Dmarrage de Lazarus la machine ; attacher une information, pas forcment une Votre ordinateur dispose de Lazarus d'un ct, du fichier documentation complte, style wiki, mais au de mots d'un autre. Pour simplifier les explications venir,
Developpez Magazine est une publication de developpez.com
Numro 42 octobre - novembre 2012 Page 17

nous vous proposons de crer un rpertoire Lexique dans localis et la compilation (construction du fichier exe) se lequel seront ouverts les sous-rpertoires Docs et Lex1. fera dans le rpertoire que vous aurez choisi. Le rpertoire Docs recevra les documents textes et pour 2.5. Interface graphique commencer, le fichier de mots. Pour l'instant, l'interface graphique se prsente sous la forme d'une fentre intitule Form1. Nous nous Lex1 sera rserv Lazarus, donc au programme source, limiterons, dans l'immdiat, trois modifications : au programme compil et l'ensemble des fichiers de Nom de l'interface. Dans le menu Fentre de service. Lazarus, slectionnez Form1. Cliquez dans cette fentre pour indiquer Lazarus que vous vous Pour les chapitres suivants, on crera le rpertoire Lex2, intressez cet objet prcis. Effectivement, Lex3, etc. de faon faciliter chaque instant le retour Lazarus, dans sa fentre Inspecteur d'objets a un tat antrieur du programme. slectionn la ligne Form1:TForm1 . Audessous, dans l'onglet Proprits, ligne Caption, Lancez Lazarus, cliquez sur on lit Form1. Remplacez ce nom par Lex1 : Fichier/Nouveau/Application. Au premier plan apparat immdiatement le nouveau nom s'affiche en tte une fentre intitule Form1 : c'est elle qui recevra les de notre interface graphique ; boutons de commande et les modules d'affichage. Bouton. Au second plan s'ouvre la fentre de l'diteur de code intitule diteur de source. 2.3. Sauvegarde de l'unit La premire ligne de l'diteur s'intitule unit Unit1 ; cliquez sur Fichier/Enregistrer sous. Choisissez : votre rpertoire de travail, par exemple Lex1 ; le nom de votre unit, par exemple uLex1, sauvegardez, option Prserver le nom. Le fichier uLex1.pas est cr dans le rpertoire Lex1. Sous la ligne du menu, cliquez sur le bouton marqu Ok, puis cliquez au centre de la fentre Lex1 : un bouton appel Button1 apparat. Dans l'inspecteur d'objets, la slection a bascul sur ce nouvel objet. Dans l'onglet Proprits, ligne Caption, remplacez Button1 par Lire ; Texte. Sous la ligne du menu, ct du bouton, figure un objet qui se prsente sous le sigle Abc. Cliquez dessus, puis cliquez dans l'interface graphique : l'objet Label1 apparat. Il est slectionn automatiquement dans l'inspecteur d'objets.

L'interface est minimaliste, mais nous aurons l'occasion de l'enrichir ! 2.4. Sauvegarde du projet Dans le menu, sous le mot Fichier, se prsente une icne avec le menu contextuel Nouvelle unit. Sous cette icne, une autre avec l'information Afficher les Units. Cliquez sur cette seconde icne : deux units sont listes. La premire, uLex1, est celle que l'on vient de crer. Cliquez sur la seconde et enregistrez sous le nom de pLex1. L'unit et le projet sont en scurit sur votre disque dur. Toutes les modifications seront enregistres et Lazarus permettra un retour en arrire aprs toute une srie de saisies. Cette phase pralable d'enregistrement (choix du rpertoire, enregistrement de l'unit et du projet) est fondamentale sous Lazarus, qui connat dornavant son espace de travail : votre programme est maintenant 2.6. Code Nous voil maintenant au pied du mur : nous imaginons un clic sur le bouton, qui dclenche la lecture du fichier texte, et une information apparat sur l'interface pour signaler que l'opration s'est droule normalement. Voici le code qui permet la lecture du fichier texte :
procedure LireListeDeMots; var MotCour: string; lettre: char; fLex: file; listeMots : TStringList; begin TopChro := 0; TopChrono(''); Numro 42 octobre - novembre 2012 Page 18

Developpez Magazine est une publication de developpez.com

listeMots := TStringList.Create; AssignFile(fLex, 'liste.de.mots.francais.frgut.txt'); {$I-} Reset(fLex, 1); {$I+} if IOResult = 0 then begin Seek(fLex, 0); MotCour := ''; while not EOF(fLex) do begin BlockRead(fLex, lettre, 1); if lettre <> Chr(10) then MotCour := MotCour + lettre else begin listeMots.Append(MotCour); MotCour := ''; end; end; CloseFile(fLex); TopChrono('Lecture octets'); Form1.Label1.Caption := 'Dernier mot (n ' + IntToStr(listeMots.Count) + ') : ' + listeMots.Strings[listeMots.Count-1]; end else ShowMessage('Erreur d''accs au fichier'); Beep; end;

Une seule instruction est crire : LireListeDeMots qu'il faut terminer par un point-virgule ; . Dans la pratique, notre programme uLex1 fabrique ( l'aide de tout l'environnement Lazarus videmment) une interface graphique Lex1 avec un bouton et une ligne de texte. Lorsque l'on clique sur le bouton, le programme excute la procdure LireListeDeMots. Quand celle-ci est termine, la ligne de texte nous prsente les informations voulues. Cliquez sur le petit triangle vert pour compiler. Cliquez sur le bouton Lire et patientez, car la lecture du fichier de mots peut durer de 30 60 secondes selon le matriel utilis. L'information voulue apparat enfin :

Il faut copier ce texte dans l'diteur de source, sous la ligne implementation. Le compilateur cherchera le fichier texte dans le rpertoire de travail : il faut donc copier le fichier de mots (en principe dans le rpertoire Docs) dans le rpertoire de travail, Lex1. 2.7. Deuxime mthode Un clic sur le petit triangle vert (sous le mot diter dans le menu Lazarus) dclenche un contrle gnral du projet, sa L'accs au contenu du fichier par l'intermdiaire de Lazarus semble bien lent. En effet, le code contient compilation et son excution (en mode dbogage). l'instruction Si rien ne se passe, c'est que tout va bien, le compilateur a fait son travail jusqu'au bout sans rencontrer de problme. BlockRead(fLex, lettre, 1); Si une erreur est intervenue, lisez attentivement les informations prsentes dans la fentre Messages. qui impose au matriel de lire le fichier lettre par lettre, chaque lettre occupant un octet. Comme le fichier a une Corrigez selon les indications donnes. longueur de 3,7 mgaoctets, il y a autant d'accs disque, ce Pour revenir en mode dition, il suffit de cliquer sur le qui est pnalisant. carr rouge, droite du triangle vert : le mode dbogage La seconde mthode consiste regrouper la lecture par est arrt, l'dition du programme peut reprendre. blocs de textes (les mots) spars par un octet de retour quoi sert le bouton Lire ? Pour l'instant, le programme la ligne. Le code devient alors : n'inclut aucune instruction pour le cas o l'on cliquerait procedure LireListe2; dessus ! Cette omission va tre rapidement corrige. Dans l'interface graphique Lex1, cliquez une fois sur le bouton Lire : son cadre est soulign par huit petits carrs permettant par exemple de modifier sa forme. Dans la fentre Inspecteur d'objets, l'objet Button1 est alors slectionn. Dans la partie infrieure de la fentre, dans l'onglet Proprits, cliquez sur la ligne OnClick : droite, trois points apparaissent ; cliquez dessus : l'diteur de source est immdiatement enrichi d'une nouvelle procdure, et le curseur d'dition clignote entre les instructions begin et end ;
var MotCour: string; fLex: TextFile; listeMots : TStringList; begin listeMots := TStringList.Create; AssignFile(fLex, 'liste.de.mots.francais.frgut.txt'); {$I-} Reset(fLex); {$I+} if IOResult = 0 then begin

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 19

while not EOF(fLex) do begin ReadLn(fLex, MotCour); listeMots.Append(MotCour); end; CloseFile(fLex); Form1.Label1.Caption := 'Lecture par mot ; mot (n ' + IntToStr(listeMots.Count) + ') : ' + listeMots.Strings[listeMots.Count-1]; end else ShowMessage('Erreur d''accs au fichier'); Beep; end;

Un clic sur le petit triangle vert pour compiler, un clic sur le bouton Lire3 et cette fois on apprcie encore. Simplicit et efficacit. 2.9. Chronomtre Pour y voir clair sur les performances de tel ou tel programme, rien de tel que de mesurer la dure qui spare le dmarrage d'une tche et son achvement. Il existe dans la bibliothque LCL une fonction GetTickCount qui donne, en millimes de seconde, la position du compteur Temps du processeur. Pour rendre cette fonction accessible, il suffit de rajouter dans la ligne uses l'unit LclIntf :
unit uLex1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, LclIntf; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Label1: TLabel; Memo1: TMemo; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { private declarations } public { public declarations } end;

Pour lancer cette procdure, on va ajouter un bouton, appel Lire2, et dans la procdure OnClick de ce bouton, glisser l'instruction LireListe2 ; un clic sur le petit triangle vert pour compiler, un clic sur le bouton Lire2 et cette fois on apprcie une raction presque immdiate. Le premier mode de lecture imposait un dchiffrage caractre par caractre, et le second passe directement d'un mot l'autre. En gros, les accs disques passent de 3 700 000 (nombre d'octets) 330 000 (nombre de mots). Plus loin nous verrons comment valuer prcisment la performance. 2.8. Troisime mthode Le rythme pourrait encore s'acclrer si la lecture pouvait s'oprer d'un bloc, avec une sparation automatique des mots Cela est possible en remplaant les instructions BlockRead (version 1) ou ReadLn (version 2) par l'instruction de haut niveau listeMots.LoadFromFile(nomFichier) (listeMots est la liste utilise prcdemment). LoadFromFile indique tout simplement qu'il faut la remplir partir du fichier prcis. Le code se rduit encore :
procedure LireListeTexte; var listeMots : TStringList; begin listeMots := TStringList.Create; listeMots.LoadFromFile('liste.de.mots.francais. frgut.txt'); Form1.Label1.Caption := 'Lecture 3 ; dernier mot (n ' + IntToStr(listeMots.Count) + ') : ' + listeMots.Strings[listeMots.Count-1]; Beep; end;

Lazarus saura identifier l'instruction GetTickCount ; le code de la procdure pourrait s'crire ainsi :
procedure TopChrono(Info : string); begin if TopChro = 0 then begin TopChro := GetTickCount; Form1.Memo1.Append('Dpart chrono'); end else Form1.Memo1.Append(Info +' Dure du processus ' + IntToStr(GetTickCount-TopChro)+' ms'); end;

Pour lancer cette procdure, on va ajouter un bouton, appel Lire3, et dans la procdure OnClick de ce bouton, La procdure modifie la variable globale TopChro. Si elle glisser l'instruction : vaut 0, le champ Memo signale le dpart du chronomtre. Sinon, le Memo prsente l'cart de temps, en LireListeTexte ; millisecondes, depuis le dpart.

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 20

Pour que ce code soit utilisable, il convient de :

Alors, pourquoi l'avoir utilise ?

Primo, dclarer la variable globale TopChro ; pour cela, D'abord pour les besoins de comparaison : aucune solution sous les lignes : ne peut tre a priori considre comme la meilleure. var Form : Tform1 ; on ajoute : Le prsent chapitre a montr comment Lazarus permet de lire un fichier de mots. Le suivant abordera l'affichage des mots et le balayage du fichier depuis le dbut jusqu' la Secundo, ajouter un composant Memo dans l'interface fin. graphique : ce composant est prsent dans le menu Lazarus entre le bouton marqu Ok, dj utilis, et le L'unit uLex1 se prsente dornavant comme suit : bouton marqu on. On clique une fois sur le composant, une fois sur l'interface Lex1 et on agence l'ensemble pour L'unit uLex1 unit uLex1; obtenir sensiblement la prsentation suivante : TopChro : integer ;
{$mode objfpc}{$H+} interface uses Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls, LclIntf; type { TForm1 } TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Label1: TLabel; Memo1: TMemo; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private { private declarations } public { public declarations } end; var Form1: TForm1; TopChro : integer; implementation { TForm1 } procedure TopChrono(Info : string); begin if TopChro = 0 then begin TopChro := GetTickCount; Form1.Memo1.Append('Dpart chrono'); end else Form1.Memo1.Append(Info +' Dure du processus ' + IntToStr(GetTickCount-TopChro)+' ms'); end; procedure LireListeDeMots; var

Ensuite parce que, la suite le montrera, cette instruction nous sera bien utile !

Le champ Memo dispose galement de nombreuses proprits directement accessibles dans l'inspecteur d'objets : cliquez sur la proprit Scrollbars ; faites passer le paramtre de ssNone ssAutoBoth. Ainsi, les ascenseurs latral et vertical permettront de naviguer sans difficult dans ce composant. Tertio, complter chaque procdure de lecture par une mise zro de la variable globale et un premier appel TopChrono, ceci en dbut de procdure, et un second appel TopChrono en fin de procdure. Pour vrifier que tout fonctionne, compilez, et cliquez successivement sur les boutons Lire, Lire2 et Lire3. Les mesures de dure sont affiches dans le mmo. Sur une machine, on obtient par exemple : Type de lecture Octet par octet Mot par mot Globale 2.10. Conclusion Une bonne utilisation du code permet de raliser des conomies spectaculaires dans les temps d'accs. En l'occurrence, l'instruction BlockRead se rvle dsastreuse par rapport l'instruction LoadFromFile. Dure millisecondes 39171 437 156

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 21

MotCour: string; lettre: char; fLex: file; listeMots : TStringList; begin TopChro := 0; TopChrono(''); listeMots := TStringList.Create; AssignFile(fLex, 'liste.de.mots.francais.frgut.txt'); {$I-} Reset(fLex, 1); {$I+} if IOResult = 0 then begin Seek(fLex, 0); MotCour := ''; while not EOF(fLex) do begin BlockRead(fLex, lettre, 1); if lettre <> Chr(10) then MotCour := MotCour + lettre else begin listeMots.Append(MotCour); MotCour := ''; end; end; CloseFile(fLex); TopChrono('Lecture octets'); Form1.Label1.Caption := 'Dernier mot (n ' + IntToStr(listeMots.Count) + ') : ' + listeMots.Strings[listeMots.Count-1]; end else ShowMessage('Erreur d''accs au fichier'); Beep; end; procedure LireListe2; var MotCour: string; fLex: TextFile; listeMots : TStringList; begin TopChro := 0; TopChrono(''); listeMots := TStringList.Create; AssignFile(fLex, 'liste.de.mots.francais.frgut.txt'); {$I-} Reset(fLex); {$I+} if IOResult = 0 then

begin while not EOF(fLex) do begin ReadLn(fLex, MotCour); listeMots.Append(MotCour); end; CloseFile(fLex); TopChrono('Lecture mots'); Form1.Label1.Caption := 'Lecture par mot ; mot (n ' + IntToStr(listeMots.Count) + ') : ' + listeMots.Strings[listeMots.Count-1]; end else ShowMessage('Erreur d''accs au fichier'); Beep; end; procedure LireListeTexte; var listeMots : TStringList; begin TopChro := 0; TopChrono(''); listeMots := TStringList.Create; listeMots.LoadFromFile('liste.de.mots.francais. frgut.txt'); TopChrono('Lecture texte'); Form1.Label1.Caption := 'Lecture 3 ; dernier mot (n ' + IntToStr(listeMots.Count) + ') : ' + listeMots.Strings[listeMots.Count-1]; Beep; end; procedure TForm1.Button1Click(Sender: TObject); begin LireListeDeMots; end; procedure TForm1.Button2Click(Sender: TObject); begin LireListe2; end; procedure TForm1.Button3Click(Sender: TObject); begin LireListeTexte; end; initialization {$I uLex1.lrs} end.

Retrouvez l'article de dimanche2003 en ligne : Lien 10

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 22

SAS
Les derniers tutoriels et articles
SAS Batch : Utilisation du mode Checkpoint/Restart L'article prsente le mode checkpoint/restart permettant un programme batch SAS interrompu par une erreur, de reprendre son excution l o il s'tait arrt.
1. Introduction L'utilisation du mode CheckPoint/Restart permet de soumettre un programme batch qui serait tomb en erreur et ce, partir de la dernire tape DATA ou PROC valide. Lorsqu'il est soumis de nouveau, le programme saute jusqu' l'tape qui tait en erreur et ne soumet pas les tapes prcdentes. programme pour que SAS puisse l'affecter ; NOWORKTERM : permet de conserver la WORK la fin de la session ; NOWORKINIT : vite d'initialiser une nouvelle WORK au dmarrage de la session ; ERRORCHECK STRICT : force l'analyse syntaxique des tapes LIBNAME, FILENAME, %INCLUDE et LOCK ; ERRORABEND : force l'arrt sur n'importe quelle erreur. SAS Batch : Utilisation du mode Checkpoint/Restart

L'objectif est de laisser la possibilit l'utilisateur de corriger son programme et de pouvoir le soumettre de 2.1.1. Illustration de la mise en place du mode nouveau en vitant de tout excuter depuis le dbut. checkpoint 2. Modes de fonctionnement Nous crons un appel de SAS sous forme de ligne de Il existe deux modes, le premier permet de tracer les commande. Le programme excut se nomme traitements et de marquer les erreurs ; le second permet de production et nous utilisons les options prcites qui reprendre les traitements l o tait marque la premire servent contrler le niveau d'erreur (avec ERRORCHECK STRICT, ERRORABBEND) et d'activer erreur (si celle-ci a t correctement corrige). le mode Checkpoint (avec STEPCHKPT). 2.1. Le mode Checkpoint Ici STEPCHKPTLIB permet de sauvegarder le catalogue Grce ce mode, SAS enregistre des points de repre dans le LIBREF savCheck. Par contre la WORK est chaque tape du programme dans le journal et dans un dtruite en fin de session : catalogue nomm CHECKPNT.SAS7BCAT qui contient les informations sur les tapes DATA et les PROC Sas -sysin "c:\projet_alpha\production.sas" uniquement. -stepchkpt -stepchkptlib savCheck -errorcheck
strict -errorabbend

Un certain nombre de prcautions doivent tre prises en compte avec ce mode pour que tout fonctionne Ici la WORK est conserve (avec NOWORKTERM correctement. NOWORKINIT). Nous verrons que ces deux options sont fondamentales ce mode de travail. Tout d'abord, le programme qui s'excute doit accder aux tables intermdiaires du traitement (notamment celles sas -sysin "c:\projet_alpha\production.sas" avant l'erreur) sinon il sera en incapacit de reprendre l -stepchkpt -noworkterm -noworkinit -errorcheck o il en tait. Par consquent, si la WORK tait utilise, strict -errorabbend elle ne doit pas tre supprime en fin de session ou recre la prochaine. Pour cela, il faut utiliser les options 2.2. Le mode Restart NOWORKTERM et NOWORKINIT (si toutes les Il faut excuter le programme avec l'option donnes sont enregistres dans des bibliothques dites STEPRESTART pour que le programme puisse tre permanentes, ces options ne sont pas utiles). relanc partir de la dernire erreur aprs que le catalogue CHECKPNT.SAS7BCAT ait t analys. Dans ce cas, Ensuite, il est prfrable de forcer SAS s'arrter ds la SAS relit le catalogue afin d'isoler les tapes s'tant premire erreur. Ceci est possible avec l'option correctement termines et reprendre celle qui tait ERRORCHECK STRICT. tombe en erreur. Dans le cadre de l'utilisation de ce mode, voici la liste des options importantes : SYSIN : permet l'appel d'un programme SAS ; STEPCHKPT : active le mode CheckPoint ; STEPCHKPTLIB : permet d'indiquer le LIBREF dans lequel SAS doit sauver le catalogue. Il faut spcifier la commande LIBNAME en amont du Ce mode excute tout d'abord les tapes gnrales telles que les LIBNAME, FILENAME et les compilations de macros car le catalogue contient uniquement les informations sur les tapes en erreur ou en succs. De cette faon, les lments cruciaux ne sont pas omis. Afin de contrler un peu plus le mode Restart, il est
Numro 42 octobre - novembre 2012 Page 23

Developpez Magazine est une publication de developpez.com

possible d'ajouter une option forant SAS excuter une tape importante. Ce peut tre une tape DATA ou la Le journal du traitement qui suit montre clairement que le dfinition de macro-variables par exemple. Ceci se fait mode Checkpoint est activ avec l'insertion des balises avec l'option CHECKPOINT EXECUTE_ALWAYS qui se CHECKPOINT avant chaque tape. place immdiatement avant l'tape considre. Enfin, le lancement du mode Restart peut galement s'accompagner du lancement du mode Checkpoint. Comme le programme peut encore tomber en erreur, il sera possible de corriger et de relancer. Ainsi nous aurons la ligne suivante qui cumule les deux modes :
sas -sysin "c:\projet_alpha\production.sas" -stepchkpt -stepRestart -stepchkptlib savCheck -errorcheck strict -errorabbend

3. Exemples de mise en uvre

Les exemples suivants vont illustrer l'utilisation du mode Checkpoint/Restart avec l'excution d'un programme SAS Le code suivant : sur une plate-forme Windows SAS 9.3. Ce procd fonctionnera en 9.2 et sur UNIX. proc sort data=premiere; 3.1. Programme avec conservation de la WORK
by level_1; run;

Pour constater l'arrt sur une erreur, nous insrons une maladresse typographique dans le programme.

Nous crons un fichier .bat permettant d'appeler le programme datametric.sas grce la commande SYSIN. Devient : Nous employons les options permettant de conserver la proc sort LOG et la WORK en plus du mode CheckPoint.

Le programme contient trois tapes simples : une tape DATA, une proc SORT et une tape DATA qui conclut le Lorsque le programme tombe en erreur, la WORK est programme. conserve avec le catalogue permettant SAS de savoir o repartir ainsi que la premire table gnre (elle n'avait pas libname libtest "C:\Data\test"; d'erreurs). %let choix=1;
data premiere; length rowid 8; * unique id; do level_1 = 0 to 2; do level_2 = 0 to 2; do x = 1 to 6+10*ranuni(1234); rowid + 1; y = sin(rowid/2); output; end; end; end; run; proc sort data=premiere; by level_1; run; data second; set premiere; where level_1=&choix; run;

data=premire; by level_1; run;

Nous relanons le programme corrig avec l'option -STEPRESTART cette fois. Par prcaution, nous laissons le mode Checkpoint afin de pouvoir stopper sur une prochaine erreur. Contenu du fichier .bat :
"C:\Program Files\SASHome\SASFoundation\9.3\sas.exe" -CONFIG "C:\Program Files\SASHome\SASFoundation\9.3\nls\en\sasv9.cfg" -LOG "C:\Data\test\monfichier.log" -sysin "C:\Data\test\Datametric.sas" -stepchkpt -stepRestart -noworkterm -noworkinit -errorcheck strict -errorabend

Voici le contenu du fichier .bat qui appelle ce programme :


"C:\Program Files\SASHome\SASFoundation\9.3\sas.exe" -CONFIG "C:\Program Files\SASHome\SASFoundation\9.3\nls\en\sasv9.cfg" -LOG "C:\Data\test\monfichier.log" -sysin "C:\Data\test\Datametric.sas" -stepchkpt -noworkterm -noworkinit -errorcheck strict -errorabend

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 24

Cette fois, la premire tape est reconnue comme tant sans erreur et donc est ignore.

Puisque la WORK n'tait pas conserve et que les donnes Dans le journal, les tapes sont encore marques en mode n'taient pas enregistres dans un rpertoire permanent, le Checkpoint car l'option STEPCHKPT est utilise par programme tombe de nouveau en erreur car la premire crainte d'une nouvelle erreur. tape crant la table PREMIERE, n'a pas t rejoue : la table source de la seconde tape n'existe pas et retourne une erreur. C'est un cercle vicieux qui s'amorce car le programme sait d'o repartir mais n'a plus les donnes pour le faire. Par consquent, il faut conserver le catalogue et les donnes dans un rpertoire qui n'est pas temporaire. 3.3. Utilisation du mode Checkpoint/Restart avec une boucle macro On teste si le mode de marquage SAS rentre dans une boucle macro. 3.2. Programme avec utilisation d'une WORK temporaire Ici le programme cre dix tables partir d'une seule. Nous introduisons une erreur de syntaxe (un point-virgule Cet exemple prouve que mme si le catalogue est manquant) qui crera une erreur uniquement sur l'tape n sauvegard dans un rpertoire permanent alors que les 5. donnes sont stockes dans une vritable WORK, alors le mode RESTART se trouve dans l'incapacit de rejouer le %macro loop; %do i= 1 %to 10; traitement. Voici le contenu du nouveau .bat o les options de conservation de la WORK sont supprimes.
"C:\Program Files\SASHome\SASFoundation\9.3\sas.exe" -CONFIG "C:\Program Files\SASHome\SASFoundation\9.3\nls\en\sasv9.cfg" -LOG "C:\Data\test\monfichier.log" -sysin "C:\Data\test\Datametric.sas" -stepchkpt -STEPCHKPTLIB libtest -errorcheck strict -errorabend data test&i; set sashelp.class; %if &i=5 %then %do; i=2 %end; run;

%end; %mend; %loop;

Comme dans le premier exemple, la ligne de commande excutant ce programme va permettre de conserver la WORK et le catalogue qui sera dedans.

Si l'on indique l'option -STEPCHKPTLIB libtest dans la ligne de commande, le catalogue est conserv dans le rpertoire li au LIBREF libtest dfini dans le programme (ici C:\Data\test). Nous obtenons dans le journal les informations suivantes, puis la mme erreur un peu plus bas.
NOTE: Begin CHECKPOINT execution mode. NOTE: Checkpoint library: C:\Data\test. NOTE: WORK library: C:\sasfiles\saswork\datametric\_TD4132_WINEH2M0MSIPC9_.

Le mode Checkpoint reconnat parfaitement chaque tape DATA et stoppe sur l'erreur.

Aprs correction, nous relanons.

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 25

Ce code signifie qu'une WORK est cre dans le sousrpertoire reprenant le nom de l'utilisateur. Ce code permet donc d'obtenir un rsultat comme celui-ci pour l'utilisateur nomm sassrv :

Aprs correction, nous lanons la ligne de commande avec l'option STEPRESTART et nous constatons que le Lorsque l'option NOWORKTERM est utilise, SAS programme reprend la cinquime tape et poursuit son stocke les tables directement dans le rpertoire nomm travail. dans le fichier sasv9.cfg sans crer de rpertoire commenant par _TD_. Il n'en crera d'ailleurs pas d'autres, tout se droulera dans ce seul rpertoire. Pour le voir, nous lanons des programmes avec nos deux options sous le user Datametric. Nous constatons dans la capture suivante que tout est crit directement dans C:\sasfiles\saswork\datametric :

4. Conservation des WORK ce stade il faut connatre le fonctionnement des options NOWORKTERM et NOWORKINIT pour comprendre comment les utiliser. Ces deux options permettent de conserver la WORK et de ne pas en recrer une afin d'exploiter celle que la prcdente session a cre. Dans ce cas, SAS n'agit pas comme l'accoutume en crant un rpertoire dynamiquement mais utilise directement le rpertoire spcifi dans l'option -WORK du fichier CFG (on peut concevoir que la WORK devient un rpertoire unique et permanent). Illustrons cela.

En conclusion, si ces options doivent tre utilises, il faut prendre garde crer un rpertoire WORK pour chaque programme lanc en batch afin que tous n'crivent pas au mme endroit. Il suffit pour cela d'ajouter la commande -WORK dans la ligne de commande SAS appele dans le batch. Il faut galement utiliser NOWORKINIT pour que SAS ne vide pas le contenu de la WORK la prochaine ouverture de session. 5. Conclusion

Le mode Checkpoint/Restart permet de relancer des traitements partir de l'tape tombe en erreur. Les deux L'environnement suivant cre les WORK dans le modes se cumulant, il est possible de relancer un rpertoire suivant : C:\sasfiles\saswork\!username car le programme aprs l'avoir corrig et de marquer de fichier sasv9.cfg contient une dfinition permettant de nouvelles erreurs. Le premier identifie l'tape, le second crer un rpertoire sous le nom de l'utilisateur. permet de repartir de l'tape incrimine.
Numro 42 octobre - novembre 2012 Page 26

Developpez Magazine est une publication de developpez.com

Ce mode de fonctionnement est finalement assez pratique pour viter de relancer tous les programmes d'un batch et leurs tapes. Cependant, il faut prendre garde utiliser le bon ensemble d'options pour que tout ceci fonctionne : il faut que toutes les tables soient accessibles afin que le programme puisse accder aux donnes ncessaires pour repartir dans de bonnes conditions ; il faut conserver le catalogue dans une bibliothque permanente pour que SAS le retrouve. Les options NOWORKTERM NOWORKINIT doivent donc tre utilises si l'on ne souhaite travailler en WORK plutt que dans

des bibliothques permanentes ; si des tapes importantes doivent tre obligatoirement excutes, l'tape CHECKPOINT EXECUTE_ALWAYS doit tre place avant elles.

Les administrateurs peuvent adopter aisment une stratgie de prise en charge des programmes en production avec ces deux modes. Une mme ligne de commande acceptant les options STEPCHKPT et STEPRESTART, il n'est pas utile de crer plusieurs .bat selon que l'on soit en mode Checkpoint ou Restart. Il faut noter enfin que tout n'est pas automatisable car une intervention humaine reste ncessaire pour corriger le programme. Retrouvez l'article de DATAMETRIC en ligne : Lien 11

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 27

Access
Les derniers tutoriels et articles
un sous-formulaire avec donnes Comment classer les ACCESS dans des tables lies et construire un formulaire pre/fils - Pourquoi et comment implanter un sous-formulaire avec ACCESS Comment classer les donnes dans des tables lies et construire un formulaire pre/fils - Pourquoi et comment implanter

Dans ce tutoriel, je vous propose une marche suivre pour les cas o l'on veut prsenter sur un cran une srie d'informations deux niveaux, par exemple : - chaque facture avec la date, le destinataire, les conditions de paiement au 1er tage et le dtail des articles facturs juste en dessous ; - un produit fini et la liste des pices dtaches qui le composent ; - ou comme ce qui va nous servir de modle dans ce tutoriel, un plat cuisin et la liste des ingrdients ncessaires.
1. Prrequis Certaines connaissances rudimentaires de base sont censes acquises : crer une table, construire une requte, un formulaire Ce texte s'adresse des utilisateurs Access dbutants. 2. Notre objectif l'accs en un clic une vido loge sur Internet ; permettre des recherches multicritres : selon la catgorie, le nom du plat, un ingrdient

J'ai voulu me focaliser sur le sujet et aussi viter tout recours la programmation : il n'y a pas une seule ligne de code VBA dans ce tutoriel.

Je me propose de traiter ces thmes dans un tutoriel Construire un formulaire principal prsent en mode venir. Vous y reviendrez, si a vous intresse, lorsque vous simple (un seul enregistrement affich la fois) et un ne serez plus dbutant Mais si c'est urgent, voyez deux sous-formulaire en mode continu (une liste d'autant de tutoriels de rfrence : lignes que d'enregistrements) pour donner le dtail. cafeine : Recherche multicritre (Lien 12) ; Comme ceci : Jeannot45 : Recherche multicritre avec ou sans code (Lien 13). 3. Organiser les donnes utiles l'application Pour la rdaction de ce chapitre, je me suis largement inspir de l'article Office : Concepts de base sur la conception d'une base de donnes (Lien 14). En vrac, les donnes utiles sont : la catgorie (entre, plat principal), la dnomination de la prparation, le texte de la recette, les quantits de chaque ingrdient et leur prix, le prix de revient par convive. 3.1. Classement tout en une Dans un premier temps, nous pourrions imaginer une table dans laquelle on stocke toutes les informations ncessaires :

Une telle solution prsente plusieurs inconvnients : il faut chaque fois rpter des donnes identiques : dnomination, le nom des ingrdients, leur prix ; Pour plus de lisibilit, le fond du formulaire principal est tenir cette table jour sera fastidieux : chaque en vert. Celui du sous-formulaire est en jaune. variation d'un prix unitaire, il faudra modifier plusieurs endroits sans en oublier ! ; Ce formulaire est volontairement minimaliste , j'aurais combien de quadruplets pu y ajouter : Ingrdient/PU/Quantit/Cot faut-il prvoir ? une image pour illustrer chaque plat ;
Developpez Magazine est une publication de developpez.com
Numro 42 octobre - novembre 2012 Page 28

D'une recette l'autre, le nombre d'ingrdients varie : pour la recette d'un uf dur, un quadruplet Dans le formulaire que nous voulons construire : suffit, pour un plat plus labor, il en faudra une douzaine ! Et sans doute, plus tard le chef trouvera une recette pour laquelle il manque des cases : la loi de Murphy s'applique aussi en cuisine Dans cette approche, chaque ligne de la table contient des informations de plusieurs sujets : relatifs au service : entre, plat principal ou dessert ; relatifs la recette : son nom, la progression, le nombre de convives ; relatifs chaque ingrdient : son nom, son prix unitaire 3.2. Classement par sujet Dans notre exemple, nous avons trois sujets d'informations : les catgories : parle-t-on d'une entre, d'un plat principal, d'un dessert ? ; les plats : comment les nomme-t-on ? Comment les prpare-t-on ? Pour combien de convives ? ; les ingrdients : comment les nomme-t-on ? Quel est leur prix ? Nous constituons ces trois tables avec chacune une colonne du type NumroAuto qui leur servira de cl primaire (un lment qui permet d'identifier de manire unique un enregistrement dans la table). Les voici :

la donne 1 provient de la table tblCategories ; la donne 2 provient de la table tblPlats ; les donnes 3 proviennent de la table tblIngredients ; les donnes 4 sont le rsultat d'une opration. En principe, on ne stocke pas ce genre d'information dans une table si on dispose dj des lments qui permettront Access d'effectuer le calcul en temps opportun.

4.1. Relation un--plusieurs Si nous considrons tblPlats, nous constatons qu' chaque ligne correspond une (et une seule) ligne dans la table tblCategories : chaque plat repris dans tblPlats est soit une entre, un plat principal ou un dessert. De manire symtrique, chaque ligne de tblCategories correspondent plusieurs lignes de tblPlats. Ce type de relation est appel une relation un-plusieurs . Pour matrialiser cette correspondance, nous allons ajouter une colonne dans tblPlats (le ct plusieurs) pour y mentionner la valeur de la cl primaire correspondante de tblCategories (le ct un).

4. tablir des relations entre les tables Nous devons maintenant trouver un moyen de rassembler les sujets de faon cohrente.
Numro 42 octobre - novembre 2012 Page 29

Developpez Magazine est une publication de developpez.com

Nous avons baptis cette colonne dans tblPlats du mme nom qu'elle porte dans tblCategories. Ce n'est pas obligatoire. Par contre, les deux types de donne doivent tre identiques (un champ NumroAuto est un Entier long ).

pour garantir la cohrence entre les enregistrements des tables lies : il sera impossible d'ajouter un enregistrement dans la table du ct plusieurs de la relation si la liaison ne peut s'tablir avec une valeur de la cl de la table ct un de la relation.

Dans tCategories (ct un de la relation) idCategorie Access pourra utiliser idCategorie de tblPlats pour trouver peut prendre les valeurs 1, 2 ou 3. le nom de la catgorie correspondant chaque plat. Consquence de l'intgrit rfrentielle, dans tPlats (ct La colonne idCategorie dans tblPlats est appele une cl plusieurs de la relation), aucun enregistrement ne trangre. Une cl trangre est la cl primaire d'une autre pourra tre ajout avec un idCategorie diffrent de 1, 2 ou table. 3. Voici la suite des oprations pour communiquer cette De mme, dans tCategories on ne pourra supprimer un relation Access : enregistrement tant que des enregistrements existent dans dans la barre des menus, cliquez sur Outils et tPlats avec cette valeur de idCategorie ; ensuite sur Relations : vous cliquez sur le bouton Crer et Access affiche la liaison comme ceci :

une fentre s'ouvre et vous invite slectionner les tables, en l'occurrence tblCategories et Pour exprimenter ce que tblPlats : rfrentielle , essayez ceci :

signifie

Intgrit

ouvrez la table tblCategories ; vous constatez une colonne supplmentaire ; cliquez sur un + , Access vous affiche les enregistrements de tblPlats qui y sont lis :

vous fermez la fentre Ajouter une table ; vous cliquez sur la cl primaire (idCategorie dans tblCategories) et en maintenant la pression, vous faites glisser sur la cl trangre (idCategorie dans tblPlats) : essayez de supprimer l'enregistrement 1, Access refuse :

une nouvelle fentre s'ouvre :

pressez la touche <ESC> pour annuler ; ouvrez tblPlats et dans la colonne idCategorie, essayez d'introduire 4 , Access refuse :

et vous cochez Appliquer l'intgrit rfrentielle . Cela


Numro 42 octobre - novembre 2012 Page 30

Developpez Magazine est une publication de developpez.com

pressez la touche <ESC> pour annuler.

4.2. Une relation plusieurs--plusieurs Considrons maintenant tblPlats et tblIngredients. Dans la plupart des cas, un plat comprendra plusieurs ingrdients et un ingrdient interviendra probablement dans plus d'un plat. Nous sommes plusieurs . devant une relation plusieurs--

Cette fois, il ne suffit pas d'ajouter une cl trangre dans tblPlats pour tablir la liaison avec tblIngredients. Pour avoir plusieurs ingrdients dans un plat, vous devriez avoir plusieurs enregistrements par plat dans la table tblPlats, chacun avec l'idIngredient correspondant.

autre table, c'est le cas dans notre exemple : l'information boudoirs pq est aussi incluse dans tblPlatsIngredients (il en faut pour le tiramis et pour le Malakof). Imaginez qu'au lieu de la valeur 6 , nous ayons choisi la valeur boudoirs pq dans tblPlatsIngredients pour tablir la relation. Cela fonctionnerait. Mais si subitement, vous vouliez changer : au lieu de boudoirs vous vouliez Madeira ou plus gnrique biscuits la cuillre , non seulement il faudrait modifier dans tblIngredients mais aussi dans tblPlatsIngredients. Cela risque de vous demander des acrobaties : neutraliser temporairement l'intgrit rfrentielle, modifier partout sans rien oublier, rtablir l'intgrit Bref, comme cl primaire, il vaut mieux choisir une valeur qui ne risque pas d'voluer dans le temps. Choisir une valeur NumroAuto comme cl primaire est une bonne garantie : Access attribue automatiquement une valeur votre place. Un identificateur de ce type ne contient aucune information factuelle dcrivant la ligne qu'il reprsente et vous ne serez jamais tent de le modifier vous n'y avez pas accs ! C'est une rgle, videmment, il y a des exceptions !

Dans tblPlatsIngredients, si nous considrons l'ensemble Et le mme souci si on aborde par l'autre bout : si nous des valeurs des deux colonnes : IdPlat et IdIngredient, ajoutions la cl trangre idPlat dans tblIngredients, il nous avons une combinaison unique qui ne risque pas de nous faudrait alors rpter les informations de l'ingrdient changer. Nous pouvons donc choisir cette combinaison comme cl primaire de notre table de liaison. pour chaque plat diffrent. 4.3. Une table de jointure pour scinder une relation plusieurs--plusieurs en deux relations un-plusieurs De plus, cela garantira qu'un mme ingrdient n'est renseign qu'une seule fois dans la composition d'une recette.

La solution : crer une table supplmentaire, appele Lorsqu'une cl primaire se compose de plusieurs colonnes, table de jointure , qui va substituer deux relations un- on parle de cl composite. -plusieurs la relation plusieurs--plusieurs. Pour dfinir une cl composite : L'astuce consiste ajouter la cl primaire de chacune des vous affichez la table en mode cration ; deux tables dans la nouvelle table et d'y stocker chaque vous slectionnez les champs concerns et dans la occurrence de relation. barre des menus, vous cliquez sur l'icne .

4.4. Complter le modle Dans la foule, c'est dans cette tblPlatsIngredients que Pour afficher les relations : dans la barre des menus, nous logerons l'information des quantits. cliquez sur Outils/Relations Rflexion sur le choix de la cl primaire La cl primaire doit permettre d'identifier sans ambigut une ligne quelconque de la table. Il faut donc garantir que sa valeur soit diffrente d'une ligne l'autre. Pour la table tblIngredients, nous aurions pu choisir le nom de l'ingrdient en clair comme cl primaire : oignons kg , boudoirs pq tous les ingrdients ont un nom diffrent. Alors, pourquoi avoir choisi un NumroAuto comme cl ? Parce que l'exprience montre que c'est plus pratique ! Cette cl primaire sert souvent de cl trangre dans une Cliquez sur le bouton et ajoutez les tables tblPlatsIngredients et tblIngredients. Faites glisser l'idPlat de tblPlats sur celui de tblPlatsIngrdients et dans la fentre Modification des relations , cochez Appliquer l'intgrit rfrentielle et Effacer en cascade les enregistrements correspondants :

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 31

Cliquez ensuite sur un contrle pour afficher ses proprits. Pour vous documenter sur une proprit de la liste, cliquez-la (elle se met en surbrillance et pressez la touche <F1> : l'aide Access s'ouvre alors la bonne page. 5.1. Vue d'ensemble

Effacer en cascade les enregistrements correspondants , cela signifie que si l'utilisateur supprime un plat dans la table tPlats, tous les enregistrements de tPlatsIngredients qui portent l'idPlat en question seront automatiquement supprims. Logique ! Si nous dcidons d'liminer une recette de notre base de donnes, nous n'avons plus besoin de connatre les ingrdients qui permettent de la raliser. 5.2. Proprits du formulaire fRecettes Si nous avions coch Mettre jour en cascade les champs correspondants , cela aurait voulu dire que si Sa source est la table tPlats. nous modifions une valeur d'idPlat dans tPlats, par exemple en remplaant le idPlat 2 par la valeur 28 , Il affichera les enregistrements de la table en mode alors automatiquement dans tPlatsIngredients tous les simple . idPlat 2 taient modifis en 28 . De plus, nous fixons la proprit Cycle Une telle fonctionnalit n'est pas utile dans notre cas : Enregistrement en cours pour viter le passage idPlat dans tPlats est du type NumroAuto, il ne peut intempestif l'enregistrement suivant lorsqu'on navigue dans les contrles. donc pas tre modifi par l'utilisateur. Procdons de mme avec l'idIngredient de tblIngredients et celui de tblPlatsIngredients, le graphique des relations devient :

5.3. Proprits de cboCategorie 5. Premire bauche du formulaire fRecettes Si vous voulez apprendre de bonnes pratiques pour la construction d'un formulaire, voyez ce tutoriel de JeanPhilippe AMBROSINO (argyronet) : Lien 15. Concentrezvous sur le chapitre 2. Prsentation du formulaire exemple . (Il sera encore temps, lorsque vous aurez acquis davantage d'exprience, de dcouvrir les autres chapitres de son tutoriel.) Prenez ds le dbut de bonnes habitudes de nommage. Si vous aimez la rigueur, voyez les Conventions typographiques du mme auteur : Lien 16. Passons en revue les diffrents contrles de ce formulaire. Cette zone de liste modifiable sera alimente (proprit contenu ) par la table tCategories. Dans Nbre de colonnes , nous exprimons qu'il faut considrer les deux premires colonnes de la table (elle n'en contient d'ailleurs que deux !). Dans Largeurs de colonnes , nous dfinissons l'espace rserv l'affichage des colonnes lors du dploiement de la liste. Dans ce cas particulier : 0 cm pour la 1 re colonne signifie que nous voulons l'occulter.

Quand l'utilisateur aura choisi une ligne de la table, c'est la valeur de la premire colonne largeur non nulle qui sera Pour examiner les proprits, affichez le formulaire en affiche. Dans notre exemple, la deuxime colonne. mode Cration et double-cliquez sur le carr suprieur gauche : Par contre dans Colonne lie , nous exprimons que la

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 32

valeur du contrle sera celle de la 1re colonne.

6. Le formulaire sfPlatIngredients

Pour vous en assurer, faites ce test : 6.1. Vue d'ensemble ouvrez fRecettes en mode formulaire , le contrle affiche Dessert , cliquez sur le champ pour le rendre actif ; ouvrez la fentre d'excution (<Ctrl> + G) et saisissez :
? forms!fRecettes!cboCategorie.value

et <Entre> ; De ce ct de la barrire, Access s'exprime dans la langue de Shakespeare ou plutt de Jean-Claude Van Damme. Traduction en franais : montrer (?) le contenu du contrle cboCategorie actuellement affich dans le formulaire fRecettes parmi la collection des formulaires (forms) actuellement actifs dans la base de donnes. Access vous affiche 3 ; saisissez : 6.2. Proprits du formulaire sfPlatIngredients Sa source est une requte dont on peut voir le graphique en cliquant sur la proprit et sur les qui apparaissent alors au bout de la ligne. La voici :

? forms!fRecettes!cboCategorie.text

Access affiche Dessert .

Remarquez galement la proprit Limiter liste gale Oui : l'utilisateur sera oblig de choisir l'une des trois lignes proposes lorsque la zone de liste modifiable est dplie. Si on veut pouvoir choisir Entremets , il faudra d'abord Nous considrons donc les tables lies tblIngredients et modifier la table tCategories tblPlatsIngredients. 5.4. Proprits de txtNbreConvives Sur la ligne Champ : La proprit Source est NbreConvives. nous prenons dans notre requte toutes les colonnes de tblPlatsIngredients ; La proprit Valeur par dfaut est 1. nous ajoutons les colonnes Ingredient et Prix de tblIngredients ; La proprit Valide si est > 0 donc obligatoirement un nous construisons une colonne Cout en nombre positif. multipliant le champ Quantite par le Prix (remarquez les crochets qui encadrent le nom des 5.5. Proprits de txtPrixRevient colonnes). Nous reviendrons plus tard sur la proprit Source de Sur la ligne Tri : ce contrle. d'abord sur idPlat ; 5.6. Proprits de txtIdPlat ensuite sur Ingredient (en clair). C'est le contrle en rouge. Sa source est idPlat. Nous Vue : reviendrons plus tard sur l'utilit de ce contrle. 5.7. L'aspect de fRecettes ce stade

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 33

6.3. Proprits de txtIngredient Sa source est idIngredient. Pourtant c'est l'ingrdient en clair qui sera affich. Voyez le contenu de la liste, c'est le SQL d'une requte : SELECT [tIngredients] Pour voir cette requte sous sa forme graphique, cliquez l'endroit marqu , il vient :

6.8. L'aspect de sfPlatIngredients ce stade

6.9. Un petit bonus Donc deux colonnes : la 1re, celle qui est lie, contient l'idIngredient qui sera affect la source du contrle ; c'est la 2e qui sera affiche puisque les largeurs sont 0cm;4cm . 6.4. Proprits de txtPrix, txtCout Essayons d'ajouter un ingrdient pour l'idPlat N 6, par exemple 1 kg d'amande pile :

La ligne se complte mais le total reste inchang. C'est Les sources sont respectivement : Prix et Cout. Les autres parce que l'enregistrement dans la table n'est pas encore proprits n'appellent pas de commentaire. ralis. D'ailleurs le en dbut de ligne est l pour vous le signaler. 6.5. Proprits de txtIdPlat C'est le contrle en rouge. Sa source est idPlat. Nous Pour enregistrer vous pouvez soit : reviendrons plus tard sur l'utilit de ce contrle. cliquer sur le slecteur ; passer un autre enregistrement du formulaire ; 6.6. Proprits de txtQuantite cliquer dans le formulaire ailleurs que sur la ligne courante ; La proprit Valide si > 0 pour empcher : passer un autre plat ; l'oubli (la valeur par dfaut est 0, puisque de type dans la barre des menus : numrique) ; Enregistrement > Sauvegarder l'enregistrement ; l'introduction d'une quantit ngative. utiliser le raccourci <Maj + Entre>. 6.7. Proprits de txtTotal La source est =Somme([Cout]) , c'est--dire la somme Si vous le faites, le total passe 35,10 et disparat. de la colonne Cout de la requte. N'oubliez pas de supprimer cet ingrdient de votre recette : N.B. [Cout] rfre une colonne de la source du c'tait juste pour voir comment Access ragit ! formulaire et non au contrle (qui d'ailleurs s'appelle txtCout ). Le bonus que je vous propose, c'est de rendre cette sauvegarde automatique. Nous allons crer une macro qui va muler la pression des touches <Maj + Entre> et dclencher l'excution de cette macro aprs chaque mise jour du contrle cboIngredient ou du contrle txtQuantite . Voici la macro (nous l'avons appele Sauvegarder ) :

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 34

Et pour provoquer son dclenchement aprs chaque mise jour de cboIngredient ou txtQuantit, nous modifions la proprit Aprs MAJ de ces deux contrles :

7. Incorporation de sfPlatIngredients dans fRecettes

Constatez qu'il ne sfPlatIngredients !

s'agit

pas

des

proprits

de

Nous allons intgrer sfPlatIngredients en tant que sous- Soyons prcis : ce que nous avons fait, c'est ajouter notre formulaire un contrle Sous-formulaire/Sous-tat, formulaire de fRecettes. disons une espce de container qui, dans notre exemple, Affichez l'cran la fentre de la base de donnes pointera sur le formulaire sfPlatIngredients. l'onglet Formulaires et fRecettes en mode Cration . Lorsque vous slectionnez ce contrle, il affiche d'abord Dans la fentre de la base de donnes, vous cliquez sur les proprits du container. sfPlatIngredients en maintenant la pression sur le Si ensuite vous cliquez sur l'un des contrles du formulaire bouton de la souris et vous faites glisser-dposer dans inclus, alors Access vous affiche les proprits de ce contrle comme si vous tiez dans le formulaire d'origine. fRecettes : Pour plus de clart, nous allons d'ailleurs modifier le nom qu'Access a attribu par dfaut ce contrle. Nous l'appellerons ctrSfPlatIngredients :

Passons en revue quelques proprits du container ctrSfPlatIngredients . Quand vous relchez la pression, fRecettes devient : Dans Champs fils et Champs pres , on indique le nom des colonnes des tables ou requtes qui servent de source au formulaire pre et au formulaire fils . Cela va servir coordonner l'affichage du pre et du fils : le formulaire fils montrera seulement les enregistrements de sa source qui sont en relation avec l'enregistrement actuellement actif dans le formulaire pre . Remarquez que les champs fils et pres sont les noms des colonnes des tables et non pas le nom des contrles (ils ne sont d'ailleurs pas encadrs de crochets et de plus les contrles s'appellent : txtIdPlat ). Dans notre exemple, ces noms sont identiques : ce n'est pas obligatoire, c'est la consquence des nommages que nous avons choisis lors de la cration des tables. ce stade voici comment se prsente notre formulaire fRecettes :
Numro 42 octobre - novembre 2012 Page 35

Access a intgr un nouveau contrle dans fRecettes. Affichez les proprits de ce contrle :

Developpez Magazine est une publication de developpez.com

5 : et enfin la source du contrle txtPrixRevient. C'est le rsultat de la division : du montant affich dans le contrle txtTotal du sous-formulaire par le montant affich dans le contrle txtNbreConvives du formulaire principal. Voici l'explication de la syntaxe :

Naviguez parmi les enregistrements : la liste des ingrdients est chaque fois limite ceux qui interviennent dans l'IdPlat affich dans le formulaire principal (ici 4). 8. Quelques retouches 9. En guise de conclusion Pour que votre apprentissage soit plus efficace, je vous suggre : de copier les tables dans une base de donnes vierge et de reconstruire le formulaire vous-mme, en suivant le tutoriel pas pas. Autre bon tuyau Pour se documenter sur les proprits d'un formulaire ou d'un tat, ou de leurs contrles : - afficher l'objet en mode construction ; - cliquer sur la proprit : elle se met en surbrillance ; - enfoncer la touche <F1> : l'aide Access s'ouvre la bonne page. On peut aussi : - ouvrir l'aide <F1>, choisir l'onglet Aide intuitive et suivre les instructions ; - ouvrir la fentre d'excution (<Ctrl>+G), saisir un motcl, y placer le curseur de la souris et enfoncer <F1>.

1 : dans les deux formulaires, nous avons un contrle nomm txtIdPlat (ils s'affichent en rouge). Ils n'ont aucun intrt pour l'utilisateur final. Je les avais prvus pour des raisons didactiques : pour montrer que la liste des ingrdients tait limite ceux du plat. Nous supprimons ces contrles.

2 : nous supprimons l'tiquette, cre par dfaut, du contrle ctrSfPlatIngredients. La dmarche propose dans ce tutoriel vaut aussi pour des tats et sous-tats. 3 : nous agrandissons la hauteur du contrle ctrSfPlatIngredients pour donner plus d'espace Pour vous familiariser, voyez aussi Implanter un sous-tat l'affichage du sous-formulaire. dans un tat de Jean BALLAT : Lien 17.

4 : il y a deux barres de boutons de dplacement : Vous pouvez tlcharger ici la base de donnes celle du formulaire principal : elle permet de se Access2000 qui m'a servi construire l'exemple : Lien 18. dplacer parmi les recettes ; celle du sous-formulaire : elle permet de se Retrouvez l'article de Claude Leloup en ligne : Lien 19. dplacer dans la liste des ingrdients. Cette dernire n'est pas trs utile, nous la supprimons.

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 36

C++
Les dernires news Le programme de rentre de la rubrique C++
Le mois de septembre est souvent associ la fin des vacances et des belles journes ensoleilles, pour ceux qui ont eu la chance d'en avoir. Pour faciliter la reprise du travail, la rubrique C++ de Developpez.com vous propose un remde simple : vous plonger dans la srie d'articles passionnants, traduits par l'quipe de rdaction. Les Guru of the Week ne sont plus prsenter (Lien 20). Ces articles de rfrence, couvrant de nombreux points du langage C++, restent incontournables pour les dbutants et les autres. Cette srie d'articles, commence un peu avant l't, va se poursuivre jusqu' ce que tous les articles soient traduits. programmation fonctionnelle en C++ (Lien 22). Ceux qui sont intresss par la comprhension bas niveau du C++ ne seront pas oublis. La srie d'articles de Bruce Dawson aborde la reprsentation des nombres virgule flottante en informatique et les problmatiques lies leurs manipulations (Lien 23). Les articles d'Alex Darby entrent plus en dtail sur le code assembleur gnr et comment viter les piges (Lien 24). Comme d'habitude, chaque nouvelle publication sera annonce sur le forum C++ (Lien 25) et le portail C++ (Lien 26). Bonne rentre tous

Quels sont les articles qui vous intressent le plus dans ce que nous vous proposons ? Pour ceux qui sont intresss par l'expressivit et les Quels autres thmes souhaiteriez-vous que l'on fonctionnalits haut niveau du C++, nous vous proposons aborde ? les traductions des articles d'Eric Niebler sur Boost Proto (Lien 21) et les langages orients domaine enfoui (DSEL Si vous souhaitez participer aux traductions, vous pouvez en anglais, pour domain-specific embedded language). contacter Guillaume Belz par message priv : Lien 27. Nous vous proposerons galement des articles de John Carmack sur l'analyse statique de code et la Commentez la news de Guillaume Belz en ligne : Lien 28.

Les derniers tutoriels et articles


Les nombres flottants et leurs piges La srie d'articles de Bruce Dawson aborde en dtail les problmatiques lies la reprsentation des nombres virgule flottante. Ce premier article pose les bases et explore le monde trange et merveilleux des mathmatiques virgule flottante.
1. Introduction Il y a quelques annes, j'ai crit un article expliquant comment comparer des nombres virgule flottante en utilisant des comparaisons d'entiers. Cet article a t plutt populaire (il est frquemment cit et les exemples de code ont t utiliss par nombre d'entreprises) et a me fait un peu peur, parce que l'article a quelques dfauts. Je ne vais pas donner de lien vers l'article : je veux le remplacer, et donc ne pas envoyer les gens le lire. Aujourd'hui, je vais commencer par poser les bases en expliquant comment et pourquoi cette astuce fonctionne, tout en explorant le monde trange et merveilleux des mathmatiques virgule flottante. Il y a beaucoup de rfrences qui expliquent la disposition binaire et le dcodage des nombres virgule flottante. Dans ce billet, je vais prsenter l'organisation binaire et expliquer comment fonctionne le procd de dcodage par des exprimentations et de la rtroconception. 2. Norme IEE 754-1985 Le standard IEEE 754-1985 (Lien 29) spcifie le format des nombres virgule flottante de 32 bits, type connu sous le nom float dans de nombreux langages. La version 2008 du standard (Lien 30) ajoute de nouveaux formats, mais ne modifie pas les existants, qui sont standardiss depuis plus de 25 ans. Un flottant (Note de traduction : par abus de langage, l'auteur utilise rgulirement le terme flottant la place de nombre virgule flottante ) de 32 bits consiste en un champ d'un bit pour le signe, un champ de 8 bits pour l'exposant et un champ de 23 bits pour la mantisse. L'union ci-dessous montre la disposition des bits d'un tel flottant. Cette union nous sera trs utile pour explorer et travailler sur la reprsentation interne des nombres virgule flottante. Je ne recommanderais pas d'utiliser cette union pour du code de production (elle est en violation des rgles d'aliasing (Note de traduction : on parle d'aliasing quand deux objets de deux types diffrents sont la mme adresse mmoire. Voir Wikipdia - Aliasing (computing) pour plus de dtails : Lien 31) tablies par certains compilateurs et ceux-ci vont donc probablement gnrer du code inefficace), mais elle nous sera utile pour apprendre. Ces articles sur l'aliasing (Lien 32) et l'undefined behavior (comportement indfini) (Lien 33) proposent des dtails supplmentaires. Les nombres flottants et leurs piges

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 37

union Float_t { Float_t(float num = 0.0f)&#160;: f(num) {} // extraction portable des composants bool Negative() const { return (i >> 31)&#160;!= 0; } int32_t RawMantissa() const { return i & ((1 << 23) - 1); } int32_t RawExponent() const { return (i >> 23) & 0xFF; } int32_t i; float f; #ifdef _DEBUG struct { // Champs de bits pour l'exploration. Ne pas utiliser en production. uint32_t mantissa&#160;: 23; uint32_t exponent&#160;: 8; uint32_t sign&#160;: 1; } parts; #endif };

les diffrents composants de num votre fentre de dbogueur et examinez-les, ce qui pourra donner cela par exemple :

Le format des nombres flottants de 32 bits a t attentivement conu pour leur permettre d'tre rinterprt comme un entier et l'aliasing de i et f devrait fonctionner sur la majorit des plates-formes (si, comme gcc et VC++, elles autorisent l'aliasing par les unions), avec le bit de signe de l'entier et du flottant occupant la mme position. La disposition des champs de bits est dpendante du compilateur, donc la structure champs de bits parts, qui est dans l'union, peut ne pas fonctionner sur toutes les plates-formes. Cependant, ceci fonctionne avec Visual C+ + sur x86 et x64, ce qui est suffisant pour ce que je souhaite tester. Sur des systmes big endian (Note de traduction : big endian se traduit par gros-boutiste et dfinit la reprsentation mmoire des nombres. Il dpend du processeur. Voir Wikipdia - Endianness pour plus de dtails : Lien 34) comme SPARC et PPC, l'ordre dans la J'ai plac quelques-uns des rsultats que vous pouvez structure champs de bits est invers. rencontrer pendant ces expriences dans le tableau cidessous : 3. Reprsentation de quelques nombres Afin de vraiment comprendre les flottants, il est important d'explorer et d'exprimenter. Une faon d'explorer est d'crire du code comme ceci, en compilant en mode debug afin que le dbogueur ne le retire pas en l'optimisant :
void TestFunction() { Float_t num(1.0f); num.i -= 1; printf("Valeur flottante, representation, signe, exposant, mantisse\n"); for (;;) { // point d'arrt ici printf("%1.8e, 0x%08X, %d, %d, 0x%06X\n", num.f, num.i, num.parts.sign, num.parts.exponent, num.parts.mantissa); } }

Vous pouvez alors commencer faire des tests interactifs, comme incrmenter la mantisse ou l'exposant, incrmenter num.i, ou inverser le bit de signe. En faisant cela, observez num.f afin de voir de quelle faon il volue. Ou bien, assignez diffrentes valeurs de flottants num.f et regardez comment les autres champs changent. Vous pouvez soit observer les rsultats dans la fentre du dbogueur, soit appuyer sur Run aprs chaque changement, afin que le printf s'excute et affiche des rsultats joliment formats. Allez-y. Placez Float_t et le code d'exemple dans un projet et jouez avec pendant quelques minutes. Dcouvrez les valeurs minimum et maximum des valeurs flottantes. Exprimentez avec les valeurs minimum et maximum de mantisse dans des combinaisons varies. Pensez aux conclusions. Ceci est la meilleure faon d'apprendre. J'attendrai.

Valeur flottant 0.0

du Reprsentatio Signe Exposant Mantisse n entire 000000000 0 0 0 1 124 127 127 127 127 128 150 254 0 1 0 0x4CCCCD 0 0400000 0600000 0x7FFFFF 0 0x7FFFFF 0x7FFFFF

1.40129846 000000001 0 e-45 1.17549435 000800000 0 e-38 0.2 1.0 1.5 1.75 2.0 0x3E4CCCC 0 D 0x3F800000 0 0x3FC00000 0 0x3FE00000 0 040000000 0

1.99999988 0x3FFFFFFF 0 16,777,215 0x4B7FFFFF 0 3.40282347 0x7F7FFFFF 0

Placez un point d'arrt sur la ligne du printf, puis ajoutez

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 38

e+38 Infini positif 0x7f800000 0 255 0

Avec ces informations nous pouvons commencer comprendre le dcodage des flottants. Les flottants utilisent un format en criture scientifique base 2, donc nous pouvons nous attendre ce que le dcodage soit mantisse 2^exposant. Cependant, dans l'encodage de 1.0 et 2.0 la mantisse est nulle, donc comment ceci peut-il fonctionner ? a fonctionne grce une astuce. Les nombres normaliss en notation scientifique base 2 sont toujours de la forme :

000 16,777,2 0x4B7FF 0 15 FFF 3.40282 0x7F7FF 0 347e+38 FFF Infini 0x7f8000 0 positif 00

150 254 255

23 127 Infini!

0x7FFFF F 0x7FFFF F 0

donc stocker le chiffre 1 initial est inutile. En l'omettant, on gagne un bit supplmentaire de prcision le champ de 23 bits d'un flottant gre en fait 24 bits de prcision car il y a un 1 implicite avec une valeur de 0x800000. L'exposant pour 1.0 devrait tre nul mais le champ exposant vaut en fait 127. C'est parce que exposant est stock sous une forme augmente de 127. Pour convertir la valeur dans le champ exposant en la valeur de l'exposant, vous devez simplement soustraire 127. Les deux exceptions cette rgle de calcul de l'exposant sont quand le champ exposant vaut 255 ou 0. 255 est une valeur pour exposant qui indique que le flottant est soit l'infini soit un NaN ( Not-a-Number ), une mantisse contenant zro indiquant l'infini. 0 est une valeur spciale pour exposant, qui indique qu'il n'y a pas de chiffre 1 initial sous-entendu, ce qui signifie que ces nombres ne sont pas normaliss. C'est ncessaire afin de reprsenter exactement la valeur zro. La valeur de l'exposant dans ce cas vaut -126, ce qui est la mme valeur que lorsque le champ exposant vaut 1. Pour clarifier les rgles d'exposant, j'ai ajout une colonne valeur de l'exposant qui montre l'exposant binaire rel correspondant au champ exposant. Reprsen Valeur tation flottante entire 000000 0.0 000 1.40129 000000 846e-45 001 1.17549 000800 435e-38 000 0x3E4CC 0.2 CCD 0x3F800 1.0 000 0x3FC00 1.5 000 0x3FE00 1.75 000 1.99999 0x3FFFF 988 FFF 2.0 040000 Champ Valeur de Mantisse exposant l'exposant 0 0 1 124 127 127 127 127 128 -126 -126 -126 -3 0 0 0 0 1 0 1 0 0x4CCC CD 0 040000 0 060000 0 0x7FFFF F 0

Signe 0 0 0 0 0 0 0 0 0

Bien que ces exemples ne le montrent pas, les nombres ngatifs sont grs en mettant 1 dans le champ de signe, ce qui est appel une forme signe-et-magnitude ( sign-andmagnitude ). Tous les nombres, mme zro et l'infini, ont des versions ngatives. Les nombres dans ce tableau ont t choisis afin de dmontrer diverses choses : 0.0 : il est utile que zro soit reprsent par tous les bits 0. Cependant, il y a aussi un zro ngatif qui a le bit de signe activ. Le zro ngatif est gal au zro positif ; 1.40129846e-45 : ceci est le plus petit flottant positif et sa reprsentation entire est le plus petit entier positif ; 1.17549435e-38 : ceci est le plus petit flottant avec un chiffre 1 initial sous-entendu, le plus petit nombre avec un exposant non-zro, le plus petit flottant normalis. Ce nombre correspond aussi FLT_MIN (Note de traduction : utiliser std::numeric_limitsfloat>::min() est une faon plus C++ de rcuprer la mme valeur que FLT_MIN. De mme pour std::numeric_limitsfloat>::max() et FLT_MAX). Notez que FLT_MIN n'est pas le plus petit flottant. Il y a en fait peu prs 8 millions de flottants positifs plus petits que FLT_MIN ; 0.2 : ceci est un exemple d'un des nombreux nombres dcimaux qui ne peuvent pas tre reprsents prcisment avec un format binaire en virgule flottante. La mantisse devrait rpter C l'infini ; 1.0 : notez l'exposant et la mantisse et mmorisez la reprsentation entire au cas o vous la verriez dans des captures hexadcimales ; 1.5 et 1.75 : juste quelques nombres un peu plus grands pour montrer la mantisse qui change alors que l'exposant reste identique ; 1.99999988 : ceci est le plus grand flottant qui a le mme exposant que 1.0 et le plus grand flottant qui est plus petit que 2.0 ; 2.0 : notez que exposant est incrment de 1 par rapport 1.0 et que la reprsentation entire et l'exposant sont tous deux plus grands que ceux de 1.99999988 ; 16777215 : ceci est le plus grand flottant impair. Le flottant suivant a une valeur d'exposant de 24, ce qui signifie que la mantisse est dplace assez vers la gauche pour que les nombres impairs soient impossibles. Notez que a signifie qu'audessus de 16777215, un flottant a moins de prcision qu'un entier ; 3.40282347e+38 : FLT_MAX. Le plus grand flottant fini, avec l'exposant (non infini ) maximum et la mantisse maximum ; infini positif : le papa ours des flottants.
Numro 42 octobre - novembre 2012 Page 39

Developpez Magazine est une publication de developpez.com

valeur du flottant est : Nous pouvons maintenant dcrire comment dcoder le format des flottants : si le champ exposant vaut 255, alors le nombre est infini (si la mantisse est nulle), ou NaN (si la mantisse n'est pas nulle) ; si le champ exposant vaut entre 1 et 254, alors l'exposant vaut entre -126 et 127, il y a un chiffre 1 initial sous-entendu et la valeur du flottant est :

si le bit de signe est plac alors la valeur du flottant est l'oppos.

Programme d'tude sur le C++ bas niveau

; si le champ exposant est nul, alors l'exposant est -126, il n'y a pas de chiffre 1 initial implicite et la Retrouvez l'article de Bruce Dawson traduit par Lo Gaspard en ligne : Lien 35 Programme d'tude sur le C++ bas niveau

L'exposant sous la forme incrmente de 127 et le chiffre 1 initial omis mnent quelques caractristiques trs utiles des flottants, mais j'ai beaucoup de choses dire dessus, donc souvenez-vous-en pour le prochain billet !

La srie d'articles de Bruce Dawson aborde en dtail les problmatiques lies la reprsentation des nombres virgule flottante. Ce premier article pose les bases et explore le monde trange et merveilleux des mathmatiques virgule flottante.
1. Contexte Dans mon article prcdent Pourquoi je suis devenu formateur (Lien 36), je dplorais le manque d'attention porte la comprhension de la programmation bas niveau qui semble manquer aux rcents diplms en informatique (du moins en Grande-Bretagne) J'ai donc reu un commentaire d'un certain Travis Woodward qui disait : Il y a de nombreux tudiants qui souhaitent se lancer dans du bas niveau, mais il est difficile de savoir par o commencer et quoi apprendre (le bon vieux problme de vous ne savez pas ce que vous ignorez . J'ai recherch un programme pour apprhender le bas niveau, mais n'ai trouv que des listes de sujets qui n'aident pas cause de l'absence de contexte ou de ressources avec lesquelles commencer. La meilleure introduction que j'ai trouve est un cours intitul CS107: Programming Paradigms from Standford sur iTunes U (Lien 37), qui traite en grande partie de comment le C et le C++ sont vus du point de vue du compilateur. Donc si des programmeurs bas niveau souhaitent se regrouper afin de crer un tel cours, incluant des ressources, s'il vous plat faites-le ! Comme il s'agit d'une ide louable, j'ai dcid de m'y mettre 2. Programme d'tude bas niveau ? Avant d'aller plus loin, je souhaiterais mettre au clair ce que j'entends par Programme d'tude bas niveau . Lorsque je travaillais dans l'industrie, j'ai aid au dveloppement de l'architecture et au dploiement multiplateforme d'un moteur Next-Gen (qui est dsormais la gnration actuelle), j'ai crit de nombreux shaders, rsolu un grand nombre de bogues en tudiant le code assembleur et l'tat de la mmoire de la machine, chass les problmes d'interblocage en milieu thread et rgulirement travaill sur des fichiers core dump de jeux de tests de PS3/Xbox 360 afin de rsoudre des bogues impossibles reproduire ; mais a ne fait pas de moi un programmeur bas niveau c'est le genre de choses que j'attends de toute personne ayant mon exprience. Je ne suis jamais rest assis des heures devant des captures GPad ou Pix, je ne me suis jamais vraiment souci de corriger un fragment shader ou des calculs parallles sur SPU ou comment tirer le meilleur de mes AltiVec et je n'ai certainement jamais recod une partie de code en assembleur en tirant parti de techniques de caches ou de mode DMA sournois pour grappiller quelques FPS c'est ce que font les programmeurs bas niveau, du code spcifique plateforme et hardware, optimis afin de tirer les meilleures performances d'une machine. Ce programme d'tude n'a pas pour but de faire de vous un programmeur bas niveau. Ce programme d'tude a pour objectif de vous faire acqurir de solides connaissances sur les fondements d'une implmentation bas niveau en C et C++ (le C sera trait comme un sous-ensemble du C++ dans cette srie d'articles) une comprhension qui selon moi devrait tre la base de tout programmeur voluant dans le jeu vido. Au cours des ventuels nombreux billets de blog, j'aborderais : 1. Les types de donnes ; 2. Les pointeurs, tableaux et rfrences ; 3. Les fonctions et la pile ; 4. Le modle objet C++ ; 5. La mmoire ; 6. La mise en cache, les diffrents caches. En supposant que vous lisiez et compreniez tous les articles de cette srie et que je parvienne communiquer les informations correctement vous devriez atteindre un niveau qui vous permettra de connatre chaque faiblesse du langage, mais aussi et c'est plus important vous comprendrez pourquoi elles existent. Par exemple, vous savez (peut-tre pas) que les fonctions virtuelles ne peuvent pas tre appeles dans un constructeur, mais avant la fin de cette srie d'articles vous
Numro 42 octobre - novembre 2012 Page 40

Developpez Magazine est une publication de developpez.com

comprendrez pourquoi elles ne peuvent l'tre. Juste pour clarifier les choses nouveau, je ne parle pas forcment du niveau de comprhension d'une personne qui crit un compilateur professionnel ; mais d'un niveau qui vous donne une meilleure ide de ce qu'il se passe aprs l'criture du code dans la chane de compilation et par consquent vous permet de comprendre ce que le code que vous avez crit peut impliquer. 3. Il n'y a pas de code source disponible pour l'emplacement en cours

exactement pourquoi mon code plantait en me l'expliquant en termes de comment le C++ se traduit en code machine et m'a indiqu comment le rparer. Ceci m'a ouvert l'esprit sur trois points : 1. Cette personne tait trs dcontracte face la bote de dialogue ; 2. Le code machine n'tait clairement pas la magie noire qu'il semblait tre ; 3. a paraissait si simple que je ne comprenais pas pourquoi a ne nous avait pas t enseign l'universit dans le cursus C++. 4. Dchirer le voile du code machine Je ne ralisais pas l'importance que a avait jusqu' ce que je rencontre un certain Andy Yelland. Si vous connaissez Andy, vous savez exactement de quoi je parle, mais pour ceux qui ne l'ont pas rencontr, je vais expliquer. Andy est une de ces personnes qui change votre point de vue. Il est plus ou moins l'exact oppos du strotype du programmeur de jeu vido : bien habill, professionnel, toujours bien inform, amical, drle et socialement intgr. Cependant, son talent le plus extraordinaire est la vitesse laquelle il peut dissquer un fichier core dump de console. Il s'assoit calmement et tudie calmement sa pile, prenant de temps en temps des notes sur la valeur de certains registres, regardant l'adresse de la fonction dans un fichier de symbole, et au bout d'un certain temps pouvant aller de 5 min quelques heures selon la difficult du problme se retourne et vous explique exactement quel tait le problme. Non seulement il peut raliser cet exploit sur du code qu'il n'a jamais vu auparavant mais mieux encore, il est toujours heureux de s'asseoir et de vous expliquer toutes les actions qu'il a accomplies. Aprs plusieurs dissections d'erreurs avec Andy, j'ai ralis que ce que je prenais pour de la magie noire tait en fait tout l'inverse. Il s'agit d'avoir une connaissance experte du fonctionnement du C++ au niveau assembleur/machine et d'appliquer ces connaissances mthodiquement via l'ingnierie inverse partir de l'tat actuel (i.e. quand l'application a plant) jusqu'au point o les donnes incorrectes ont t introduites. a demande clairement beaucoup de pratique et pour atteindre le niveau d'Andy, il faut des annes (sauf pour Rain Man). Je ne dis pas que tout le monde devrait tre capable de dchiffrer le code machine d'un code crit par quelqu'un d'autre je n'en suis certainement pas capable. Je pense que tout programmeur de jeu vido devrait tre capable de regarder le code machine et tre capable d'au moins comprendre ce qu'il se passe et en s'appuyant sur leur comprhension de comment le C++ est implment bas niveau peut-tre avec des manuels sur le matriel un moment donn devrait alors tre capable de comprendre l'erreur. La premire rgle du cours bas niveau est : tu ne craindras pas le code machine. Supposons que vous soyez d'accord avec moi, par o commencer ? Je pense que le meilleur moyen est de regarder un peu de code machine, alors commenons par a. Faites-vous un projet de test dans votre EDI C++ prfr et crivez ce simple code dans la fonction main.

Noooon ! vite-moi l'hexadcimal ! Je suis sr que la vaste majorit des programmeurs qui utilisent Visual Studio ont paniqu les premires fois qu'ils ont vu cette bote de dialogue. Ce fut mon cas. J'ai appris programmer sur un cran vert (ou orange si les crans verts taient dj pris), sur un environnement Unix mainframe. Vous savez, les mmes qu'ils ont dans les vieux films comme Alien. Les tudiants de seconde et troisime anne avaient priorit pour utiliser les machines XWindows (et le peu de machines Silicon Graphics taient rserves aux projets graphiques des tudiants de troisime anne), donc j'ai appris mon mtier grce ces Unix. Mme les machines XWindows ne possdaient pas d'EDI j'utilisais Emacs et les makefile GNU et le seul dbogueur tait GDB en ligne de commande, qui n'est pas vraiment ce qu'on appellerait user-friendly . J'utilisais finalement std::cout. Quand j'ai t diplm, je suis pass d'un monde aux claviers en baklite, d'images rmanentes et lignes de commandes, au monde de Windows 95 et Visual Studio 4 (juste avant que naissent Direct X et les acclrations graphiques matrielles). Quand j'ai vu cette bote de dialogue pour la premire fois, j'ai paniqu et a n'aurait pas d arriver ! Grce l'enseignement focalis sur les lments haut niveau comme la syntaxe du langage et l'architecture du code, je n'avais aucune ide de ce qui se cachait derrire le compilateur part ce que mes brves incursions avec GDB m'avaient offert. Je venais d'tre diplm d'une universit trs respecte o ils ne m'avaient rien enseign du tout sur l'assembleur dans le cadre du cursus principal et j'avais suppos que c'tait parce qu'ils pensaient que c'tait trop pour mon esprit chtif. Assez parl, j'ai surmont ma peur mais j'ai pris cette bote de dialogue comme un signe d'absence d'informations plus longtemps que je ne voudrais l'admettre. Je n'ai vraiment commenc la surmonter que quelques annes plus tard, alors que je travaillais en collaboration avec quelqu'un qui avait obtenu un emploi dans l'industrie du jeu vido par sa connaissance de l'assembleur. J'ai eu un crash et il a juste cliqu sur le bouton Voir le code machine . Il m'a alors montr, de manire naturelle,

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 41

Pour ma part j'utilise Visual Studio 2010 sur PC Windows.


int x = 1; int y = 2; int z = 0;

vrifi (Note de traduction : a semble galement tre le cas sur Visual Studio 2010 sur Windows 7 64 bits)). 6. Comment a marche ?

Nous savons que le code assembleur gnr par notre code C++ initialisera les trois variables x, y et z ; puis ajoutera x z = x + y; et y et stockera le rsultat dans z. Mettez-vous en configuration Debug et placez un point Regardons chaque ligne assembleur de manire isole (on d'arrt sur la ligne 5 (z = x + y), puis excutez le ignorera l'adresse de la ligne). programme. dword ptr [ebp-8],1 Quand le point d'arrt est rencontr, faites un clic droit mov dans la fentre d'dition du code et choisissez Code Cette instruction initialise x en dplaant la valeur 1 machine . l'adresse mmoire ebp-8. NE PANIQUEZ PAS !
mov dword ptr [ebp-14h],2

Cette instruction initialise y en dplaant la valeur 2 l'adresse mmoire ebp-14h note : le h est ncessaire parce que 14 en dcimal est diffrent de 14 en hexadcimal ce n'tait pas ncessaire pour x car 8 en dcimal est galement 8 en hexadcimal.
mov dword ptr [ebp-20h],0

NOTE : assurez-vous d'avoir les mmes options slectionnes dans le menu contextuel !

Vous devriez avoir un affichage proche de l'image cidessus. Le texte en noir avec le numro de ligne est notre mov eax, dword ptr [ebp-8] code compil, le code en gris sous chaque ligne montre le code assembleur gnr pour chaque ligne. Cette instruction dplace la valeur l'adresse ebp-8 (soit x) dans le registre eax 5. Alors qu'est-ce que tout a signifie ? Le numro en hexadcimal en dbut de chaque ligne d'assembleur (grise) est l'adresse mmoire de la ligne souvenez-vous que le code n'est qu'un flux de donnes qui indique au CPU ce qu'il doit faire, donc logiquement il doit avoir une adresse mmoire. Ne vous inquitez pas trop ce sujet, je voulais juste vous montrer que les instructions sont galement en mmoire. mov et add sont des mnmoniques (mots-cls) assembleur chacun reprsente une instruction, une par ligne avec ses arguments. eax et ebp sont deux registres dans un CPU x86 (32 bits). Les registres sont des zones mmoires pour le CPU : des fragments de mmoire dans le CPU lui-mme et auxquels le CPU peut accder instantanment. Plutt que de parler d'adresse comme pour la mmoire, les registres sont nomms en assembleur parce qu'il en existe gnralement un (relativement) petit nombre. Le registre eax est usage gnral, mais est principalement utilis pour les oprations mathmatiques. Le registre ebp est le pointeur de base . En assembleur x86, les variables locales seront gnralement accdes via un offset partir de ce registre. Nous verrons l'utilisation du registre ebp plus tard. Comme mentionn dans le paragraphe prcdent, ebp-8, ebp-14, et ebp-20 sont les adresses mmoires des variables locales, respectivement x, y et z, auxquelles on accde via offset partir de ebp. dword ptr[...] signifie la valeur code sur 32 bits, stocke l'adresse entre crochets (ceci est vrai pour de l'assembleur Win32, a peut diffrer en Win64 je n'ai pas
add eax, dword ptr [ebp-14h]

Cette instruction initialise la valeur de z. Maintenant nous sommes rendus la partie intressante, l'arithmtique pour assigner le rsultat z.

cette instruction ajoute la valeur l'adresse ebp-14h (soit y) au registre eax


mov dword ptr [ebp-20h],eax

et cette instruction dplace la valeur du registre eax l'adresse ebp-20h (soit z). Donc, comme vous le voyez, alors que le code assembleur a l'air totalement diffrent, il est logiquement isomorphe au code C++ dont il est gnr (i.e. son comportement peut tre un peu diffrent mais il fournira la mme sortie pour une entre donne). 7. Allons, pourquoi a-t-on revu a ? Ceux d'entre vous qui ont le cerveau connect leurs yeux auront remarqu que le code machine que je viens de fournir est un peu ringard . Honntement, c'tait le but en choisissant un tel exemple. Le but tait de montrer comment quelque chose d'aussi simple qu'ajouter deux entiers et de stocker le rsultat dans un troisime en C++ se traduisait en assembleur. Vous pouvez utiliser cette technique pour voir comment la majorit du code C++ est traduit et gnr en code machine, et le but tait de montrer que c'est plutt simple raliser. videmment cet exemple ne montre que deux mnmoniques de l'assembleur x86 et il y en a beaucoup
Numro 42 octobre - novembre 2012 Page 42

Developpez Magazine est une publication de developpez.com

Analyse statique de code

plus. 9. pilogue Si vous rencontrez des mnmoniques que vous ne Il y a d'autres points sur lesquels je voudrais attirer votre connaissez pas, il suffit gnralement de les rechercher sur attention partir de ce simple exemple : Google afin de connatre leur utilit et leur 1. Le principe de variable en C++ (ou de tout autre fonctionnement. C'est ce que j'ai toujours fait et il y a langage qui utilise des variables) n'existe pas au tellement d'informations sur l'assembleur x86 sur le web niveau de la machine. En code machine, les que vous ne devriez avoir aucun souci dchiffrer du valeurs de x, y et z sont stockes des adresses code. mmoires spcifiques, et le CPU y accde via J'ai trouv une page trs utile qui regroupe les registres leur adresse mmoire respective. Une variable est x86 en dtail : Lien 38 un concept haut niveau du langage, qui est plus Voici un lien vers une page pour tlcharger un fichier simple manipuler, mais est dj un concept PDF antische sur l'assembleur x86 : Lien 39 abstrait d'identification d'une variable dans une Bien sr la page Wikipdia : Lien 40 adresse mmoire ; Et un lien tir de la page Wikipdia : Lien 41 2. Notez que pour raliser toute action intressante (comme ajouter une valeur une 8. Rsum autre), le CPU doit avoir au moins une partie de ses donnes dans un registre (je suis sr que Alors que peu de programmeurs auront besoin d'crire de certains CPU doivent tre capables d'oprer l'assembleur, tout programmeur de jeu vido aura tt ou directement sur la mmoire, mais ce n'est tard compris l'avantage de comprendre et dchiffrer certainement pas la faon usuelle de les raliser). celui-ci. C'est incroyable tout ce que vous pouvez comprendre avec une faible connaissance de l'assembleur Finalement, je pense que cet exemple extrmement simple et de sa faon de traduire le code C++. L'exemple que nous avons vu, comme je l'ai dj concd, illustre ce qui est pour ma part un des faits les plus importants en programmation : tait trs simple. Le but de ce premier article n'tait pas de vous donner des Les langages haut niveau existent pour nous faciliter la rponses, mais de vous montrer que le code assembleur vie, ils ne sont pas du tout reprsentatifs de la faon de n'est intimidant que si vous le laissez l'tre ; et vous fonctionner du CPU en fait, mme l'assembleur est une encourager explorer ce que le compilateur fait partir du commodit ct du code binaire que les mnmoniques (mov, add, etc.) reprsentent. code que vous lui fournissez. N'abandonnez pas parce que vous ne comprenez pas ce Je vous conseille de ne pas trop vous inquiter du code que vous voyez ; utiliser Google ou poser des questions binaire, et souciez-vous encore moins des lectrons et de la spcifiques aux bons endroits comme silicone. http://stackoverflow.com (Note de traduction : ou plutt Retrouvez l'article d'Alex Darby traduit par Bousk en http://www.developpez.net/forums/f20/autresligne : Lien 42 langages/assembleur/). Analyse statique de code

L'analyse statique de code permet d'amliorer la qualit d'un code et de minimiser les risques d'apparition d'erreurs. Dans cet article, John Carmack, le clbre dveloppeur de Doom et Quake, compare diffrents outils d'analyse statique de code et plus gnralement ce qui fait la qualit du code.
1. Introduction La chose la plus importante que j'ai faite en tant que programmeur ces dernires annes est de poursuivre nergiquement l'analyse statique de code. Encore plus prcieux que les centaines de bogues srieux qu'elle m'a vits, c'est le changement de mentalit propos de ma faon de voir la fiabilit logicielle et la qualit du code. Il est important de dire d'emble que la qualit n'est pas tout, et reconnatre ce fait n'est pas une sorte de faute morale. La valeur est ce que vous essayez de produire et la qualit n'est qu'un aspect de celle-ci, entreml avec le cot, les fonctionnalits et d'autres facteurs. Il y a eu de nombreux titres trs apprcis et ayant obtenu un immense succs qui taient remplis de bogues et plantaient frquemment ; adopter le mme style de dveloppement pour un logiciel destin une navette spatiale et des jeux vido serait idiot. Pourtant, la qualit reste importante. J'ai toujours pris soin d'crire du bon code, l'une de mes importantes motivations internes est celle de l'artisan et j'ai toujours envie de m'amliorer. J'ai lu des tas de livres aux titres de chapitres austres comme Politiques, normes et plans qualit , et mon travail avec Armadillo Aerospace m'a mis en contact avec le monde trs diffrent du dveloppement de logiciel critique. Il y a dix ans, lors du dveloppement de Quake 3, j'ai achet une licence pour PC-lint et essay de l'utiliser l'ide de pointer automatiquement les erreurs dans mon code avait l'air excellente. Cependant, l'utiliser en ligne de commande et passer au crible les monceaux de commentaires qu'il produit n'a pas russi me convaincre, et je l'ai abandonn assez rapidement. Le nombre de programmeurs et la taille du code ont tous les deux augment d'un ordre de grandeur depuis et le langage d'implmentation est pass du C au C++, ce qui constitue un terreau d'autant plus fertile pour les erreurs logicielles. Il y a quelques annes, aprs avoir lu un certain nombre d'articles de recherche sur l'analyse de code statique moderne, j'ai dcid de voir comment les choses avaient chang dans la dcennie depuis que j'avais essay PC-lint. ce stade, nous compilions au niveau de warning 4 en dsactivant seulement quelques warnings trs spcifiques,

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 43

et le mode warning-as-error forait les programmeurs s'y conformer. Malgr la prsence de quelques tronons de code poussireux ayant accumul des annes de cochonneries, la plupart du code tait assez moderne. Nous pensions avoir une assez bonne base de code. 2. Coverity Au dpart, j'ai pris contact avec Coverity (Lien 43) et sign pour une priode d'essai. C'est un logiciel srieux, avec des cots de licence bass sur le nombre total de lignes de code et nous nous sommes retrouvs avec une estimation cinq chiffres. Quand ils ont prsent leur analyse, ils ont dit que notre base de code tait l'une des plus propres de cette taille qu'ils avaient vu (peut-tre qu'ils disent cela tous les clients pour qu'ils se sentent de bonne humeur), mais ils ont prsent un ensemble d'une centaine de problmes qui avaient t identifis. C'tait trs diffrent de l'ancien PC-lint. Le ratio signal/bruit tait trs lev - la plupart des problmes soulevs taient du code manifestement erron qui pouvait avoir des consquences graves. Cela nous a ouvert les yeux, mais le cot tait assez lev pour qu'il nous donne rflchir. Il nous restait plus qu' esprer que le nombre de nouvelles erreurs que nous allions introduire ne soit pas trop important avant de livrer le jeu. 3. Microsoft /analyze Je me serais probablement convaincu de finalement acheter Coverity, mais alors que j'tais encore en train d'en dbattre, Microsoft prempta le dbat en intgrant leur fonctionnalit /analyze dans le SDK 360. /analyze (Lien 44) tait auparavant disponible pour la version haut de gamme, ridiculement chre de Visual Studio, mais il tait maintenant disponible pour tous les dveloppeurs 360 sans supplment. Mon interprtation est que Microsoft estime que la qualit des jeux sur la 360 a plus d'impact que la qualit des applications Windows. Techniquement, l'outil de Microsoft effectue seulement une analyse locale, il devrait donc tre infrieur l'analyse globale de Coverity, mais il a suffi de l'activer pour qu'il dverse une montagne d'erreurs, beaucoup plus que ce que Coverity avait signal. Certes, il y avait beaucoup de faux positifs, mais il y avait aussi beaucoup de choses vraiment, vraiment effrayantes. J'ai progress lentement dans le code, en corrigeant en premier lieu mon code personnel, puis le reste du code systme, puis le code du jeu. J'y travaillais pendant des bouts de temps libre, de sorte que le processus s'est tendu sur deux ou trois mois. L'un des avantages secondaires de cette longue priode est d'avoir montr de manire concluante qu'il signalait des choses trs importantes durant ce temps il y avait eu une chasse au bogue pique, mobilisant de nombreux programmeurs pendant de nombreux jours et qui a fini par tre attribue quelque chose que /analyze avait signal, mais que je n'avais pas encore corrig. Il y a eu plusieurs autres cas, moins dramatiques, o le dbogage a conduit directement quelque chose dj signal par /analyze. C'tait des problmes rels. Finalement, j'ai eu tout le code utilis pour gnrer l'excutable 360 compilant sans warnings avec /analyze, je l'ai alors tabli comme comportement par dfaut pour les builds 360. Chaque programmeur travaillant sur la 360 a

ensuite vu son code analys chaque fois qu'il lanait un build, de sorte qu'il remarquait par lui-mme les erreurs qu'il venait de commettre, plutt que ce soit moi qui les corrige silencieusement plus tard. Cela ralentissait la compilation quelque peu, mais /analyze est de loin l'outil d'analyse le plus rapide avec lequel j'ai travaill, et il en vaut tellement la peine. Nous avons eu une priode o, sur l'un des projets, l'option d'analyse statique fut accidentellement dsactive pendant quelques mois, et quand je l'ai remarque et ractive, il y avait eu des tas de nouvelles erreurs introduites dans l'intervalle. De mme, les programmeurs travaillant seulement sur PC ou PS3 archivaient du code dfectueux et ils ne le ralisaient pas jusqu' ce qu'ils obtiennent un rapport build 360 chou par mail. C'tait des dmonstrations que le processus normal de dveloppement produit constamment ces classes d'erreurs et /analyze nous avait effectivement protg de nombre d'entre elles. Bruce Dawson a blogu sur le travail avec /analyze un certain nombre de fois : code reliability (Lien 45). 4. PVS-Studio Parce que nous utilisions /analyze uniquement sur le code pour 360, nous avions encore beaucoup de codes non couverts par l'analyse les codes spcifiques pour PC et PS3, ainsi que tous les utilitaires tournant uniquement sur PC. L'outil suivant sur lequel j'ai port mon attention tait PVS-Studio : Lien 46. Il s'intgre bien avec Visual Studio, et possde un mode de dmonstration pratique (essayezle !). Par rapport /analyze, PVS-Studio est douloureusement lent, mais il a dtect un certain nombre d'autres erreurs importantes, mme dans du code qui tait dj compltement propre avec /analyze. En plus de dtecter des erreurs logiques, PVS-Studio dtecte aussi un certain nombre de modles communs d'erreurs de programmation, mme si a reste du code tout fait raisonnable. Cela garantit de produire des faux positifs, mais que je sois damn si nous n'avions pas des instances de ces patterns d'erreurs communs ncessitant des corrections. Il y a un certain nombre de bons articles sur le site de PVS-Studio (Lien 47), la plupart avec des exemples de codes tirs de projets open source montrant exactement le genre de choses que l'on trouve. J'ai envisag d'ajouter des exemples reprsentatifs d'avertissements d'analyse de code dans cet article, mais il y a dj des exemples mieux documents prsents l-bas. Allez les voir, et ne vous moquez pas en pensant : jamais je n'crirais a ! . 5. PC-lint Enfin, je suis retourn PC-lint (Lien 48), coupl avec Visual Lint (Lien 49) pour intgration dans l'IDE. Dans la grande tradition Unix, il peut tre configur pour faire peu prs n'importe quoi, mais ce n'est pas trs amical, et on est en gnral loin du cl en main . J'ai achet un pack de cinq licences, mais cela a t si problmatique qu'il me semble que tous les autres dveloppeurs ayant essay ont abandonn. La flexibilit prsente des avantages j'ai pu le configurer pour analyser l'ensemble de notre code spcifique la plate-forme PS3 , mais ce fut un travail pnible. Une fois de plus, mme dans du code qui avait t nettoy la fois par /analyze et PVS-Studio, de nouvelles erreurs
Numro 42 octobre - novembre 2012 Page 44

Developpez Magazine est une publication de developpez.com

significatives ont t trouves. J'ai fait un rel effort pour nettoyer notre base de code avec Lint, mais je n'ai pas russi. Je l'ai fait pour le code systme, mais me suis essouffl face tous les rapports dans le code du jeu. J'ai tri en m'occupant en priorit des classes de rapports qui m'inquitaient le plus, et en ignorant l'essentiel des rapports qui taient plus d'ordre stylistique ou concernant des soucis potentiels. Essayer de moderniser une base de code importante pour tre propre aux niveaux maximums offerts par PC-lint est probablement futile. J'ai fait un peu de programmation feu vert o j'ai servilement trait un par un chaque commentaire Lint, mais c'est un ajustement que la plupart des programmeurs expriments C/C++ ne vont pas vouloir faire. J'ai encore besoin de passer un peu de temps essayer de dterminer le bon ensemble de warnings activer pour permettre de tirer le meilleur profit de PC-lint. 6. Discussion J'ai appris beaucoup de choses grce ce processus. Je crains que certaines de ces choses ne soient pas facilement transmissibles. Et que sans parcourir personnellement des centaines de rapports, en trs peu de temps et en ressentant encore et encore ce nud dans l'estomac, tout est OK ou ce n'est pas si mal seront les rponses par dfaut. La premire tape est d'admettre sans rserve que le code que vous crivez est truff d'erreurs. C'est une pilule amre avaler pour beaucoup de gens, mais sans elle, la plupart des propositions de changement seront vues avec irritation voire franche hostilit. Vous devez chercher avoir des critiques de votre code. L'automatisation est ncessaire. Il est frquent d'avoir une sorte de satisfaction suffisante en entendant des rcits de faillites retentissantes des systmes automatiques, mais pour chaque chec de l'automatisation, les checs de l'homme sont lgion. Les exhortations crire du meilleur code , les projets de revue de code, de programmation en binme, et ainsi de suite, ne sont tout simplement pas suffisants, en particulier dans un environnement avec des dizaines de programmeurs travaillant sur des dlais trs courts. La valeur qu'il y a capturer mme le plus petit sous-ensemble d'erreurs accessibles l'analyse statique tous les coups est immense. J'ai remarqu qu' chaque fois que PVS-Studio tait mis jour, il trouvait quelque chose dans notre base de code avec les nouvelles rgles. Cela semble vouloir dire que si vous avez une base de code suffisamment grande, toute classe d'erreur qui est syntaxiquement lgale existe probablement l-dedans. Dans un grand projet, la qualit du code est tout aussi statistique que les proprits physiques des matriaux des dfauts existent partout, on ne peut qu'esprer minimiser l'impact qu'ils ont sur les utilisateurs. Les outils d'analyse travaillent avec une main attache dans le dos, en tant obligs de dduire des informations partir de langages qui ne fournissent pas ncessairement ce qu'ils veulent, et en faisant gnralement des hypothses trs conservatrices. Vous devez collaborer autant que possible favorisez l'indexation plutt que l'arithmtique de pointeurs, essayez de garder votre graphe d'appel dans un seul fichier source, utiliser les annotations explicites, etc. Tout ce qui n'est pas clair pour un outil d'analyse statique n'est probablement pas clair non plus pour vos

collgues programmeurs. Le ddain classique du hacker pour la rigueur et les contraintes est une vision court terme les besoins des gros projets ayant une longue dure de vie et de multiples dveloppeurs sont simplement diffrents du travail rapide que vous faites pour vousmme. Les pointeurs NULL sont la plus grande source d'erreur en C/C++, du moins dans notre code. L'utilisation duale d'une valeur unique la fois comme un flag et comme une adresse provoque un nombre incroyable de problmes fatals. En C++ les rfrences doivent tre prfres par rapport aux pointeurs chaque fois que c'est possible. Bien qu'une rfrence ne soit en ralit qu'un pointeur, elle possde le contrat implicite de ne pas tre NULL. Faites le check du NULL au moment de transformer un pointeur en rfrence et vous pourrez par la suite ignorer le problme. Il y a de nombreux patterns profondment enracins dans la programmation de jeu vido qui sont tout simplement dangereux, mais je ne suis pas sr de savoir comment migrer en douceur loin de tous ces check de NULL. Les erreurs de formatage de printf taient la deuxime plus grande source d'erreur dans notre base de code, accentues par le fait que le passage d'une idStr au lieu d'un idStr::c_str() entrane presque toujours un crash, cependant annoter toutes nos fonctions variadiques avec les annotations de /analyze pour que les types soient correctement contrls a tu ce problme pour de bon. Il y avait des dizaines d'erreurs de ce style, caches dans des messages de warnings riches en enseignement qui se transformaient en crash quand certaines conditions inhabituelles activaient le chemin d'excution, ce qui est aussi un commentaire sur la faon dont la couverture du code de nos tests en gnral faisait dfaut. Un grand nombre des erreurs graves rapportes sont dues des modifications dans du code longtemps aprs qu'il a t crit. Un motif d'erreur incroyablement courant est d'avoir un bout de code en parfait tat qui vrifie un pointeur NULL avant de faire une opration, mais une modification du code plus tard change de sorte que le pointeur est utilis nouveau sans vrifier. Examin sparment du contexte, ceci peut tre un argument en faveur de la complexit du code, mais quand vous revenez sur le droulement de ce qui c'est pass, il est clair que cela provient plus d'un manque de communication sur les prconditions d'utilisation avec le dveloppeur qui modifie le code. Par dfinition, vous ne pouvez pas vous concentrer sur tout, donc concentrez-vous sur le code qui va tre livr aux clients, plutt que sur le code qui sera utilis en interne. Migrer de force le code destin tre livr sur des projets de dveloppement isols. Un article rcent a remarqu que toutes les diffrentes mtriques de qualit du code taient corrles au moins aussi fortement avec le taux d'erreurs que la taille du code, ce qui donne la taille du code seule essentiellement la mme capacit de prdiction du taux d'erreur. Rduisez la taille de votre code important. Si vous n'tes pas profondment effrays par tous les problmes additionnels soulevs par la programmation parallle, vous n'avez pas rflchi suffisamment ce sujet. Il est impossible de faire du vrai contrle de test dans le dveloppement logiciel, mais je crois que le succs que nous avons eu avec l'analyse de code a t suffisamment clair pour que je puisse le dire sans dtour : il est irresponsable de ne pas l'utiliser. Il y a des donnes objectives dans les rapports automatiques des crashs de console montrant que Rage, en dpit d'tre la pointe de la
Numro 42 octobre - novembre 2012 Page 45

Developpez Magazine est une publication de developpez.com

technologie bien des gards, est remarquablement plus robuste que la plupart des titres contemporains. Le lancement PC de Rage a malheureusement t tragiquement entach par des problmes de pilote - je parierais qu'AMD n'utilise pas l'analyse statique de code sur leurs pilotes graphiques. Ce qu'il faut retenir : si votre version de Visual Studio possde /analyze, activez-le et essayez-le. Si je devais choisir un seul outil, je choisirais l'option Microsoft. Pour tous ceux qui travaillent avec Visual Studio, essayez au

moins la dmonstration de PVS-Studio. Si vous dveloppez des logiciels commerciaux, l'achat d'outils d'analyse statique est de l'argent bien dpens. Un dernier commentaire venant de Twitter : Dave Revell @dave_revell : Plus je passe du code l'analyse statique, plus je m'merveille que les ordinateurs dmarrent tout court. Retrouvez l'article de John Carmack traduit par Arzar en ligne : Lien 50

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 46

Qt
Les blogs Qt Les modules de Qt 5
support des boutons supplmentaires sur les souris (souris pour joueurs), jusque 27 boutons pour XCB, XLIB ou DirectFB, jusque 16 pour Wayland, Evdev ou OS-X, jusque 8 pour BlackBerry/QNX et 5 sur Windows (limitation due au systme). Lun des principaux changements que lon trouvera dans Qt 5 est la rorganisation des modules. Les modules sont regroups en deux groupes : les Essentials, installs automatiquement, et les Add-ons, installs la demande. Puisque Qt 5 nest pas encore en version finale, les informations donnes dans cet article sont susceptibles Le module Qt Gui dtre modifies. Ce module fournit les fonctionnalits de base pour crer une interface utilisateur. Les anciennes classes QWidget et Les modules Essentials drives sont spares dans un module indpendant. Ce module contient de nouvelles classes comme QWindow, Le module Qt Core QScreen, QSurfaceFormat permettant le support de Ce module fournit les fonctionnalits de base de Qt, fonctionnalits de base et est surtout destin tre utilis except ce qui concerne linterface graphique. Tous les par les autres modules (QWidget, QQuickView, Qt 3D autres modules sont lis ce module. Voici la liste de View, etc.). quelques ajouts dans Qt 5 : En particulier, ce module fournit les classes QOpenGLxxx QStandardPaths : permet de rcuprer les (QOpenGLFramebufferObject, QOpenGLShaderProgram, rpertoires par dfaut en fonction de la QOpenGLFunctions, QOpenGLContext, etc.) permettant plateforme. Cest une volution de de fournir lacclration matrielle pour tous les modules QDesktopServices avec plus de fonctionnalits, graphiques (widgets traditionnels, Qt Quick). La classe sur le modle de KStandardDirs de KDE. Cela QOpenGLContext est plus gnrique que QGLContext et permet par exemple de faire une recherche de est dcouple de QWindow, pour permettre dutiliser un toutes les occurrences dun fichier dans les contexte commun pour plusieurs affichages. diffrents rpertoires ; QOpenGLPaintDevice permet dutiliser directement support de JSON : permet de crer ou de lire un QPainter sur un contexte OpenGL sans devoir driver de fichier JSON partir dune reprsentation binaire QWindow ou QopenGLFramebufferObject. en mmoire ; Voir larticle OpenGL dans Qt 5 pour plus de dtails : extension prise en charge MIME : permet de Lien 52. dterminer le type mime dun fichier ou de donnes en mmoire, en fonction de lextension Le module Qt QML et/ou du contenu. Ce module utilise une base de Ce module permet dutiliser le langage de script dclaratif donnes des types MIME par QMimeDatabase QML grce au QML engine. Il prsente des amliorations fourni par freedesktop.org shared-mime-info des performances et des ajouts de fonctionnalits par project. Cette base de donnes est incluse par rapport celui inclus dans Qt 4. dfaut dans le systme sous Linux et fourni par Le module Qt Js backend (JavaScript) Qt sur Windows et Mac OS X ; vrification des connexions signaux/slots la Ce module fournit un interprteur JavaScript, permettant compilation : vrifie lexistence du signal et du de scripter les applications crites en C++ et en QML. Il receveur et que les arguments sont compatibles. utilise un nouveau moteur JS v8 (Lien 53) plus rapide. Il Cette fonctionnalit utilise les templates et est inclut de nouvelles classes (QJSEngine, QJSValue), le compatible avec C++11. Il est possible de support de nouveaux types (QColor avec les proprits r, connecter un signal des fonctions lambda, des g, b et a, QVector4D constructible avec Qt.vector4d()). Il fonctions membres ou des fonctions statiques, est possible dajouter des fonctionnalits dans un sans avoir besoin de dclarer comme slots. Voir namespace avec la fonction qmlRegisterModuleApi et larticle dtaill sur le sujet : Les signaux et slots dimporter du QML et du JS directement dans un fichier JS. dans Qt 5 (Lien 51); QRegularExpression : nouveau moteur dexpressions rgulires compatible Perl, plus Le module Qt Quick puissante et rapide que QRegExp, avec plus de Ce module permet de crer des interfaces dynamiques fonctionnalits (lazy and possessive quantifiers, riches, en utilisant les modules QML et le JS. Cette lookbehinds, named capturing groups and nouvelle version de Qt Quick correspond au module qtquick2 alors que lancienne version correspond au iteration of matches) ; amlioration des performances, en particulier module qtquick1. Linterface graphique de Qt Quick 2 se base maintenant sur scenegraph et permet lacclration pour les structures de donnes ; amlioration du support C++11 quand cest matrielle en utilisant les classes QOpenGLxxx de Qt Gui. On trouve de nouvelles classes (QQuickView, possible (mais compatibilit avec C++98) ; QQuickCanvas, QQuickItem et QQuickPaintedItem qui
Numro 42 octobre - novembre 2012 Page 47

Developpez Magazine est une publication de developpez.com

remplacent les classes quivalentes de QDeclarative), de nouveaux items (Canvas permet le support de lAPI Context2D de HTML 5, le rendu est ralis dans Canvas.Image et Canvas.FramebufferObject, avec support multithread en arrire-plan). Le moteur de particules 2D Qt Quick.Particles 2.0 et la collection deffets de shaders qui taient avant des projets spars dans Qt Labs sont maintenant inclus dans Qt.

Le module Qt 3D Le module Qt 3D est galement un ancien projet Les autres modules provenant de Qt Labs et est inclus dans Qt 5. Il a permis Qt Multimedia : fournit les fonctionnalits de dans Qt 4 lajout de nombreuses fonctionnalits de calculs base pour lire laudio, la vido, la radio et grer 3D comme les classes QMatrix44, QGLShaderProgram les camras ; et QVector3D. Il utilise en interne le module Qt QML et le Qt SQL : fournit une prise en charge portable des support OpenGL de Qt Gui. Ce module contient deux bases de donnes SQL ; bibliothques : Qt 3D (pour utiliser directement la 3D en Qt Test : fournit les outils ncessaires pour C++) et Qt 3D Quick (pour lutilisation dans Qt Quick). implmenter des tests unitaires ; Plusieurs fonctionnalits sont ajoutes : Qt WebKit : bas sur WebKit 2, mais sans gestion de scnes 3D, avec rendu en OpenGL ; changement de lAPI C++. Ce module continue lecture de fichiers 3D (par exemple .obj et .3ds) ; lamlioration de prise en charge HTML 5 et des gestion des lumires, des meshs, des textures, des performances. matriaux, des animations, des camras, des vues ; Les modules Add-ons ajout de shader directement ou par fichier dans les proprits QML ; Le module Qt Widget Ce module fournit lensemble des classes QWidget et Le module Qt Location drives pour la compatibilit avec Qt 4. Il utilise la Ce module est un ajout dans Qt 5, mais il existait dj nouvelle architecture Qt Platform Abstraction (QPA) : depuis des annes comme sous-ensemble de Qt Mobility. Lien 54. Il fournit les services ncessaires pour la localisation : GPS, cartographie, etc. Le module Qt Quick 1 Il inclut une fonctionnalit permettant dafficher des cartes Ce module permet dutiliser la version de Qt Quick avec MapQuickItem. Laffichage se base sur une approche disponible dans Qt 4, pour compatibilit. Pour utiliser ce modle/vue et bnficie de lacclration OpenGL dans module, il suffit dajouter dans le .pro : scenegraph. Les gestuelles pour les zooms et les panoramas dynamiques, le routage et le gocodage, lajout QT += quick1 de repres sur les cartes sont pris en charge. Et dinclure les fichiers den-ttes : Le module Qt Network Ce module fournit une interface portable pour utiliser les #include QtQuick1/QDeclarativeView rseaux. Parmi les volutions : amlioration du support IPv6 et des rseaux #include QtQuick1/QDeclarativeItem utilisant les types dadresse IP, de manire transparente par dfaut. En rception, QTcpServer Les autres modules Qt Script : permet de rendre les applications et QUdpSocket lancs avec QHostAddress::Any scriptables, compatibilit avec Qt 4. Il utilise les permet de recevoir dans les deux modes ; avec classes QJSxxx du module Qt Js ; QHostAddress::AnyIPv4 et QHostAddress::AnyIPv6 permet de travailler sur Qt Bluetooth : prise en charge du Bluetooth ; un mode uniquement. En mission, Qt D-Bus : interprocessus communication avec QNetworkAccessManager tente dutiliser les D-Bus ; deux modes et garde le premier qui russit ; Qt Graphical Effects : collection deffets QTcpSocket peut maintenant tre attach un graphiques ; socket existant avant de lancer une connexion, Qt Image Formats : prise en charge de formats pour limiter les connexions dans un dimages supplmentaires (TIFF, MNG, TGA, environnement multihte ; WBMP) ; QDnsLookup permet de rechercher des Qt OpenGL : module 3D OpenGL compatible enregistrements DNS. Il ne remplace pas avec Qt 4 ; QHostInfo, qui permet de rsoudre les noms en Qt Print Support : support pour limpression ; adresse IP, mais permet principalement dutiliser Qt Publish and Subscribe ; les autres types denregistrements DNS : SRV, Qt Script Tools : outils supplmentaires pour TXT et MX ; scripter ; les classes QFtp et QHttp ne sont pas conserves Qt Sensor : gestion des capteurs (acclromtre, dans ce module, mais restent disponibles dans un dtecteur de lumire ambiante, compas, etc.) ;
Numro 42 octobre - novembre 2012 Page 48

module indpendant pour la compatibilit. Elles sont remplaces par QnetworkAccessManager ; extensions et vrifications des certificats SSL : prise en charge des extensions des certificats. La vrification des certificats ne se fait plus uniquement lors de la connexion un serveur ; support des cls prives masques : permet de lire une cl prive partir dun priphrique, par exemple un dongle PKCS#11.

Developpez Magazine est une publication de developpez.com

XSLT et XML Schema validation. Qt Service Framework : permet de fournir des services en ligne ; Qt SVG : prise en charge du format dimage SVG Les modules accessoires Le support de ces modules nest pas encore dtermin. (image vectorielle) ; Active Qt : support des ActiveX et Com Qt System Info : informations sur le systme (Windows) ; (profile utilisateur, batterie, stockage, etc.) ; Qt Feedback ; Qt Tools : outils divers (Qt Designer, Qt Help, Qt JSON DB ; etc.) ; Phonon : support du framework phonon pour la Qt Pim : contacts, organiseur, vCard, etc. ; vido et audio ; Qt WebKit Widgets : version de wekbit 1, pour Qt QA : auto test, pour gestion automatique des compatibilit avec Qt 4 ; tests ; Qt XML : fichier XML avec SAX et DOM. Ce Qt QLALR : interprteur LALR. module est dprci, il faut maintenant utiliser QXmlStreamReader/Writer ; Qt XML Patterns : support pour XPath, XQuery, Retrouvez ce billet blog de Guillaume Belz en ligne : Lien 55.

Les dernires news Sortie de Qt 5 alpha


La premire version majeure du Qt Project autonome se concentre sur les performances et les capacits graphiques Le Qt Platform Abstraction Layer (QPA) (Lien 54) Pour amliorer la portabilit de Qt, il a t ncessaire de restructurer l'architecture pour isoler toutes les fonctionnalits de bas niveau qui sont spcifiques une plateforme. Ce travail a permis d'aboutir au QPA, facilitant le portage de Qt sur toutes nouvelles plateformes. Cette abstraction a t introduite dans Qt 4.8 en remplacement de QWS pour les versions embarques de Qt, mais elle est maintenant disponible pour toutes les ditions dans Qt 5. La meilleure preuve de lefficacit de cette abstraction est que plusieurs portages sont en cours de dveloppement : pour QNX, iOS et Android, par exemple.

La version 5 de Qt vient de sortir en version alpha. Cette version est la premire version majeure depuis que Qt est devenu autonome avec la cration du Qt Project. Beaucoup de personnes ont contribu cette nouvelle version, pas uniquement des dveloppeurs de chez Nokia. Les diffrents modules ont t regroups en deux catgories, les essentiels, installs par dfaut, et les addLa rorganisation de la pile graphique ons, installs la demande. L'objectif de cette version Un autre objectif majeur pour Qt 5 est l'amlioration des alpha est de rcuprer les retours des utilisateurs, performances graphiques, en particulier pour les versions principalement sur les modules essentiels. embarques. Pour ce faire, il a fallu rorganiser la pile graphique, pour bnficier au maximum de l'acclration Lars Knoll, le responsable en chef du projet Qt, a publi en matrielle. Pour cela, l'accent a t mis sur l'utilisation mai dernier deux discussions sur les QtLabs pour prsenter d'OpenGL. les approches choisies pour Qt 5 (voir les discussions Par exemple, QtQuick 2 a subi une rorganisation Thoughts about Qt 5 (Lien 56) et Responses to Qt 5 importante se basant sur le graphe de scne et utilisant (Lien 57)). La pense directrice est rsume dans les OpenGL (GL ES 2 minimum) en arrire-plan. QtGui phrases suivantes : contient maintenant des classes QOpenGL la place des classes QGL (maintenues dans le module QtOpenGL pour Qt 5 doit tre le fondement d'une nouvelle faon de la compatibilit). dvelopper des applications. Tout en offrant la puissance On note lapparition de nouvelles classes : de Qt natif en C++, l'accent sera mis sur un modle o le QGuiApplication, plus lgre que QApplication C++ sera principalement utilis pour implmenter des (hrite de QCoreApplication et drive par fonctionnalits modulaires d'arrire-plan pour Qt Quick , QApplication) ; a dclar Lars Knoll. QWindow, pour manipuler les fentres de premier plan. QWidget et drives continuent de Neuf mois de travail, plusieurs centaines d'intervenants et fonctionner, comme dans Qt 4, avec QPainter, plusieurs milliers de modifications du code ont t bien que cet outil soit moins utilis pour les autres ncessaires pour aboutir cette version alpha. Pour cette piles graphiques (il est maintenant limit la premire version majeure, l'accent a t mis sur la partie rastrisation logicielle sur cran, les images et les embarque, proche de la vision que Lars Knoll a dcrite, pixels, avec un backend OpenGL et un autre pour mais il faudra attendre les versions 5.1 ou 5.2 pour que la gnration de PDF et l'impression). cette vision soit entirement applique pour la version desktop. Cette version alpha est l'aboutissement d'un travail important sur quatre points : QPA, la pile graphique, la modularit et le nettoyage de larchitecture en dplaant les QWidgets dans les modules add-ons. L'architecture modulaire Objectif : flexibilit, possibilit de choisir ses modules pour les utilisateurs, meilleure intgration de QtMobility, faciliter les contributions en les incluant comme modules tiers. Il sagit principalement de mnage interne, peu visible par les utilisateurs (toujours en cours).
Numro 42 octobre - novembre 2012 Page 49

Developpez Magazine est une publication de developpez.com

Dplacer QWidget dans un module indpendant Dplacer ces classes dans le module "widgets" permet de garantir la continuit des QWidget et drivs, mais galement l'volution vers d'autres approches (QML et QtQuick). Cela nettoie larchitecture sur le long terme. Installation et compilation Il y a plusieurs moyens d'installer Qt 5. Le plus simple est d'utiliser les binaires non officiels, rgulirement mis jour : partir des dpts ppa (Linux) : Lien 58 ; partir de Git : Building Qt 5 from Git (Lien 59) ; partir des sources Qt 5.0 Alpha release en diffrents format (7z, tar.bz2, tar.gz, tar.xz, zip) : Lien 60 ; pour compiler : Qt 5 Alpha building instructions (Lien 61).

maintenir activement les deux , d avoir une communaut Qt forte et unie , sachant que faire avancer la technologie est extrmement important . La transaction comprenait galement le financement et la gestion de linfrastructure du Qt Project ; ce transfert est actuellement presque achev, ne restent que quelques items (comme le systme dintgration continue). Transfert du copyright

En pratique, quest-ce que cela change que la technologie, le copyright et les marques Qt soient transfrs Digia ? Il faut adapter tous les en-ttes des fichiers sources ; aussi, Digia devient le seul interlocuteur, quelle que soit la licence choisie (commerciale ou open source). ce sujet, Qt reste disponible tant sous la GPL que sous la LGPL, en ce qui concerne lopen source. galement, un processus de dfinition dun programme de partenaires et dautres est en cours dlaboration pour rguler lutilisation des logos Passer de Qt 4 Qt 5 Les changements importants pour conserver la Qt et des autres marques dposes. compatibilit du code crit pour Qt 4 avec Qt 5 sont dintgrer le module widgets si on utilise des QWidget ou Cela implique notamment le changement du drapeau drivs et de renommer le module QtQuick en quick1. proximit des bureaux : Voici un exemple de code dans le fichier .pro pour garantir la compatibilit :
greaterThan(QT_MAJOR_VERSION, 4) { QT += widgets QT += quick1 } else { QT += declarative }

Le script Perl qtbase/bin/fixqt4headers.pl met jour les inclusions des fichiers d'en-tte. Pour la cration de plugins, les macros Q_EXPORT_PLUGIN et Q_EXPORT_PLUGIN2 sont dprcies et doivent tre remplaces par la macro Q_PLUGIN_METADATA, qui permet de lire les informations sans devoir charger le plugin avec la fonction dlopen(). Commentez la news de Guillaume Belz en ligne : Lien 62

Rpercussions sur le Qt Project Selon le principe de gouvernance ouverte (ou de dmocratie, dautres chelles), le Qt Project est hberg par une fondation but non lucratif : Digia fournit les moyens financiers ncessaires pour son bon fonctionnement. Le fonctionnement des services nen sera pas chang, une exception prs. Le systme dintgration continue est toujours hberg chez Nokia (il sagit dun garde-fou pour la qualit de Qt : une combinaison doutils de grande capacit de compilation et de procdures pour sassurer que toute modification sur Qt fonctionne correctement) ; en mme temps que le transfert chez Digia, un changement du logiciel utilis est prvu : Jenkins sera utilis, pour faciliter lajout de nouvelles plateformes de validation par des agents extrieurs. Le changement devrait tre achev dans le mois ; pendant ce temps, le systme actuel continuera de fonctionner.

Premier jour de Qt chez Digia, aprs son rachat de Nokia : le framework restera disponible sous GPL et LGPL

Ce 18 septembre 2012 tait le premier jour avec Digia propritaire de Qt. Avec une quipe renforce (notamment par Lars Knoll), Digia annonce que le vrai potentiel de Qt sera libr, ainsi que son cosystme . Ds lannonce du rachat en aot dernier, une srie de questions se posaient sur lavenir de lcosystme libre : Qt sera-t-il toujours disponible sous la LGPL ? Quid de Necessitas, pour le support dAndroid, puisquun objectif tait le Plateformes mobiles support tant diOS et dAndroid ? Un des objectifs clairement annoncs depuis le rachat pour Lobjectif de Digia est toujours de garder Qt disponible Qt 5 est le support de plus de plateformes mobiles tant en commercial quen open source, tout en continuant notamment, iOS et Android , de telle sorte que tous aient
Developpez Magazine est une publication de developpez.com
Numro 42 octobre - novembre 2012 Page 50

accs ce support (tant en commercial quen open source). Ce support a dj t initi par la communaut, par le projet Necessitas (KDE) pour Android par exemple. Ds aujourdhui, cette solution peut tre utilise par tous ; cependant, des discussions ont eu lieu entre les dveloppeurs de Necessitas et Digia, les deux parties saccordant sur le fait quil ne pourrait tre quune bonne chose de continuer le dveloppement de Necessitas sous lombrelle du Qt Project, pour suivre la tendance de KDE envers Qt. En ce qui concerne iOS, les Qt Labs prsentaient une preuve que le support est possible (Lien 63) ; il existe galement une solution (entirement commerciale) de Mediator Software, bien que pas aussi complte que pour Android. Des discussions sont en cours pour voir s'il est possible dutiliser cette solution pour le Qt Project. De mme, il faudra tudier les restrictions imposes par iOS qui retardent le support de Qt Quick. Le support dans le Qt Project pour ces plateformes est prvu pour Qt 5.1 (deuxime trimestre de 2013), bien quil soit dj possible de dvelopper des applications pour ces plateformes avec Qt 4.8 et 5.0. Plateformes pas seulement mobiles

La Qt Developer Conference europenne se droulera du 12 au 14 novembre, le planning des formations est disponible
L'dition europenne de la Qt Developer Conference est maintenant sur les rails. Elle se droulera du 12 au 14 novembre, Berlin. On y retrouvera une srie de keynotes, de formations, de confrences et bien d'autres.

La date limite pour se prsenter comme confrencier tant hier, on devrait avoir sous peu le dtail de ce qu'on pourra y dcouvrir. On sait d'ores et dj qu'on pourra voir des reprsentants talentueux de l'cosystme Qt pendant ces deux jours. Comme pour les DevDays, des formations seront possibles le premier jour, mlangeant des prsentations ex cathedra et des sances pratiques (il est d'ailleurs recommand de prendre son portable). Les possibilits sont : Introduction to Qt for the desktop Introduction to Qt Quick Introduction to Qt for embedded Linux Introduction to Testing Qt application with Squish Model/View programming using Qt Multithreading with Qt Modern OpenGL with Qt5 Whats new in C++11 (with a Qt5 focus) Getting up to speed with git

Un des objectifs de Qt est de supporter une plthore de plateformes, cependant avec un code utilisateur commun, tant pour les plateformes mobiles que desktop. Ct Qt Quick, on peut atteindre cet objectif par les Qt Quick Components (aux exceptions des spcificits de chaque plateforme), aussi disponibles en dition Desktop. Tout ne sera pas orient vers les plateformes mobiles, le desktop sera toujours support ; de mme, les widgets resteront Il n'y aura pas de foire d'emploi cause de problmes de une option viable . vie prive relevs par bon nombre de potentiels participants, elle sera remplace par des opportunits de Qt 5.0 rseautage social. Il sagit du projet de recherche et dveloppement le plus grand men par Digia pour le moment ; jusqu prsent, une alpha et la premire bta sont disponibles pour recueillir lavis des utilisateurs : grce eux, cette version majeure est en cours de finalisation pour une sortie prvue au dernier trimestre de 2012. Commentez la news de Thibaut Cuvelier en ligne : Lien 64 Un salon d'exposition sera galement ouvert pour les trois jours. Le site de la confrence : Lien 65 Commentez la news de Thibaut Cuvelier en ligne : Lien 66

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 51

2D/3D/Jeux
Les blogs 2D/3D/Jeux Dboguer avec OpenGL 4
Lorsque lon dbute lapprentissage dOpenGL et des shaders (et mme ensuite), on est vite confront au problme du dbogage, soit parce que le programme sarrte brusquement, soit parce que le rsultat obtenu ne correspond pas ce que lon attend. Traditionnellement, on utilise la fonction glGetError, mais elle est encore trop souvent oublie par les dveloppeurs et elle donne finalement assez peu dinformations. Heureusement, cette problmatique a t prise en compte dans les dernires spcifications dOpenGL avec lajout de nouvelles extensions pour le dbogage. Ce billet de blog aborde les fonctionnalits de dbogage introduites dans OpenGL 4.1 avec lextension ARB_debug_output et compltes dans OpenGL 4.3 avec lextension KHR_debug. Les outils externes de dbogage ne sont pas abords. Les nouvelles extensions Lextension ARB_debug_output (GL 4.1) Dans la version OpenGL 4.1, a t ajoute lextension ARB_debug_output, qui est une promotion de lextension GL_AMD_debug_output propose par AMD. Cette extension ajoute la possibilit de crer des contextes avec un mode de dbogage. En lactivant, un systme dvnements est activ et permet dobtenir des informations varies, par exemple sur les problmes rencontrs lors de la compilation des shaders GLSL, des appels de fonction non valides ou des problmes potentiels de performance. Les messages gnrs par ce systme peuvent tre stocks dans une pile ( message log ) ou tre rcuprs par une fonction callback dfinie par lutilisateur. Lextension KHR_debug (GL 4.3) Dans le but duniformiser les diffrentes versions dOpenGL (en particulier avec OpenGL ES), lvolution dOpenGL tend reprendre des fonctions provenant dOpenGL ES. Cest le cas de lextension KHR_debug dans OpenGL 4.3 qui est une promotion de lextension ARB_debug_output dOpenGL 4.1 et des extensions EXT_debug_marker et EXT_debug_label dOpenGL ES. Cette extension ajoute ainsi des fonctions pour annoter les vnements ou des groupes de commandes OpenGL.
int attribs[] = { #ifdefWIN32 WGL_CONTEXT_MAJOR_VERSION_ARB, WGL_CONTEXT_MINOR_VERSION_ARB, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, WGL_CONTEXT_PROFILE_MASK, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, #endif #ifdef__linux__ GLX_CONTEXT_MAJOR_VERSION_ARB, GLX_CONTEXT_MINOR_VERSION_ARB, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, GLX_CONTEXT_PROFILE_MASK, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, #endif 0 }; 4, 1,

4, 1,

// intialisation HDC hdc; // Handle to a device context HGLRC hglrc; // Handle to an OpenGL rendering context hglrc = wglCreateContext (hdc); wglMakeCurrent (hdc, hglrc); // contexte attribs int pixelFormat, numFormats; glChoosePixelFormatARB(hdc, attribList, NULL, 1, &pixelFormat, &numFormats); HGLRC wglCreateContextAttribsARB(HDC hDC, HGLRC hshareContext, const int *attribList); // aprs utilisation wglMakeCurrent (NULL, NULL) ; wglDeleteContext (hglrc);

Les fonctionnalits de dbogage sont actives en utilisant la constante GL_DEBUG_OUTPUT. Celle-ci peut tre active ou dsactive avec glEnable et glDisable. Par dfaut, cette constante est active dans un contexte de dbogage et dsactive dans le cas contraire.
// active les messages de dbogage glEnable(GL_DEBUG_OUTPUT); // dsactive les messages de dbogage

glDisable(GL_DEBUG_OUTPUT); Cration dun contexte de dbogage (GL 4.1) La premire chose faire pour utiliser un contexte de dbogage est de vrifier que lextension Plusieurs niveaux de dbogage sont possibles en fonction ARB_debug_output est bien prise en charge. Un exemple de la cration ou non dun contexte de dbogage et de si de code pour vrifier une extension est donn dans le lon active GL_DEBUG_OUTPUT : tutoriel Les extensions OpenGL : Lien 67. si on ne cre pas un contexte de dbogage et que Pour crer un contexte de dbogage, il faut simplement lon active GL_DEBUG_OUTPUT, les messages crer un contexte en appelant la fonction envoys et le contenu sont laisss lapprciation CreateContextAttribs avec le paramtre des implmentations dOpenGL, mais lappel des CONTEXT_DEBUG_BIT. En fonction du systme fonctions de dbogage ne produit pas derreur ; dexploitation, on aura donc un code quivalent celui-ci : si on cre un contexte de dbogage et que lon Numro 42 octobre - novembre 2012 Page 52

Developpez Magazine est une publication de developpez.com

nactive pas GL_DEBUG_OUTPUT, aucun message de dbogage nest lanc ; si on cre un contexte de dbogage et que lon active GL_DEBUG_OUTPUT, toutes les fonctionnalits de dbogage sont actives.

Crer des contextes de dbogage partir dune bibliothque (GL 4.1) Il existe plusieurs bibliothques graphiques qui permettent de travailler sur des contextes OpenGL (SFML, SDL, Qt, etc.). Voyons comment crer un contexte de dbogage dans ces cas dutilisation. Avec FreeGlut (Lien 68) FreeGlut fournit directement une constante pour crer un contexte en mode dbogage : GLUT_DEBUG.
// FreeGlut glutInitContextFlags(GLUT_DEBUG);

settings.stencilBits << std::endl; std::cout << "antialiasing level:" << settings.antialiasingLevel << std::endl; std::cout << "version:" << settings.majorVersion << "." << settings.minorVersion << std::endl;

Pour plus de dtails, voir larticle Using OpenGL in a SFML window (Lien 76) sur le site de SFML. Avec SDL 1.3 (Lien 77) La bibliothque SDL fournit les constantes SDL_GL_CONTEXT_MAJOR_VERSION pour dfinir la version du contexte que lon souhaite utiliser.
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); mainwindow = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); maincontext = SDL_GL_CreateContext(mainwindow);

Avec Qt (Lien 69) La bibliothque Qt fournit des outils pour crer et manipuler directement des fentres contenant un contexte OpenGL avec le module QtOpenGL (Lien 70). Pour crer un contexte spcifique dune version OpenGL, il suffit Pour plus de dtails, voir larticle Creating a Cross dutiliser la fonction setVersion (Lien 71) de la classe Platform OpenGL 3.2 Context in SDL sur le site de QGLFormat (Lien 72) : SFML : Lien 78.
#include QtOpenGL ... QGLFormat format; format.setVersion(4, 3); format.setProfile( QGLFormat::CoreProfile ); // ncessite Qt >= 4.8 format.setSampleBuffers( true ); GLWidget* w = new QGLWidget(format);

Les modes de synchronisation (GL 4.1) Par dfaut, les appels de fonction OpenGL sont asynchrones, ce qui veut dire que les fonctions peuvent simplement envoyer les commandes aux contextes OpenGL puis passent linstruction suivante dans le code. Par exemple, le code suivant peut poser des problmes puisque rien ne garantit que lon mesure rellement le temps dexcution de la commande :
boost::timer t; glDrawElement(...); double elapsed_time = t.elapsed();

Pour plus de dtails, voir larticle How to use OpenGL Core Profile with Qt (Lien 73) sur le wiki de Qt. Avec SFML 2.0 (Lien 74) La bibliothque SFML permet de demander lors de la cration dune fentre la version du contexte OpenGL utiliser avec la classe sf::ContextSettings (Lien 75). Sil nest pas possible de crer un contexte avec les paramtres demands, SFML va crer un contexte le plus proche possible. Il est donc important de vrifier la version de contexte rellement cre.
#include SFML/OpenGL.hpp ... sf::ContextSettings settings; settings.depthBits = 24; settings.stencilBits = 8; settings.antialiasingLevel = 4; settings.majorVersion = 4; settings.minorVersion = 3; sf::Window window(sf::VideoMode(800, 600), "OpenGL", sf::Style::Default, settings); sf::ContextSettings settings = window.getSettings(); std::cout << "depth bits:" << settings.depthBits << std::endl; std::cout << "stencil bits:" <<

Lorsque lon dbogue une application utilisant OpenGL, il peut alors y avoir un dcalage entre lappel dune fonction et une erreur gnre. Pour faciliter le dbogage, il est possible de changer le mode de synchronisation pour forcer OpenGL attendre la fin de la commande avant de passer linstruction suivante dans le code. Cette fonctionnalit garantit la synchronisation dans un contexte, mais pas la synchronisation entre plusieurs contextes, qui reste sous la responsabilit de lapplication.
// active le mode synchrone glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);

Il est possible de tester le mode avec glIsEnabled (Lien 79) et de le dsactiver avec glDisable (Lien 80). Activer cette fonctionnalit peut tre trs coteux en termes de performance et doit tre utilise uniquement pour le dbogage. La pile des vnements (GL 4.1) La pile des vnements, appele message log contient les messages lancs dans un contexte de dbogage. Cette pile est de taille limite, ce qui signifie que si elle est pleine, les vnements les plus anciens seront perdus. Il
Numro 42 octobre - novembre 2012 Page 53

Developpez Magazine est une publication de developpez.com

faut donc la vider rgulirement en lisant les messages. Lorsque lon utilise plusieurs contextes, chaque contexte possde sa propre pile des vnements. La fonction glGetIntegerv (Lien 81) permet dobtenir des informations sur les capacits et le contenu de la pile.
GLint maxMessages, totalMessages, len, maxLen, lens[10]; GLenum source, type, id, severity, severities[10]; glGetIntegerv(GL_MAX_DEBUG_LOGGED_MESSAGES_ARB, &maxMessages); printf("Nombre de messages maximum que peut contenir la pile : %d\n", maxMessages);

glGetIntegerv(GL_DEBUG_LOGGED_MESSAGES_ARB, &totalMessages); printf("Nombre de messages contenus actuellement dans la pile : %d\n", totalMessages); glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH_ARB, &maxLen); printf("Taille maximale de message : %d\n", maxLen); glGetIntegerv(GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH _ARB, &len); printf("Taille du prochain message : %d\n", len);

Retrouvez la suite du billet blog de Guillaume Belz en ligne : Lien 82

Les dernires news Sortie des spcifications d'OpenGL 4.3 et OpenGL ES 3.0
Lors de la confrence SIGGRAPH 2012, le groupe Khronos a annonc la sortie des spcifications d'OpenGL 4.3 et d'OpenGL ES 3.0. Cette nouvelle version apporte 27 nouvelles extensions, dont les suivantes : ajout d'une nouvelle extension nomme GL_ARB_compute_shader, permet d'utiliser un nouveau type de shader : les Compute Shaders. Ceux-ci permettent de raliser des calculs complexes sur les images ou les volumes en bnficiant de la puissance du paralllisme des cartes graphiques. Ils ont donc la mme utilisation que ce que fournit OpenCL. La diffrence vient du fait que les Compute Shaders sont destins aux calculs s'intgrant dans le pipeline graphique, alors qu'OpenCL est destin aux calculs ne ncessitant pas le pipeline graphique ; ajout d'un nouveau type de Buffer Object : les shader storage buffer objects (extension GL_ARB_shader_storage_buffer_object). Ce sont des espaces mmoire accessibles en criture et en lecture par tous les types de shaders. Ils facilitent donc la transmission de gros volumes d'informations entre les shaders ; les texture parameter queries permettent d'obtenir des informations sur le support des textures sur la plateforme d'excution ; les compressions de texture haute qualit ETC2 / EAC (extension GL_ARB_ES3_compatibility) ; l'extension GL_ARB_arrays_of_arrays ajoute les tableaux multidimensionnels dans le GLSL (pour pouvoir crire par exemple float f[4] [3];) ; fonctionnalits de dbogage pendant l'excution ; texture views pour travailler sur les textures selon diffrentes manires, sans devoir les dupliquer ; les indirect multi-draws permettent de raliser des instanciations multiples en deux temps, le premier temps permettant de faire des calculs et de stocker les paramtres dans un Buffer Object, puis de les rutiliser dans une seconde tape de rendu ; amlioration de l'utilisation d'OpenGL par plusieurs applications : scurisation des espaces mmoire pour viter qu'une application crive dans l'espace mmoire d'une autre application (extension GL_ARB_robust_buffer_access_behavior) et viter que le reset de la carte graphique dclench par une application perturbe les autres applications.

NVIDIA a sorti les drivers 305.53 pour Windows et 304.15.00.02 pour Linux supportant OpenGL 4.3. Tlcharger ici : Lien 83. Quelles sont les nouvelles fonctionnalits qui vous intressent le plus ? Que pensez-vous de l'ajout des Compute Shaders, en particulier font-ils double-emploi avec OpenCL ? Spcifications : - 3D : OpenGL Core profile 4.3 (06/08/2011) : Lien 84, Compatibility profile 4.3 (06/08/2011) : Lien 85 et OpenGL Shading Language 4.30.6 (06/08/2012) : Lien 86 - 3D embarqu : OpenGL ES 3.0.0 (06/08/2012) : Lien 87 et OpenGL ES Shading Language 3.00.3 (06/08/2012) : Lien 88 Commentez la news de Guillaume Belz en ligne : Lien 89

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 54

Java
Les derniers tutoriels et articles
Binding XML - Java travers un exemple concret, cet article prsente l'API JAXB qui nous permet de transformer un fichier XML en objets Java, et vice versa.
1. Objectif Il sera d'obtenir une requte SQL partir de son nom et du groupe auquel elle appartient. Voyons pour commencer quoi pourrait ressembler l'interface de notre QueryLoader : interface IQueryLoader
public interface IQueryLoader { Map<String, String> getQueries(String queriesName); String getQuery(String groupName, String queryName); } } public final String getQuery() { return query; } public final void setQuery(String query) { this.query = query; }

Binding XML - Java

Puis notre groupe de requtes : class QueryGroup


public class QueryGroup { private String name; private List<Query> queries = new LinkedList<Query>(); public String getName() { return name; } public final void setName(String name) { this.name = name; } public final List<Query> getQueries() { return queries; } public final void setQueries(List<Query> queries) { this.queries = queries; } }

Crons ensuite notre fichier XML qui nous servira d'exemple : Fichier exemple
<?xml version="1.0" encoding="UTF-8"?> <queries> <group name="group1"> <query name="query1"> SELECT field1 FROM table1 </query> <query name="query2"> SELECT field2 FROM table2 </query> </group> <group name="group2"> <query name="query3"> SELECT field3 FROM table3 </query> <query name="query4"> SELECT field4 FROM table4 </query> </group> </queries>

partir de ce fichier, nous pouvons crire assez facilement nos classes Java correspondantes. Tout d'abord Il nous faut aussi une classe pour contenir la liste des notre requte : groupes de requtes : class Query
public class Query { private String name; private String query; public final String getName() { return name; } public void setName(String name) { this.name = name; }

class Queries
public class Queries { private List<QueryGroup> queryGroups = new LinkedList<QueryGroup>(); public final void setQueryGroups(List<QueryGroup> queryGroups) { this.queryGroups = queryGroups; } public final List<QueryGroup> getQueryGroups() { return queryGroups; Numro 42 octobre - novembre 2012 Page 55

Developpez Magazine est une publication de developpez.com

} }

</dependency>

Sinon, on peut le tlcharger ici par exemple : Lien 98. Il nous reste voir l'implmentation de notre interface IQueryLoader, nous le ferons trs bientt. Occupons-nous 3.1. Annotations de nos classes maintenant de JAXB. Nous avons dit que tout se faisait par annotations. Nous allons commencer par la classe correspondant la racine 2. Prsentation de JAXB de notre arborescence XML. Il s'agit ici de Queries, qui JAXB est l'acronyme de Java Architecture for XML sera annote avec Binding (Lien 90). JAXB est donc capable de srialiser javax.xml.bind.annotation.XmlRootElement : des objets Java en un fichier XML, et de les dsrialiser. Il existe galement d'autres API pour manipuler le XML en @XmlRootElement Java, comme SAX (Simple API for XML : Lien 91) ou public class Queries { ? JAXP (Java API for XML Processing : Lien 92). SAX fait } d'ailleurs partie de JAXP. Mais ces API n'ont pas la mme finalit que JAXB, elles servent davantage manipuler et parcourir l'arborescence XML qu' raliser la srialisation Cet lment correspond la balise racine <queries/>, qui d'objets en XML. est unique par dfinition. C'est toujours la premire balise rencontre, il est inutile d'indiquer son nom. Il n'en va pas Si on prend l'exemple de SAX, on va parcourir de mme de la balise suivante, <group/>, dont nous l'arborescence XML avec un parser, instanci depuis une devons indiquer le nom. L'annotation est factory. Ce parser lit ses donnes partir d'un InputStream, javax.xml.bind.annotation.XmlElement, et se place sur le et appelle diverses mthodes d'un handler, que nous crons getter : en hritant d'un DefaultHandler (Lien 93). Le dbut de l'analyse du document se fait ainsi par l'appel de la @XmlElement(name = "group") mthode startDocument(), l'arrive sur une balise avec la public final List<QueryGroup> getQueryGroups() { return queryGroups; mthode startElement(), et ainsi de suite pour chaque lment trouv. Nous devons donc dfinir le } comportement attendu en fonction des cas : est-ce une balise, est-ce celle attendue, ses attributs sont-ils corrects, Passons maintenant au contenu de cette balise <queries/>, etc. Tout ceci est plutt lourd mettre en place, d'autant reprsent par la classe QueryGroup. Cette balise contient attribut, son nom. L'annotation est plus que notre handler ne conserve aucune donne en un mmoire quand il parcourt le flux XML. C'est notre javax.xml.bind.annotation.XmlAttribute : implmentation de tout enregistrer.
@XmlAttribute

Si on connait exactement le format des donnes attendues, public String getName() { return name; ou mieux, si on dispose du schma, JAXB est beaucoup plus simple utiliser, puisque quelques classes Java } annotes lui suffisent pour analyser le flux XML. Une API qui se rapprocherait de JAXB est Castor (Lien 94), qui fait On retrouve l'annotation @XmlElement pour la balise la mme chose : transformer un flux XML en POJO, et <Query/> : rciproquement. Mais plus ancienne, elle passe par l'analyse d'un fichier XML de mapping, parfois complexe @XmlElement(name = "query") public final List<Query> getQueries() { crire.
return queries;

Il existe d'autres solutions permettant la srialisation, par } exemple les classes XMLEncoder (Lien 95) et XMLDecoder (Lien 96), Jakarta Commons Digester Finissons par la classe Query. Elle possde un attribut (Lien 97) de la fondation Apache, ou encore l'API XML, son nom : XStream. Ne connaissant pas ces solutions, je n'en parlerai pas, et vous laisse les dcouvrir travers les tutoriels sur @XmlAttribute(name = "name") Developpez.com, dont vous trouverez les liens en fin public final String getName() { return name; d'article.
}

3. Utilisation de JAXB

Et aussi une valeur, la requte SQL, annote avec Pour disposer de JAXB dans notre classpath, avec Maven javax.xml.bind.annotation.XmlValue : il suffit d'ajouter les dpendances suivantes dans notre pom : @XmlValue Dependency maven pour JAXB
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.2.4</version> public final String getQuery() { return query; }

Voil pour ce qui est des annotations. Il n'y a rien de plus

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 56

faire, JAXB est maintenant capable trs simplement de faire le lien entre nos POJO et notre fichier XML. La transformation d'objets Java en flux XML se nomme le marshalling, l'unmarshalling tant la transformation de XML en POJO. Et ceci se fait simplement avec une seule ligne de code :
Queries queries = JAXB.unmarshal(xmlInputStream, Queries.class);

group = queryGroups.get(1); assertThat(group.getName(), is("group2")); assertThat(group.getQueries().size(), is(2)); queryList = group.getQueries(); query = queryList.get(0); assertThat(query.getName(), is("query3")); assertThat(query.getQuery().trim(), is("SELECT field3 FROM table3")); query = queryList.get(1); assertThat(query.getName(), is("query4")); assertThat(query.getQuery().trim(), is("SELECT field4 FROM table4")); } @Test public void marshallingTest() throws Exception { StringWriter writer = new StringWriter(); JAXB.marshal(queries, writer); String xmlString = writer.toString(); System.out.println(xmlString); Queries queries2 = JAXB.unmarshal(new StringReader(xmlString), Queries.class); checkQueries(queries2, queries); } private void checkQueries(Queries queries, Queries expected) { List<QueryGroup> groups = queries.getQueryGroups(); List<QueryGroup> expectedGroups = expected.getQueryGroups(); checkGroups(groups, expectedGroups); } private void checkGroups(List<QueryGroup> groups, List<QueryGroup> expectedGroups) { assertThat(groups.size(), is(expectedGroups.size())); Iterator<QueryGroup> iterator1 = groups.iterator(); Iterator<QueryGroup> iterator2 = expectedGroups.iterator(); while (iterator1.hasNext()) { checkGroup(iterator1.next(), iterator2.next()); } } private void checkGroup(QueryGroup group, QueryGroup expectedGroup) { assertThat(group.getName(), is(expectedGroup.getName())); List<Query> queriesList = group.getQueries(); List<Query> expectedQueriesList = expectedGroup.getQueries(); checkQueriesList(queriesList, expectedQueriesList); } private void checkQueriesList(List<Query> queriesList, List<Query> expectedQueriesList) {

Et c'est tout. Il ne nous reste plus qu' tester que tout fonctionne. 3.2. Tests On crit une petite classe de test unitaire pour JUnit. Pour tester l'unmarshalling, on part du fichier, et on vrifie que toutes les requtes sont bien prsentes. Pour le test du marshalling, on commence par notre objet unmarshall , et qu'on marshallera dans une String. Et on unmarshalle nouveau cette String dans un objet Queries, qu'il nous reste comparer au premier. Voici le code du test : Classe de test
import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; // Autres import public class QueriesTest { private Queries queries; @Before public void before() { InputStream xmlStream = Queries.class.getResourceAsStream("queriesTest.xm l"); queries = JAXB.unmarshal(xmlStream, Queries.class); } @Test public void unmarshallingTest() throws Exception { List<QueryGroup> queryGroups = queries.getQueryGroups(); assertThat(queries.getQueryGroups().size(), is(2)); QueryGroup group = queryGroups.get(0); assertThat(group.getName(), is("group1")); assertThat(group.getQueries().size(), is(2)); List<Query> queryList = group.getQueries(); Query query = queryList.get(0); assertThat(query.getName(), is("query1")); assertThat(query.getQuery().trim(), is("SELECT field1 FROM table1")); query = queryList.get(1); assertThat(query.getName(), is("query2")); assertThat(query.getQuery().trim(), is("SELECT field2 FROM table2"));

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 57

assertThat(queriesList.size(), is(expectedQueriesList.size())); Iterator<Query> iterator1 = queriesList.iterator(); Iterator<Query> iterator2 = expectedQueriesList.iterator(); while (iterator1.hasNext()) { checkQuery(iterator1.next(), iterator2.next()); } } private void checkQuery(Query query, Query expectedQuery) { assertThat(query.getName(), is(expectedQuery.getName())); assertThat(query.getQuery().trim(), is(expectedQuery.getQuery().trim())); } }

class XmlQueryLoader
public class XmlQueryLoader implements IQueryLoader { private final Map<String, Map<String, String>> queriesGroup = new LinkedHashMap<String, Map<String, String>>(); public XmlQueryLoader(InputStream xmlStream)

Nous avons imprim notre String XML, ce qui nous permet de vrifier visuellement quoi elle ressemble. Et maintenant que tout est correct, il nous reste implmenter notre QueryLoader. 3.3. Implmentation du QueryLoader Prenons de bonnes habitudes, et commenons par notre classe de test : class XmlQueryLoaderTest
import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; // Autres imports public class XmlQueryLoaderTest { private XmlQueryLoader queryLoader; @Before public void before() { InputStream xmlStream = XmlQueryLoader.class.getResourceAsStream("queries Test.xml"); queryLoader = new XmlQueryLoader(xmlStream); } @Test public void getQueryTest() throws Exception { assertThat(queryLoader.getQuery("group1", "query1"), is("SELECT field1 FROM table1")); } @Test public void getQueriesTest() throws Exception { Map<String, String> queries = queryLoader.getQueries("group2"); assertThat(queries.size(), is(2)); assertThat(queries.get("query3"), is("SELECT field3 FROM table3")); assertThat(queries.get("query4"), is("SELECT field4 FROM table4")); } }

Queries queries = JAXB.unmarshal(xmlStream, Queries.class); for (QueryGroup group : queries.getQueryGroups()) { String groupName = group.getName(); Map<String, String> queryGroup = new LinkedHashMap<String, String>(); queriesGroup.put(groupName, queryGroup); for (Query query : group.getQueries()) { String queryName = query.getName(); String sqlQuery = query.getQuery(); queryGroup.put(queryName, sqlQuery.trim()); } } } @Override public Map<String, String> getQueries(String groupName) { return queriesGroup.get(groupName); } @Override public String getQuery(String groupName, String queryName) { return queriesGroup.get(groupName).get(queryName); } }

Nous avons utilis une LinkedHashMap (Lien 99), car elle nous permet de parcourir les requtes SQL dans leur ordre de dclaration si on veut les excuter les unes la suite des autres, par exemple pour enchainer la cration de tables. 4. Schma XML 4.1. Gnration du schma JAXB offre la fonctionnalit de gnrer un schma XML, ce qui nous permettra de valider le flux XML reu. Pour ceci, les quelques lignes de code suivantes suffisent : Gnration du schma
final File baseDir = new File("."); class MySchemaOutputResolver extends SchemaOutputResolver { @Override public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException { return new StreamResult(new File(baseDir,

Et enfin, l'implmentation tester :

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 58

suggestedFileName)); } } JAXBContext context = JAXBContext.newInstance(Queries.class); context.generateSchema(new MySchemaOutputResolver());

context.createUnmarshaller(); unmarshaller.setSchema(schema); Queries unmarshall = (Queries) unmarshaller.unmarshal(xmlStream);

En cas de non-conformit du flux XML par rapport au schma, la mthode unmarshall() lve une javax.xml.bind.UnmarshalException. De la mme manire que nous avons obtenu notre Unmarshaller, on obtient un Marshaller, auquel on peut prciser le schma, et qui transformera nos objets en flux XML. Nemek me fait remarquer que la srialisation (le marshalling) ne produit pas ncessairement un XML valide vis--vis du XSD, et qu'il est donc conseill de prciser le schma. 4.3. Gnration des classes

Nous obtenons un fichier schema1.xsd : Schma


<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="queries" type="queries"/> <xs:complexType name="queries"> <xs:sequence> <xs:element name="group" type="queryGroup" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="queryGroup"> <xs:sequence> <xs:element name="query" type="query" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="name" type="xs:string"/> </xs:complexType> <xs:complexType name="query"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="name" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:schema>

Le schma ne sert pas qu' la validation du flux XML. Nous pouvons aussi l'employer pour gnrer nos classes, l'aide de l'utilitaire xjc du JDK :
xjc schema.xsd

Les classes gnres sont par dfaut dans le package generated. On retrouve bien nos trois classes Queries, QueryGroup et Query, ainsi qu'une classe ObjectFactory. Je vous laisse dcouvrir quoi ressemblent ces classes, elles sont trs proches des ntres, avec essentiellement quelques commentaires Javadoc en plus. Les deux options les plus utiles de xjc sont : -help : affiche l'aide et les diffrentes options disponibles ; -p : permet de prciser le package. Par exemple avec -p fr.atatorus.gen, les classes seront dans fr/atatorus/gen et non plus dans generated ; -d : prcise le rpertoire o seront les classes gnres. 5. Conclusion

Voil, j'espre que ce petit tutoriel vous a permis de dcouvrir JAXB, et d'apprcier sa facilit d'utilisation. Nous pouvons utiliser le schma pour valider le flux Pour ma part, j'ai vraiment aim sa simplicit. Ma premire exprience avec le binding Java XML a XML : commenc avec JAXP, o on devait tout faire soi-mme. La dcouverte de Castor a t un soulagement, mme si Gnration avec validation SchemaFactory schemaFactory = j'ai d me dbattre avec les fichiers de mapping. ct, SchemaFactory.newInstance("http://www.w3.org/2001 JAXB est un vrai bonheur ! 4.2. Validation du flux
/XMLSchema"); Schema schema = schemaFactory.newSchema(new File(baseDir, "schema1.xsd")); Unmarshaller unmarshaller =

Si vous voulez dcouvrir toutes les possibilits de JAXB, je vous renvoie sa documentation : Lien 100. Retrouvez l'article de Denis Thomas en ligne : Lien 101

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 59

Les dernires news JavaOne 2012 dmarre en force : innovation, Cloud, GPU, mobile, rsum de la 1re journe de la plus grande confrence autour de Java
IBM Keynote

Les prsentations dIBM, lunique Diamond Sponsor de lvnement, ont directement suivi la Strategy Keynote dOracle. Les confrenciers de la socit ont essentiellement voqu le support du Cloud au sein du JavaOne 2012, la grand-messe annuelle des dveloppeurs langage. et experts de lindustrie autour de lcosystme Java a IBM sest galement pench sur le partage des ressources ouvert ses portes hier. (Sharing), avec notamment le Cache pour partager les Pendant cinq jours, le Masonic Auditorium de San classes compiles par le JIT, le Multi-tenancy pour Francisco sera le thtre de plus 500 sessions prsentes ladaptation dynamique de plusieurs instances dexcution par prs de 540 confrenciers, autour du thme central du JVM aux changements suivant la disponibilit des ressources ainsi que lisolement dans une seule JVM. prparer Java du futur . Enfin, IBM a prsent son hardware System Z, spcialement optimis pour lexcution de Java ainsi que La confrence sest ouverte avec une session sur la limpact important du hardware sur les performances. stratgie dOracle pour Java. Le tableau de bord de lditeur pour lanne 2012 est ax principalement autour Application mobile Scala1 de trois domaines : linnovation technique, la participation Typesafe, la socit fonde par le crateur du langage de communautaire et le leadership dOracle. programmation moderne Scala a dvoil lapplication Au cours de cette session, lditeur a fait un rsum des mobile Scala1. Scala1 permet aux dveloppeurs de trouver volutions en 2012 dans Java 7, JavaFx, JEE 8, JDK 8 et facilement de nouvelles discussions sur Scala, de 9, etc. Les points voqus ont t les sorties rapides des collaborer avec les autres dveloppeurs, de sinformer sur mises jour pour Java 7 ainsi que la forte migration vers les volutions du langage, de trouver rapidement des experts Scala, etc. cette version. Strategy Keynote Des dtails ont t dvoils sur la feuille de route de Java, JDK 8 et 9. La caractristique de JDK 8 mise en avant est le projet Nashorn, un moteur dexcution JavaScript entirement dvelopp en Java par Oracle. Il est bas sur la machine virtuelle Da Vinci et profite dinvokedynamic pour fournir des performances leves. Le projet Nashorn bnficie dj du soutien dIBM, RedHat et Twitter. JDK 8 sera disponible dans NetBeans 7.3. En ce qui concerne JavaFX, Oracle a annonc que sa plateforme de cration d'applications internet riches (RIA) tait dsormais disponible pour toutes les plateformes majeures, y compris Linux ARM. Lditeur a rappel que loutil tait livr avec la version actuelle de Java et que NetBeans 7.2 intgrait SceneBuilder, un outil pour la cration dinterfaces graphiques avec JavaFX. Lapplication open source Scala1 est disponible sur Android et iOS et son code source est publi sur GitHub. Acclration GPU pour les applications Java JavaOne a t loccasion pour AMD de prsenter le projet Sumatra, une modification de la JVM pour utiliser le GPU de manire transparente pour le programmeur. Le projet Sumatra vise mettre fin lutilisation des bibliothques externes pour lacclration GPU des applications Java ainsi quau processus de conversion entre Java et OpenCL (librairie multiplateforme qui permet d'utiliser les processeurs graphiques pour raliser des calculs lourds).

Lide autour du projet est de profiter des structures de Sortie de Java Embedded Suite 7.0 et Oracle Java ME donnes dans la mise en uvre des outils OpenJDK et de laisser la machine virtuelle Java gnrer et compiler le Embedded 3.2. code OpenCL en fonction des indices dans le code. Le Nandini Ramani, vice-prsidente de la division projet Sumatra pourrait sortir au mme moment que dveloppeur chez Oracle a annonc la sortie dOracle Java Java 9. Embedded Suite 7.0 et Oracle Java ME Embedded 3.2 (Lien 102). Oracle Java Embedded Suite est une JavaOne 2012 sachvera le 4 octobre et dici l, Oracle va plateforme de dveloppement qui facilite la cration des encore dvoiler plusieurs nouveauts autour de la applications pouvant sexcuter travers une large gamme plateforme Java. de systmes embarqus, tandis que Java ME Embedded 3.2 est un environnement complet dexcution Java Commentez la news d'Hinault Romaric en ligne : Lien 103 optimis pour les microcontrleurs et autres dispositifs limits en ressources.

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 60

JavaOne 2012 : Oracle dvoile ses plans pour Java, les prversions du JDK 8 et JavaFX Scene Builder 1.1 disponibles

nouvelle API sera propose pour la cration dinterfaces utilisateur avec un meilleur support des balises HTML5, WebView et JavaFX Scene Builder 2.0.

JavaFX Scene Builder, loutil de mise en page visuelle pour la plateforme JavaFX, qui permet aux utilisateurs de JavaOne 2012, la plus grande confrence annuelle autour crer des interfaces utilisateur en glissant et en de la plateforme Java se droule actuellement San positionnant les composants partir d'une palette dans une scne est actuellement disponible en version 1.1 Francisco. dveloppeur avec un support pour Linux 32 et 64 bits. Oracle a profit de loccasion pour dvoiler sa feuille de route pour Java et renouveler son engagement faire Toutes ces annonces montrent lengagement dOracle voluer le langage afin de rassurer les utilisateurs vouloir faire voluer lcosystme Java. sceptiques face aux rcentes dcouvertes de failles dans la Commentez la news d'Hinault Romaric en ligne : Lien 105 plateforme. Pendant ces prochains mois, Oracle travaillera essentiellement sur Java SE 8. Au menu : lditeur prvoit lintgration des expressions lambda, du moteur JavaScript Nashorn (dj disponible dans la prversion de NetBeans 7.3 : Lien 104), les annotations, la nouvelle API date and time et bien plus. Oracle a galement officialis le projet Sumatra, qui vise mettre fin lutilisation des bibliothques externes pour lacclration GPU des applications Java ainsi quau processus de conversion entre Java et OpenCL (librairie multiplateforme qui permet d'utiliser les processeurs graphiques pour raliser des calculs lourds). Le projet Sumatra sera disponible avec Java SE 8.

JavaOne 2012 : Oracle prsente la spcification JSR 353, l'API Java pour la manipulation avec souplesse du format JSON
JavaOne 2012 sest achev hier. Lvnement Java le plus important de lanne a lev le voile sur un nombre impressionnant de nouveauts, innovations et ambitions pour lcosystme Java. Oracle pendant ses sessions a prsent sa feuille de route (Lien 106) pour le langage et les points sur lesquels lentreprise travaille actuellement pour la prochaine version de Java, dont lintgration des expressions lambda, du moteur JavaScript Nashorn, des annotations, de la nouvelle API date and time et bien plus. Une session a t entirement rserve au support du format JSON dans les futures versions du langage. Pour rappel, JSON (JavaScript Object Notation) est un format de donnes textuel, gnrique, driv de la notation des objets du langage ECMAScript. Il permet de reprsenter de faon structure des informations.

Lavantage de ce format de donnes est quil est lger, flexible et facilement interprtable pour les machines. JSON a t adopt comme format dchange par plusieurs La prversion du JDK 8 peut dj tre teste sur le site sites Web populaires qui offrent des services Web java.net. La sortie de la version finale est prvue pour RESTfull reposant sur le format, notamment Twitter et septembre 2013. On va regretter cependant le report Java Amazon. 9 du projet Jigsaw, qui devait ajouter au langage un Actuellement, les dveloppeurs Java utilisent diffrentes systme de module. bibliothques tierces pour produire et consommer des Java EE 7 (ldition pour entreprise) est annonc pour donnes JSON. Il devient donc ncessaire de normaliser avril 2013 et apportera comme nouveauts : une API une API JSON afin que les applications qui utilisent le WebSocket, lAPI JCACHE pour une mise en cache format naient plus besoin de regrouper des bibliothques temporaire des objets Java, un modle de programmation externes. Cest le but de la spcification JSR 353 qui a t pour applications Batch et une API pour la manipulation prsente par Oracle JavaOne 2012. des donnes au format JSON. Avec cette version de Java EE, Oracle proposera Glassfish 4.0 comme plateforme de La spcification JSR 353 : API Java pour le traitement de JSON, vise rendre lutilisation de JSON avec le langage rfrence. plus lgre, plus propre et plus cohrente. La spcification En ce qui concerne sa plateforme de dveloppement JSR 353 dcrit actuellement une API (Streaming API) pour dApplications Internet Riches JavaFX, Oracle envisage produire et consommer en continu des donnes JSON et de passer de JavaFX 2.0 (la version actuelle) JavaFX 8 une API (Object Model API) du modle objet pour lorsque sortira le JDK 8. Cette version de JavaFX reprsenter JSON. disposera par dfaut au niveau de linterface utilisateur dune boite outils pour Java SE 8 Embedded. Une LAPI Streaming implmentera les mthodes JsonParser
Numro 42 octobre - novembre 2012 Page 61

Developpez Magazine est une publication de developpez.com

pour la conversion et JsonGenerator pour la gnration. LAPI Object Model quant elle, implmentera les Le groupe dexperts travaillant sur cette spcification mthodes JsonObject et JsonArray, ainsi que JsonBuilder, inclut les employs dOracle, RedHat, Twitter ainsi que JsonReader et JsonWriter. des membres autonomes. La spcification est actuellement au stade dexamen Les dtails sur la spcification JSR 353 : Lien 107 prcoce et est mise en uvre en tant que projet open source sur java.net. La fin de la phase dexamen prcoce Commentez la news d'Hinault Romaric en ligne : Lien 108 est prvue pour le 7 octobre prochain.

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 62

NetBeans
Les dernires news JavaOne 2012 : Oracle sort la Preview de NetBeans 7.3 et dvoile le projet Easel une extension pour la cration des clients RESTful base de JavaScript
Pour rappel, le projet Nashorn est un moteur dexcution JavaScript entirement dvelopp en Java par Oracle. Il est bas sur la machine virtuelle Da Vinci et profite dinvokedynamic pour offrir des performances leves. En fournissant un environnement unique o les dveloppeurs peuvent crer des services Java et des clients bass sur HTML5, la prversion de NetBeans 7.3 offre JavaOne 2012 bat son plein. Le Masonic Auditorium de ceux-ci des outils pour crer et dboguer des applications San Francisco vibre aux couleurs de lcosystme Java qui Web et mobiles qui consomment les services Java en est en train dtre dissqu par les experts de lindustrie. utilisant les derniers standards du Web. Lors de la session consacre NetBeans, lenvironnement La prversion de NetBeans 7.3 est disponible pour de dveloppement intgr open source pour Java, PHP, C Windows, Mac OS X, Solaris et Oracle Linux. et C++, Oracle a annonc la sortie de la preview de NetBeans 7.3, la prochaine mise jour majeure de lEDI. Toujours concernant NetBeans et HTML5, Oracle a dvoil le projet Easel, une plateforme qui permet le dveloppement HTML5 et JavaScript dans un environnement Java. Le projet Easel dispose dune interface ddition pour HTML5, JavaScript et jQuery avec support de Le futur standard du Web HTML5 a vol la vedette Java lautocompltion. Il intgre un nouveau dbogueur durant cette session. La nouveaut phare de NetBeans 7.3 JavaScript bas sur des API de dbogage distance de est une meilleure prise en charge du HTML5, CSS3 et WebKit. JavaScript, permettant de dvelopper plus rapidement des applications Web riches et mobiles. Le but du projet Easel est de permettre aux dveloppeurs de crer rapidement des clients JavaScript (en utilisant Les dveloppeurs dapplications Web et mobiles pourront MVC) pour consommer ou tester des services RESTful. trouver comme nouvelles fonctionnalits dans cette version : un nouvel diteur de code HTML5 avec la La premire version dEasel pourrait sortir la semaine compltion de code pour les lments HTML5 ; un nouvel prochaine comme une extension pour NetBeans. Le diteur et dbogueur JavaScript bas sur le projet Nashorn, support de JDeveloper est prvu pour la version suivante. la compltion de code pour jQuery, une meilleure prise en charge du CSS3, la gnration du code client JavaScript Tlcharger la prversion NetBeans 7.3 : Lien 109 pour les services REST Java existants. Commentez la news d'Hinault Romaric en ligne : Lien 110

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 63

Eclipse
Les derniers tutoriels et articles
JFace Databinding avec des composants JFace Ce tutoriel se propose de dtailler l'utilisation du framework JFace Databinding sous Eclipse afin de permettre la liaison entre un modle de donnes et des composants de visualisation JFace. Cet article se situe donc dans la droite ligne de l'article JFace Databinding avec SWT (Lien 111).
1. Introduction L'API JFace Databinding d'Eclipse permet de lier facilement les donnes du modle objet aux informations affiches par l'interface graphique. Il est en effet intressant que les donnes entres par l'utilisateur soient rpercutes directement dans le modle, et vice versa. Dans le prcdent article, nous avons tudi les diffrents mcanismes de l'API au travers d'un exemple simple qui utilisait uniquement des composants graphiques SWT. On se propose ici de mettre en uvre ce framework sur des composants graphiques JFace. Pour cet article, il est ncessaire d'avoir des connaissances de base dans les domaines suivants : dveloppement de plugins avec Eclipse (Lien 112) : cration de vues, gestion des dpendances ; utilisation de SWT (Lien 113), notamment sur les diffrents composants et leurs proprits. 2. Un premier exemple
} return result; }

JFace Databinding avec des composants JFace

Nous allons maintenant afficher notre liste de personnes dans un viewer JFace de type tableau. Crons la vue FirstView au sein de notre application de la manire suivante : FirstView.java
Voir le code en ligne : Lien 114

Si l'on observe ce code, on s'aperoit que le viewer ne possde ni ContentProvider, ni LabelProvider. Il n'y a pas non plus d'appel effectu la mthode setInput. Au lieu de cela, on utilise un objet de type WritableList que l'on initialise grce la ligne :
input = new WritableList(PersonList.getPersonList(), PersonBean.class);

Dans ce premier exemple, nous allons lier de manire la plus simple possible une liste d'lments de notre modle D'autre part, on lie le contenu du viewer directement un viewer JFace. Commenons par modifier notre modle cette liste grce l'instruction : de manire travailler sur une liste d'objets. Pour cela, nous nous basons sur la classe PersonBean.java que nous ViewerSupport.bind(viewer, input, avons cre dans le premier article. Nous crons ensuite la BeanProperties.values(new String[] {"firstname", classe PersonList qui peut nous retourner une liste d'objets "name", "male", "age"})) PersonBean grce une mthode statique : On indique qu'on lie les valeurs firstname , name , PersonBean.java male et age aux diffrentes colonnes du tableau. La Voir le code en ligne : Lien 114 classe ViewerSupport permet de simplifier la mise en place du databinding pour les viewers JFace. Il permet PersonList.java d'enregistrer les changements effectus au sein du modle /** dans sa globalit, mais aussi ceux effectus sur les * Cette classe comprend une unique methode lments individuels. C'est cette classe qui se charge de statique qui permet de creer une crer automatiquement le ContentProvider et le * liste d'objets PersonBean. LabelProvider. Lanons l'exemple pour constater le * @author A. Bernard fonctionnement du mcanisme : */
public class PersonList { public static List<PersonBean> getPersonList() { List<PersonBean> result = new ArrayList<PersonBean>(); result.add(new PersonBean("Bernard", "Alain", 24, true)); result.add(new PersonBean("Dupont", "Michel", 49, true)); result.add(new PersonBean("Jacques", "Jocelyne", 51, false)); result.add(new PersonBean("Martin", "Francois", 31, true)); Numro 42 octobre - novembre 2012 Page 64

Developpez Magazine est une publication de developpez.com

partir du ContentProvider grce l'instruction :


IObservableSet knownElements = contentProvider.getKnownElements();

On peut ensuite crer un objet IObservableMap pour chaque attribut du modle pour lequel on souhaite observer les changements. Enfin, on peut crer un LabelProvider pour notre viewer, en passant en paramtre un tableau d'IObservableMap :
// Creation du LabelProvider pour le tableau ILabelProvider labelProvider = new ObservableMapLabelProvider(labelMaps) { @Override public String getColumnText(Object element, int columnIndex) { if (columnIndex == 0) { return names.get(element) + " (" + firstNames.get(element) + ")"; } else { return genders.get(element) + " (" + ages.get(element) + ")"; } } };

Application et modle aprs rinitialisation et suppression d'un lment 3. Observer les changements plus prcisment La premire vue que nous avons cre affiche tous les lments, mais nous laisse peu de latitude quant la personnalisation de l'affichage en lui-mme : le LabelProvider est gnrique et on ne peut pas le modifier. Grce aux lments que nous allons mettre en uvre, nous allons pouvoir remdier ce problme. Crons la vue SecondView de la manire suivante :
Voir code en ligne : Lien 115

Comme nous avons pu le constater lorsque nous avons Nous pouvons visualiser le rsultat et vrifier le bon excut notre exemple, les donnes sont bien mises jour en temps rel. fonctionnement de l'application : 4. Utilisation de WindowBuilder Une fois encore, WindowBuilder nous permet de raliser nos bindings facilement. Crons la vue ThirdView en l'initialisant de la manire suivante :
Voir le code en ligne : Lien 116

Nous avons initialis nos donnes d'entre au travers de la variable input , mais nous n'avons pas encore dfini le ContentProvider ni le LabelProvider. Ouvrons la vue avec WindowBuilder, et rendons-nous dans l'onglet Bindings . Dans la partie gauche, slectionnons l'objet graphique viewer et sa caractristique input (carrs Utilisation des ObservableMap rouges). Dans la partie droite, slectionnons l'objet input et la caractristique Object as Il nous faut cette fois-ci dfinir le ContentProvider. La IObservableList (carrs orange). Enfin, crons le binding classe ObservableListContentProvider ncessite que les en cliquant sur le bouton idoine (carr vert) : donnes d'entre du viewer implmentent l'interface IObservableList. Notons qu'une liste classique peut tre transforme en IObservableList grce la classe Properties, comme le montre l'exemple ci-dessous :
List<PersonBean> persons = PersonList.getPersonList(); IObservableList input = Properties.selfList(PersonBean.class).observe(p ersons) ;

Afin d'observer les modifications dans les listes d'lments, on utilise des objets IObservableMap. Ces Premire tape avec WindowBuilder objets permettent d'observer les modifications d'un attribut au sein des diffrents lments d'une collection de type IObservableSet. Cette collection est obtenue directement Une fentre s'ouvre et nous permet de slectionner les proprits afficher dans les colonnes de notre viewer.
Numro 42 octobre - novembre 2012 Page 65

Developpez Magazine est une publication de developpez.com

Elle nous permet aussi de dfinir des diteurs pour les cellules :

viewer.setInput(input); // return bindingContext; }

En lanant l'application, nous pouvons constater le fonctionnement correct du databinding :

Deuxime tape avec WindowBuilder Le binding est cr. On retrouve dans le code source gnr les lments que nous avons mentionns dans cet article :
protected DataBindingContext initDataBindings() { DataBindingContext bindingContext = new DataBindingContext(); // ObservableListContentProvider listContentProvider = new ObservableListContentProvider(); viewer.setContentProvider(listContentProvider ); // IObservableMap[] observeMaps = BeansObservables.observeMaps(listContentPro vider.getKnownElements(), PersonBean.class, new String[]{"firstname", "age"}); viewer.setLabelProvider(new ObservableMapLabelProvider(observeMaps)); //

Rsultat avec WindowBuilder 5. Liens utiles JFace Databinding sur le site de Lars Vogel : Lien 117. 6. Conclusion Dans ce second article, nous avons vu comment mettre en uvre le framework JFace Databinding sur des composants JFace. Cela nous permet d'observer les changements effectus sur une collection d'objets, soit de manire trs simple et rapide, soit de manire plus prcise. Retrouvez l'article d'Alain Bernard en ligne : Lien 118

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 66

Android
Les dernires news Android est-il un OS de Geeks ? Il serait fait par des ingnieurs qui travaillent dans leur coin et qui ncoutent jamais personne
Faites un test simple. Prenez une tablette ou un Smartphone sous Android. Mettez-le dans les mains du premier venu (vos enfants, votre conjoint, vos grandsparents, peu importe). Et observez. Sauf ceux qui travaillent dans lIT ou ont t familiariss avec l'OS, il y a fort parier que votre cobaye soit vite Son exemple est intressant pour deux raisons. dboussol. La premire cest quil nest absolument pas anti-Android. Recommencez avec un iPad ou un iPhone, et lavis sera Au contraire. Mais pour lui, c'est un OS qui perd le grand neuf fois sur dix radicalement diffrent. public. Ou plus exactement que le client achte sans le savoir ( on achte un Samsung, pas un Android ) juste Je calme tout de suite les fans boys. Il ne sagit pas de dire parce qu'il veut un tlphone et pas ncessairement un quAndroid est moins bon quiOS. Smartphone. Il s'agit de se demander si Android est adapt au grand public et surtout ce que Google pourrait faire pour amliorer lexprience utilisateur de son systme d'exploitation. Un systme par ailleurs numro un mondial incontest du secteur. La deuxime, cest que ce jeune dveloppeur franais travaille depuis des annes dans la Silicon Valley et quil y a li des relations, notamment avec des employs de Google. Des employs qui ne cachent pas que les quipes marketing peuvent parfois sarracher les cheveux. Un pote de chez Google ma expliqu pourquoi [Android est si complexe]. Android est fait par des quipes dingnieurs qui travaillent dans leur coin. chaque fois quun nouveau arrive, il rajoute son truc. Et ils ncoutent jamais personne de lextrieur , nous expliquait-il. En rsum, un OS fait par des Geeks, pour des Geeks. Ce qui en soi n'est pas un mal, mais pose la question de savoir si vous le recommanderiez vos enfants, votre conjoint, vos grands-parents, etc.

Android, numro un mondial du secteur mobile

Prenez un des dveloppeurs d'Infinite Flight, le meilleur simulateur de vol disponible sur iOS (Lien 119) et sur Personnellement, je l'ai fait. Et on ne m'en a pas remerci. Windows Phone (Lien 120) avec X-Plane. Commentez la news de Gordon Fowler en ligne : Lien 121 Assez peu fan dApple et possesseur parfaitement combl dun Smartphone sous Android, son avis nen est pas Android : de nouvelles sources de moins tranch sur la question : Si aujourdhui on me menace l'horizon demande un conseil pour acheter un Smartphone, sans Des chercheurs s'apprtent publier un hsiter je rponds "un iPhone ou un Windows Phone. framework modulaire d'exploit Android cest trs bien, mais au bout dun moment tu te rends compte que cest compliqu. Des fois tu te dis mais Une nouvelle source de menace pour l'OS Android se quest-ce que cest que ce bazar ? Y a des boutons de profile. Deux experts en scurit affirment qu'ils partout ! a part dans tous les sens. Il ny a pas de publieront le mois prochain un nouveau framework open consistance (sic) . source modulaire appel AFE (Android Framework for Exploitation). Cet outil permettra toute personne bien intentionne (ou pas du tout !) de crer et de personnaliser son application Android malveillante. Adity Gupta et Subho Halder sont
Developpez Magazine est une publication de developpez.com
Numro 42 octobre - novembre 2012 Page 67

les deux crateurs derrire cet outil, et se considrent Marketplace, qui permet aux dveloppeurs de publier des comme des white-hat hackers , spcialiss dans la applications de faon anonyme. scurit mobile. Mais qu'est-ce qui pousse deux White Hats mettre une Ils prsenteront leur Framework dans le ToorCamp, qui se telle plaie entre les mains des pirates en herbe ? Les droulera ce mois-ci dans l'tat de Washington, ainsi que chercheurs ne l'expliquent pas, en tout cas pas avant le dans la NullCon prvue Delhi le mois prochain. ToorCamp. Mais on se doute qu'ils fassent partie de ces nombreux Les modules raccourcissent considrablement le temps et chercheurs qui croient que Google pourrait mieux faire simplifient le dveloppement d'un logiciel malveillant. Ils pour protger les utilisateurs de sa plateforme. permettent l'utilisateur de choisir parmi 20 fonctionnalits prconstruites, comme la rcupration des Afin de dtecter ces menaces, Google a pourtant mis en contacts, des emails, des donnes de la carte SD, ou l'accs place en fvrier dernier un mcanisme appel Bouncer, l'emplacement du mobile en utilisant le dispositif GPS. conu pour dtecter automatiquement les comportements On peut mme forcer la numrotation de n'importe quel malveillants. Nanmoins, une prsentation au Black Hat le numro premium. mois dernier a permis d'illustrer par quelle facilit ce Bouncer peut tre vaincu. AFE est essentiellement crit en PHP, Ruby, Bash et Python. La semaine dernire, Google a aussi mis jour le guide des dveloppeurs d'applications Android publies dans le Les deux experts considrent cet outil comme une option Google Play, afin de contrer le problme des spams, des plus dvastatrice que la mthode "classique", qui requiert applications truques et celles qui violent la vie prive. Les de prendre une application lgitime, la dcompiler en applications existantes seront supprimes en 30 jours, si utilisant APKTool ou Dex2Jar et JF-GUI, insrer nos leurs dveloppeurs ne suivent pas la ligne directrice fixe codes, puis la redistribuer . En effet, cet outil permet de par Google. masquer le malware en tant qu'application lgitime, tels un explorateur de fichier, ou un jeu Tic Tac Toe, pour faciliter Esprons que ces mesures seront assez suffisantes pour sa dissmination dans Google Play. protger les utilisateurs d'Android. Aprs distribution, il ne reste plus qu' tromper l'utilisateur Commentez cette news de Tarik Zakaria en ligne : pour l'amener tlcharger l'application via l'Android Lien 122

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 68

Liens
Lien 01 : http://www.w3.org/TR/html5/embedded-content-0.html#dom-innerhtml Lien 02 : http://blog.developpez.com/web/p11267/web/html5_quelques_nouveautes_de_l_api_dom_p Lien 03 : https://developer.mozilla.org/en-US/docs/DOM/window.navigator.onLine Lien 04 : https://github.com/Progi1984/DVP Lien 05 : http://f-lefevre.developpez.com/tutoriels/html5/offline/ Lien 06 : http://torgar.developpez.com/articles/css/bordures-css3/ Lien 07 : http://www.pallier.org/ressources/dicofr/dicofr.html Lien 08 : http://www.pallier.org/ressources/dicofr/liste.de.mots.francais.frgut.txt Lien 09 : http://sourceforge.net/projects/lazarus/files/ Lien 10 : http://lazarus.developpez.com/cours/mots-croises/ Lien 11 : http://datametric.developpez.com/tutoriels/sas/sas-batch-modes-checkpoint-restart/ Lien 12 : http://cafeine.developpez.com/access/tutoriel/recherchemulti/ Lien 13 : http://jeannot45.developpez.com/articles/access/recherchemulticriteres/ Lien 14 : http://office.microsoft.com/fr-ca/access-help/concepts-de-base-sur-la-conception-d-une-base-de-donnees-HA001224247.aspx Lien 15 : http://argyronet.developpez.com/office/access/highlightrecord/ Lien 16 : http://argyronet.developpez.com/office/vba/convention/ Lien 17 : http://jeannot45.developpez.com/articles/access/implantationsousetat/ Lien 18 : http://claudeleloup.developpez.com/tutoriels/access/comment-implanter-un-sous-formulaire/Comment%20implanter%20un%20sousformulaire.mdb Lien 19 : http://claudeleloup.developpez.com/tutoriels/access/comment-implanter-un-sous-formulaire/ Lien 20 : http://cpp.developpez.com/gotw Lien 21 : http://cpp.developpez.com/boost/proto Lien 22 : http://cpp.developpez.com/carmack Lien 23 : http://cpp.developpez.com/flottant Lien 24 : http://cpp.developpez.com/bas-niveau Lien 25 : http://www.developpez.net/forums/f19/c-cpp/cpp/ Lien 26 : http://cpp.developpez.com/ Lien 27 : http://www.developpez.net/forums/private.php?do=newpm&u=268393 Lien 28 : http://www.developpez.net/forums/d1258293/c-cpp/cpp/programme-rentree-rubrique-cpp/ Lien 29 : http://en.wikipedia.org/wiki/IEEE_754 Lien 30 : http://en.wikipedia.org/wiki/IEEE_754-2008 Lien 31 : http://en.wikipedia.org/wiki/Aliasing_%28computing%29 Lien 32 : http://labs.qt.nokia.com/2011/06/10/type-punning-and-strict-aliasing/ Lien 33 : http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html Lien 34 : http://fr.wikipedia.org/wiki/Endianness Lien 35 : http://cpp.developpez.com/redaction/data/pages/rubrique/cpp/flottant/flottant1/ Lien 36 : http://altdevblogaday.com/2011/10/25/why-i-became-an-educator/ Lien 37 : http://www.udemy.com/cs-107-programming-paradigms/ Lien 38 : http://www.swansontec.com/sregisters.html Lien 39 : http://www.jegerlehner.ch/intel/ Lien 40 : http://en.wikipedia.org/wiki/X86_instruction_listings Lien 41 : http://home.comcast.net/%7Efbui/intel.html Lien 42 : http://cpp.developpez.com/redaction/data/pages/rubrique/cpp/bas-niveau/bas-niveau1/ Lien 43 : http://www.coverity.com/ Lien 44 : http://msdn.microsoft.com/en-us/library/d3bbz7tz%28v=VS.100%29.aspx Lien 45 : http://randomascii.wordpress.com/category/code-reliability/ Lien 46 : http://www.viva64.com/en/pvs-studio/ Lien 47 : http://www.viva64.com/en/developers-resources/ Lien 48 : http://www.gimpel.com/html/pcl.htm Lien 49 : http://www.riverblade.co.uk/products/visual_lint/index.html Lien 50 : http://cpp.developpez.com/redaction/data/pages/rubrique/cpp/carmack/analyse-statique/ Lien 51 : http://blog.developpez.com/gpu/p10958/langages-frameworks/c/les_signaux_et_slots_dans_qt5 Lien 52 : http://blog.developpez.com/gpu/p10904/langages-frameworks/opengl/opengl_dans_qt5 Lien 53 : http://code.google.com/p/v8/ Lien 54 : http://qt-project.org/wiki/Qt-Platform-Abstraction Lien 55 : http://blog.developpez.com/gpu/p11283/langages-frameworks/qt/les-modules-de-qt-5 Lien 56 : http://labs.qt.nokia.com/2011/05/09/thoughts-about-qt-5/ Lien 57 : http://labs.qt.nokia.com/2011/05/11/responses-to-qt-5/ Lien 58 : https://launchpad.net/%7Eforumnokia/+archive/fn-ppa Lien 59 : http://qt-project.org/wiki/Building_Qt_5_from_Git Lien 60 : http://releases.qt-project.org/qt5.0/alpha/ Lien 61 : http://qt-project.org/wiki/Qt-5-Alpha-building-instructions Lien 62 : http://www.developpez.net/forums/d1209764/c-cpp/bibliotheques/qt/sortie-qt-5-beta/ Lien 63 : http://blog.qt.digia.com/2011/08/09/update-on-uikit-lighthouse-platform/ Lien 64 : http://qt.developpez.com/actu/47705/Premier-jour-de-Qt-chez-Digia-apres-son-rachat-de-Nokia-le-framework-restera-disponible-sous-GPLet-LGPL/ Lien 65 : http://www.developpez.com/redirect/572 Lien 66 : http://www.developpez.net/forums/d1248904/c-cpp/bibliotheques/qt/avenir-qt-developer-days/ Lien 67 : http://alexandre-laurent.developpez.com/tutoriels/OpenGL/OpenGL-Extensions/#L2-B Lien 68 : http://freeglut.sourceforge.net/ Lien 69 : http://qt-project.org/ Lien 70 : http://qt-project.org/doc/qt-4.8/qtopengl.html Lien 71 : http://qt-project.org/doc/qt-4.8/qglformat.html#setVersion Lien 72 : http://blog.developpez.com/gpu/p11241/langages-frameworks/opengl/qt-project.org/doc/qt-4.8/qglformat.html Lien 73 : http://qt-project.org/wiki/How_to_use_OpenGL_Core_Profile_with_Qt Lien 74 : http://www.sfml-dev.org/index-fr.php Lien 75 : http://www.sfml-dev.org/documentation/2.0/structsf_1_1ContextSettings.php Numro 42 octobre - novembre 2012 Page 69

Developpez Magazine est une publication de developpez.com

Lien 76 : http://www.sfml-dev.org/tutorials/2.0/window-opengl.php Lien 77 : http://www.libsdl.org/ Lien 78 : http://www.opengl.org/wiki/Tutorial1:_Creating_a_Cross_Platform_OpenGL_3.2_Context_in_SDL_%28C_/_SDL%29 Lien 79 : http://www.opengl.org/sdk/docs/man/xhtml/glIsEnabled.xml Lien 80 : http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml Lien 81 : http://www.opengl.org/sdk/docs/man/xhtml/glGet.xml Lien 82 : http://blog.developpez.com/gpu/p11241/langages-frameworks/opengl/deboguer_avec_opengl Lien 83 : http://developer.nvidia.com/opengl-driver Lien 84 : http://www.opengl.org/registry/doc/glspec43.core.20120806.pdf Lien 85 : http://www.opengl.org/registry/doc/glspec43.compatibility.20120806.pdf Lien 86 : http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf Lien 87 : http://www.khronos.org/registry/gles/specs/3.0/es_spec_3.0.0.pdf Lien 88 : http://www.khronos.org/registry/gles/specs/3.0/GLSL_ES_Specification_3.00.3.pdf Lien 89 : http://www.developpez.net/forums/d1250751/applications/developpement-2d-3d-jeux/api-graphiques/opengl/sortie-specifications-dopengl4-3-opengl-es-3-0-a/ Lien 90 : http://jaxb.java.net/ Lien 91 : http://www.saxproject.org/ Lien 92 : http://www.oracle.com/technetwork/java/intro-140052.html Lien 93 : http://docs.oracle.com/javase/6/docs/api/org/xml/sax/helpers/DefaultHandler.html Lien 94 : http://www.castor.org/ Lien 95 : http://docs.oracle.com/javase/7/docs/api/java/beans/XMLEncoder.html Lien 96 : http://atatorus.developpez.com/tutoriels/intro-jaxb/fichiers/XMLDecoder.html Lien 97 : https://commons.apache.org/digester/ Lien 98 : http://jaxb.java.net/ Lien 99 : http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html Lien 100 : http://jaxb.java.net/2.2.5/docs/ Lien 101 : http://atatorus.developpez.com/tutoriels/intro-jaxb/ Lien 102 : http://www.developpez.com/actu/47940/ Lien 103 : http://www.developpez.net/forums/d1266011/java/general-java/javaone-2012-demarre/ Lien 104 : http://www.developpez.com/actu/48206/ Lien 105 : http://www.developpez.net/forums/d1266773/java/general-java/javaone-2012-oracle-renouvelle-engagement-faire-evoluer-java-devoileplans/ Lien 106 : http://www.developpez.com/actu/48228/ Lien 107 : http://www.jcp.org/en/jsr/detail?id=353 Lien 108 : http://www.developpez.net/forums/d1267436/java/general-java/javaone-2012-oracle-presente-specification-jsr-353-a/ Lien 109 : http://dlc.sun.com.edgesuite.net/netbeans/7.3/beta/ Lien 110 : http://www.developpez.net/forums/d1266726/java/edi-outils-java/netbeans/javaone-2012-oracle-sort-preview-netbeans-7-3-a/ Lien 111 : http://alain-bernard.developpez.com/tutoriels/eclipse/databinding-swt Lien 112 : http://eclipse.developpez.com/cours/?page=platform-cat#plugin-dev Lien 113 : http://eclipse.developpez.com/cours/?page=platform-cat#ihm-dev Lien 114 : http://alain-bernard.developpez.com/tutoriels/eclipse/databinding-jface/#LII Lien 115 : http://alain-bernard.developpez.com/tutoriels/eclipse/databinding-jface/#LIII Lien 116 : http://alain-bernard.developpez.com/tutoriels/eclipse/databinding-jface/#LIV Lien 117 : http://www.vogella.de/articles/EclipseDataBinding/article.html Lien 118 : http://alain-bernard.developpez.com/tutoriels/eclipse/databinding-jface/ Lien 119 : http://goo.gl/k9GD1 Lien 120 : http://goo.gl/DSdk7 Lien 121 : http://www.developpez.net/forums/d1267472/general-developpement/debats-developpement-best-of/android-os-geeks/ Lien 122 : http://www.developpez.net/forums/d1250546/club-professionnels-informatique/actualites/android-nouvelles-sources-menace-lhorizonchercheurs-sappretent-publier-framework-dexpl/

Developpez Magazine est une publication de developpez.com

Numro 42 octobre - novembre 2012 Page 70

Vous aimerez peut-être aussi