Bonjour,
Je dois développer un programme de conversion docx --> html
Voici mon code, lors de son exécution, le programme ne se déroule pas jusqu'à la fin, sans doute due à une fuite mémoire.
entete.h présent dans tout les fichiers :
main.c :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 /* Permet de factoriser les bibliothèques */ #include <stdlib.h> #include <stdio.h> #include <sys/stat.h> #include <gtk/gtk.h> #include <glib-2.0/glib.h> #include "xmlParser.h" #include "docxProperties.h" #include "docxConverter.h" #include "htmlWriter.h" #include "util.h" /*************** CONFIGURATION ***************/ #define LOGS_PATH_FILE "logs/logs.txt" #define DOCX_GENERAL_LAYERS_PATH_FILE "docx_general_layers.txt" #define DOCX_TABLES_LAYERS_PATH_FILE "docx_tables_layers.txt" #define DOCX_PARAGRAPH_LAYERS_PATH_FILE "docx_paragraph_layers.txt" #define MAPPING_DOCX_HTML_PATH_FILE "mapping_docx_html.txt" typedef struct docxLayers { char** layer1; int* nbNodeLayer1; char** layer2; int* nbNodeLayer2; char** layer3; int* nbNodeLayer3; char** layer4; int* nbNodeLayer4; char** tableLayers; int* nbNodeTableLayers; } docxLayers;xmlParser.c :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 int main (int argc, char **argv) { convertDocx("docx/word/document.xml"); return 0; }
docxProperties.c :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 #include "entete.h" /** * Permet de récupérer la balise fermante à partir de la balise ouvrante. */ char* getEndNode(const char* node) { char* endNode; int tailleNode; int i; tailleNode = strlen(node); endNode = (char*) malloc(tailleNode+1*sizeof(char)); endNode = strncpy (endNode, node, tailleNode+1); // Décalage des caractères vers la droite, de l'élément 1 à n. for (i = tailleNode+1; i >= 2; i--) { endNode[i] = endNode[i-1]; } // Insertion du caratère de fin de chaine endNode[tailleNode+1] = '\0'; // Insertion du "/" (</...>) endNode[1] = '/'; return endNode; } char* finNode(char* node, const char* chaine) { char* posNode1; char* posNode2; char* myNode; myNode = (char*) malloc((strlen(node)+1)*sizeof(char)); myNode = strncpy (myNode, node, strlen(node)-1); myNode[strlen(node)-1] = ' '; myNode[strlen(node)] = 0; posNode1 = strstr(chaine, myNode); // Cas "<XXX " posNode2 = strstr(chaine, node); // Cas "<XXX>" free(myNode); if (posNode1 != NULL && posNode2 != NULL) { if (posNode1 < posNode2) return posNode1; else return posNode2; } else { // Marche aussi pour le cas ou les 2 pos sont à NULL --> return NULL if (posNode1 == NULL) return posNode2; else return posNode1; } } /** * Permet de récupérer le contenu d'une balise et de le ranger dans s. * Retourne NULL si la balse n'est pas trouvée. */ char* getNode(char** s, const char* node, const char* chaine) { char* endNode; char* p1; // Position de la première balise char* p2; // Position de la dernière balise int tailleNodeOuvrante; int tailleContenuNode; int tailleNode = strlen(node); p1 = finNode(node, chaine); if (p1 == NULL) { return NULL; } // Calcule de la taille du premier node p2 = strchr(p1,'>'); tailleNodeOuvrante = p2-p1+1; endNode = getEndNode(node); p2 = strstr(p1, endNode); tailleContenuNode = p2-p1-tailleNodeOuvrante; *s = (char*) malloc(tailleContenuNode*sizeof(char)); *s = strncpy(*s, p1+tailleNodeOuvrante, tailleContenuNode); (*s)[tailleContenuNode] = 0; // Libération de la mémoire free(endNode); return p2+tailleNode+1; } /** * Permet de compter le nombre d'occurence d'une balise dans une chaine. */ int countNode(const char* node, const char* chaine) { char* curseur; // Position de la première balise int nbOccu = 0; int tailleNode = strlen(node); curseur = finNode(node, chaine); while (curseur != NULL) { nbOccu++; curseur += tailleNode-1; curseur = finNode(node, curseur); } return nbOccu; } /** * Permet de récupérer la première occurrence entre deux noeud dans une chaine. */ int findFirstNode(char* node1, char* node2, const char* chaine) { char* posNode1; char* posNode2; posNode1 = finNode(node1, chaine); posNode2 = finNode(node2, chaine); if (posNode2 != NULL && posNode1 != NULL) { if (posNode1 > posNode2) return 2; else if (posNode2 > posNode1) return 1; else { return 1; // TODO Cherche nodes identiques } } else { if (posNode2 == NULL && posNode1 == NULL) return 0; else if (posNode2 == NULL) return 1; else return 2; } }docxConverter.c :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127 #include "entete.h" /** * Permet de récupérer les noeuds d'une couche. */ char** getNodes(const char* layer) { char* myLayer; char** tabNodes; char* sTemp; int nbNodes = strCharCount(layer, '<'); int i=0; if (nbNodes > 0) { myLayer = strdup(layer); tabNodes = (char**) malloc(nbNodes*sizeof(char*)); sTemp = strtok(myLayer, ","); tabNodes[i] = (char*) malloc((strlen(sTemp)+1)*sizeof(char)); tabNodes[i] = strcpy(tabNodes[i], sTemp); for(i = 1; i < nbNodes; i++) { sTemp = strtok(NULL, ","); tabNodes[i] = (char*) malloc((strlen(sTemp)+1)*sizeof(char)); tabNodes[i] = strcpy(tabNodes[i], sTemp); } tabNodes[i-1][strlen(tabNodes[i-1])-1] = 0; // Supprime le saut de ligne à la fin du dernier noeud // TODO methode util qui supprime les saut de ligne free(myLayer); return tabNodes; } else { return NULL; } } /** * Permet de récupérer la configuration des couches du docx. */ docxLayers* layersLoader() { docxLayers* layers; FILE* file; int longLigne = 100; char ligne[longLigne]; layers = (docxLayers*) malloc(1*sizeof(docxLayers)); if ((file = fopen(DOCX_GENERAL_LAYERS_PATH_FILE, "r")) == NULL) { loggerVoid("Impossible d'ouvrir le fichier : \"docx_general_layers.txt\""); exit(1); } fgets(ligne, longLigne, file); layers[0].layer1 = getNodes(ligne);// TODO filtre layers[0].nbNodeLayer1 = (int*) malloc(1*sizeof(int)); *(layers[0].nbNodeLayer1) = countNodeFromLayer(1, DOCX_GENERAL_LAYERS_PATH_FILE); fgets(ligne, longLigne, file); layers[0].layer2 = getNodes(ligne); layers[0].nbNodeLayer2 = (int*) malloc(1*sizeof(int)); *(layers[0].nbNodeLayer2) = countNodeFromLayer(2, DOCX_GENERAL_LAYERS_PATH_FILE); fgets(ligne, longLigne, file); layers[0].layer3 = getNodes(ligne); layers[0].nbNodeLayer3 = (int*) malloc(1*sizeof(int)); *(layers[0].nbNodeLayer3) = countNodeFromLayer(3, DOCX_GENERAL_LAYERS_PATH_FILE); fgets(ligne, longLigne, file); layers[0].layer4 = getNodes(ligne); layers[0].nbNodeLayer4 = (int*) malloc(1*sizeof(int)); *(layers[0].nbNodeLayer4) = countNodeFromLayer(4, DOCX_GENERAL_LAYERS_PATH_FILE); fclose(file); if ((file = fopen(DOCX_TABLES_LAYERS_PATH_FILE, "r")) == NULL) { loggerVoid("Impossible d'ouvrir le fichier : \"docx_tables_layers.txt\""); exit(1); } fgets(ligne, longLigne, file); layers[0].tableLayers = getNodes(ligne); layers[0].nbNodeTableLayers = (int*) malloc(1*sizeof(int)); *(layers[0].nbNodeTableLayers) = countNodeFromLayer(1, DOCX_TABLES_LAYERS_PATH_FILE); fclose(file); return layers; } void layersUnloader(docxLayers* layers) { int i; for (i=0; i<*((*layers).nbNodeLayer1); i++) free((*layers).layer1[i]); free((*layers).layer1); free((*layers).nbNodeLayer1); for (i=0; i<*((*layers).nbNodeLayer2); i++) free((*layers).layer2[i]); free((*layers).layer2); free((*layers).nbNodeLayer2); for (i=0; i<*((*layers).nbNodeLayer3); i++) free((*layers).layer3[i]); free((*layers).layer3); free((*layers).nbNodeLayer3); for (i=0; i<*((*layers).nbNodeLayer4); i++) free((*layers).layer4[i]); free((*layers).layer4); free((*layers).nbNodeLayer4); for (i=0; i<*((*layers).nbNodeTableLayers); i++) free((*layers).tableLayers[i]); free((*layers).tableLayers); free((*layers).nbNodeTableLayers); free(layers); layers = NULL; } /** * Permet de compter le nombre de noeud à partir du numéro de la couche. */ int countNodeFromLayer(const int indLayer, const char* pathFile) { FILE* file; int i; int longLigne = 100; char ligne[longLigne]; if (indLayer > 0) { if ((file = fopen(pathFile, "r")) == NULL) { loggerVoid("Impossible d'ouvrir le fichier : \"docx_layers.txt\""); exit(1); } for(i = 0; i < indLayer; i++) fgets(ligne, longLigne, file); fclose(file); return strCharCount(ligne, '<'); } else { return 0; } }util.c :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 #include "entete.h" int getFirstNodeFromLayer(const char* s, const char** nodesLayer, const int nbNode) { int firstNode; int firstNodeTemp; int i = 0; if (nbNode > 1) { // Si au moin 2 nodes dans le layer do { firstNodeTemp = findFirstNode(nodesLayer[i], nodesLayer[i+1], s); i++; } while (i < nbNode-1 && firstNode == 0); if (firstNodeTemp != 0) { // Si 1 node à été trouvée if (firstNodeTemp == 2) // Si le premier node trouvée est en pos 2 firstNode = i; else firstNode = i-1; for (i; i<nbNode-1; i++) { firstNodeTemp = findFirstNode(nodesLayer[firstNode], nodesLayer[i], s); if (firstNodeTemp == 2) firstNode = i; } return firstNode; } else { return -1; } } else { if (nbNode > 0) if (NULL != strstr(s, nodesLayer[0])) return 0; else return -1; else return -1; } } /** * Permet de convertir un paragraphe d'un fichier xml word 2007 en un paragraphe html. */ int convertParagraph(const char* chaine) { char* contenuNode; char* curseur; docxLayers* layers; layers = layersLoader(); loggerVoid("\n=====>> Début méthode : \"convertParagraph\""); curseur = getNode(&contenuNode, (*layers).layer4[0], chaine); while (NULL != curseur) { loggerString("\n- contenuNode = %s", contenuNode); free(contenuNode); curseur = getNode(&contenuNode, (*layers).layer4[0], curseur); } layersUnloader(layers); loggerVoid("\n<<===== Fin méthode : \"convertParagraph\"\n"); return 1; } /** * Permet de convertir un tableau d'un fichier xml word 2007 en un tableau html. */ int convertTable(const char* chaine) { char* contenuNode1; char* contenuNode2; char* curseur; // TODO TEMP var char* t1 = "<w:p>"; char* t3 = "<w:t>"; loggerVoid("\n=====>> Début méthode : \"convertParagraph\"\n"); curseur = getNode(&contenuNode1, t1, chaine); loggerString("- contenuNode1 : %s\n", contenuNode1); loggerInt("- Pos fin paragraphe : %d\n", curseur); getNode(&contenuNode2, t3, contenuNode1); loggerString("- contenuNode2 : %s\n", contenuNode2); loggerVoid("<<===== Fin méthode : \"convertParagraph\"\n\n"); return curseur; } /** * Permet de convertir un fichier xml word 2007 en un fichier html. */ int convertDocx(const char* pathFile) { char* docx; char* tempDocx; // Permet de en pas perdre le pointeur sur le début de la chaine (ficher xml) int longLigne = 100; char ligne[longLigne]; FILE* file; // Variable pour le parsing char* tempContenuNode; int indNode; char* curseur; docxLayers* layers = layersLoader(); loggerVoid("\n\n========================================================================\n"); loggerVoid(" Début parsing docx \n"); loggerVoid("========================================================================\n"); initHtmlFile(); file = fopen(pathFile,"r"); isPFILENull(file, "Impossible d'ouvrir le docx\n"); // Réservation de la mémoire = Taille du ficher document.xml docx = (char*) malloc(getFileSize(pathFile)*sizeof(char)); isPCharNull(docx, ""); tempDocx = docx; while (fgets(ligne, longLigne, file) != NULL) { tempDocx = strcpy(tempDocx, ligne); tempDocx += strlen(ligne); // strlen(ligne) --> Au cas ou la ligne serait plus courte que longLigne } *tempDocx = 0; indNode = getFirstNodeFromLayer(docx, (*layers).layer1, *((*layers).nbNodeLayer1)); curseur = getNode(&tempContenuNode, (*layers).layer1[indNode], docx); curseur = docx; free(tempContenuNode); indNode = getFirstNodeFromLayer(curseur, (*layers).layer2, *((*layers).nbNodeLayer2)); while (-1 != indNode) { curseur = getNode(&tempContenuNode, (*layers).layer2[indNode], curseur); loggerInt("\n- indNode = %d", indNode); loggerString("\n- tempContenuNode = %s", tempContenuNode); // loggerString("\n- curseur = %s", curseur); if (indNode == 0) { // Conversion d'un paragraphe convertParagraph(tempContenuNode); } else { // Conversion d'un tableau } free(tempContenuNode); indNode = getFirstNodeFromLayer(curseur, (*layers).layer2, *((*layers).nbNodeLayer2)); loggerInt("\n- Next indNode = %d", indNode); } // Inutil de récupérer la position pour le noeud "<w:body>" // loggerString("\n- body : %s\n", body); // first = findFirstNode(t1, t2, body); // loggerString("- First node = \"%s\"\n", first); // // curseur = convertParagraph(body); closeHtmlFile(); free(docx); layersUnloader(layers); loggerVoid("\n\n========================================================================\n"); loggerVoid(" Fin parsing docx \n"); loggerVoid("========================================================================\n"); return 0; }
Je n'arrive pas à corriger la fuite, est ce que quelqu'un aurait une idée de l'erreur?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 #include "entete.h" /** * Permet de ouvrir le flux vers le fichier de log. */ //FILE* openLogger(char* mode) { // FILE* file; // char* pathFileLogs = "logs/log.txt"; // // if ((file = fopen(pathFileLogs, mode)) == NULL) { // printf("Impossible d'ouvrir le fichier de logs\n"); // exit(1); // } // return file; //} /** * Permet de logger une chaine de caractère sans aucun paramètre. */ void loggerVoid(const char* log) { FILE* file; if ((file = fopen(LOGS_PATH_FILE, "a")) == NULL) { printf("Impossible d'ouvrir le fichier de logs\n"); exit(1); } fprintf(file, log); fclose(file); } /** * Permet de une chaine de caratère avec un int en paramètre. */ void loggerInt(const char* log, const int parameter) { FILE* file; if ((file = fopen(LOGS_PATH_FILE, "a")) == NULL) { printf("Impossible d'ouvrir le fichier de logs\n"); exit(1); } fprintf(file, log, parameter); fclose(file); } /** * Permet de une chaine de caratère avec un string en paramètre. */ void loggerString(const char* log, const char* parameter) { FILE* file; if ((file = fopen(LOGS_PATH_FILE, "a")) == NULL) { printf("Impossible d'ouvrir le fichier de logs\n"); exit(1); } fprintf(file, log, parameter); fclose(file); } long getFileSize(const char* fileName) { struct stat s; if (stat(fileName, &s) != 0) { loggerString("Erreur de récupération des stats du docx : %s\n", fileName); exit(1); } return s.st_size; } void isPCharNull(char* pChar, char* message) { if (pChar == NULL) { loggerString("- isPCharNull message : %s\n", message); exit(1); } } void isPFILENull(char* pFile, char* message) { if (pFile == NULL) { loggerString("- isPFILENull message : %s\n", message); exit(1); } } /** * Permet de compter le nombre d'occurer d'un caractère dans une chaîne. */ int strCharCount(const char* s, char c) { char* curseur; int nbOccu = 0; curseur = strchr(s, c); while (curseur != NULL) { nbOccu++; curseur += 1; curseur = strchr(curseur, c); } return nbOccu; }
Merci
Partager