# Manuel Bluefish, chapitre 4

préc | sommaire | suiv

# Chapitre 4: Règles de développement

Ce document décrit les conventions de codage utilisées pour le projet Bluefish. Merci de nous communiquer les améliorations ou suppléments.

Ceci n'est pas fait pour vous empêcher de programmer, mais pour structurer un peu le programme. Bluefish n'est pas très bien structuré pour le moment mais j'essaie d'améliorer ça un peu.

Bonne programmation !
Olivier Sessink
http://bluefish.openoffice.nl/

### Debugger Bluefish

#### Plantages - la backtrace

Pour faire une backtrace utile, si vous n'avez aucune idée de l'endroit où le programme se plante, aller dans le répertoire où se trouve le source de Bluefish et exécuter la commande suivante :`make distclean ./configure --with-debugging-output make gdb src/bluefish` Cela va démarrer le debugger avec le nouveau binaire fraîchement compilé. Si vous avez une idée, ouvrir ce fichier et ajouter `#define DEBUG` au début, et exécuter`make distclean ./configure make gdb src/bluefish` Une fois le debugger démarré, tapez `r<enter>`, si le debugger s'arrête en disant qu'il n'est pas autorisé à lire la mémoire, taper `c<enter>`. Exécuter le programme jusqu'à ce qu'il se plante, exécuter alors `bt<enter>`. Envoyer la sortie (disons les 50 dernières lignes) à la mailing list de développement. Cela nous donne des informations de débogage et nous dit où est localisé exactement le plantage dans le programme.

### Style de formatage et indentation

Sois juste paresseux et utilise :`cd src indent -kr -ts4 *.c *.h` C'est le style de codage de Kernighan & Ritchie, avec une indentation de 4.

Ne pas utiliser de commentaires à la C++ mais des commentaires de type C, /* et */. gcc fait les choses bien, mais d'autres compilateurs pourraient se plaindre de ça.

### Nommer

Utiliser void name_cb() pour un appel qui peut être global, comme l'appel pour ouvrir un dialogue (cela peut être autre chose qu'un void)

Utiliser static void name_lcb() pour appel local, comme le clic sur OK dans une boîte de dialogue. (cela aussi peut être autre chose qu'un void)

Essayer d'avoir des noms qui expliquent ce que fait la fonction, par exemple doc_do_replace() devrait faire un remplacer dans un document spécifique,etc.

Dans document.c nous avons réellement un standard maintenant. Toutes les fonctions commencant par doc_...() prennent un Tdocument comme argument. Toutes les fonctions sans, sont soit vieilles (et doivent être renommées) ou sont des fonctions qui travaillent sur le main_v->current_document (un pointeur sur le document visible courant)

### Nom des titres, boîtes de dialogue, entrées de menus, etc.

Pour fournir une interface homogène nous devons être sûr qu'elle est un peu organisée:

- Les entrées de menu qui mènent sur un dialogue doivent être suivies de trois points (...)
- Les titres de fenêtre devraient tous ressembler à quelque chose comme :
  - Bluefish: Avertissement, un fichier (ou plusieurs) ont été modifiés!
  - Bluefish: Préférences
  - Bluefish: Avertissement, le fichier est ouvert

### Déclaration de procédures

Toujours déclarer static les fonctions qui n'ont pas besoin d´être visible en dehors du fichier courant static. Raison: Eviter de polluer l'espace de dénomination global. Les fonctions statiques seront liées uniquement à l'intérieur du même fichier. Toutes les procédures utilisées dans d'autres fichiers (public) doivent être déclarées dans le fichier .h declaré.

Toutes les variables qui sont utilisées dans d'autres fichiers (public) doivent être dans le .h avec un extern devant elles. Mais essayez d'éviter les variables globales. La plupart du temps vous pouvez les éviter en créant une structure typedef.

Ne mettez aucun extern bla() au début d'un fichier .c, utilisez #include otherfile.h à l'intérieur à la place. Ainsi si vous modifiez une fonction vous avez seulement à modifier le fichier .h. En résumé : Déclarez les fonctions globales dans le fichier .h et nulle part ailleurs.

### Fichiers d'en-tête

Si vous incluez des fichiers d'en-tête comme `#include <string.h>` ajoutez s'il vous plait un commentaire qui explique pourquoi ce fichier est nécessaire, comme `#include <string.h> /* strlen() */`

### Nouveaux fichiers

Si vous écrivez un nouveau fichier .c, écrivez aussi un fichier .h pour lui et incluez le fichier .h dans le fichier .c. Utilisez des directives d'inclusion conditionnelle dans tous les fichiers .h comme dans bluefish.h

    #ifdef __BLUEFISH_H
    #define __BLUEFISH_H
    ... all the declarations here ...
    #endif

Raison: permettre au compilateur de vérifier la cohérence entre le .c et le .h

### Quels fichiers

Par ordre alphabétique:

- bflib.c - fonctions générales sans rapport avec l'interface, comme des fonctions de traitements de chaînes et plus
- bluefish.c - démarrage et sortie, gestion de la file des messages
- callbacks.c - fonctions générales comme l'appel à Weblint
- cap.c - balises HTML en majuscules ou pas
- char_table.c - une table des caractères et des entités spéciales
- coloursel.c - dialogue de sélection des couleurs
- configure.c - dialogue de configuration
- document.c - toutes les fonctions qui gère le Tdocument, couper, copier et coller et d'autres fonctions qui travaillent sur les documents
- gtk_easy.c - raccourcis vers des fonctions GTK faciles à utiliser, afin d'éviter la répétition de code, utilisé dans de nombreux autres fichiers
- highlight.c -code pour la mise en surbrillance de la syntaxe
- html.c - dialogues html et fonctions
- html_diag.c - fonctions utilisées pour construire les dialogues HMTL
- html_table.c - dialogues pour les tableaux html et fonctions
- html_form.c - dialogues pour les formulaires html et fonctions
- images.c -dialogues pour les images et les aperçus d'image
- init.c - lecture des fichiers de configuration (rcfile) et des options de chargement passées à la ligne de commandes, réglages par défaut pour toutes les variables, vérification de l'existence des répertoires nécessaires, etc.
- interface.c - l'interface utilisateur et l'écran d'ouverture
- javascript.c - ??
- network.c - disponible pour le code en rapport avec le web, un analyseur de liens pourrait très bien être ajouté ici
- menu.c - le menu principal et le menu personnalisé, avec aussi l'éditeur de menus personnalisés
- project.c - toutes les fonctions en rapport avec le Tproject
- pixmaps.c - chargement de fichiers xpm dans un widget GTK
- ref_dialog.c - le code de réference pour les dialogues
- rpopup.c - menu du clic droit de la souris et analyse du HTML en GList
- snr2.c - chercher et remplacer, gestion de liens (utilisation de regex)
- spell.c - vérificateur d'orthographe
- spell_gui.c - interface du vérificateur d'orthographe
- stringlist.c - fonctions de gestion des listes de chaînes (GList avec des chaînes), interface idoine, et gestion de tableaux de listes avec interface

- stringlist: une GList (voir la doc de glib) contenant uniquement des gchar *
- arraylist: une GList contenant des tableaux de gchar * terminés par un NULL.

- toolbars.c - les barres d'outils principale et html
- undo.c - ancien Défaire/Refaire
- undo2.c - réecrit de A à Z, utilisé par défaut maintenant
- wizards.c - assistants, comme html*.c, avec la possibilités d'insérer plusieurs balises à la fois
- wml.c - support de WML

### Patches

Antti-Juhani Kaijanaho a écrit:

1. Je garde deux arbres du code de bluefish, l'un inchangé (un officiel non compressé) et un sur lequel je travaille. Pour chaque changement isolé je fais un nouvel arbre avec mes modifications.
2. Avant de faire un patch, exécuter "make distclean".
3. Quand je veux faire un patch, je vais dans le réprtoire parent des deux arbres. J' exécute alors "diff -Naur official-pre-tree my-changed-tree | bzip2 -9c > patchbla.diff.bz2" (où official-pre-tree et my-changed-tree sont les deux arbres du code de Bluefish).

### CVS - utilisation

Olivier a écrit:
En utilisant bash (remplacer par votre propre nom d'utilisateur):

    CVSROOT=:pserver:USERNAME@cvs1.openave.net:/home/cvsroot/bluefish1
    export CVSROOT
    cvs login
    cvs checkout bluefish

Cela doit télécharger la version de développement courante de Bluefish. Si vous l'avez déjà fait vous pouvez utiliser :

    cvs update -dP

pour mettre à jour vos fichiers locaux avec les nouelles modifications. Pour envoyer des fichiers :

    cvs commit

doit envoyer vos modifications sur le CVS. S'il vous plaît faites toujours un update immédiatement avant de faire un commit, pour vérifier s'il y a d'autres personnes qui travaillent sur le même source!

D'autres commandes qui pourraient s'avérer utiles :

- cvs log src/document.c affiche l'historique des révisions du fichier
- cvs diff -c -r 1.2 -r 1.3 src/document.c renvoie un patch avec les différences entre les révisions 1.2 et 1.3 de document.c (-c = affichage lisible par un humain)
- cvs annotate src/document.c affiche une annotation complète pour chaque patch et les commentaires pour ce fichier.

### CVS - règles d'usage

Antti-Juhani à écrit:

- Répercuter ses changements sur le tronc principal est toujours autorisé, tant que vous ne cassez pas le programme. Si vous ajouter de nouvelles fonctionnalités significatives (importantes), parlez-en d'abord sur la mailing list. Le tronc est la branche "instable". Le tronc est ce que vous obtenez en utilisant

      cvs checkout

- Quand on veut figer le programme avant le lancement d'une nouvelle version, une branche "gelée" est créee. (avec le nom, par exemple, rel_0_5_branch pour la version 0.5 figée. Les commits sur une branche gelée sont autorisés uniquement si :
  - vous ne cassez pas le programme
  - vous n'ajoutez pas de nouvelle fonctionnalité
  - votre commit est nécessaire pour la sortie de la version (correction de bug, mise à jour de .po, etc)
  Vous pouvez le faire en utilisant :

      cvs checkout -r name_of_branch

- Quand une branche figée est prête à sortir, le jeu de fichiers le plus récent dans la branche est taggé avec, par exemple, "rel_0_5" (pour la version 0.5).La branche est alors déclarée "stable". Les Tarballs, debs et rpms sont construits. Aucun commit n'est autorisé dans une branche stable. Après la sortie, la branche stable est fusionnée avec le tronc.

Ce plan de sortie en trois étapes, inspiré du cycle de sortie de Debian, permet des développements instables avec en parallèle la sortie de version.

Pour créer une branche:

    cvs tag -b name_of_branch

Notez que l'arbre sur lequel vous faites le tag cvs est toujours le tronc, pas la branche. Vous avez alors besoin d'obtenir une nouvelle copie à partir de la branche:

    cd somewhere_else
    cvs checkout -r name_of_branch

Les commits sur cette nouvelle copie sont répercutés sur la branche, et le tronc reste inchangé. Les autres personnes peuvent accéder à la branche en faisant le même

    cvs checkout -r.

Quand vous voulez répercutez vos changements sur le tronc, faites

    cvs update -j name_of_branch

dans l'ancien arbre (le tronc). Corrigez tous les conflits et faites un commit.

### Traductions

Roland Steinbach (roland@ratisbona.com) a écrit :
si vous voulez commencer par exemple la traduction en grec (gr) vous aurez à :

- copier bluefish.pot en gr.po
- les lignes msgid contiennent le texte à traduire, les lignes msgtxt la traduction
- envoyez-moi le fichier .po ou à la liste

Si vous avez besoin de modifier le fichier .po dans les versions futures vous aurez à :

- chercher les lignes contenant le mot "fuzzy" (à l'exception de la ligne 6, là cela est juste). Ce sont les lignes qui doivent être modifiées, supprimé la ligne avec le mot "fuzzy" et corriger la traduction
- chercher les lignes sans traduction (chercher 'msgtxt ""') et les traduire.

C'est tout!

### Quelques astuces

- si vous voulez ajouter une propriété, ajoutez la à Tproperty (dans bluefish.h) et donner une ligne d'initialisation dans main_v_props_init() dans init.c, ça devrait le faire. Si vous la voulez dans l'interface vous devez modifier configure.c, c'est à dire ajouter une ligne dans configure_cb() et une ligne dans apply_config(). Cela peut être plus de lignes pour des propriétés plus avancées.
- gtk_easy.c contient une tonne de fonctions faciles à utiliser pour créer des dialogues et initialiser les variables.
- La macro DEBUG_MSG() marche comme la fonction printf(), si #define DEBUG est défini au début du fichier, ou --with-debug est utilisé avec ./configure, sinon elle sera enlevé par le préprocesseur.

### Versions

Les choses à faire avant le lancement d'une nouvelle version:

- suppression de #define DEVELOPMENT dans le fichier default_header.h
- commenter le include .depends du Makefile (cassé sous HP-UX)
- utiliser cvs export

... Je dois finir ça

### Liens utiles

- Référence de glib, particulièrement les fonctions utilitaires de traitement de chaînes et les listes doublement chaînées.
- Référence de gdk, polices et couleurs
- Référence de gtk, le reste, tous les widget, prototypes de fonctions, etc.
- Préprocesseur C
- autoconf/automake, ou le système de configuration GNU
- Programmation en C, un très bon tutorial
- Livre de CVS, un bon bouquin sur l'utilisation de CVS
- cvs2cl, CVS-ChangeLog generator

préc | sommaire | suiv