Aller au contenu

Linux Attitude

Le libre est un état d'esprit

Archive

Catégorie : Développement

Niveau : Star Star Empty Empty Empty
Résumé :

Aujourd'hui un thème un peu polémique mais pas trop quand même.

Le XML est un descendant du SGML. C'est un format structuré de données comme l'est l'ASN1 ou le LDIF.

Tous ces formats ont été inventés dans une seule optique : être facile à parser par une machine. Et pourtant quand on voit les subtilités du XML et les difficultés à faire un parseur, on peut avoir des doutes... Mais de ce fait ils sont peu lisibles.

Ne vous méprenez pas, le XML a tout à fait sa place dans les échange de données, dans la communication entre machines. Le format est bien défini et fonctionne quel que soit le type de machine. Il est d'ailleurs très utilisé car on trouve des parseurs partout, dans presque tous les langages, et dans presque tous les frameworks.

Mais à force d'en user on en abuse.

Non le XML n'est PAS fait pour les humains ! Le xml n'est pas à sa place dans les fichiers de configuration, à moins que vous n'ayez pour objectif que l'utilisateur ne touche jamais à ces fichiers et que vous ayez le temps de développer une interface entre l'utilisateur et la modification (texte ? graphique ? sonore ?).

Le XML est pratique car il permet au développeur d'éviter l'usage de protocoles binaires incompréhensibles et mal parsés entre deux applications. Il est pratique car un autre développeur peut lire ce protocole sans l'avoir appris. Mais vous remarquerez que je ne parle que de développeurs, pas d'utilisateurs.

Alors par pitié arrêtez le XML dans les fichiers destinés aux HUMAINS. Il existe bien d'autres formats ayant des parseurs et tout aussi lisibles :

Mieux, il existe LUA qui vous permet à la fois d'avoir un fichier de configuration simple et lisible, mais qui en plus autorise l'utilisateur à faire des choses que vous n'auriez pas prévu, comme des configuration conditionnelles !

Niveau : Star Star Star Star Empty
Résumé :

Maintenant que nous savons nous servir d'un interpréteur postscript, nous allons pouvoir développer. Postscript est un langage complet au sens de Turing. C'est à dire qu'on peut tout faire avec, même faire décoller une fusée. Mais bon, avant d'en arriver là, on va essayer de faire quelque chose d'utile.

Pour vous présenter le langage, je vous propose un exemple basé sur la fourmi de Langton. C'est une fourmi qui a ceci de particulier qu'elle ne sait que tourner. Son univers ressemble beaucoup à celui du jeu de la vie, c'est-à-dire une grille infinie de cases noires ou blanches. Lorsque la fourmi est sur une case noire, elle tourne à droite, lorsqu'elle est sur une case blanche, elle tourne à gauche. De plus elle inverse la couleur de la case sur laquelle elle se trouve.

Le concept est assez simple, et lorsqu'on lance la fourmi sur une grille blanche, son comportement a l'air aléatoire. Et pourtant au bout d'un moment elle fabrique ce qui ressemble à une autoroute.

Tout ça pour dire que le postscript c'est bien. C'est un langage à pile, qui fonctionne en notation inversée. Les possesseurs de HP48 et amateurs de RPL y retrouveront leurs petits (ou de vieux souvenirs). Les développeurs forth (faite sous savoir si vous êtes dans la salle) apprécieront aussi probablement.

La base

Les commentaires

Toute ligne commençant par un % est un commentaire. Exemple :

% Rien

Les commandes

Les commandes sont des mots simples. Étant donné la notation inversée, la commande se trouve après ses arguments. Par exemple une addition :

5 9 add

A cette notation est associée une pile. 5 pose 5 sur la pile, 9 pose 9 sur la pile, add retire les 2 derniers éléments (donc 9 et 5) puis additionne et repose le résultat sur la pile. D'où la représentation de la pile :

    %avant la ligne de commande
5   % 5 
5 9 % 9
    %pendant le add (invisible)
14  % après le add 

Les commandes peuvent être séparées par des espaces ou des retours à la ligne.


... continuer la lecture ...

Niveau : Star Star Star Empty Empty
Résumé : perlconsole

Vous développez régulièrement vos scripts en perl ? Si oui : lisez ceci ou cela ou encore d'autres choses plus ou moins utiles.

Si oui vous devez faire des tests de temps en temps. Je me suis habitué à faire des perl -e ou perl -pe pour des petites choses. Mais il existe un outil bien plus pratique : perlconsole.

Son usage est simple :

$ perlconsole

Pour le debug, cet outil est sympa puisqu'il permet de taper les commandes une par une et d'en avoir la valeur de retour.

Pour le développement cet outil est parfois un peu lourd puisqu'il renvoie la valeur de retour de toutes les commandes tapées, même si cela ne nous intéresse pas vraiment.

Autre fonctionnalité qui ravira certains, les valeurs de retours peuvent être affichées sous différentes formes. Ce qui veut dire qu'il est possible d'avoir un dump complet du résultat de chaque commande. Il suffit pour cela d'entrer la commande suivante pour les habitués de Data::Dumper :

:set output=dumper

Mais il existe aussi une sortie yaml, que je trouve personnellement plus lisible pour des structures ne dépassant pas une page.

:set output=yaml

Niveau : Star Star Empty Empty Empty
Résumé : perl

Perl fait beaucoup de choses, trop, tellement que certaines sont complètement inutiles

Il est possible de changer la numérotation des tableaux :

# le premier élément d'un tableau sera maintenant le numéro 42
$[=42;

Il est possible d'allouer de la mémoire inutilisée :

# alloue 64Mio de mémoire pour que perl puisse les utiliser quand il meurt a cause du manque de mémoire !!
# ce qui ne l'empêche pas de mourir bien sur
$^M=64<<20; 

Les sections BEGIN {} et END {} sont des blocs très utiles qui s'écrivent tels quel, mais il peuvent aussi être écrits comme des méthodes :

sub BEGIN {}

Perl disposes de modules en provenance du CPAN. Parmi ces modules on trouve les modules Acme, dont voici quelques exemples pour bien en comprendre l'utilité :

  • Acme::Anything qui permet de charger des modules qui n'existent pas
  • Acme::Error qui permet d'afficher toutes les erreurs en capitales.
  • Acme::Godot qui vous permet d'attendre Godot
  • Acme::EyeDrops pour convertir votre code perl en ascii art (fonctionnel en perl), très joli d'ailleurs
  • Acme::Code::Police supprime toute erreur de code qui n'utiliserait pas strict en supprimant le code.

Niveau : Star Star Star Empty Empty
Résumé : perl

Quelques trucs et astuces de perlistes en vrac. Pour des vrais astuces de pro régulières, n'hésitez pas à visiter le site des moines de perl.

Initialiser un tableau de chaînes sans avec une syntaxe légère, très lisible quand on n'a que des mots, le séparateur étant les caractères blancs, incluant le retour à la ligne :

@tableau = qw( mot1 mot2 mot3 );

Passer du mode script de quelques lignes au mode développement long. Cela vous oblige à déclarer et initialiser toutes vos variables entre autre :

use strict;

Le debug facile :

use Data::Dumper;
# variable peut être n'importe quoi, toutes les sous-sous parties sont écrites :
print Dumper($variable,\@variable);
print Dumper(\%variable);

L'aide en ligne facile, ça fait tout de suite classe dans un script (format) :

use Pod::Usage;
# imprime le contenu de SYNOPSIS et termine le programme avec un code d'erreur 1
pod2usage(1);
# attention, pod est chatouilleux sur les retours à la ligne avant et après les =

=head1 SYNOPSIS

commande  [-o|--option=<valeur>]

=cut

La page de manuel facile (pas seulement le SYNOPSIS comme précédemment) :

# où fichier.pl est le code précédent
$ pod2man fichier.pl > fichier.1
$ man ./fichier.1

Et le dernier pour la route, le parsing d'options facile, très classe, surtout en combinaison avec pod2usage (format) :

use Getopt::Long;
my $options = {
        option => 'defaut'
};
GetOptions( $options, qw(
        option|o=s
));

Niveau : Star Star Star Empty Empty
Résumé : chmod +x test.c

Après une technique utilisant du perl, voici une nouvelle façon d'utiliser du C aussi simplement qu'un script.

Cette fois nous évitons l'usage de perl, on se passe donc de ses avantages en terme de parsing. Par contre, on utilise un en-tête court et le code fonctionne avec n'importe quel code valide en C. Comme d'habitude, on fait propre et on renvoie le bon code de retour.

#!/bin/sh
tail -n +4 $0 | gcc -Wall -o /tmp/cscript.$$ -x c - && /tmp/cscript.$$ $*
ret=$? ; rm -f /tmp/cscript.$$ ; exit $ret
//
// Code C
//
#include <stdio.h>
int main(int argc, char** argv)
{
        printf( "Appel de %s avec %d arguments\n", argv[0], argc-1 );
        return 0;
}

Et maintenant on teste pour prouver que ça marche :

chmod +x test.c
./test.c 1 2 3 && echo "OK" | | echo "KO"

Niveau : Star Star Star Star Empty
Résumé : SSE

Aujourd'hui l'avenir (et un peu le passé aussi). Vous souvenez-vous des cray ? Ces machines surpuissantes qui avaient au moins la puissance de calcul d'une TI92. Comment faisaient-ils pour avoir une telle puissance ? Il faisaient des calculs identiques en parallèle et multipliaient ainsi par n le nombre d'opérations. C'est ce qu'on appelle une architecture vectorielle.

Intel dans sa grande bonté a commencé à mettre en place une telle architecture dans ses processeurs. Tout d'abord avec les instructions MMX. Ces instructions utilisent les registres servant au calcul en virgule flottante (quelques transistors de gagnés), lesquels font 64 bits. On peut ainsi exécuter des instructions identiques simultanément sur 4 fois 1 octets ou sur 2 fois 2 octets. Ce qui est bien, mais pas top.

Le SSE est une amélioration du concept. Tout d'abord on utilise de nouveaux registres (ce qui libère les calculs en virgule flottante) et on leur donne une taille de 128bits. Du coup on peut manipuler deux fois plus d'entiers et cela devient intéressant pour les flottants. On peut caser 4 flottants simple précision et 2 flottants double précision dans 128 bits. Le SSE s'arrête aux 4 flottants et le SSE2 ajoute quasiment toutes les autres combinaisons possibles (flottants et entiers).

Version normale

Comme nous sommes joueurs, nous allons jouer à améliorer notre code de calcul de Mandelbrot. Mais cette fois, nous allons le laisser tourner sous linux. Comme ne sommes plus dans notre monde, mais sur un vrai système, nous allons devoir faire quelques modifications. Nous allons continuer à écrire directement en mémoire, donc on garde nos fonctions d'écriture de pixels, mais cette fois dans une mémoire allouée avec malloc. Ajoutons le support de l'écriture d'un des format d'image les plus simples, le BMP, pour stocker notre image dans un fichier et pouvoir admirer le résultat. Pour cela on prend la première documentation venue.

/* Ecriture de l'image dans un fichier bitmap (on écrit l'en-tête kivabien puis les données) */
void writebitmap(char* filename, char*bitmap, int width, int height);

Et voilà, cela nous donne une première version du code quasiment identique à la précédente et donc non optimisée pour le SSE (disponible à la fin de l'article).


... continuer la lecture ...