Sommaire

Style du code d'Inkscape

Cette page documente les conventions utilisées dans le code source d'Inkscape. Veuillez suivre ces conventions lorsque vous écrivez du nouveau code. Si vous voyez du code qui ne s'y conforme pas, sentez-vous libre de le corriger !

Les bases : indentation, espaces et accolades

Le code est systématiquement indenté avec quatre espaces. Les caractères de tabulation ne doivent jamais être utilisés dans le code. Seuls font exception les fichiers de compilation système et de création (Makefile) dont la syntaxe impose des caractères de tabulation.

Les éléments suivants sont indentés :

Les éléments suivants ne sont pas indentés :

Le code est écrit avec des accolades compactes, ce qui signifie que l'accolade ouvrante va sur la même ligne que l'instruction de contrôle. L'accolade fermante d'un bloc if se trouve sur la même ligne que le mot-clé else suivant. Il y a néanmoins une exception : si la condition d'un if ou d'un while ou l'en-tête d'une boucle for sont écrites sur plus d'une ligne, l'accolade ouvrante va sur une ligne séparée. Les accolades sont exigées et ne doivent pas être omises même lorsque le corps du bloc ne comprend qu'une seule instruction. Pour les définitions de fonction, l'accolade ouvrante devrait aller sur une ligne séparée si la fonction fait plus de quelques lignes ou si la liste de paramètres fait plus d'une ligne. Les accolades ouvrantes des constructeurs avec initialisation de membres doivent aller sur une ligne séparée.

Des espaces sont placées aux endroits suivants :

Les espaces sont absentes aux endroits suivants :

Les listes d'initialisation de membres et les listes de classes de base qui contiennent plus d'une classe doivent être écrites avec une indentation de style Boost : chaque membre ou classe va sur une ligne séparée et est précédé par le symbole approprié et une espace. Cela rend la détection d'erreurs facile.

namespace Inkscape {
namespace UI {

Sandwich make_sandwich(int x);
int make_a_mess(float y);

} // namespace UI
} // namespace Inkscape

class Bunkum
    : public Nonsense
    , protected PublicSpeech
{
public:
    Bunkum()
        : _x(1024)
        , _y(42)
    {}
private:
    void _forget();
    int _x, _y;
};

template <typename Basket>
void fill_basket(Basket &b)
{
    switch (a) {
    case 1:
        do_one();
        break;

    case 2:
        do_two();
        break;

    default:
        break;
    }

    for (int i = 0; i < 30; ++i) {
        b << Inkscape::UI::make_sandwich();
    }
    return b;
}

Conventions de nommage

Les noms de classe et d'espace de noms utilisent la casse ChatMotMajuscule. Les fonctions globales et statiques publiques, les variables de la pile, et les membres de classe (variables de classe) utilisent la casse serpent_minuscule. Les fonctions membres de classe (méthodes) utilisent la casse chatMotMinuscule. Les membres de classe protégés et privés sont préfixés par un sous-tiret « _ ». Les macros et les constantes utilisent la casse SERPENT_MAJUSCULE. Les paramètres de patrons qui sont des types utilisent la casse ChatMotMajuscule, tandis que ceux qui sont des entiers utilisent la casse SERPENT_MAJUSCULE, comme les constantes. Les préfixes de type, la notation hongroise, etc. sont interdits. Utilisez des suffixes significatifs si vous devez enlever une ambiguïté ; par exemple text_raw et text_escaped.

Les noms de variables doivent être des substantifs (noms). Les noms de fonctions doivent être des verbes, sauf les fonctions d'accès qui peuvent être des substantifs. Par exemple, une propriété de classe appelée position aurait la fonction d'altération setPosition() et la fonction d'accès position().

Conventions de noms de fichier

Tous les fichiers qui font partie de la source d'Inkscape devraient utiliser la casse minuscule-avec-tirets. Les fichiers C++ devraient avoir l'extension .cpp, tandis que les fichiers d'en-tête devraient avoir l'extension .h. Les espaces, les lettres en majuscule et les sous-tirets ne sont pas autorisés. Utiliser des nombres dans les noms de fichier est déconseillé.

Placement de const

Le qualificateur const se place à gauche, et non à droite. Cette qualité est souvent oublié, donc afin que tout le monde la garde à l'esprit, nous exigeons que le qualificateur const soit écrit après le type.

#define SOME_MACRO(x) x
void call_global();
unsigned const IMPORTANT_CONSTANT = 42;

class Example {
public:
    void callPublic();
    static void call_public_static();
    int public_variable;
protected:
    void _callProtected();
    static void _call_protected_static();
    int _protected_variable;
private:
    void _callPrivate();
    static void _call_private_static();
    int _private_variable;
};

template <typename TypeParam, int INTEGER_PARAM>
void call_global_template(boost::array<TypeParam, INTEGER_PARAM> const &array);

Préprocesseur

La compilation conditionnelle avec des directives au préprocesseur est fortement déconseillée, car cela fait moisir le code. Utilisez-la seulement lorsqu'elle ne peut être évitée, par exemple lors de l'utilisation d'une dépendance optionnelle. Un cas particulier est l'utilisation de compilation conditionnelle pour exclure un fichier en fonction de la plateforme, ce qui est permis.

De préférence par rapport à la compilation conditionnelle spécifique à une plateforme, vous devriez chercher à écrire du code portable qui fonctionne de la même manière indépendamment de la plateforme. Utiliser les bibliothèques Glib et GTK+ peut nettement aider dans cette tâche. Si vous devez utiliser du code différent en fonction de la plateforme, essayez de l'encapsuler dans des fonctions utilitaires, de sorte que la quantité de code qui diffère entre les plateformes soit conservée au minimum.

Organisation des fichiers

Les fichiers d'Inkscape ont une organisation fixée. Chaque fichier de code doit contenir ses composants dans cet ordre :

  1. un commentaire Doxygen avec une brève description de ce qui se trouve dans le fichier ;
  2. un commentaire non Doxygen séparé avec des informations sur l'auteur et la licence ;
  3. l'ouverture de la condition d'inclusion (dans les en-têtes) ;
  4. les inclusions d'en-têtes systèmes, comme #include <header>. Ces en-têtes devraient être ordonnés soit alphabétiquement soit en fonction des dépendances des bibliothèques ;
  5. les inclusions d'en-têtes internes, comme #include "header.h". Ces en-têtes devraient être ordonnés alphabétiquement ;
  6. le code lui-même, dans l'espace de noms Inkscape. Ici, l'ordre est plus libre, mais généralement, les déclarations de fonctions globales sont placées après les déclarations de classes. L'ordre des définitions dans le fichiers .cpp devrait correspondre à l'ordre des déclarations dans le fichier .h ;
  7. la fermeture de la condition d'inclusion ;
  8. un commentaire avec les lignes de mode standards pour Vim et Emacs, également utilisables par d'autres éditeurs. Ce bloc est le même pour tous les fichiers.

Le code ci-dessous présente un petit exemple de fichier qui est conforme à l'organisation requise.

/** @file
 * Selector component (click and rubberband)
 *//*
 * Authors:
 *   Krzysztof Kosiński <tweenk.pl@gmail.com>
 *
 * Copyright (C) 2009 Authors
 * Released under GNU GPL, read the file 'COPYING' for more information
 */

#ifndef SEEN_UI_TOOL_SELECTOR_H
#define SEEN_UI_TOOL_SELECTOR_H

#include <memory>
#include <gdk/gdk.h>
#include <2geom/rect.h>
#include "ui/tool/manipulator.h"

class SPDesktop;
class CtrlRect;

namespace Inkscape {
namespace UI {

class SelectorPoint;

class Selector : public Manipulator {
public:
    Selector(SPDesktop *d);
    virtual ~Selector();
    virtual bool event(SPEventContext *, GdkEvent *);
    
    sigc::signal<void, Geom::Rect const &, GdkEventButton*> signal_area;
    sigc::signal<void, Geom::Point const &, GdkEventButton*> signal_point;
private:
    SelectorPoint *_dragger;
    Geom::Point _start;
    CtrlRect *_rubber;
    gulong _connection;
    bool _cancel;
    friend class SelectorPoint;
};

} // namespace UI
} // namespace Inkscape

#endif

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace .0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim:filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99:

Formateurs de code source

Il peut être plus facile de garder les fichiers sources conformes au style de codage avec des formateurs de code source automatiques.

Options de Artistic Style

Artistic Style (astyle) est un formateur de code source en C++. Vous pouvez l'utiliser pour reformater tout code source non normalisé. Pour le style de code d'Inkscape, copiez les options suivantes dans votre fichier .astylerc :

--style=stroustrup
--indent=spaces=4
--indent-preprocessor
--indent-col1-comments
--pad-oper
--unpad-paren
--pad-header
--align-pointer=name
--align-reference=name
--add-brackets
--convert-tabs

Le même contenu est disponible dans le fichier astylerc dans le dépôt du code source d'Inkscape, que vous pouvez indiquer en paramètre avec l'option --options. Vous pouvez aussi utiliser une ligne de commande équivalente.

astyle --options=astylerc
astyle -A4 -s4 -k3 -W3 -cjHpUwY

Options de clang-format

clang-format est un formateur de code source qui fait partie du compilateur Clang, basé sur LLVM. Les révisions récentes d'Inkscape comprennent un fichier _clang-format, ce qui signifie que clang-format devrait récupérer les bons paramètres.