%
%     This file is part of the Code_Saturne Preprocessor, element of the
%     Code_Saturne CFD tool.
%
%     Copyright (C) 1998-2007 EDF S.A., France
%
%     contact: saturne-support@edf.fr
%
%     The Code_Saturne Preprocessor is free software; you can redistribute it
%     and/or modify it under the terms of the GNU General Public License
%     as published by the Free Software Foundation; either version 2 of
%     the License, or (at your option) any later version.
%
%     The Code_Saturne Preprocessor is distributed in the hope that it will be
%     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
%     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%     GNU General Public License for more details.
%
%     You should have received a copy of the GNU General Public License
%     along with the Code_Saturne Preprocessor; if not, write to the
%     Free Software Foundation, Inc.,
%     51 Franklin St, Fifth Floor,
%     Boston, MA  02110-1301  USA
%


\section{Conventions et règles\label{cha:convention}}


\subsection{Nommage\label{sec:nommage}}


\subsubsection{Généralités\label{sec:nommage.gener}}

Les règles suivantes sont appliquées dans le \pcs~:

\begin{liste}
\item le nom d'un identificateur comporte au plus 31~caractères (ANSI C)~;
\item le nom d'un identificateur est en minuscules
  sauf le nom d'une macro ou d'une énumération qui est entièrement
  en majuscules~;
\item un identificateur global a un nom préfixé par
  \verb=ecs_= ou \verb=ECS_=~;
\item un identificateur local à un fichier a un nom préfixé par
  \verb=ecs_loc_= ou  \verb=ECS_LOC_=~:
  \begin{liste}
  \item le nom d'une fonction locale à un fichier (\fc{static})
    sera préfixé par \verb=ecs_loc_=~;
  \item le nom d'une énumération locale à un fichier 
    sera préfixé par \verb=ECS_LOC_=~;
  \item le nom d'une macro locale à un fichier
    sera préfixé par \verb=ECS_LOC_=~;
  \item le nom d'une macro locale à une fonction
    sera préfixé par \verb=ECS_FCT_=~;
  \end{liste}
\end{liste}


\subsubsection{Nommage des énumérations\label{sec:nommage.enum}}

Dans la version 1.0, les énumérations étaient écrites sous la forme~:

\begin{quote}
\begin{alltt}
typedef enum \{ ECS_ENUMERATION_ENUMERATEUR1,
               ECS_ENUMERATION_ENUMERATEUR2,
              \( /* etc. */ \)
             \} ECS_ENUMERATION_E;
\end{alltt}
\end{quote}

On préfère maintenant utiliser la forme~:

\begin{quote}
\begin{alltt}
typedef enum \{ ECS_ENUMERATION_ENUMERATEUR1,
               ECS_ENUMERATION_ENUMERATEUR2,
              \( /* etc. */ \)
             \} ecs_enumeration_t;
\end{alltt}
\end{quote}


\subsubsection{Nommage des \classes\label{sec:nommage.classe}}

La structure objet du \pcs reposant aussi sur des conventions,
on a donc déjà eu l'occasion d'exposer les 
conventions de nommage sur les \classes~:
on se reportera aux sections~\ref{sec:config},
\ref{sec:structure} et \ref{sec:util.paquet}.

On reprend ici le cas d'une \classe générique dont la structure~C
a pour nom \classet
(définie comme alias par \fc{typedef} de \verb=struct _ecs_classe_t=).

Les macros et les énumérations liées à la \classe
sont préfixées par \verb=ECS_CLASSE_=.

Les fonctions implémentant les \methodes ont un nom de la forme~:

\begin{quote}
\fc{ecs\_}[\fc{loc\_}]\classe[\fc{\_}mot-clé]\fc{\_\_\textit{xyz()}}
\end{quote}

où~:
\begin{liste}
\item \fc{loc\_} est présent s'il s'agit d'une fonction locale à un fichier;
\item \og mot-clé \fg désigne, pour le sous-système \Base~:
  \begin{liste}
  \item soit une sous-\classe;
  \item soit une classe associée;
  \item soit un type de collection de la classe (\fc{chaine} ou \fc{arbre}).
  \end{liste}
\end{liste}

Les fichiers contenant ces fonctions sont de la forme~:
\begin{quote}
\fc{ecs\_}\classe[\fc{\_}mot-clé].c
\end{quote}

Dans la section~\ref{sec:structure.champ.repart} on a donné
les fichiers qui contiennent les fonctions de la structure \champt.

Ci-dessous, on trouve deux exemples concernant la structure \descrt~:\\
l'exemple~\ref{ex:nommage.descr.1} retranscrit le fichier
\verb=ecs_descr.h= tandis que ~\ref{ex:nommage.descr.2}
donne l'exemple d'une fonction déclarée dans
\verb=ecs_descr_chaine.h=.


\begin{exemple}{Nommage pour un \descr (1)\label{ex:nommage.descr.1}}
/*---------------------------------------------------------------------------
 *  Déclaration de la structure
 *---------------------------------------------------------------------------*/

typedef struct _ecs_descr_t ecs_descr_t;


/*---------------------------------------------------------------------------
 *  Définition d'énumération
 *---------------------------------------------------------------------------*/

typedef enum \{ ECS_DESCR_COULEUR,
               ECS_DESCR_GROUPE
             \} ecs_descr_typ_t;


/*---------------------------------------------------------------------------
 *  Définition de macros
 *---------------------------------------------------------------------------*/

#define ECS_DESCR_NUM_NUL -1
#define ECS_DESCR_IDE_NUL -1
#define ECS_DESCR_ENT_NUL -1
\end{exemple}


\begin{exemple}{Nommage pour un \descr (2)\label{ex:nommage.descr.2}}
/*----------------------------------------------------------------------------
 *  Fonction qui recherche dans une liste chaînée de descripteurs
 *   dont la tête est donnée,
 *   un numéro de descripteur donné
 *
 *  La fonction renvoie :
 *  -    le pointeur du descripteur si le numero de descripteur a ete trouve
 *  - ou NULL                       sinon
 *----------------------------------------------------------------------------*/

ecs_descr_t *
ecs_descr_chaine__cherche_num(ecs_descr_t  *descr_tete,
                              ecs_int_t     num);
\end{exemple}


\subsection{Présentation des sources\label{sec:codage}}


\subsubsection{Généralités}

Le codage des sources du \pcs respecte
les conventions de présentation suivantes~:
\begin{liste}
\item pas d'indentation~: 2 caractères~;
\item longueur maximale des lignes~: 80 caractères~;
\item emploi systématique des minuscules pour
  les instructions et les identificateurs, sauf pour les identificateurs
  des macros et des énumérations qui sont entièrement en majuscules.
\end{liste}


\subsubsection{Présentation des fonctions}

L'exemple~\ref{ex:nommage.descr.2} donne un exemple
de présentation des fonctions dans le \pcs.


\subsection{Programmation\label{sec:regle}}


\subsubsection{Langage\label{sec:regle.lang}}

Le langage C est utilisé dans sa version ANSI 1989.

Afin de donner un certain confort à l'utilisateur du \pcs,
quelques extensions à la norme ANSI ont été introduites dans le code.
Ces extensions ne sont intégrées que si des variables d'environnement
ont été effectivement positionnées au moment de la compilation
\refpar{sec:compil.var}.
Autrement dit, il est toujours possible d'exclure
ces extensions sans que le fonctionnement du \pcs en soit
perturbé.

Certains aspects douteux du langage~C ont été conservés par la norme ANSI
pour des raisons historiques
de compatibilité avec les versions diffusées du langage avant
normalisation. On pense surtout à la possibilité de définir une fonction
sans en avoir préalablement défini un prototype (i.e. déclaré son interface).
Ces aspects du langage (qui n'ont d'ailleurs pas été retenus en C++) ne seront
pas utilisés dans le cadre du module \pcs.
Les versions récentes des compilateurs~C préviennent généralement
par un \og warning \fg en cas d'utilisation de ces aspects du langage.
La compilation en C++ du \pcs permet de les repérer à coup sûr.

La compilation systématique sur différentes plates-formes (avec les options
de compilation appropriées) et la compilation en C++,
devrait garantir le respect de la norme ANSI, ainsi que
l'absence d'utilisation d'aspects douteux du langage~C.


\subsubsection{Règles de programmation\label{sec:regle.regle}}

Les règles de programmation utilisées dans le \pcs sont classiques.

Citons quelques règles en vrac~:

\begin{liste}
\item chaque variable doit être initialisée avant d'être utilisée\\
  (les pointeurs seront systématiquement initialisés à NULL)

\item l'usage des variables globales doit être évité en dehors des
  fonctions utilitaires de base de la librairie ou des chaînes de
  caractère statiques représentant les divers messages affichés.\\
  Si la création d'une variable globale à un fichier est justifiée,
  elle doit être déclarée \fc{static}.\\
  De même, une variable globale à une fonction doit être déclarée \fc{static}.

\item un type \fc{const} ne doit pas être converti en un type non-\fc{const}

\item chaque fois que la valeur d'une expression doit être testée parmi
  un ensemble de constantes,
  une construction \fc{switch} doit être préférée à une construction\\
  \fc{if \dots\ else if \dots\ else \dots}

\item les clauses \fc{case} d'un \fc{switch} doivent être des énumérateurs

\item chaque \fc{switch} doit avoir une clause \fc{default}

\item tous les paramètres des macros doivent être entourés de parenthèses

\item les structures qui ne sont utilisées qu'à travers des pointeurs
  ne doivent pas être incluses dans les fichiers d'en-tête (\og .h \fg)

\item lorsqu'une fonction est définie dans un fichier source \og .c \fg,
  le fichier d'en-tête \og .h \fg qui contient sa déclaration
  doit être inclus

\item un fichier d'en-tête \og .h \fg doit se suffire à lui-même

\item un fichier d'en-tête \og .h \fg doit avoir un mécanisme pour
  prévenir les inclusions multiples

\item le type de retour d'une fonction doit toujours être indiqué
\end{liste}


Deux règles concernant les arguments des fonctions, n'ont
pas toujours, à tort, été appliquées~:

\begin{liste}
\item l'attribut \fc{const} sera utilisé si un pointeur ou une variable
  n'est pas modifié
\item si un paramètre pointeur est utilisé en tant que tableau
  dans la fonction, le paramètre doit être déclaré avec des crochets
\end{liste}


\subsubsection{Assertions\label{sec:regle.assert}}

Les assertions sont des conditions qui doivent toujours être remplies.\\
Elles servent~:
\begin{liste}
\item à la mise au point du programme~;
\item à la vérification du programme~;
\item à l'auto-documentation du programme.
\end{liste}

Les assertions jouent un rôle important dans la mise en \oe{}uvre
de la programmation par contrat.\\
Chaque fonction doit répondre à un contrat.
Une fonction reçoit des paramètres en entrée qui doivent répondre à
certaines contraintes, et doit effectuer les traitements attendus
par la fonction appelante.\\
On peut donc définir trois types de conditions devant être remplies~:
\begin{liste}
\item pré-condition~: condition devant toujours être remplie
  à l'entrée de la fonction~;
\item post-condition~: condition devant toujours être remplie
  à la fin d'une fonction~;
\item invariant~: condition devant toujours être remplie à n'importe quel
  endroit de la fonction.
\end{liste}
Grâce aux assertions, le programme se teste de lui-même lors
de son exécution~!

Le~C~ANSI déclare une macro-instruction \fc{assert()} permettant
de vérifier si une condition est vraie.
Si la condition n'est pas vérifiée, le programme est interrompu et un message
d'erreur indique le fichier et la ligne où la macro \fc{assert()}
a été appelée.
Le \pcs fait un usage fréquent des assertions,
en particulier pour vérifier les pré-conditions.

Si la macro \fc{NDEBUG} est définie à la compilation, tous les \fc{assert()}
se réduisent à une instruction nulle. C'est le cas pour les options
de compilation utilisées par défaut.
Par conséquent, pour la version \og principale \fg installée, l'utilisateur
ne sera pas pénalisé par les tests d'assertion, mais il pourra en bénéficier
en cas de problème avec une version \og DEBUG \fg.


\subsubsection{Constantes nommées\label{sec:regle.const}}

L'utilisation de constantes numériques nommées en lieu et place de constantes
littérales rend les modifications des valeurs des constantes plus
fiables et aisées. Elle facilite donc largement la maintenance ultérieure
du programme, ainsi que son extension.

Leur définition en~C prendra l'une des formes suivantes~:
\begin{liste}
\item constante énumérée, pour une constante appartenant à un ensemble
  de constantes liées sémantiquement et pouvant ainsi former
  une liste d'énumérations
\item une macro du pré-processeur.
\end{liste}

En particulier, les constantes nommées apparaîtront systématiquement
dans les \fc{case} des \fc{switch}. Les constantes énumérées sont
préférées, car elles apparaissent sous leur nom (et non valeur)
sous un débogueur, et certains compilateurs (tels que GCC)
peuvent afficher des messages d'avertissement lorsque
certaines valeurs d'une constante énumérée ne son pas traitées
dans un \fc{switch}.

\subsubsection{Internationalisation\label{sec:regle.intl}}

L'internationalisation des messages se fait au moyen du mécanisme
de type {\tt gettext()}. Les messages on été passés en Anglais
dans le code source, et la version Française est disponible
via un catalogue de traductions {\tt po\/fr.po}. Ceci a l'avantage
avec la version GNU de {\tt gettext()} de fonctionner aussi bien
avec un environnement Latin-1 (ou Latin-9 ou Latin-15) qu'avec
une environnement \og Unicode \fg de type UTF-8 (à condition
que l'encodage utilisé par le terminal soit consistant avec
la variable d'environnement {\tt LANG}, soit en général
{\tt LANG=fr\_FR} ou {\tt LANG=fr\_FR.UTF-8}.

On doit donc encapsuler les déclarations de chaînes de caractère
immédiatement traduisibles dans une macro {\tt\_( )} (correspondant
à une abbréviation pour {\tt gettext()} si ce mécanisme est disponible
sur la machine cible, ou à une macro vide sinon). On encapsulera les
chaînes dont la traduction ne peut se faire à l'initialisation (i.e.
déclarées via des constantes) dans une macro {\tt N\_( )} (macro vide
permettant le repérage de ces chaînes par les outils de gestion des
catalogues de traduction), en n'ommettant pas d'encapsuler la variable
résultante dans la macro {\tt\_( )} lors de son utilisation.

Si une chaîne n'est pas traitée de la sorte ou que sa traduction
n'est pas disponible, la chaîne non traduite sera utilisée. Les
conséquences ne sont donc pas catastrophiques.

On notera qu'avec des chaînes de caractères de type UTF-8,
les caractères accentués sont représentés sur plusieurs octets,
alors que les caractères ASCII de base sont représentés
sur un seul octet. La fonction C {\tt strlen()} permet donc
de connaître la taille d'un chaîne en octets, mais pas de dire
combien de colonnes elle occupe pour l'affichage. On utilisera
la fonction {\tt ecs\_print\_padded\_str()} pour imprimer
une telle chaîne en la complétant automatiquement par le bon
nombre de caractères blancs lorsqu'on souhaite occuper une
largeur de colonne donnée.


\subsubsection{Fonctions utilitaires\label{sec:regle.fonct}}

Aux fonctions de la librairie~C standard, on préférera, quand elles existent,
les fonctions (ou les macros) de la librairie BFT ou du \pcs qui les
encapsulent.\\
Ces fonctions ont l'avantage d'intégrer les tests de retour des fonctions
de la librairie, en produisant les messages d'erreur appropriés
en cas d'erreur.

Le tableau ci-dessous recense les principales fonctions de la librairie~C standard
qui ont une fonction utilitaire correspondante dans le \pcs ou dans la librairie
BFT. Cette librairie propose ou \og améliore \fg (au sens de l'écriture
d'un code scientifique) d'autres services, et dispose de sa propre documentation
en ligne.

\begin{center}
\begin{tabular}{|l|l|l|l|}
\hline
\multicolumn{1}{|c}{Fonction de}    & \multicolumn{1}{|c}{Fichier en-tête} & \multicolumn{1}{|c}{Macro ou fonction} & \multicolumn{1}{|c|}{Fichier}\\
\multicolumn{1}{|c}{la librairie~C} & \multicolumn{1}{|c}{système}         & \multicolumn{1}{|c}{utilitaire}        & \multicolumn{1}{|c|}{\pcs}\\
\hline
\verb=exit()=   & \verb=stdlib.h=& \verb=ecs_exit()=        & \verb=ecs_exit.c=\\
\verb=fopen()=  & \verb=stdio.h= & \verb=bft_file_open()=   & \verb=bft_file.h=\\
\verb=fclose()= & \verb=stdio.h= & \verb=bft_file_free()=   & \verb=bft_file.h=\\
\verb=fprintf()=& \verb=stdio.h= & \verb=bft_printf()=      & \verb=bft_printf.h=\\
\verb=malloc()= & \verb=stdlib.h=& \verb=BFT_MALLOC()=      & \verb=bft_mem.h=\\
\verb=realloc()=& \verb=stdlib.h=& \verb=BFT_REALLOC()=     & \verb=bft_mem.h=\\
\verb=free()=   & \verb=stdlib.h=& \verb=BFT_FREE()=        & \verb=bft_mem.h=\\
\hline
\end{tabular}
\end{center}


%\passepage

