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:
- 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.
- Avant de faire un patch, exécuter "make distclean".
- 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:
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