Logiciel libre, droits d'utilisation précisés en français
dans le fichier : licence-fr.txt
Traductions des droits d'utilisation dans les fichiers :
licence-en.txt , licence-es.txt , licence-pt.txt ,
licence-eo.txt , licence-eo-utf.txt
Droits d'utilisation également sur la page web :
http://cyloop.tuxfamily.org/voir.php?page=droits
Bibliothèque de fonctions permettant de prendre en compte
un changement de cycle ou de se positionner dans le cycle
en cours pour un mise à jour du fichier cyloop.
*/
// variables globales (pour éviter des tas de passages de paramètre)
extern FILE *descfic; // descripteur du fichier cyloop
extern desc_cyloop entetefic; // entête du fichier cyloop
extern desc_var entetevar; // entête de la variable du fichier cyloop
// récupération du nom du fichier cyloop et rajout éventuel de son suffixe
char *recup_nomfic (char *nom)
{
char *nomfic;
int lg_nomfic;
// si un nom de fichier a été passé en paramètre
if (nom)
{
// récupérer sa taille
lg_nomfic = strlen (nom);
// si ce nom se termine par le suffixe .cyl
if ((lg_nomfic > 4) && (strcmp (nom + lg_nomfic - 4, ".cyl") == 0))
{
// mémoriser le nom tel quel
nomfic = malloc (lg_nomfic + 1);
strcpy (nomfic, nom);
}
// sinon
else
{
// rajouter au nom le suffixe .cyl et mémoriser le résultat
nomfic = malloc (lg_nomfic + 5);
strcpy (nomfic, nom);
strcpy (nomfic + lg_nomfic, ".cyl");
}
}
// retourner le nom du fichier
return nomfic;
}
/*
Prend en compte un passage à l'heure d'hiver ou d'été
retourne le valeur OUI ou NON selon qu'il faille reporter
une mise à jour d'entetefic dans le fichier cyloop
*/
int maj_type_heure (int passage_ete, long timep)
{
// si on vient juste de passer à l'heure d'été
if (passage_ete)
{
// mémoriser le changement d'heure
entetefic.etat_cyloop = entetefic.etat_cyloop | heure_ete;
// et modifier l'instant de début du cycle
entetefic.deb_cycle = entetefic.deb_cycle - 3600;
// on reportera plus tard la mise à jour dans le fichier cyloop
return (OUI);
}
// sinon on vient juste de passer à l'heure d'hiver
else
{
// si ce changement d'heure ne fait pas revenir au cycle précédent
if (entetefic.deb_cycle + 3600 <= timep)
{
// mémoriser le changement d'heure
entetefic.etat_cyloop = entetefic.etat_cyloop & mask_heure_hiver;
// et modifier l'instant de début du cycle
entetefic.deb_cycle = entetefic.deb_cycle + 3600;
// on reportera plus tard la mise à jour dans le fichier cyloop
return (OUI);
}
// sinon
else
// le changement d'heure sera pris en compte une autre fois
return (NON);
}
}
// prise en compte d'un changement de cycle
void changement_cycle (long timep)
{
// structure contenant la date et l'heure du début du cycle
struct tm oldstm;
int cycles_sautes; // compteur de cycles
uint32 duree_cycle; // durée du cycle
int coef_pond; // coefficient de pondération à appliquer
// initialisation, durée du cycle
duree_cycle = entetefic.duree_cycle;
// si cycle de longueur irrégulière basé sur le calendrier
if (entetefic.caract_gen & cycle_ireg)
{
// découper les caractéristique de l'instant du début de cycle
if (entetefic.caract_gen & temps_utc)
gmtime_r (&entetefic.deb_cycle, &oldstm);
else
localtime_r (&entetefic.deb_cycle, &oldstm);
// initialisation compteur
cycles_sautes = 0;
// si cycle annuel
if (entetefic.caract_gen & cycle_annuel)
{
// on avance année par année
do
{
entetefic.deb_cycle += duree_cycle;
cycles_sautes ++;
}
// jusqu'à ce qu'on tombe sur la bonne
while (entetefic.deb_cycle + duree_cycle <= timep);
}
// sinon, cycle mensuel
else
{
// on avance mois par mois
do
{
entetefic.deb_cycle += duree_cycle;
switch (++ oldstm.tm_mon)
{
// février
case 1: if (oldstm.tm_year % 4)
entetefic.duree_cycle = 28 * secjour;
else
entetefic.duree_cycle = 29 * secjour;
break;
case 3: // mois de 30 jours
case 5:
case 8:
case 10: entetefic.duree_cycle = 30 * secjour;
break;
// mois de 31 jours (7 mois par an)
default: entetefic.duree_cycle = 31 * secjour;
}
cycles_sautes ++;
}
// jusqu'à ce qu'on tombe sur le bon
while (entetefic.deb_cycle + duree_cycle <= timep);
}
}
// sinon (cas général, cycle de longueur régulière)
else
{
// calculer de combien de cycles on avance
cycles_sautes = (timep - entetefic.deb_cycle) / duree_cycle;
// calculer l'instant de début du cycle courant
entetefic.deb_cycle += cycles_sautes * duree_cycle;
}
// si calcul de pondération
if (entetevar.ponderation)
{
// calcul du coefficient de pondération
coef_pond = entetevar.ponderation;
if (entetevar.typedon & cpt_cycle_vide)
{
while (--cycles_sautes)
coef_pond = (coef_pond * entetevar.ponderation) >> 8;
}
// appliquer le calcul de pondération sur la variable
pondere (coef_pond);
}
}
// Retourne la durée du cycle actuel en secondes
// saute si nécessaire le 29 février dans les cycles annuels
uint32 duree_cycle_actuel (int32 *timep)
{
struct tm stm; // structure contenant la date et l'heure courante
// si cycle calendaire de longueur irrégulière
if (entetefic.caract_gen & cycle_ireg)
{
// dans le cas des cycles annuels
if (entetefic.caract_gen & cycle_annuel)
{
// récupérer la date courante
if (entetefic.caract_gen & temps_utc)
gmtime_r (timep, &stm);
else
localtime_r (timep, &stm);
// sauter le 29 février le cas échéant
if ((stm.tm_mon >= 2) && (stm.tm_year % 4))
*timep = *timep + secjour;
// l'année est compté sur 366 jours pour le graphique
return (366 * secjour);
}
// sinon, on est dans le cas des cycles mensuels
else
// le mois est compté sur 31 jours pour le graphique
return (31 * secjour);
}
// sinon (cas général, cycle de longueur régulière)
else
// on utilise la vraie durée du cycle
return (entetefic.duree_cycle);
}
// calcul du numéro de l'instant du cycle à mettre à jour
uint16 calcul_instant (uint32 timep, uint32 duree_cycle)
{
uint32 depuis_deb_cycle; // temps écoulé depuis le début du cycle
uint16 result; // résultat du calcul
// temps écoulé depuis le début du cycle courant
depuis_deb_cycle = timep - entetefic.deb_cycle;
// si on peut calculer le numéro d'instant
// sans débordement mathématique
if (((depuis_deb_cycle * entetefic.nb_don_cycle) / entetefic.nb_don_cycle)
== depuis_deb_cycle)
// calcul exact en arithmétique entière
result = depuis_deb_cycle * entetefic.nb_don_cycle / duree_cycle;
else
// sinon calcul approché en arithmétique flottante
result = (float)depuis_deb_cycle * entetefic.nb_don_cycle / duree_cycle;
// retour du résultat, les numéros d'instant
// vont de 1 à entetefic.nb_don_cycle
return (result + 1);
}