home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / PRGMANIA / INITFILE / INITFILE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-25  |  19.9 KB  |  579 lines

  1. /*******************************************************************
  2.  * Fonctions de gestion de fichiers de paramètres (.inf)           *
  3.  *                                                                 *
  4.  * Fichier source des fonctions.                                   *
  5.  *                                                                 *
  6.  * (C) 1996 - Philippe Castella                                    *
  7.  *                                                                 *
  8.  *******************************************************************/
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <malloc.h>
  12. #include <string.h>
  13. #include "InitFile.h"
  14.  
  15. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
  16.  * Déclaration des fonctions priéves au module.                    *
  17.  *=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  18. static int ReadLine (FILE *ficIni, char *ligne);
  19. static void ReadFile (FILE *fileHandle, InitFile **strIni);
  20. static InfSection *AddSection (InitFile **strIni, char *section);
  21. static void AddVar (InitFile **strIni, char *section, char *var, char *val);
  22. static void SaveFile (InitFile *strIni);
  23. static void GetValeur (InitFile *strIni, char *section, char *var, char *buf);
  24.  
  25. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
  26.  * Définition des fonctions de la librairie.                       *
  27.  *=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  28.  
  29. /*-----------------------------------------------------------------*
  30.  * InfCreate : fonction de création/ouverture d'un fichier .inf    *
  31.  *                                                                 *
  32.  * Entrée : nom du fichier .inf                                    *
  33.  * Sortie : un pointeur sur la nouvelle structure créée            *
  34.  *                                                                 *
  35.  * Dernière modification : 11 décembre 1996                        *
  36.  *-----------------------------------------------------------------*/
  37. InitFile *InfCreate (char *nomFic)
  38. {
  39.     InitFile *strIni;
  40.     FILE *fileHandle;
  41.  
  42.     /* Allocation de la mémoire nécessaire à la structure */
  43.     strIni = (InitFile *)malloc (sizeof (InitFile));
  44.     if (strIni)
  45.     {
  46.         /* Ouverture du fichier */
  47.         fileHandle = fopen (nomFic, "r");
  48.  
  49.         /* Mise jour de la structure */
  50.         strIni->FileName = (char *)malloc (strlen(nomFic) + 1);
  51.         if (! strIni->FileName)
  52.         {    /* Si Pb, on libère la mémoire et on s'en va */
  53.             free(strIni);
  54.             return (InitFile *)0;
  55.         }
  56.         strcpy (strIni->FileName, nomFic);
  57.         strIni->FirstSection = (InfSection *)0;
  58.  
  59.         /* Si fichier existe, on lit son contenu */
  60.         if (fileHandle)
  61.         {    /* Lecture ligne à ligne du fichier = remplir la structure */
  62.             ReadFile (fileHandle, &strIni);
  63.  
  64.             /* Fermeture du fichier */
  65.             fclose (fileHandle);
  66.         }
  67.     }
  68.     else
  69.         strIni = (InitFile *)0;
  70.  
  71.     return strIni;
  72. }
  73.  
  74. /*-----------------------------------------------------------------*
  75.  * InfWriteBool    : Ajout d'une variable de type booléen.         *
  76.  * InfWriteInteger : Ajout d'une variable de type entier.          *
  77.  * InfWriteString  : Ajout d'une variable de type chaîne de car.   *
  78.  *                                                                 *
  79.  * Entrée : nom de la section                                      *
  80.  *          nom de la variable                                     *
  81.  *          valeur de la variable                                  *
  82.  * I/O    : L'adresse du pointeur sur la structure de données.     *
  83.  *                                                                 *
  84.  * Dernière modification : 11 décembre 1996                        *
  85.  *-----------------------------------------------------------------*/
  86. void InfWriteBool (InitFile **strIni, char *section, char *var, short val)
  87. {
  88.     if (val)
  89.         AddVar (strIni, section, var, "1");
  90.     else
  91.         AddVar (strIni, section, var, "0");
  92. }
  93.  
  94. void InfWriteInteger (InitFile **strIni, char *section, char *var, long  val)
  95. {
  96.     char buf[10];
  97.  
  98.     ltoa (val, buf, 10);
  99.     AddVar (strIni, section, var, buf);
  100. }
  101.  
  102. void InfWriteString (InitFile **strIni, char *section, char *var, char *val)
  103. {
  104.     AddVar (strIni, section, var, val);
  105. }
  106.  
  107. /*-----------------------------------------------------------------*
  108.  * InfReadBool    : Lecture d'une variable de type booléen.        *
  109.  * InfReadInteger : Lecture d'une variable de type entier.         *
  110.  * InfReadString  : Lecture d'une variable de type chaîne de car.  *
  111.  *                                                                 *
  112.  * Entrée : Le pointeur sur la structure de données.               *
  113.  *          nom de la section                                      *
  114.  *          nom de la variable                                     *
  115.  *          valeur par défaut de la variable si non trouvée        *
  116.  * I/O    : valeur de la variable                                  *
  117.  *                                                                 *
  118.  * Dernière modification : 11 décembre 1996                        *
  119.  *-----------------------------------------------------------------*/
  120. void InfReadBool (InitFile *strIni, char *section, char *var, short def, short *val)
  121. {
  122.     char buf[129];
  123.  
  124.     /* Récupération de la valeur de la variable */
  125.     GetValeur (strIni, section, var, buf);
  126.  
  127.     /* Si rien trouvé -> retourner val par défaut, sinon la valeur */
  128.     if (! *buf)
  129.         *val = def;
  130.     else
  131.         *val = (short)atoi (buf);
  132. }
  133.  
  134. void InfReadInteger (InitFile *strIni, char *section, char *var, long  def, long  *val)
  135. {
  136.     char buf[129];
  137.  
  138.     /* Récupération de la valeur de la variable */
  139.     GetValeur (strIni, section, var, buf);
  140.  
  141.     /* Si rien trouvé -> retourner val par défaut, sinon la valeur */
  142.     if (! *buf)
  143.         *val = def;
  144.     else
  145.         *val = atol (buf);
  146. }
  147.  
  148. void InfReadString (InitFile *strIni, char *section, char *var, char *def, char  *val)
  149. {
  150.     char buf[129];
  151.  
  152.     /* Récupération de la valeur de la variable */
  153.     GetValeur (strIni, section, var, buf);
  154.  
  155.     /* Si rien trouvé -> retourner val par défaut, sinon la valeur */
  156.     if (! *buf)
  157.         strcpy (val, def);
  158.     else
  159.         strcpy (val, buf);
  160. }
  161.  
  162. /*-----------------------------------------------------------------*
  163.  * InfFree : Fonction de sauvegarde du fichier .inf et de          *
  164.  *           restitution de la mémoire allouée dynamiquement.      *
  165.  *                                                                 *
  166.  * Entrée : Le pointeur sur la structure de données.               *
  167.  *                                                                 *
  168.  * Dernière modification : 11 décembre 1996                        *
  169.  *-----------------------------------------------------------------*/
  170. void InfFree (InitFile *strIni)
  171. {
  172.     /* Si on ne pointe pas sur du vide */
  173.     if (strIni != (InitFile *)0)
  174.     {
  175.         /* Sauvegarde du fichier */
  176.         SaveFile (strIni);
  177.  
  178.         /* Effacement de la structure */
  179.         free (strIni->FileName);
  180.         free (strIni);
  181.     }
  182. }
  183.  
  184. /*-----------------------------------------------------------------*
  185.  * InfDeleteVar : Fonction de suppression d'une variable.          *
  186.  *                                                                 *
  187.  * Entrée : Le pointeur sur la structure de données.               *
  188.  *          Le nom de la section                                   *
  189.  *          Le nom de la variable                                  *
  190.  *                                                                 *
  191.  * Dernière modification : 25 décembre 1996                        *
  192.  *-----------------------------------------------------------------*/
  193. void InfDeleteVar (InitFile **strIni, char *section, char *var)
  194. {
  195.     InfSection *strSection;
  196.     InfVar *strVar, *oldVar;
  197.  
  198.     if (*strIni)
  199.     {
  200.         /* On recherche si la section existe bien */
  201.         strSection = (*strIni)->FirstSection;
  202.         while (strSection != (InfSection *)0)
  203.         {
  204.             if (strcmp(strSection->SectionName, section) == 0)
  205.             {
  206.                 strVar = oldVar = strSection->FirstVar;
  207.                 while (strVar != (InfVar *)0)
  208.                 {
  209.                     if (strcmp (strVar->VarName, var) == 0)
  210.                     {
  211.                         oldVar->NextVar = strVar->NextVar;
  212.                         free (strVar->VarName);
  213.                         free (strVar->VarVal);
  214.                         free (strVar);
  215.                         return;
  216.                     }
  217.                     oldVar = strVar;
  218.                     strVar = strVar->NextVar;
  219.                 }
  220.             }
  221.             strSection = strSection->NextSection;
  222.         }
  223.     }
  224. }
  225.  
  226. /*-----------------------------------------------------------------*
  227.  * InfDeleteSection : Fonction de suppression d'une section.       *
  228.  *                                                                 *
  229.  * Entrée : Le nom de la section                                   *
  230.  *          Le nom de la variable                                  *
  231.  * I/O    : L'adresse du pointeur sur la structure de données.     *
  232.  *                                                                 *
  233.  * Dernière modification : 25 décembre 1996                        *
  234.  *-----------------------------------------------------------------*/
  235. void InfDeleteSection (InitFile **strIni, char *section)
  236. {
  237.     InfSection *strSection, *oldSection;
  238.  
  239.     if (*strIni)
  240.     {
  241.         /* On recherche si la section existe bien */
  242.         strSection = (*strIni)->FirstSection;
  243.         oldSection = strSection;
  244.         while (strSection != (InfSection *)0)
  245.         {
  246.             if (strcmp(strSection->SectionName, section) == 0)
  247.             {
  248.                 if (oldSection == strSection)
  249.                     (*strIni)->FirstSection = strSection->NextSection;
  250.                 else
  251.                     oldSection->NextSection = strSection->NextSection;
  252.                 free (strSection->SectionName);
  253.                 free (strSection);
  254.                 return;
  255.             }
  256.             oldSection = strSection;
  257.             strSection = strSection->NextSection;
  258.         }
  259.     }
  260. }
  261.  
  262. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
  263.  * Définition des fonctions privées de la librairie                *
  264.  *=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  265.  
  266. /*-----------------------------------------------------------------*
  267.  * ReadLine : Fonction de lecture d'une ligne dans un fichier ASCII*
  268.  *                                                                 *
  269.  * Entrée : Le descripteur du fichier ouvert avec fopen            *
  270.  * I/O    : un buffer pour stocker les données lues                *
  271.  * Sortie : Le nombre de caractères composant la ligne, -1 si EOF  *
  272.  *                                                                 *
  273.  * Dernière modification : 11 décembre 1996                        *
  274.  *-----------------------------------------------------------------*/
  275. static int ReadLine (FILE *ficIni, char *ligne)
  276. {
  277.     register char car;
  278.     register int cpt = 0;
  279.  
  280.     /* Lire car. par car. jusqu'à fin de ligne ou fin de fichier   */
  281.     while (! feof(ficIni) && ((car = fgetc(ficIni)) != '\n'))
  282.         ligne[cpt++] = car;
  283.     ligne[cpt] = '\0';
  284.  
  285.     /* Si fin de fichier, on le signale */
  286.     if (feof(ficIni))
  287.         cpt = -1;
  288.  
  289.     /* Renvoie le nombre de caractères lus */
  290.     return cpt;
  291. }
  292.  
  293. /*-----------------------------------------------------------------*
  294.  * ReadFile : Fonction de lecture des données contenue dans le     *
  295.  *            fichier .inf                                         *
  296.  *                                                                 *
  297.  * I/O    : L'adresse du pointeur sur la structure de données.     *
  298.  *                                                                 *
  299.  * Dernière modification : 11 décembre 1996                        *
  300.  *                                                                 *
  301.  * Remarque : une ligne ne doit pas dépasser 256 caractères c-à-d  *
  302.  *            128 car. pour la variable et autant pour la valeur.  *
  303.  *-----------------------------------------------------------------*/
  304. static void ReadFile (FILE *fileHandle, InitFile **strIni)
  305. {
  306.     register int nbCar, i, j;
  307.     char section[65];
  308.     char read_buf[257];
  309.     char var[129];
  310.     char val[129];
  311.  
  312.     /* Lecture du fichier ligne par ligne */
  313.     while ((nbCar = ReadLine (fileHandle, read_buf)) > -1)
  314.     {
  315.         if (nbCar > 0)
  316.         {    /* Pas une ligne vide */
  317.             if (read_buf[0] == '[') /* Si début de Section */
  318.             {    /* [nom de la section] */
  319.                 i = 1;
  320.                 j = 0;
  321.                 /* Lire titre de la section */
  322.                 while (read_buf[i] != ']' && read_buf[i] != '\0')
  323.                     section[j++] = read_buf[i++];
  324.                 section[j] = '\0';
  325.  
  326.                 /* Création de la section dans la structure de données */
  327.                 AddSection(strIni, section);
  328.             }
  329.             else
  330.             {    /* var=val */
  331.                 i = 0;
  332.                 j = 0;
  333.                 /* Lire nom de la variable */
  334.                 while (read_buf[i] != '=')
  335.                     var[j++] = read_buf[i++];
  336.                 var[j] = '\0';
  337.                 i++;
  338.  
  339.                 /* Lire valeur de la variable */
  340.                 j = 0;
  341.                 while (read_buf[i] != '\0')
  342.                     val[j++] = read_buf[i++];
  343.                 val[j] = '\0';
  344.  
  345.                 /* Création de la variable dans la structure de données*/
  346.                 AddVar(strIni, section, var, val);
  347.             }
  348.         }
  349.     }
  350. }
  351.  
  352. /*-----------------------------------------------------------------*
  353.  * AddSection : Fonction permettant de créer une nouvelle section  *
  354.  *              si celle-ci n'existe pas déjà.                     *
  355.  *                                                                 *
  356.  * Entrée : le nom de la section                                   *
  357.  * I/O    : L'adresse du pointeur sur la structure de données.     *
  358.  *                                                                 *
  359.  * Dernière modification : 11 décembre 1996                        *
  360.  *-----------------------------------------------------------------*/
  361. static InfSection *AddSection (InitFile **strIni, char *section)
  362. {
  363.     InfSection *strSection = (*strIni)->FirstSection;
  364.     InfSection *NewSection;
  365.  
  366.     /* On recherche si la section existe déjà */
  367.     while (strSection != (InfSection *)0)
  368.     {
  369.         if (strcmp(strSection->SectionName, section) == 0)
  370.             return strSection;
  371.         strSection = strSection->NextSection;
  372.     }
  373.  
  374.     /* Si elle n'existe pas, on la rajoute */
  375.     NewSection = (InfSection *)malloc (sizeof(InfSection));
  376.     if (NewSection)
  377.     {
  378.         /* Allocation mémoire pour le nom de la section */
  379.         NewSection->SectionName = (char *)malloc (strlen(section) + 1);
  380.         if (! NewSection->SectionName)
  381.         {
  382.             free (NewSection);
  383.             return (InfSection *)0;
  384.         }
  385.  
  386.         /* Mettre à jour le contenu de la structure */
  387.         strcpy (NewSection->SectionName, section);
  388.         NewSection->NextSection = (InfSection *)0;
  389.         NewSection->FirstVar = (InfVar *)0;
  390.  
  391.         strSection = (*strIni)->FirstSection;
  392.         /* Si première section ...*/
  393.         if (strSection == (InfSection *)0)
  394.         {
  395.             (*strIni)->FirstSection = NewSection;
  396.             return (*strIni)->FirstSection;
  397.         }
  398.         else /* ...sinon */
  399.         {
  400.             while (strSection->NextSection != (InfSection *)NULL)
  401.                 strSection = strSection->NextSection;
  402.  
  403.             strSection->NextSection = NewSection;
  404.           return strSection->NextSection;
  405.       }
  406.     }
  407.     return (InfSection *)0;
  408. }
  409.  
  410. /*-----------------------------------------------------------------*
  411.  * AddVar : Fonction permettant de créer une nouvelle variable dans*
  412.  *          une section données si elle n'existe pas déjà.         *
  413.  *                                                                 *
  414.  * Entrée : le nom de la section                                   *
  415.  *          le nom de la variable                                  *
  416.  *          la valeur de la variable                               * 
  417.  * I/O    : L'adresse du pointeur sur la structure de données.     *
  418.  *                                                                 *
  419.  * Dernière modification : 11 décembre 1996                        *
  420.  *-----------------------------------------------------------------*/
  421. static void AddVar (InitFile **strIni, char *section, char *var, char *val)
  422. {
  423.     InfSection *strSection;
  424.     InfVar *strVar, *NewVar;
  425.     short ok = FALSE;
  426.  
  427.     if (*strIni)
  428.     {
  429.         /* Recherche la bonne section (création si nécessaire) */
  430.         strSection = AddSection (strIni, section);
  431.         if (strSection == (InfSection *)0)
  432.             return;
  433.  
  434.         /* On recherche si la variable existe déjà */
  435.         strVar = strSection->FirstVar;
  436.         while (strVar != (InfVar *)0)
  437.         {
  438.             /* Si on trouve la variable, on sort de la boucle */
  439.             if (strcmp(strVar->VarName,var) == 0)
  440.             {
  441.                 ok = TRUE;
  442.                 break;
  443.             }
  444.             strVar = strVar->NextVar;
  445.         }
  446.  
  447.         /* Si variable non trouvée, on la crée */
  448.         if (! ok)
  449.         {
  450.             NewVar = (InfVar *)malloc (sizeof(InfVar));
  451.             if (NewVar)
  452.             {
  453.                 NewVar->VarName = (char *)malloc(strlen(var) + 1);
  454.                 if (! NewVar->VarName)
  455.                 {
  456.                     free (NewVar);
  457.                     return;
  458.                 }
  459.                 strcpy (NewVar->VarName, var);
  460.                 NewVar->NextVar = (InfVar *)0;
  461.           
  462.                 strVar = strSection->FirstVar;
  463.                 if (strVar == (InfVar *)0)
  464.                 {
  465.                     strSection->FirstVar = NewVar;
  466.                     strVar = strSection->FirstVar;
  467.                 }
  468.                 else
  469.                 {
  470.                     while (strVar->NextVar != (InfVar *)NULL)
  471.                         strVar = strVar->NextVar;
  472.  
  473.                     strVar->NextVar = NewVar;
  474.                     strVar = strVar->NextVar;
  475.                 }
  476.             }     
  477.         }
  478.  
  479.         /* Mise à jour de la valeur de la variable */
  480.         strVar->VarVal = (char *)malloc (strlen(val) + 1);
  481.         if (strVar->VarVal)
  482.             strcpy (strVar->VarVal, val);
  483.     }
  484. }
  485.  
  486. /*-----------------------------------------------------------------*
  487.  * SaveFile : Fonction permettant de sauvegarder le fichier .inf   *
  488.  *            tout en effacant au fur er à mesure la structure.    *
  489.  *                                                                 *
  490.  * Entrée : Le pointeur sur la structure de données.               *
  491.  *                                                                 *
  492.  * Dernière modification : 11 décembre 1996                        *
  493.  *-----------------------------------------------------------------*/
  494. static void SaveFile (InitFile *strIni)
  495. {
  496.     FILE *fileHandle;
  497.     InfSection *strSection, *oldSection;
  498.     InfVar *strVar, *oldVar;
  499.  
  500.     /* Ouvrir fichier paramètre */
  501.     fileHandle = fopen (strIni->FileName, "w");
  502.  
  503.     strSection = strIni->FirstSection;
  504.     while (strSection != (InfSection *)0)
  505.     {
  506.         /* Ecriture du nom de la section */
  507.         fprintf (fileHandle, "[%s]\n", strSection->SectionName);
  508.  
  509.         /* Première variable */
  510.         strVar = strSection->FirstVar;
  511.         while (strVar != (InfVar *)0)
  512.         {
  513.             /* Ecriture de la variable et de sa valeur */
  514.             fprintf (fileHandle, "%s=%s\n", strVar->VarName, strVar->VarVal);
  515.  
  516.             /* Variable suivante */
  517.             oldVar = strVar;
  518.             strVar = strVar->NextVar;
  519.  
  520.             /* Supprimer variable, valeur et structure */
  521.             free (oldVar->VarName);
  522.             free (oldVar->VarVal);
  523.             free (oldVar);
  524.         }
  525.         fprintf (fileHandle, "\n");
  526.         /* Section suivante */
  527.         oldSection = strSection;
  528.         strSection = strSection->NextSection;
  529.  
  530.         /* Supprimer nom et structure */
  531.         free (oldSection->SectionName);
  532.         free (oldSection);
  533.     }
  534.  
  535.     /* Fermer fichier paramètre */
  536.     fclose (fileHandle);
  537.  
  538. }
  539.  
  540. /*-----------------------------------------------------------------*
  541.  * GetValeur : Fonction permettant de récupérer le contenu d'une   *
  542.  *             variable donnée d'une section donnée.               *
  543.  *                                                                 *
  544.  * Entrée : Le pointeur sur la structure de données.               *
  545.  *          le nom de la section                                   *
  546.  *          le nom de la variable                                  *
  547.  * I/O    : Le buffer qui va contenir la valeur                    *
  548.  *                                                                 *
  549.  * Dernière modification : 11 décembre 1996                        *
  550.  *-----------------------------------------------------------------*/
  551. static void GetValeur (InitFile *strIni, char *section, char *var, char *buf)
  552. {
  553.     InfSection *strSection;
  554.     InfVar *strVar;
  555.  
  556.     /* Recherche de la section */
  557.     strSection = strIni->FirstSection;
  558.     while ((strSection != (InfSection *)0) && strcmp(strSection->SectionName, section) != 0)
  559.         strSection = strSection->NextSection;
  560.  
  561.     /* Si section non trouvée, buffer vide */
  562.     if (strSection == (InfSection *)0)
  563.         strcpy (buf, "");
  564.     else
  565.     {
  566.         /* Recherche de la variable */
  567.         strVar = strSection->FirstVar;
  568.         while ((strVar != (InfVar *)0) && strcmp(strVar->VarName, var) != 0)
  569.             strVar = strVar->NextVar;
  570.  
  571.         /* Si variable non trouvée, buffer vide */
  572.         if (strVar == (InfVar *)0)
  573.             strcpy (buf, "");
  574.         else /* sinon copier la valeur dans le buffer */
  575.             strcpy (buf, strVar->VarVal);
  576.     }
  577. }
  578.  
  579. /*******************************************************************/