le preprocésseur m4

Creation: 8 aout 2019
Mise à jour: 26 octobre 2021
Version: 1.0
Author: Jean-Louis Bicquelet-Salaün
Location: http://jlbicquelet.free.fr
Copyright: (c) 2019 Jean-Louis BICQUELET-SALAÜN


presentation de m4

m4 est un langage de traitement macros. C'est un programme qui existe depuis longtemps (1977) Brian Kernighan et Dennis Ritchie et qui est un macro processeur un peu comme cpp pour le langage C.

m4 permet en particulier:

  • le remplacement de texte ;
  • la substitution de paramètres ;
  • l'inclusion de fichier ;
  • manipulation de chaĂ®nes de caractères ;
  • l'Ă©valuation conditionnelle ;
  • l'Ă©valuation d'expressions arithmĂ©tiques ;
  • l'interfaçage avec le système ;

Parmi les usages courrants on trouve M4 dans Autoconf et dans Sendmail pour générer le fichier de configuration sendmail.cf qui configure vos envoie de mails.

Il n’a pas été ciblé pour un langage informatique particulier. Vous pouvez l'utiliser lorsque vous avez un fichier texte (ou plusieurs) long et répétitif et que vous souhaitez ne plus éditer ce fichier à chaque modification. m4 est une solution à vos problèmes.

m4 est un langage de macro, c'est-à-dire qu'il ne sert qu'à prendre du texte pour générer du texte.

syntaxe de m4

Premier pas

premier programme

m4 recopie tout ce qu'on lui donne, y compris les retours Ă  la ligne, sauf ce qui suit un dnl.

Un commnetaire commence par le caractère #.

Ecrivons un programme debut.m4

dnl #---------------------------
dnl # commentaires
dnl #---------------------------

dnl commentaires
texte
`deuxieme texte'
# troiseme texte

Utilisation de m4

Pour le lancer:

m4 debut.m4

On peut aussi rediriger le résultat dans un fichier

m4 debut.m4 > debut.txt 

On peut preprocesser plusieurs fichiers. En supposant que le fichier htmllib.m4 soit un fichier de macros permettant de générer un fichier html:

m4 htmllib.m4 html.m4 > html.html

on Peut passer des parametres Ă  un fichier m4:

param.m4

param

m4 -Dparam=test param.m4
test

un exemple d'addition par script m4 en passant les valeurs au script:

eval(X+Y)

add.m4

m4 -DX=3 -DY=4 add.m4
7

Attention, les variables sont case sensitives.

macros

La defnition de macro se fait avec le mot cle define. Il faut ajouter dnl si vous ne voulez pas voir afficher votre definition.

debut.m4:

dnl #---------------------------
dnl # commentaires
dnl #---------------------------

dnl commentaires
texte
`deuxieme texte'
# troiseme texte

m4 debut.m4

texte
deuxieme texte
# troiseme texte

macros.m4

define(version,1.0)
define(date,03/08/2019) dnl
version
date

resultat:


 1.0
03/08/2019

exemple d'utilisation de m4

Création d'une page html avec une librairie de macros M4

La librairie htmllib.m4 permet d'utiliser des macros pour préparer un fichier qui une fois passer dans m4 générera un fichier html correspondant.

Exemple test.m4

_HEAD

_B(texte) en _I(italique)

_P

_Start_Table(BORDER=1)
_Table_Hdr(,valeur 1, valeur 2, valeur  3)
_Table_Row(pieces a,100,250,300)
_Table_Row(pieces b,200,500,100)
_Table_Row(pieces c,500,50,90)
_Table_Row(pieces d,,23,2444)
_Table_Row(pieces e,,,20)
_End_Table

_P

cree le syscmd(date /t)
_FOOT

On génére le fichier html:

m4 htmllib.m4 ex.m4 > ex.html

cela donne le resultat suivant:


texte en italique

valeur 1 valeur 2 valeur 3
pieces a 100 250 300
pieces b 200 500 100
pieces c 500 50 90
pieces d 23 2444
pieces e 20

cree le 02/08/2019


Téléchargement

librairieversiondatefichier
test.m41.002/08/2019test.m4
htmllib.m41.002/08/2019htmllib.m4

Création de scripts à partir d'un template m4

On va générer automatique un script bat pour lancer un perl à partir d'un template. Cela fait gagner beaucoup de temps et uniformise vos scripts.

Un premier fichier sert de template.

batch_perl.m4:


@echo off

set PROG=_NOM_.pl
set LOCALPERL=c:\usr\perl\bin\perl
set LOCALBIN=c:\usr\local\bin


if "%1"=="/@" goto description
if "%1"=="/d" goto description
if "%1"=="/?" goto HELP
if "%1"=="/h" goto HELP

if [%1]==[] goto HELP

%LOCALPERL% %LOCALBIN%\%PROG% %*

goto :EOF



:HELP
for /f "tokens=1,* delims=~ " %%A in ('"findstr /b /c:"::h" "%~f0""') do echo.%%B
exit /b

:DESCRIPTION  >> %1.bat 
for /f "tokens=1,* delims=~ " %%A in ('"findstr /b /c:"::d" "%~f0""') do echo.%%B
exit /b 

J'ai pris comme convention que les macros deraient en majuscules bordées de chaque coté par le caractère _.

Le fichier mkbatpl.m4 qui sert Ă  generer le script ressembleĂ  ceci:

dnl #-----------------------------
dnl # definitions
dnl #-----------------------------

define(_NOM_,mkbatpl)dnl
define(_DESCRIPTION_,genere un fichier bat pour lancer un script perl)dnl
define(_CAT_,2html)dnl
define(-LANGAGE_,perl)dnl
define(_AUTEUR_,Jean-Louis Bicquelet)dnl
define(_DATE_,esyscmd(date /t))dnl
define(_VERSION_,1.0)dnl

dnl #-----------------------------
dnl # generation fichier
dnl #-----------------------------
include(tpl\batch_perl.m4)dnl

pour générer le script, il suffit de taper la commande suivante:

m4 mkbatpl.m4 > mkbatpl.bat

Téléchargement

Voici quelques exemples que j'utilise:

librairieversiondatefichier
mkbatpl.m41.002/08/2019mkbatpl.m4
batch_perl.m41.002/08/2019batch_perl.m4
perl.m41.002/08/2019perl.m4