Projet

Général

Profil

SOP 001-Programmation » Historique » Révision 80

Révision 79 (Patrice Nadeau, 2022-11-13 10:55) → Révision 80/82 (Patrice Nadeau, 2022-11-13 10:55)

# SOP 001-Programmation 

 Mes standards autant au niveau du style que de la documentation. 

 La plate-forme (logiciel et matériel) est documenté dans le [[SOP_002-Environnement_informatique]]. 


 --- 

 {{toc}} 

 ## Diagrammes 

 Les représentations des différents processus d’un programme ou d’un circuit. 

 Les diagrammes DOIVENT être faits avec le logiciel Dia. 
 Ils PEUVENT être exportés en d’autre format. 

 ### LibreOffice Draw 

 Icônes : 

 * Cisco : http://www.cisco.com/web/about/ac50/ac47/3015_jpeg.zip 
 * http://www.vrt.com.au/downloads/vrt-network-equipment ou http://extensions.libreoffice.org/extension-center/vrt-network-equipment/ 

 ## Système de gestion de version 

 Le logiciel [Git](http://www.git-scm.com/) DOIT être utilisé. 

 La version DOIT être en format: *majeur*.*mineur*.*revision*. 
 Les nombres *majeur*, *mineur* NE DOIVENT PAS contenir de zéro non significatif et DEVRAIT se limiter à deux chiffres. 

 Ex. 
 > Version 1.2.06 

 Les modifications DOIVENT se faire avec **git commit**, de la manière suivante : 

 * nom du fichier modifié, 
 * 1 espace, 
 * nom de l’item modifié entre parenthèses, 
 * un deux- points (<notextile>:</notextile>) sans espace avec l’item précédent, 
 * 1 espace, 
 * le texte du changement en anglais, commençant par une majuscule, au présent, 
 * un point (.) 

 Ex. : 
 > Modification ajouté manuellement 


     git commit -m "usart.c (usart_Init): Add a new variable ctr." 

 > Modification par un éditeur texte 

     git commit 

 Si les commit sont fait sans l’option **-m**, chaque fichier DOIT être séparé par une ligne vide. 

 ## Code source 

 Les différents type de langage et de script décrit dans ce SOP. 

 ### Généralités 

 #### Langue 

 La langue (macros, variables, fonctions, commentaires, etc...) DOIT être l’anglais. 

 #### Commentaires 

 Les commentaires DOIVENT être : 

 * sur la ligne précédent l’item à documenter 
 * en minuscules et commencer par une majuscule 


 #### Nombre magique 

 L’utilisation de [nombre magique](:http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Unnamed_numerical_constants) ne DOIT PAS être utilisé directement dans le code. 
 Il DOIVENT être définis dans une macro ou une variable globale. 

 ## C 

 Le langage C, version C99 (ISO/IEC 9899:1999) utilisé avec le compilateur GCC. 

 ### Commentaires 

 Les commentaires ne devant pas être inclus dans une documentation, DOIVENT être de style « C » : 

 ``` c 
 /* Une seule ligne... */ 

 ... 

 /* 
 * Sur 
 * plusieurs 
 * lignes 
 */ 
 ``` 

 ### Doxygen 

 Chaque item DOIT être documentés de manière à générer une documentation avec le logiciel [Doxygen](http://www.stack.nl/~dimitri/doxygen/index.html). 

 Seulement les items définis dans les fichiers d’en-tête sont documentés par défaut. 
 Un commentaire Doxygen commence par *<notextile> /** </notextile>* , le compilateur le comprenant comme un commentaire ordinaire. 

 Les règles typographiques du [[SOP_000-Documentation]] s’appliquent : 

 * Gras (**@b**) : Items devant être inscrit tel quel. 
 * Italique & emphase (**@e**) : Items à remplacer par un choix ou nécessitant une attention particulière. 

 Les items DOIVENT être inscrit dans cet ordre : 

 ``` c 
 /** 
 * @brief Short description 
 * @param[in,out] var Description. @n Possible values : 
 * − @b value1 
 * − @b value2 
 * @return 
 * @retval @b value Description 
 * @par Example : 
 * Example Title 
 * @code 
 * ... 
 * @endcode 
 * @pre Requirements 
 * @post Changes after the call to this function 
 * @see See also ... 
 * @note 
 * @warning 
 * @bug 
 * @todo 
 */ 
 ``` 

 Des **@todo**, **@warning** et **@bug** supplémentaires PEUVENT être ajoutés dans le code. 
 L’item **@brief** DOIT toujours exister. 

 ### Code 

 Le code est dans le style K&R 

 * Le « tab » DOIT être équivalent à 4 espaces. 
 * Le « backslah » DOIT être utilisé pour les lignes de plus de 80 caractères. 
 * Une instruction par ligne. 
 * Un espace avant et après un opérateur sauf pour les opérateurs « [unary](http://en.wikipedia.org/wiki/Unary_operation). 

 ``` c 
 int fonction (void) 
 { 
     int x; 
     /* the comment goes here, before the loop */ 
     if (var != 1) { 
         x = x + 1; 
         y++; 
         printf("This is a long\ 
         line that should be splitted"); 
     } else { 
         /** @warning this is a Doxygen warning */ 
         x--; 
     } 
     return(0); 
 } 
 ``` 

 #### Fichier entête 

 Avertissement 
 >Le gabarit **template.h** DOIT être utilisé. 

 Les fichiers « header » DOIVENT contenir les déclarations des fonctions, macros et la partie « mainpage » de Doxygen. 

 Le nom du fichier DOIT être composé de la manière suivante : 

 * en minuscule 
 * 8 caractères maximum 
 * l’extension DOIT être **.h** 

 Une définition macro DOIT être faite pour éviter de ré-inclure le fichier. 
 La macro DOIT être dans le format *_fichier_h* 

 ``` c 

 #ifndef _usart_h 
 #define _usart_h 
 ... 

 #endif /*_usart.h*/ 
 ``` 

 #### Fichier source 

 Le nom du fichier DOIT être composé de la manière suivante : 

 * en minuscule 
 * 8 caractères maximum 
 * l’extension DOIT être **.c** 

 #### Librairies 

 Fichiers comprenant plusieurs déclarations et définitions reliés entre eux. 

 * Le nom DOIT respecter les standards ([[SOP_001-Programmation#Fichiers-Entêtes|1]] & [[SOP_001-Programmation#Fichiers-Sources|2]]) et être significatifs. 
 * Un fichier d’entête DOIT toujours exister. 
 * Les items sont précédés du nom de la librairie (minuscule) et séparés par un « underscore » (_). 

 L’utilisation de macros DOIT être utilisé au lieu de constates globales. 
 Il NE DEVRAIT PAS exister de de variables globales. 

 #### Déclarations locales 

 Une déclaration n’ayant qu’une visibilité locale DOIT être précédé d’un « underscore » (_) et être de classe *static*. 

 ``` c 
 /** 
 * @brief Local function 
 **/ 
 static void _LocalFunc(void) 
 { 
     ... 
     return; 
 } 
 ``` 

 #### Items désuets 

 Les déclarations ne devant plus être utilisés, DOIVENT générer un message lors de la compilation (*-Wall*) si un appel est effectué. 

 L’attribut **__attribute\_\_((deprecated))** DOIT être ajouté à la déclaration. 
 La documentation DOIT indiquer les substituts à utiliser. 

 ``` c 
 /** 
 * @brief OldFunction 
 * @detail will generate a warning if used 
 * @see @b NewFunction 
 */ 
 int OldFunction(void) __attribute__((deprecated)); 
 ``` 

 #### Constantes 

 La déclaration DOIT inclure aussi la définition. 

 Utilisé au lieu d’une macro quand le type ou la visibilité de la variable doit être définis. 

 * En majuscule 
 * Séparé par un «underscore» (_) si contient plusieurs mots 
 * De classe _static_ ou _extern_ selon le besoin 

 Ex. : 

 ``` c 
 /**  
 * @name List of constants 
 * @{ 
 */ 

 /** 
 * @brief Local const 
 */ 
 static int _PI = 3.15; 
 /** 
 * @brief The initialization string of the project 
 */ 
 static const char INIT_STR[6] = {'P', 'O', 'W', 'E', 'R'}; 
 /** 
 * @brief Global const in the random library 
 */ 
 extern int random_MAX = 25; 

 /** 
 * @} 
 */ 
 ``` 

 #### Typedef 

 Format : 

 * En minuscule, suivie de **_t** 

 Définition de typedef 

 ``` c 
     /** Unsigned integer 8 bits */ 
     typedef unsigned int new_t 
     /** Type of structure in the ds1305 library */ 
     typedef struct { 
         /** @brief last two digits : &ge; 00, &le; 99 */ 
         uint8_t year; 
    	 /** @brief 01 - 12 */ 
         uint8_t month; 
         /** @brief 01 - 31 */ 
         uint8_t date; 
         /** @brief 1 - 7 */ 
         uint8_t day; 
    	 /** @brief 00 - 23 */ 
         uint8_t hours; 
         /** @brief 00 - 59 */ 
         uint8_t minutes; 
         /** @brief 00 - 59 */ 
         uint8_t seconds; 
     } ds1305_time_t; 
 ``` 

 #### Variables 

 Format : 

 * En minuscule. 
 * Séparé par un « underscore » (_) si contient plusieurs mots. 

 Définition de variables 

 ``` c 
     /** @brief Local variable */ 
     int _ctr; 
     /** @brief Global variable from the random librairy */ 
     int random_ctr; 
 ``` 

 #### Structures 

 Format 
 * En minuscule, séparé par des «underscores» si nécessaire. 

 Définition de structures 

 ``` c 
 /** 
 * @brief Structure for a local menu 
 * @see MenuSelect 
 */ 
 struct menu { 
 /** @brief Character used for the item */ 
 char choice; 
 /** @brief Description of the item */ 
 char *item; 
 }; 
 ``` 

 #### Fonctions 

 Le nom est formé d’une lettre majuscule pour chacune des premières lettres des mots. 

 Le nom DOIT être dans un deux formats suivants : 

 * ActionItemAttribut, où _Action_ signifie : 
   * *Get* : Lis un registre 
   * *Read*, *Write* : Lis ou écris dans un fichier 
   * *Set* : Écris une valeur prédéfini dans un registre 
   * *Init* : Fonction d’initialisation 
 * isItemEtat 
   * *is* : Verifie si _Item_ est dans l’état _Etat_ 

 Exception 
 > Les fonctions définies dans une librairie de bas niveau pour du matériel (« driver »). Dans ce cas, le nom définis dans le « datasheet » aura préséance. Ex. ReadRegister. 

 Une fonction DEVRAIT retourner une valeur.  

 Dans le cas d'un « oui/non », la valeur DOIT être : 

 * Succès : **0** 
 * Erreur : **1** 

     > L'utilisation d'un type booléen (*true* & *false*) est permise avec la librairie **\<stbool.h\>** (C99). 

 Dans le cas d'une fonction retournant un pointeur : 

 * Erreur : **NULL** 
 * Autre valeur    : adresse du pointeur 

 Définition de fonctions 

 ``` c 
 /** 
 * @brief Check if a timer is set 
 * @param[in] nb Timer number. @n Possible values : 
 * − @b TIMER_1 
 * − @b TIMER_2 
 * @return 
 * @retval true Timer @e nb is set 
 * @retval false Timer @e nb is NOT set 
 * @par Example : 
 * Check if the timer is set 
 * @code{.c} 
 * ... 
 * result = isTimerSet(); 
 * ... 
 * @endcode 
 * @pre TimerInit 
 **/ 

 static bool isTimerSet(uint8_t nb); 
 /** 
 * @brief Set the led to green 
 **/ 
 SetLedColor(GREEN); 
 /** 
 * @brief Set register of the chip XYZ 
 * 
 * The name does not follow the standards but does match the datatsheet 
 * This is a local function not meant to be called outside this librairy 
 **/ 
 static void _WriteReg(void); 
 ``` 

 ### Macros 

 Les directives du préprocesseur C. 

 * Utilisé dans le code source et les fichiers entête. 
 * DOIT toujours commencer à la colonne 0. 

 #### #include 

 Pour inclure d’autres fichier comme les fichiers entête. 
 >N’est pas documenté dans Doxygen. 

 #### ifdef / ifndef 

 Surtout utiliser pour des options de compilation sur différentes plateforme. 
 > N’est pas documenté dans Doxygen. 

 ``` c 
 #ifndef usart_AVR 

 #error "usart.h is not supported on this AVR !" 

 #endif 
 ``` 

 #### #error 

 Affiche une erreur et arrête la compilation 
 >N’est pas documenté dans Doxygen. 

 ``` c 

 #ifndef __test__ 

     #error "Error !" 

 #endif 
 ``` 

 #### #warning 

 Affiche une erreur mais n’arrête la compilation 
 >N’est pas documenté dans Doxygen. 

 ``` c 
 #ifndef __test__ 

 #warning "Warning !" 

 #endif 
 ``` 

 #### #define  

 Définis une valeur au moment de la compilation. 

 * Format 
     * En majuscule. 
     * Séparé par un «underscore» si contient plusieurs mots. 
 * Doxygen 
     * @brief 
     * @name pour les listes de macros (regroupement dans la documentation) 

 Définition de macros 

 ``` c 
 /** 
 * @name Mathematical macros listed together 
 * @{ 
 */ 
 /** @brief Value for PI */ 

 #define _PI 3.14 
 /** @brief Another number */ 
 #define _MAGIC_NUMBER 42 
 /** 
 * @} 
 */ 
 /** @brief Even parity */ 

 #define usart_PARITY_EVEN 'e' 
 ``` 

 ### Atmel AVR 

 Particularités pour les micro-contrôleurs AVR d’Atmel. 

 * Progmem : Pour mettre une fonction en Flash au lieu de SRAM. 
     * Le nom de la fonction est suivie de **_P** 
 * main : Ne revient jamais à un niveau supérieur. 
     * Définir la fonction main avec l’attribut **noreturn** 
     * La boucle sans fin la plus optimisé est le **for (;;)** 
 * Atomic : Opérations ne devant pas être interrompus 

 Particularités pour AVR 

 ```c 
 /** 
 * @brief Progmem function 
 * @return An unsigned 8 bits integer 
 */ 
 uint_8t PrintString_P() 

 /* main function */ 
 void main(void) __atribute__((noreturn)) 
 { 
     ... 
     /* never return */ 
     for (;;) { 
     } 
 } 

 /* atomic operations */ 

 #ifndef S_SPLINT_S 
 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { 
 /*  
 * operations that must not be interupted 
 * like loading a 16 bit register with a 8 bit register  
 */ 
 } 
 #endif 
 ``` 

 ### Distribution 

 Les fichiers suivants DOIVENT être inclus dans une distribution en format **tar.gz** :  

 * ChangeLog 
 * README 
 * Files.lst 
 * Makefile 
 * Makefile.mk 
 * LICENSE.txt 
 * *.c 
 * *.h 
 * projet.pdf (généré par Doxygen) 

 Avec mon makefile : 

 ```bash 
 make dist 
 ``` 

 ### Modifications 

 Un changement à un fichier (source ou en-tête), doit se refléter dans _Git_. 

 Chaque changement est fait avec : 

 ```bash 
 git add nom_fichier 
 git commit 
 ``` 

 La ligne DOIT  

 * être au temps présent 
 * être en anglais 
 * se termine par un point 
 * être dans le format suivant : 
     > La partie _section_ est facultative 


     fichier1 (fonction) <section>:  
     Ajoute une description au temps présent. 
     Décrire les bogues réglés si il y en avaient. 

 ### Changelog 

 La somme de toutes les modification doivent apparaitre dans un fichier « changelog ». 
 > Le standard seras celui GNU : http://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs 

 Ce fichier doit s'appeler **ChangeLog** et DOIT être généré à partir de _Git_ (les doubles espaces ne sont pas une erreur de frappe : 

 ```bash 
     git log --no-merges --format="%ad    %an    <%aE> %n * %B" --date=short > ChangeLog 
 ``` 
   
 ### Validation du code 

 Le logiciel _splint_ est utilisé. 

 * Un « typecast » DOIT être utilisé lorsque détecté. 
 * L’utilisation du typecast *void* DOIT être utilisé lorsque qu’une fonction retourne un résultat non utilisé. 

 ## Makefile 

 ## Nagios 

 ### Plugins 

 https://nagios-plugins.org/doc/guidelines.html 

 Un message d'une ligne (< 80 caractères) DOIT être retourné via _STDOUT_ dans le format 
 > *SERVICE STATUS:* texte 

 Les codes de retour sont les suivants : 

 |_. Valeur |_. Service Status |_. Description | 
 | 0 | OK | Le service fonctionne | 
 | 1 | Warning | Le service fonctionne, problème avec le seuil de la valeur _Warning_ | 
 | 2 | Critical | Le service ne fonctionne pas ou problème avec le seuil de la valeur _Critical_    | 
 | 3 | Unknow | Arguments non valides ou erreur interne (fork, tcp socket)| 

 Les arguments suivants DOIVENT être fournis : 

 * *-H* (*--hostname*) : 
 * *-w* (*--warning*) : 
 * *-c* (*--critical*) : 
 * *-V* (*--version*) : 
 * *-h* (*--help*) : 

 L'argument _--help_ DOIT aussi appeler l'argument _--version_. 

 En _C_, les fonctions suivantes DOIT être utilisées : 

 * _print_revision_ (utils.c) 
 * _print_help_ 
 * _getopt_long_ (getopt.h) 

 ## Puppet 

 ### Généralités 

 Inspiré des recommandations disponible au http://docs.puppetlabs.com/guides/style_guide.html. 

 * Tabulation : 2 espaces 
 * Largeur : 80 caractères (« backslah » (\) pour séparer une longue ligne). 
 * Commentaires : Style # 
 * Guillemets 
     * Simple : Pour une « string » sans variables. 
     * Double : Pour une « string » avec variables ayant besoin d’être extrapolé. 
         * La variable doit être entourée des symboles *<notextile>{</notextile>* et *<notextile>}</notextile>*. 
 * Nom des ressources : DOIVENT être entouré du symbole *<notextile> ’ </notextile>*. 
 * Alignement de => : DOIT être aligné dans un même paragraphe. 
 * Ordre : Si l’attribut _ensure_ doit être inclus, il DOIT être le premier. 
 * Lien symbolique : DOIT être déclaré avec *ensure => link* 

 Ex. : 

     file { '/var/log/syslog': 
     ensure => link, 
     target => '/var/log/messages', 
     } 

 * File mode :  
     * 4 chiffres 
     * simple guillemet 
 * Variables 
     * lettres 
     * chiffres 
     * « underscore » 

 ### Documentation 

 http://docs.puppetlabs.com/learning/modules2.html#module-documentation 

 Format Rdoc (http://rdoc.rubyforge.org/RDoc/Markup.html) : 

 * Bloc de commentaires qui commence sur la première ligne du fichier 
 * Titre avec le symbole *<notextile>=</notextile>* 
 * Séparation avec le symbole *<notextile>-</notextile>* 
 * Emphase (mot entouré du symbole) 
     * * : gras 
     * _ : souligné 
     * + : Police de caractères pour le code 
 * Sections 
     * = Class: 
     * == Parameters: 
     * == Requires: 
     * == Sample Usage: 
 * Classe 
     * Une classe par fichier « manifest » 

 ## Script 

 ### Bash 

 ``` bash 

 #/bin/bash 

 function print_revision { 
 } 

 function print_help { 
     print_revision 
 } 
 ``` 
    
 ### Perl 

 

 ### PowerShell 

 Version 4.0. Supporte : 

 * Windows 8.1 (natif) 
 * Windows Server 2012 R2 (natif) 
 * Windows 7 SP1 
 * Windows Server 2008 R2 SP1 
 * Windows Server 2012 

 #### Fichier 

 Le fichier DOIT être composé de la manière suivante : 

 * L’extension est **.ps1** 
 * Une longue ligne peux être séparée avec un « back tick » (‘). 

 #### Commentaires 

 L’aide est accédée par _Get-Help_ 


	 #REQUIRES -Version 2.0 
	 <# 
	 .SYNOPSIS 
	 A brief description of the function or script. 
	 This keyword can be used only once in each topic. 
	 .DESCRIPTION 
	 A detailed description of the function or script. 
	 This keyword can be used only once in each topic. 
	 .NOTES 
	 File Name 
	 : xxxx.ps1 
	 Author 
	 : 
	 Prerequisite 
	 : PowerShell V2 over Vista and upper. 
	 Copyright 2011 - 
	 .LINK 
	 Script posted over: 
	 http:// 
	 .EXAMPLE 
	 Example 1 
	 .EXAMPLE 
	 Example 2 
	 #> 

 ## Vim 

 * Entête (en commentaires) 
     * Titre 
     * Last Change: 
     * Maintainer: 
     * License: This file is placed in the public domain. 
 * Autre mots reconnus 
     * BUG: (Error:) 
     * TODO: 
     * Note: 
     * FIXME 

 ## Références 

 Références ayant servis à ce document. 

 [ChangeLog](http://www.gnu.org/prep/standards/html_node/Change-Logs.html#Change-Logs) 
 [GNU deprecated attribute](http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/Type-Attributes.html)