Autour du codeDevelopper toujours mieux
Posté le

M4 Tout n'est que substitution

Dans cet article, on va faire un peu d'archéologie, et étudier M4 sortie en 1977, c'est le grand successeur de M3.

M4 est un processeur de macros écrit dans les laboratoires de Bell par Brian et Dennis, leur nom de famille étant respectivement Ritchie et Kernighan, je les donne au cas où il y est d'autre acolyte aussi populaire avec les même prénoms smile . En M4, le principe de base est la substitution, vous ne pouvez rien faire d'autre. La premiére chose à faire est de définir une macro avec define ainsi si dans un fichier text, hello.m4, je met ceci:

define(foo, bar)
foo

Et que j'appele

$ m4 hello.m4

Je vais avoir bar qui s'affiche. Facile n'est-ce pas ?

L'importance des quotes

M4 cherche par tout les moyens de substitué sauf si vous entouré du text par ceci `', M4 supprimera les quotes mais ne substitura pas l'intérieure.

define(`foo', one) # defini une macro foo -> one
define(`foo', two) # redefini la macro foo -> two

define(foo, one) # defini une macro foo -> one
define(foo, two) # defini une macro one -> two

Les paramètres

Une macro peut avoir des paramètre les noms de ses paramètre sont prédéfini. Ainsi, $1 est le 1er argument, $2 le second, ect... On les utilises dirrectement dans la substitution.

define(`hello', `Salut $1 !')
hello(`toto') # Salut toto !

Il existe d'autres paramètres prédéfinis $0 est le nom de la macro. $# le nombre d'arguments passé à la macro. $@ la concaténation de tous les arguments passée séparée par ',' (une virgule)

Les substitutions conditionnelles avec ifelse

ifelse est une macro très puissante. Si le 1er argument est égal au second, elle affiche le 3éme. Si vous donné 4 arguments elle affiche le 4éme si le 1er est différent du 2éme. Avec plus de 4 arguments vous faites un swith case.

ifelse(`a', `a', `33') # 33
ifelse(`a', `b', `33') #
ifelse(`a', `b', `33', `44') # 44
ifelse(`a', `b', `33', `a', `a', `55', `77') # 55
ifelse(`a', `b', `33', `a', `c', `55', `77') # 77

Il ne nous manque plus que shift

Shift prend N paramètre est les affiches tous sauf le premier. Avec les macro précédentes on peut faire tout ce que l'on veux avec un peu de récursivités. Voici une macro qui indique si le premier argument est dans les autres

define(`in', `ifelse(`$#', 0, `false',    # Si pas d'argument on affiche false
                     `$#', 1, `false',    # Sinon si un seul d'argument on affiche false
                     `$1', `$2', `true',  # Sinon si l'argument 1 est égale au 2éme on affiche true
                     `$#', 2, `false',    # Sinon s'il n'y avait que 2 arguments on affiche false
                     `in(`$1', shift(shift($@)))')') # sinon on substitue avec la macro in
                                                     # en retirant le 2er argument
in(1, 2, 3, 1) # -> true
in(1, 2, 3, 4) # -> false

Inverser les paramétres

define(`reverse', `ifelse(`$#', `0', ,
                          `$#', `1', ``$1'',
                          `reverse(shift($@)), `$1'')')
reverse(3,4,5) # 5,4,3

Vous trouverez plein d'autre macro ici comme forloop

forloop(`i', `1', `8', `i ') # 12345678

Ok, mais on a fait quoi avec M4 ?

C'est utiliser par autoconf et sendmail, ou pour factoriser du code assembleur. Certaines personnes ont utilisé M4 pour générer leur html. Il y des libs htm4l Pour moi, ça ressemble juste à une grosse blague sauf qu'il y a des sites maintenus avec finder.

Mais par contre, le M4 dans le CSS, ça roxe du poney !

define(`COLOR1', `#FF00')
#element1 {
    background-color: COLOR1;
}
.element2 {
    color: COLOR1;
}

Oups! j'ai oublié de vous mettre en garde... Voici avertissement que l'on peut trouver en introduction du manuel M4

Certaines personnes trouvent m4 assez addictif. Ils utilisent d'abord m4 pour des problèmes simples, puis relever des défis toujours plus grands, apprennent à écrire des ensembles complexes de macros m4. Une fois vraiment accro, les utilisateurs continue avec l'écriture d'applications m4 sophistiquées même pour résoudre des problèmes simples, en consacrant plus de temps au débogage de leurs scripts m4 que de faire véritablement le travail. Méfiez-vous, m4 peut être dangereux pour la santé des programmeurs compulsifs.

Mais, j'imagine que vous n'été pas du genre à essayer de programmer un automate cellulaire en M4 pendant plus de 72 heures. X)

Si vous souhaitez aller plus loin:

D'ici là, à vos PDP-11 et bon code ! laughing