Chapitre 3. Exemple de module d'exportation

Valeurs séparées par des virgules (CSV)

Le code source du module export_csv.so est reproduit ci-dessous. Ce module, simple, exporte les données de l'emploi du temps dans un format CVS (Comma Separated Values - Valeurs Séparées par des Virgules), qui permet de les importer depuis d'autres programmes (comme les tableurs). Ce format requiert que chaque ligne soient séparées en de multiples champs, en utilisant la virgule "," comme caractère de séparation. Les champs contenant des virgules doivent être mis entre guillemets. Les champs numériques sont écrits sans enrobage.

La sortie consiste en 4 lignes d'en-tête et une table d'évènements. Les trois premières lignes contiennent le titre, l'auteur et l'adresse de l'institution. Ensuite, vient la ligne qui contient l'ajustage de l'emploi du temps exporté et une ligne d'en-tête pour la table d'évènements. Chaque évènement est représenté sur une seule ligne. Le premier champ contient le nom de l'évènement et les champs suivants contiennent les noms des ressources utilisées par cet évènement, triés par type.

#include "export.h"

int export_function(table *tab, moduleoption *opt, char *file)
{
        int typeid,tupleid;

        FILE *out;

        char *name;
        int resid;

        assert(tab!=NULL);

        if(file==NULL) {
                out=stdout;
        } else {
                out=fopen(file, "w");
                if(out==NULL) fatal(strerror(errno));
        }

        fprintf(out, "\"Titre\",\"%s\"\n", dat_info.title);
        fprintf(out, "\"Adresse\",\"%s\"\n", dat_info.address);
        fprintf(out, "\"Auteur\",\"%s\"\n", dat_info.author);

        fprintf(out, "\"Ajustage\",%d\n", tab->fitness);

        fprintf(out, "\"Nom de l'évènement\"");
        for(typeid=0;typeid<dat_typenum;typeid++) {
                fprintf(out, ",\"%s\"", dat_restype[typeid].type);
        }
        fprintf(out, "\n");

        assert(dat_typenum==tab->typenum);

        for(tupleid=0;tupleid<dat_tuplenum;tupleid++) {
                fprintf(out, "\"%s\"", dat_tuplemap[tupleid].name);

                for(typeid=0;typeid<dat_typenum;typeid++) {
                        assert(dat_tuplenum==tab->chr[typeid].gennum);

                        resid=tab->chr[typeid].gen[tupleid];
                        name=dat_restype[typeid].res[resid].name;

                        fprintf(out, ",\"%s\"", name);
                }

                fprintf(out, "\n");
        }

        if(out!=stdout) fclose(out);

        return 0;
}

Comme vous pouvez le voir, ce module n'est constitué que de la fonction d'exportation. Un module d'exportation plus complexe pourrait contenir des fonctions additionnelles, appelées dans la fonction d'exportation. Le fichier en-tête export.h contient tous les prototypes et définitions de types requis par les modules d'exportation.

En premier, la fonction d'exportation ouvre le fichier de sortie. Comme mentionné dans l'introduction, si le nom de fichier est NULL, alors nous écrivons dans la sortie standard au lieu d'un fichier.

Ensuite, nous trouvons 4 appels à la fonction fprintf() pour écrire les lignes d'en-tête. Le titre de l'emploi du temps exporté et les informations à propos de l'auteur peuvent être trouvée dans la variable globale dat_info (structure miscinfo ). La valeur d'ajustage de l'emploi du temps peut être trouvé dans le champ fitness de la structure table .

Nous écrivons ensuite l'en-tête de la table d'évènements. La première colonne contient le nom de l'évènement, la seconde la ressource du premier type, la troisième la ressource du second type, et ainsi de suite. La première boucle "for" parcourt tous les types de ressource et écrit leurs noms.

Ensuite, deux boucles "for" imbriquées écrivent toute la table d'évènements. La boucle principale parcourt tous les évènements (l'identifiant du tuple courant est dans la variable tupleid). Nous écrivons le nom de l'évènement en début de ligne et entrons dans la seconde boucle. Elle parcourt de nouveau tous les types de ressources et récupère l'identifiant (resid) de la ressource que l'évènement courant utilise pour chaque type de ressource. Nous cherchons ensuite le nom de cette ressource dans la variable globale dat_restype qui contient les pointeurs vers toutes les structures de ressources resource, et l'écrivons.