Niveau :
Résumé : m4
m4 est un langage de macro bien utile. Le jour ou vous avez un fichier texte (ou plusieurs) un peu long et répétitif et que vous en avez marre d'éditer 50 lignes à chaque modification, alors m4 est probablement fait pour vous.
Tout d'abord m4 est un langage de macro, c'est-à-dire qu'il ne sert qu'à prendre du texte pour générer du texte, et il s'écrit inline. Donc votre fichier de configuration apache est déja un fichier m4 :
$ m4 /etc/apache2/apache2.conf
C'est cool non ! Pas besoin de partir de zéro, vous faites avec ce que vous avez.
Maintenant écrivons un petit fichier m4 pour apprendre :
dnl ###############=>
dnl # commentaire #
dnl ###############
dnl
Premier test
`Deuxième test'
# `troisième test'
Premier test
Deuxième test
# `troisième test'
Donc m4 recopie tout ce qu'on lui donne, y compris les retours à la ligne, sauf tout ce qui suit un dnl. Ensuite une chaîne de caractères est délimitée par `', une chaine de caractère est aussi recopiée telle quelle. Et enfin, ce qui suit un # est appelé commentaire en m4, il est recopié sans interprétation aucune.
Passons à quelque tests plus sympas :
Bonjour, ceci n'est pas une macro=>
define(`macro1',`Bonjour, ceci est une macro')dnl
define(`macro2',`Bonjour, ceci est $1')dnl
define(macro3,Ca marche aussi comme ca)dnl
macro1
macro2(`une macro avec arguments')dnl
macro3()
Bonjour, ceci n'est pas une macro
Bonjour, ceci est une macro
Bonjour, ceci est une macro avec argumentsdnl
Ca marche aussi comme ca
Remarquez que vous définissez les macros directement dans le texte. Remarquez que les définition sont suivies de dnl pour ne pas afficher le retour à la ligne qui suit la définition de la macro. Remarquez aussi que les arguments d'une macro s'utilisent simplement avec $X, X étant le numéro de l'argument. Et remarquez enfin qu'une macro peut s'appeler directement sans parenthèses (une macro qui n'a pas pas d'argument explicite est simplement une macro donc les arguments sont vides).
Avec ces premiers points, vous avez déjà tout ce qu'il faut pour répondre à la plupart de vos besoins. m4 dispose de nombreuses autres fonctionnalités, avoir plusieurs sorties, utiliser des buffers, des expressions régulières, faire des tests ou des calculs. Mais si vos besoins s'éloignent largement de ces fonctions de base, il est probable qu'un script perl avec un bon fichier de configuration soit plus pratique et plus lisible qu'un fichier m4.
Continuons tout de même.
Notez que l'évaluation des define se fait toujours a posteriori :
define(hello,bye)dnl=>
define(bye,`kitty')dnl
define(kitty,cindy)dnl
hello
cindy
On peut passer des paramètres à m4 :
$ m4 -Dparam="J'aime les filles"=>
param
J'aime les filles
Ou inclure des fichiers :
include(`file')
On peut aussi utiliser plusieurs buffers :
divert(1)dnl=>
Ce message sera affiché après la fin du fichier
divert(0)dnl
Message de départ
Message de départ
Ce message sera affiché après la fin du fichier
m4 dispose de 10 buffers, tout appel à la macro divert change le buffer dans lequel on écrit. Le buffer 0 est la sortie en cours, tandis que les 9 suivants seront écrits dans l'ordre à la fin du traitement. Si vous utilisez un No de buffer négatif, le contenu sera supprimé.
Et un dernier point sur la manipulation de chaînes :
regexp(`Salut mon ami',`(.*) ami',`1 pote')=>
substr(`Salut mon ami',10,3)
Salut mon pote
ami
Et si vous voulez vraiment aller plus loin : http://www.gnu.org/software/m4/manual/index.html