Pourquoi ajouter des modules ?
Il est aisé d'extraire des fichiers, des lignes complètes, contenant une chaîne déterminée de caractères. Voir la commande Grep et Awk.
Les fichiers de textes sont de plus en plus compliqués, il est difficile d’extraire des blocs de commentaires débarrassés des signes de balisage; d'où l'intérêt de créer des modules adaptés aux langages de programmation ou d'éditions utilisant des balises; Postscript, SGML et autres méta langages; Xml, Html, ... .
Comment ajouter un module ?
Quel langage de programmation ?
Tous les langages de programmation peuvent convenir à condition qu'ils soient compilable avec gcc pour produire des fichiers objets liables entre eux (linkables)
Définir le module.
Il faut déterminer quel est le style de commentaire à extraire.
Repérer éventuellement un fichier similaire existant. Il existe en standard des modules d' "extraction de lignes" et des modules d' "extraction de blocs".
Certains fichiers ont des commentaires plus compliqués comme : avec quatre caractères voire plus. Dans des cas plus complexes il pourrait être préférable de repérer des chaînes de caractères plutôt que des caractères ASCII. Ceci aurait l'avantage d'être adapté aux caractères asiatiques en UTF 8, 16, ou 32 avec des chaînes de caractères données paramètres d'entrée.
Créer le pseudo-code.
Le pseudo code que nous utilisons est un commentaire qui va décrire ce que l'on fait et ce que l'on doit obtenir, ce qu'il faut faire dans certaines conditions comme créer une boucle jusqu'à ce que l'on obtienne ce que l'on cherche. 
Il y a de nombreux ouvrages qui décrivent les manières de programmer. Le plus célèbre est sans aucun doute la méthode Merise pour la programmation impérative.
Il est préférable d'écrire le pseudo code avant d'écrire les lignes de codes.
 //O Ceci est un pseudo code style C++
 std::cout « "Unable to open file "« fprj « std::endl; // message to stdout
Examinez les fichiers à disposition pour avoir une meilleure idée de l'utilisation du pseudo code.
Intégration des lignes de codes.
Langue de programmation et internationalisation.
Nous utilisons gettext pour adapter les messages aux différentes langues parlées.
Pour que l'on puisse facilement traduire les messages il convient de les écrire en anglais US (ASCII).
Les divers caractères accentués des langues européennes ne sont pas si faciles à traduire.
Compilation de l'unité de test.
Les options du fichier version.h.
Le fichier d'entête version.h est utilisé pour compiler la série d'applications dérivées de la commande mkd.La vérification des options est indispensable avant toute compilation.
/*P
 NOM DU FICHIER: version.h
 PROJET INITIAL: mkd console linux & MSDOS
 DOSSIER INITIAL : mkdoc3.12 Centre d’Électronique de Montpellier
 PROGRAMMEUR: JPL 
 DATE: 18/12/2009
 MODIFICATIONS:
 le: 09/01/2011 par JPL objet: Ajouté l'option de compilation pour MSDEV41
 le: 10/01/2012 par JPL objet: Ajouté la définition std_C pour compilation UNIX STD
 le: 25/03/2012 par Clara objet: internationalisation
 le: 27/03/2012 par jpl objet: internationalisation en utf-8
 le: 10/04/2013 par Cardabela: Modification mineure. Alignement des commentaires.
// le: ../../.. par ... objet de la modification ...
/**# MKD.C ############################*/ /*H*/
/*U UTILISATEURS */ /*H*/
/*O ORGANIGRAMME */ /*H*/
/*S STRUCTURE */ /*H*/
/*T TESTS */ /*H*/
/*P PROGRAMMEUR */ /*H*/
/*www remarques particulières */ /*H*/
/**####################################*/ /*H*/
// define VERSION line 173
//#define GTKMM /*O Version fenêtrée avec gtkmm pour mkdcppw uniquement */
/*#define PC_ONLY*/ /*H find_ ne reconnaît pas: .s .f .p .sh .csh */
//#define VC10 /*O Microsoft Visual C 10.- */
 /*H*/
 /*H*/
/*H #D *************************************************************************************/
/*H *** #Define OPTIONS DE COMPILATION: options par défaut, redéfinissables: **************
 (#D pour l'extraction des options de compilation en ligne avec l'option CD3='#') */
/*H****************** #Define 'l' (ligne) commence par #define en 1ère colonne : ***********/
 /*H #Define Option '%' commentaire postcript */
 /*H #Define Option '#' commentaire shell ou pour Makefile voir option S
 #D ( le commentaire se termine avec new_line ) */
 /*H #Define Option '\" commentaires Basic */
 /*H #Define Option ';' commentaires assembleur */
/*H ***************** #Define Option 'p' (dans la page) #define en 1ère colonne : **********/
 /*H #Define **************************************************************/
/*H #D *************************************************************************************/
/*U*** MKD ********************************************************************
 /*H*/
 /*H*/
 /*H*/
 #define putch _putch /*H ISO C++ */
 #define getch _getch /*H ISO C++ */
 #define access _access /*H ISO C++ */
 /*H*/
 //#define STD_C /*H SVr4, 4.3BSD, C89, C99.*/
 #include <string.h> /*H*/
 /*H*/
 #define bool int
 //#define STD_C /*H SVr4, 4.3BSD, C89, C99.*/
 /*#define getch() getchar()*/
 #define putch putchar /*H*/
La fonction maîtresse - main().
La fonction main doit ouvrir les fichiers source et cible et transmettre l'adresse de ces fichiers ouverts à la fonction à éprouver (tester).
Elle doit en retour, s'il y a lieu, d'afficher la valeur de retour de fonction à défaut de d'afficher un message correspondant à cette valeur de retour.
Il n'est pas interdit d'ouvrir "en dur" toujours les mêmes fichiers source et cible, cela dépend des tests demandés.
L'essentiel pour les tests unitaires est de répondre aux directives. Il peut cependant être nécessaire d'entrer des arguments comme n, s, t par exemple pour l'épreuve de la fonction cpp_() que nous prenons souvent en exemple.
// #include "" // entête du fichier à tester app.h si la fonction est indépendante comme cpp.c
// #include "" // fichier de la fonction app.i si la fonction doit être incluse
// Variables globales:
 unsigned char A,B,C,F,P,S,a,f,j,l,n,p,s,t,v,w;
 char codes[5] = {0,0,0,0,0};
//*O Début de la fontion main():
 int main(int argc, char **argv)
 //O Déclarations
 int ret=0;
 char fsrc[MAX]; /* Nom du fichier source */
 char fdoc[MAX]; /* Nom du fichier cible */
 FILE *pnfile; /* FICHIER A EXTRAIRE */
 FILE *pfdoc; /* FICHIER A DOCUMENTER */
 //O Pseudo code des instructions
 return ret;
//*O Fin de la fontion main()
Exemple complet avec mkdcpp (Éditeur ISO-8859-1)
//O Programme de tests de la fonction cpp_()
// Variables globales
 unsigned char n=0,s=0,t=0,v=0; /*P déclaration et initialisation des variables */
 char codes[5] = {0,0,0,0,0}; /*P version qui copie les codes avec l'option t dans cpp_()
 Il peut être nécessaire de modifier les lignes ~161 dans cpp.c */
 // char codes[5] = {' ',' ',' ',' ',' '}; /*P version qui copie les commentaires après le caractère ' ' dans cpp_()*/
int main(int argc, char *argv[])
// char *fprj= ""; /*P nom fichier projet s'il existe */
 char fdoc[MAX]; /*P nom fichier documentaire en sortie */
// char fdoc[] = "C++_doc.txt"; /*P nom fichier documentaire en sortie */
 char fsrc[MAX]; /*P nom fichier source a documenter */
// char fsrc[] = ".\\C++_FILE.a"; /*P nom fichier source a documenter */
 extern char codes[]; /*P codes */
 extern unsigned char A,B,C,F,P,S,a,f,j,l,n,p,s,t,v,w; /*P rappels options booléennes */
/*O init options par défaut */
//?? {n=0;s=0;t=0;v=0;} /*O option v = 0 (verbose) de compilation; v n'est pas utilisé dans cpp_() */
// O=0; /* Option=0 */
 int i=0; /*P compteurs */
 int k=0;
 char isource=0; /*P position nom du fichier source dans path source */
 char itarget=0; /*P position fin du path_target avec '*' ou ':'(PC) */
 char ktar=0; /*P position du '.' dans p_target */
 static char O; /*P booleen =1 si option validee */
 static char L; /*P booleen =1 si option langage */
 register int c=0; /*P char (variable) */
 int c1=0; /*P char (variable) pour version PC */
// FILE *pfprj; /*P FICHIER PROJET */
 FILE *pnfile; /*P FICHIER SOURCE A TRIER */
 FILE *pfdoc; /*P FICHIER A DOCUMENTER */
 printf("Epreuve de cpp.c ; mkdcpp version 01/2011 compilation avec MSDEV41 pour x86-32 (Windows XP a Windows 7\n");
 printf("Debug cpp.c ; mkdcpp version 01/2011 compiled with MSDEV41 for x86-32 (Windows xp to Windows 7\n");
 printf("argv[0] = %s\n",argv[0]); /*T*/
 if (argc > 1) printf("argv[1] = %s\n",argv[1]); /*T*/
 if (argc > 2) printf("argv[2] = %s\n",argv[2]); /*T*/
 if (argc > 3) printf("argv[3] = %s\n",argv[3]); /*T*/
/*O Si la syntaxe n'est pas correcte (argc <2) "mkdcpp [--nst] [-Code(DHOPSTUw)] Source_cpp" */
 if (argc < 2) 
/*O Alors Préciser la syntaxe et quitter sur erreur de syntaxe -1*/
 { /*S syntaxe intégrée */
//#ifdef FR
 printf("Syntaxe : %s [--Options(nst)] [-5 Codes(DHOPSTUw)] source_cpp\n",argv[0]);
 printf("Appuyer sur la touche 'Entree' pour quitter.\n\n");
//#endif
//#ifdef EN
 printf("Syntax: %s [--Options(nst)] [-5 Codes(DHOPSTUw)] cpp_source\n",argv[0]);
 printf("Press 'Enter' to quit.\n");
//#endif
 getc(stdin); // attente touche 'Entrée' */ 
 exit(-1);
 } /*S syntaxe intégrée */
/*O si argc = 2 (source cpp en premier paramètre) */
 if (argc == 2)
 { /*S argc = 2 */
 if (strcpy_s(fsrc,argv[1])!=0) /*w strcpy_s : évite l'erreur overflow */
 if (strcpy(fsrc,argv[1])==NULL)
 printf("Err SRC : %d chars max\n",MAX);
 exit(-1);
 else
 { /*S*/
 strcpy_s(fdoc,argv[1]); /*w strcpy_s : évite l'erreur overflow */
 strcat_s(fdoc,".txt");
 strcpy(fdoc,argv[1]); 
 strcat(fdoc,".txt");
 printf("SRC = %s\n",fsrc); /*T*/
 printf("DST = %s\n",fdoc); /*T*/
 printf("argc=2 - Options n=%d,s=%d,t=%d,v=%d Codes %c,%c,%c,%c,%c\n",n,s,t,v,codes[0],codes[1],codes[2],codes[3],codes[4]); /*T*/
 } /*S*/
 } /*S argc = 2 */
/*O si argc = 3 (option ou code) */
 if (argc == 3)
 { /*S argc = 3 */
 if (argv[1][0]=='-' && argv[1][1]=='-') /*O Options ! */
 { /*S Options */
 int i;
 // printf("argv[1][0]=%c - argv[1][1]=%c\n",argv[1][0],argv[1][1]); /*T*/
 for (i=0 ; i<4 && (argv[1][(i+2)]!=0) ; i++) 
 { /*S*/
 if (argv[1][(i+2)]=='n') n=1; /*O n,s,t sont des variables globales */
 else if (argv[1][(i+2)]=='s') s=1; /*O*/
 else if (argv[1][(i+2)]=='t') t=1; /*O*/
 else if (argv[1][(i+2)]=='v') v=1; /*O*/
 // printf("argv[1][%d]=%c & n=%c, s=%c, t=%c\n",(i+2), argv[1][i+2],n,s,t); /*T*/
 } /*S*/
 } /*S Options */
 else if (argv[1][0]=='-' && argv[1][1]!='-') /*O Codes ! */
 { /*S Codes */
 int i;
 for (i=0 ; i<5 && (argv[1][i+1]!=0) ; i++) codes[i]=argv[1][i+1]; /*O affectation */ 
 } /*S Codes */
 else /*O sinon erreur de syntaxe */
 { /*S*/
 puts("Options ? || Codes ?\n"); /*O*/
 exit(-1); /*O*/
 } /*S*/
/*O affectation du nom de fichier (.cpp) au nom de fichier destinataire, et ajouter .txt */
 if (strcpy_s(fsrc,argv[2])!=0)
 if (strcpy(fsrc,argv[2])==NULL)
 { /*S*/
 printf("Err SRC : %d chars max\n",MAX);
 exit(-1);
 } /*S*/
 else
 { /*S*/
 strcpy_s(fdoc,argv[2]);
 strcat_s(fdoc,".txt");
 strcpy(fdoc,argv[2]); 
 strcat(fdoc,".txt");
 printf("SRC = %s\n",fsrc); /*T*/
 printf("DST = %s\n",fdoc); /*T*/
 printf("argc=3 - Options n=%d,s=%d,t=%d,v=%d Codes %c,%c,%c,%c,%c\n",n,s,t,v,codes[0],codes[1],codes[2],codes[3],codes[4]); /*T*/
 } /*S*/
 } /*S argc = 3 */
/*O si argc = 4 (options et code) */
 if (argc == 4)
 { /*S argc = 4 */
 if (argv[1][0]=='-' && argv[1][1]=='-') /*O Options */
 { /*S Options */
 int i;
 for (i=0 ; i<4 && (argv[1][i+2]!=0) ; i++) 
 { /*S*/
 if (argv[1][i+2]=='n') n=1; /*O n,s,t sont des variables globales */
 else if (argv[1][i+2]=='s') s=1;
 else if (argv[1][i+2]=='t') t=1;
 else if (argv[1][(i+2)]=='v') v=1;
 } /*S*/
 } /*S Options */
 else
 { /*S err */
 puts("Options ?\n");
 exit(-1);
 } /*S err */
 if (argv[2][0]=='-' && argv[2][1]!='-') /*O Codes */
 { /*S Codes */
 int i;
 for (i=0 ; i<5 && (argv[2][i+1]!=0) ; i++) codes[i]=argv[2][i+1]; 
 } /*S Codes */
 else /*O erreur de syntaxe */
 { /*S*/
 puts("Codes ?\n");
 exit(-1);
 } /*S*/
 if (strcpy_s(fsrc,argv[3])!=0)
 if (strcpy(fsrc,argv[3])==NULL)
 { /*S*/
 printf("Err SRC : %d chars max\n",MAX);
 exit(-1);
 } /*S*/
 else
 { /*S*/
 strcpy_s(fdoc,argv[3]);
 strcat_s(fdoc,".txt");
 strcpy(fdoc,argv[3]);
 strcat(fdoc,".txt");
 printf("SRC = %s\n",fsrc); /*T*/
 printf("DST = %s\n",fdoc); /*T*/
 printf("argc=4 - Options n=%d,s=%d,t=%d,v=%d Codes %c,%c,%c,%c,%c\n",n,s,t,v,codes[0],codes[1],codes[2],codes[3],codes[4]); /*T*/
 } /*S*/
 } /*S argc = 4 */
/*O ouvrir le fichier source en lecture binaire*/
 { /*S démarrage du test */
/*O si l'ouverture du fichier source n'est pas correcte */
 if (fopen_s(&pnfile, fsrc,"rb") !=0 )
 if (( pnfile = fopen ( fsrc,"rb" )) == 0 ) // old syntax 
 { /*S ! open source pnfile */
/*O ecrire fichier "nomfich" non trouvé ou erreur d'ouverture */
 printf ("fichier \'%s\' : non trouvé ou erreur d'ouverture\n",fsrc);
 puts("Tapez sur la touche 'Entrée' pour quitter\n\n");
 printf ("file \'%s\' : non found or open error\n",fsrc);
 puts("Press 'Enter' to quit.\n");
 getchar();
 exit(2);
 } /*S ! open source pnfile */
/*O sinon, ouvrir le fichier à documenter en écriture ou réécriture */
 else
 { /*S open pfdoc write */
/*O si il y a une erreur à l'ouverture l'écrire et quitter en renvoyant le code d'erreur 2 */
 if((fopen_s(&pfdoc,fdoc,"wb")) != 0)
 if((pfdoc = fopen(fdoc,"wb")) == NULL) // old syntax
 { /*S si err à l'ouverture de pfdoc*/
 printf("fichier \'%s\' : erreur d'ouverture en écriture\n",fdoc);
 puts("Tapez sur la touche 'Entrée' pour quitter\n\n");
 printf("file \'%s\' : open error\n",fdoc);
 puts("Press 'Enter' to quit.\n");
 getchar();
 exit(-2);
 } /*S si err à l'ouverture de pfdoc*/
 else
 { /*S sinon*/
/*O si options n ou v ou s et pas t écrire le nom du fichier lu */
 if(n||v||s)
 { /*S si n ou v ou s valide */
 if (!t) fprintf(pfdoc,"%s\n(file %s :)", NL, fsrc );
 if( v || s ) printf("\n\n(file %s :)\n",fsrc);
 if (!t)fprintf (pfdoc," Options n=%d s=%d t=%d verbose=%d",n,s,t,v);
 if (!t)fprintf (pfdoc, "%s", NL );
 } /*S si n ou v ou s valide */
 } /*S sinon*/
 } /*S open pfdoc write */
 cpp_(pfdoc,pnfile);
/*O fermer le fichier source et en cas d'erreur écrire "Erreur de fermeture */
 if (fclose(pnfile))
 { /*S si*/
 printf("Erreur de fermeture : \'%s\'\n",fsrc);
 printf("Error on closed : \'%s\'\n",fsrc);
 exit(2);
 } /*S fin si*/
/*O Fermer tous les autres fichiers */
 { /* fermer */
 int numclosed = _fcloseall( );
 printf( "Nombre de fichiers fermés par _fcloseall : %u\n", numclosed );
 printf( "Number of files closed by _fcloseall: %u\n", numclosed );
 } /* fermer */
 } /*S demarrage du test */
 puts("Tapez sur la touche 'Entrée' pour quitter\n");
 puts("Press 'Enter' to quit.\n");
 getchar(); 
 return 0;
} /*O main Test */
Le Makefile pour la compilation de l'unité.
Le makefile suivant, mkdcpp.mak complet pour une installation standard a été bridé pour les tests unitaires.
 ### UNIX version ###
CC = gcc
MKDOC = mkd
PGM = mkdcpp
BINDIR = #/usr/bin
BINMODE = 755
MAN = mkdcpp.1.gz
LANG = F
MANDIR = /usr/local/man
MANMODE = 644
SRCS = mkdcpp.c cpp.c
HDRS = version.h cpp.h
OBJS = cpp.o mkdcpp.o
LIBS =
CFLAGS = -O
LDFLAGS =
SPLINTFLAG = -weak -nestcomment
install: $(BINDIR)/$(PGM) #$(MANDIR)/$(MAN)
$(BINDIR)/$(PGM): $(SRCS) $(HDRS)
 -@echo "*********** update $(PGM) ***********"
 $(CC) -c cpp.c mkdcpp.c
 @#$(CC) $(CFLAGS) -o $(PGM) $(SRCS)
 $(CC) $(LDFLAGS) -o $(PGM) $(OBJS) $(LIBS)
 -@strip $(PGM) #clean ASM and LINK reloc.
 -@echo " -- update $(BINDIR)/$(PGM):" #install pgm
 -@if [ -d $(BINDIR) ]; then \
 cp -f $(PGM) $(BINDIR)/$(PGM);\
 chmod $(BINMODE) $(BINDIR)/$(PGM);\
 if [ $(BINDIR) != "/bin" ]; then \
 ln -s $(BINDIR)/$(PGM) /bin/$(PGM);\
 fi \
 else \
 echo "couldn't find $(BINDIR)";\
 fi
$(MANDIR)/$(MAN): manuel
 -@echo "*********** update $(MAN) ***********"
 #-$(MKDOC) -Ctw M manuel $(PGM).1
 -$(MKDOC) -Ctw $(LANG) manuel $(PGM).1
 #mkdcpp --t -$(LANG) manuel | mv manuel.txt $(PGM).1
 -@gzip $(PGM).1
 -@echo " -- update $(MANDIR)/$(MAN):" #install manual
 -@if [ -d $(MANDIR) ]; then \
 cp -f $(MAN) $(MANDIR)/$(MAN);\
 chmod $(MANMODE) $(MANDIR)/$(MAN);\
 echo " -- update $(CATMANDIR):";\
 catman -M $(MANDIR)/$(MAN) 1;\
 else \
 echo "couldn't find $(MANDIR)/$(MAN)";\
 fi
lint:
 -@echo "*** lint -> warnings (file), lint n'existe plus ... ! installez splint ***"
 splint $(SPLINTFLAGS) $(SRCS) > warnings
 more warnings
clean:
 #rm -f $(PGM) $(OBJS) $(MAN)
Épreuve unitaire.
Éprouver le module (Test unitaire).
Le répertoire des tests unitaire se compose:
Exemple pour le Styles C.
Fichiers de tests unitaires de la fonction cpp_() dans mkd
//T File Test_cpp_U.cc to test function cpp_()
/*P
 Fonction cpp_(); Fichier cpp.c
 Directives de tests unitaires version alpha 2013:
 Vérifiez les options n, s et t séparément:
 Vérifiez que la numérotation des lignes est correcte dans tous les cas de
 décodage (lignes et blocs). n, ns. nt, nst.
 Vérifiez que le texte reste à la bonne place dans tous les cas de décodage:
 toute la ligne (dans la cas de la directive de compilation FULL_LINE), ou 
 texte seul.
 -- Vérifiez que les tabulations sont bien prises en charge dans tous les 
 cas, décodage des lignes et des blocs.
 -- Vérifiez de même pour les espaces.
 La fonction doit être éprouvée de telle sorte qu'un commentaire qui se 
 termine par le caractère de fin de fichier soit entièrement copié dans le
 fichier cible.
 Le caractère de fin de fichier décodé avant le(les) caractère(s) de fin de
 commentaire doit être remplacé par un caractère de fin de ligne.
 Le caractère de fin de fichier (EOF) NE DOIT JAMAIS APPARAÎTRE DANS LE
 TEXTE DU FICHIER CIBLE.
 Ceci provoquait un bug dans la version Alpha de l'application fenêtrée
 mkdcppw à l'étape du test d'intégration.
/*T
12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
/*T
12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
 //T test in ligne with 2 tabulations
 //T test in ligne with 5 spaces
/*T test bloc in first line end bloc*/
/*T test bloc in first line
 with 2 tabs
 with 5 spaces end bloc */
/*T
12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
 /*T test bloc in line with 2 tabs end bloc*/
 /*T test bloc in line 
 2 tabs
 with 5 spaces
 end bloc */
//T see also "/*T" with out end of block comment and EOL in file Test_cpp_U.c
//T test inline with out end of line (EOL)(NL)(CR/LF)
File Test_cpp_U.c
//T File Test_cpp_U.c
/*T with out end of block comment and EOL (NL) in file Test_cpp_U.c
File Tests
 cat Test_cpp_U.cc > Test_cpp_U.tstcpp
 mkd -savC T Test_cpp_U.cc *.tstcpp > tstcpp.screen
 mkd -tavC T Test_cpp_U.cc *.tstcpp # » tstcpp.screen
 mkd -navC T Test_cpp_U.cc *.tstcpp # » tstcpp.screen
 mkd -nsavC T Test_cpp_U.cc *.tstcpp » tstcpp.screen
 mkd -ntavC T Test_cpp_U.cc *.tstcpp » tstcpp.screen
 mkd -nstavC T Test_cpp_U.cc *.tstcpp » tstcpp.screen
 mkd -nstvwC T Test_cpp_U.cc *.tstcpplastline1 > tstcpplastline.screen1
 gedit Test_cpp_U.tstcpp
 gedit tstcpp.screen
 gedit Test_cpp_U.tstcpplastline1
File Tests_Clean
 rm -f Test_cpp_U.tstcpp
 rm -f tstcpp.screen
 rm -f Test_cpp_U.tstcpplastline1
 rm -f tstcpplastline.screen1
 rm -f Test_cpp_U.tstcpplastline2
 rm -f tstcpplastline.screen2
 rm -f *.doc
Analyse des tests unitaires.
Éprouver le module unitaire nécessite de répondre aux recommandations des tests contenus dans la documentation.
Exemple de fichier Analysis
Fichier Analysis texte UTF-8
Analyse du : 4 avril 2013 par Clara pour le retour à la conception détaillée.
Résultats du test unitaire de la fonction cpp_() du fichier cpp.c intégrée à 
la commande mkd 2012: mkd_120508
Ce test est effectué avec la version mkd 2012 pour évaluer les modifications
à effectuer dans la version alpha 2013.
Note : Nous n'avons pas effectué ce test avec les commandes mkdcpp et mkdcppw
qui aboutiraient aux mêmes résultats.
 D'après les directives et les fichiers d'analyse Test_cpp_U.tstcpp et
 tstcpp.screen
 Directives de tests unitaires version alpha 2013:
1: Vérifiez les options n, s et t séparément:
 - les essais séparés fonctionnent correctement et sont conformes
2: Vérifiez que la numérotation des lignes est correcte dans tous les cas de
 décodage (lignes et blocs). n, ns. nt, nst.
 - Les essais réalisés ont été conformes
3: Vérifiez que le texte reste à la bonne place dans tous les cas de décodage:
 toute la ligne (dans la cas de la directive de compilation FULL_LINE), ou 
 texte seul.
 - Le résultat est conforme (Sans la numérotation des lignes)
4: -- Vérifiez que les tabulations sont bien prises en charge dans tous les 
 cas, décodage des lignes et des blocs.
 -- Vérifiez de même pour les espaces.
 - Les résultats sont conformes. Il est à noter que les tabulations créent un
 décalage du texte avec l'option -n numérotation
 La réponse aux épreuves 4 est "conforme".
5: La fonction doit être éprouvée de telle sorte qu'un commentaire qui se 
 termine par le caractère de fin de fichier soit entièrement copié dans le
 fichier cible.
 Le caractère de fin de fichier décodé avant le(les) caractère(s) de fin de
 commentaire doit être remplacé par un caractère de fin de ligne.
 - Le fichier Test_cpp_U.tstcpplastline1 commentaire ligne; fait apparaître
 une fin de fichier conforme.
 - Le fichier Test_cpp_U.tstcpplastline2 commentaire bloc; n'a pas été 
 réalisée (erreur EOF avec une boucle sans fin)
 La réponse à l'épreuve 5 est "non conforme".
6: Le caractère de fin de fichier (EOF) NE DOIT JAMAIS APPARAÎTRE DANS LE
 TEXTE DU FICHIER CIBLE.
 Ceci provoquait un bug dans la version Alpha de l'application fenêtrée
 mkdcppw à l'étape du test d'intégration.
 - La réponse est incluse dans les tests 5:
 - Nous avons constaté qu'un caractère EOF peut exister dans un fichier 
 cible lorsqu'un fichier source ne se termine pas par un retour chariot.
 Le fichier cible (document) n'est alors pas éditable en UTF-8
 En ce cas il faut vérifier son existence avec un éditeur hexadécimal 
 comme "Bless Hex Editor" ou Ghex. (EOF = généralement 0xFF)
 Voir End-Of-File sur wikipedia.
 Ceci apparaît avec l'actuelle fonction cpp_() lorsque le fichier se termine
 par */ sans le retour chariot.
 - Tous les caractères sont recopiés octets par octets. La commande mkd 
 ignore le format du texte recopié. Il n'en est pas de même pour mkdcppw 
 qui ne reconnaît que les caractères UTF-8 nécessaires à l'impression.
 La réponse à l'épreuve 6 est donc "non conforme".
Intégration du module.
L'intégration du module se fait par la compilation d'une application qui utilise ce "module", cette fonction: mkd, mkdcpp, mkdcppw par exemple. Le fichier d'entête version.h doit être modifié en fonction des compilateurs et options de compilation.
Ce module peut être intégré par inclusion (#include) avec l'option de compilation gtkmm pour mkdcppw.
Il peut être compilé séparément sous forme d'objet éventuellement intégrable dans une librairie.
Le module objet sera lié (Link) à l'application par la compilation.
Attention : Une fonction intégrée dans une librairie est figée. Il faut alors veiller à proposer un fichier d'entête correspondant à l'objet; on ne peut plus utiliser version.h. 
Notes et références.
[[Catégorie:Mkd (Extracteur de documents) (livre)]]