2
0
Fork 0
Verif_Herezh/Perl/genere_catalogue_tests.pl

490 lines
19 KiB
Perl
Executable file
Raw Blame History

#!/usr/bin/perl -s
use strict;
use warnings;
use File::Basename;
use English;
use Encode;
use File::Spec::Functions qw(rel2abs);
use File::Temp qw/ cleanup /;#creation d un repertoire temporaire qui s efface automatiquement en sortie de programme => my ($handle, $nom_rep) = File::Temp->newdir(TEMPLATE => "toto_XXXX");
#fonction cleanup() => appel a cleanup() pour forcer la destruction des repertoires et fichier temporaires
my $NOM_PROG = basename $PROGRAM_NAME;#$NOM_PROG contient le nom de ce script (utile pour afficher le nom du script dans les warning (warn) ou les messages d erreur (die) )
#pattern d un reel pour les regex (pour eviter d utiliser $RE{num}{real} du package Regexp::Common qui n est pas toujours disponible)
my $format_reel = '[+-]?[\.]?\d+[\.]?\d*(?:[eE][+-]?\d*)?';
#####################################################################################################
# script pour generer automatiquement un document pdf qui resume les tests
# disponibles (recopie des rubriques "But du test" et "Description du calcul" du
# fichier README de cahque repertoire de test)
#
# Notes aux utilisateurs :
# les repertoires de tests sont recherches dans toute l arborescence depuis l endroit ou
# ce script est lance (recherche de tous les repertoires commencant par Test_R ou Test_L
# A noter que si un des repertoires n a pas de fichier README, le script s arrete sans
# creation du .pdf
#
# Notes aux developpeurs :
# - l une des plus grandes difficultes est l encodage des fichiers pour gerer les accents
# (en cas de gros probleme, la meilleure solution est de supprimer/remplacer les caracteres
# les plus problematiques des fichiers README)
# - c est difficile d anticiper ce que les gens vont ecrire dans les fichiers README.
# un certain nombre de caracteres ou de groupes de caracteres ne sont pas directement utilisables
# dans un fichier .tex
# (par exemple : <, >, _, etc... ou bien encore les exposants ^3.14159265)
# la gestion de ces caracteres se fait au cas par cas dans la subroutine ecrire_rubrique_README()
# au niveau du bloc suivant (substitution de caracteres s///) :
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
#A FAIRE EVOLUER : gestion au cas par cas des caracteres speciaux dans Latex
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
# ...
# ...
# ...
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
#####################################################################################################
#nom du fichier catalogue de tests
my $NOM_PDF_CATALOGUE = "documentation_tests.pdf";
#encodage du fichier .tex temporaire (pour accepter les accents)
my $ENCODAGE_TEX = 'iso-8859-15';
#########################################################################################################
# verifications prealables
#########################################################################################################
#verif validite de l encodage $ENCODAGE_TEX
@_ = grep {/^$ENCODAGE_TEX$/i} Encode->encodings(":all");
($#_ > -1) or die "\nErreur (prog:$NOM_PROG) : encodage $ENCODAGE_TEX non disponible (changer la variable \$ENCODAGE_TEX dans l en-tete de ce script)...\n\n";
$ENCODAGE_TEX = $_[0];
#verif validite de la commande pdflatex
verif_commande('pdflatex') or die "\nErreur (prog:$NOM_PROG) : commande pdflatex introuvable...\n\n";
#-verif validite de l option -halt-on-error de la commande pdflatex
@_ = qx(pdflatex -help | grep -- -halt-on-error);
($#_ > -1) or die "\nErreur (prog:$NOM_PROG) : commande pdflatex => option -halt-on-error non existante...\n\n";
#########################################################################################################
# liste des repertoires de test
#########################################################################################################
#liste des repertoires de tests rapides (Test_R)
my @REP_TESTS_R = map {chomp($_); $_} qx(find . -name "Test_R*" -type d);
#print "$_\n" for @REP_TESTS_R;
#liste des repertoires de tests rapides (Test_R)
my @REP_TESTS_L = map {chomp($_); $_} qx(find . -name "Test_L*" -type d);
#print "$_\n" for @REP_TESTS_L;
#########################################################################################################
# verification de la presence d un fichier README dans les tests rapides @REP_TESTS_R et les tests longs @REP_TESTS_L
#########################################################################################################
my $is_absence_README = 0;
#-dans les tests rapides
foreach my $rep_test (@REP_TESTS_R,@REP_TESTS_L) {
(-e "$rep_test/README") or do {
print "\n" if(not $is_absence_README);#on passe une ligne si c est le premier repertoire defaillant
warn "Erreur (prog:$NOM_PROG) : repertoire de test $rep_test ne contient pas de fichier README...\n";
$is_absence_README = 1;
};
}
#arret du programme si il y a absence d au moins 1 fichier README
if($is_absence_README) {
print "\n";
print_ligne_pointilles();
print "Erreur (prog:$NOM_PROG) : arret a cause de l absence de fichiers README\n";
print_ligne_pointilles();
die "\n";
}
#########################################################################################################
# generation du catalogue des tests au format .pdf
# rq : generation d un document latex puis d un document .pdf via pdflatex
# a la fin, seul le .pdf restera, tous les fichiers intermediaires seront effaces)
#########################################################################################################
#on va creer un repertoire temporaire qui est sense s effacer automatiquement
# le probleme est que si un signal d interruption est envoye (ctrl-c par exemple), le repertoire ne sera pas efface.
# donc, on va capturer certains signaux pour faire un appel a la subroutine sortie_programme()
$SIG{INT} = \&sortie_programme;#INT => capture signal : ctrl-c ou kill -2
$SIG{TERM} = \&sortie_programme;#TERM => capture signal : kill -15
#remarque : par essence, le signal kill -9 ne peut pas etre capture
#creation d un repertoire temporaire (... qui s effacera automatiquement en sortie de programme grace a l utilisation de la construction objet File::Temp->newdir()
my $rep_tmp = File::Temp->newdir("rep_tmp_".$NOM_PROG.'_XXXXX');
my $racine_fic_latex = "toto";
#deplacement vers le repertoire temporaire
chdir $rep_tmp;
#------------------------------------------------------------------------------------------
#creation du fichier .tex avec encodage $ENCODAGE_TEX (et debut du document : preambule)
#------------------------------------------------------------------------------------------
open(my $HANDLE_TEX, ">:encoding($ENCODAGE_TEX)", "$racine_fic_latex.tex");
preambule_fic_tex_tmp($HANDLE_TEX);
#------------------------------------------------------------------------------------------
#corps du texte (d abord les tests rapides, ensuite les tests longs)
#------------------------------------------------------------------------------------------
#--- tests rapides ---
print $HANDLE_TEX "\\clearpage\\newpage\n";
print $HANDLE_TEX "\\section{Tests rapides}\n";
my $no_test = 0;
foreach my $rep_test (@REP_TESTS_R) {
$_ = $rep_test; s/^\.+\///;
print "ajout test : $_\n";
#incrementation numero test
$no_test++;
#chemin du fichier README
my $fic_README = "../$rep_test/README";
#derniere partie du nom du repertoire
my $nom_test = basename $rep_test;
$nom_test =~ s/_/\$\\_\$/g;#tiret bas entre dollars
#ecriture d une nouvelle sous-section pour ce test
print $HANDLE_TEX "\\subsection{Test\$\\_\$R n\$^\\circ\$$no_test : $nom_test}\n";
#ecriture du nom complet du repertoire sous forme d une arborescence simple
print $HANDLE_TEX "\\noindent \\underline{R\\\'epertoire} :\\\\\n";
my @rep_arbo = split(/\/+/, $rep_test);
shift(@rep_arbo) if($rep_arbo[0] =~ /^\.+$/);#suppression d un eventuel ./ ou ../ devant le nom du repertoire
#--variables pour faire une jolie indentation via \hspace
my $hspace_cm = 0.5;
my $hspace_cm_incr = 0.35;
foreach my $rep_arbo (@rep_arbo) {
$rep_arbo =~ s/_/\$\\_\$/g;
print $HANDLE_TEX "\\hspace*{${hspace_cm}cm}\$\\triangleright\$ $rep_arbo\\\\\n";
$hspace_cm += $hspace_cm_incr;
}
#saisie de l encodage du README (par defaut : rien) (rq : on utilise la commande linux/Unix "file")
my $encodage_source = '';
#cas UTF-nombre (exemples : UTF-8, UTF-16, etc...)
if(qx(file $fic_README) =~ /utf-(\d+)/i) {
$encodage_source = ":encoding(UTF-$1)";
}
#ecriture de la partie "But du test"
ecrire_rubrique_README($fic_README, $encodage_source, $HANDLE_TEX, qw(But du test) );
#ecriture de la partie "Description du calcul"
ecrire_rubrique_README($fic_README, $encodage_source, $HANDLE_TEX, qw(Description du calcul) );
}
#--- tests longs ---
print $HANDLE_TEX "\\clearpage\\newpage\n";
print $HANDLE_TEX "\\section{Tests longs}\n";
$no_test = 0;
foreach my $rep_test (@REP_TESTS_L) {
$_ = $rep_test; s/^\.+\///;
print "ajout test : $_\n";
#incrementation numero test
$no_test++;
#chemin du fichier README
my $fic_README = "../$rep_test/README";
#derniere partie du nom du repertoire
my $nom_test = basename $rep_test;
$nom_test =~ s/_/\$\\_\$/g;#tiret bas entre dollars
#ecriture d une nouvelle sous-section pour ce test
print $HANDLE_TEX "\\subsection{Test\$\\_\$L n\$^\\circ\$$no_test : $nom_test}\n";
#ecriture du nom complet du repertoire sous forme d une arborescence simple
print $HANDLE_TEX "\\noindent \\underline{R\\\'epertoire} :\\\\\n";
my @rep_arbo = split(/\/+/, $rep_test);
shift(@rep_arbo) if($rep_arbo[0] =~ /^\.+$/);#suppression d un eventuel ./ ou ../ devant le nom du repertoire
#--variables pour faire une jolie indentation via \hspace
my $hspace_cm = 0.5;
my $hspace_cm_incr = 0.35;
foreach my $rep_arbo (@rep_arbo) {
$rep_arbo =~ s/_/\$\\_\$/g;
print $HANDLE_TEX "\\hspace*{${hspace_cm}cm}\$\\triangleright\$ $rep_arbo\\\\\n";
$hspace_cm += $hspace_cm_incr;
}
#saisie de l encodage du README (par defaut : rien) (rq : on utilise la commande linux/Unix "file")
my $encodage_source = '';
#cas UTF-nombre (exemples : UTF-8, UTF-16, etc...)
if(qx(file $fic_README) =~ /utf-(\d+)/i) {
$encodage_source = ":encoding(UTF-$1)";
}
#ecriture de la partie "But du test"
ecrire_rubrique_README($fic_README, $encodage_source, $HANDLE_TEX, qw(But du test) );
#ecriture de la partie "Description du calcul"
ecrire_rubrique_README($fic_README, $encodage_source, $HANDLE_TEX, qw(Description du calcul) );
}
#------------------------------------------------------------------------------------------
#fin de l ecriture du fichier .tex : ajout de end{document}
#------------------------------------------------------------------------------------------
print $HANDLE_TEX "\\end{document}\n";
close($HANDLE_TEX);
#------------------------------------------------------------------------------------------
#compilation pdflatex (1 premiere fois pour voir si ca marche et une 2eme fois pour generer la table des matieres et les hyperliens
#------------------------------------------------------------------------------------------
print "\n";
print "compilation pdflatex (1ere fois)\n";
#-1ere comilation (pdflatex avec option -halt-on-error pour forcer a quitter a la moindre erreur)
system("pdflatex -halt-on-error $racine_fic_latex.tex > toto.log");
#-verif presence .pdf
if(not -e "$racine_fic_latex.pdf") {
warn "\nErreur (prog:$NOM_PROG) : erreur a l execution de pdflatex.\n";
warn " Les fichiers suivants ont ete cree a des fins de debug :\n";
warn " - $NOM_PDF_CATALOGUE.tex (fichier .tex donne en argument de pdflatex)\n";
warn " - $NOM_PDF_CATALOGUE.error_log (affichage renvoye par pdflatex)\n";
warn "\n";
system("mv -f $racine_fic_latex.tex ../$NOM_PDF_CATALOGUE.tex");
system("mv -f toto.log ../$NOM_PDF_CATALOGUE.error_log");
chdir "..";
sortie_programme();
}
#-2eme compilation (etant donne que ca a marche la 1ere fois, pdflatex ne peut pas echouer cette 2eme fois)
print "compilation pdflatex (2eme fois)\n";
system("pdflatex $racine_fic_latex.tex > toto.log");
#deplacement du catalogue final vers le repertoire de depart sous le nom prevu par la variable $NOM_PDF_CATALOGUE
system("mv -f $racine_fic_latex.pdf ../$NOM_PDF_CATALOGUE");
#retour au repertoire de depart
chdir "..";
#affichage fin programme
print "\n";
print_ligne_pointilles();
print "Le fichier $NOM_PDF_CATALOGUE a ete cree...\n";
print_ligne_pointilles();
print "\n";
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#remarque : fin du programme => le repertoire temporaire $rep_tmp sera efface automatiquement
# car utilisation de File::Temp->newdir()
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#--------------------------------------------------
#subroutine de sortie du programme
#--------------------------------------------------
sub sortie_programme {
#effacement du repertoire temporaire (subroutine cleanup() du package File::Temp)
cleanup();
exit;
}
#--------------------------------------------------
#subroutine qui ecrit une rubrique du fichier du README
#--------------------------------------------------
sub ecrire_rubrique_README {
my $fic_source = shift;
my $encodage_source = shift;
my $handle_fic_destination = shift;
my @mots_rubriques = @_;
my $regexp = shift(@mots_rubriques);
foreach my $mot (@mots_rubriques) {
$regexp .= '\s+'."$mot";
}
open(my $Hlocal, "<$encodage_source", "$fic_source");
while(<$Hlocal>) {
next if(not /^\s*$regexp\s*$/i);
$_ = <$Hlocal>;
print $handle_fic_destination "\\subsubsection{Description du calcul}\n";
while(<$Hlocal>) {
last if(/^\s*-+$/);
chomp();
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
#A FAIRE EVOLUER : gestion au cas par cas des caracteres speciaux dans Latex
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
s/_/\$\\_\$/g;#tiret bas (solution : entre dollars)
s/\^($format_reel)/\$\^$1\$/g;#cas d un exposant mathematique : symbole circonflexe suivi d un nombre (solution : entre dollars)
s/([<>])/\$$1\$/;#symboles inferieur et superieur (solution : entre dollars)
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
print $handle_fic_destination "$_\\\\\n";
}
last;
}
close($Hlocal);
}#sub ecrire_rubrique_README
#--------------------------------------------------
#subroutine permettant d ecrire une ligne de pointilles de la largeur du terminal
#--------------------------------------------------
sub print_ligne_pointilles {
use Term::ReadKey;
my $nb_char_largeur_terminal = ( GetTerminalSize() )[0];
my $ligne_pointilles = '';
$ligne_pointilles .= '-' for(1 .. $nb_char_largeur_terminal);
print "$ligne_pointilles\n";
}#sub print_message_avec_pointilles
#--------------------------------------------------
#subroutine d ecriture du preambule du fichier .tex temporaire
#--------------------------------------------------
sub preambule_fic_tex_tmp {
my $handle = shift;
print $handle '\documentclass[a4paper,12pt]{scrartcl}
\usepackage[latin1]{inputenc}
\usepackage[francais]{babel}
\usepackage{epsfig,color}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{fancybox}
\usepackage{wrapfig}
%\usepackage{pslatex}
\usepackage{amsmath}
\usepackage{subfigure}
%\usepackage{/Users/troufflard/LATEX/BIBLIOTHEQUE/macro_figure}
%\usepackage{eurosym}
\usepackage{calc}
%\usepackage{t1enc}
\usepackage{ifthen}
\usepackage{lscape}
\usepackage{tabularx}
\usepackage{multirow}
\usepackage{colortbl}
%\newcolumntype{M}[1]{>{\raggedright}m{#1}}
\usepackage{tikz}
\usetikzlibrary{trees}
\addto\captionsfrench{\def\figurename{Figure}}
\addto\captionsfrench{\def\tablename{Tableau}}
%\usepackage{hangcaption}
\oddsidemargin 0.1cm
\evensidemargin -0.9cm
\topmargin -1cm
\headsep 1cm
\textwidth 17cm
\textheight 24cm
\parindent 0.5cm
\raggedbottom
\sloppy
\setcounter{tocdepth}{2}
\usepackage{hyperref}
\hypersetup{
colorlinks=true, %colorise les liens
breaklinks=true, %permet le retour <20> la ligne dans les liens trop longs
urlcolor= blue, %couleur des hyperliens
linkcolor= blue, %couleur des liens internes
citecolor= green %couleur citation biblio
}
%creation d une longueur egale a \baselineskip pour l utiliser dans les tabular (car un bug incroyable fait que \baselineskip est egal a 0 dans les tabular!!!!)
\newlength{\savebaselineskip}
\setlength{\savebaselineskip}{\baselineskip}
\title{Catalogue des tests}
\date{\today}
%\pagestyle{arabic}
\pagenumbering{arabic}
\begin{document}
\maketitle
\tableofcontents
';
}#sub preambule_fic_tex_tmp
#####################################################################################################
#subroutine qui recherche l existence d une commande et renvoie le premier path trouve (renvoie 0 si commande introuvable)
#####################################################################################################
# en entree :
# - nom de la commande
#
# en sortie :
# - chemin aboslu de la commande (0 si commande introuvable)
#
sub verif_commande {
my $cmd = shift;#nom de la commande
#cas d un chemin absolu ou relatif (si la commande commence par . ou /. Par exemple : ./HZpp ../HZppfast ou /Users/dupont/bin/HZppfast)
if($cmd =~ /^\./ or $cmd =~ /^\//) {
#on passe la commande en chemin absolu
$cmd = rel2abs($cmd);
return $cmd;
}
#sinon on regarde dans la variable environnement $PATH
foreach my $path (split(/\s*:\s*/, $ENV{PATH})) {
if(-x "$path/$cmd") {
#on s assure que c est un chemin absolu
$cmd = rel2abs("$path/$cmd");
return $cmd;
}
}
#on regarde a nouveau si la commande est en chemin absolu ou relatif
# (cas d une commande qui ne commence pas par . ou / et qui n est pas dans les PATH. Par exemple : rep/HZpp)
if(-x $cmd) {
#on passe la commande en chemin absolu
$cmd = rel2abs($cmd);
return $cmd;
}
#cas ou la commande est introuvable
return 0;
}#sub verif_commande