Sommaire

Style du code d'Inkscape

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

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 :

  • le corps des instructions de contrôle : for, if, while, switch, etc. ;
  • les blocs d'instructions libres, c'est-à-dire les blocs entre accolades qui ne suivent pas une instruction de contrôle. Ils sont parfois utilisés pour limiter la portée des objets ;
  • le corps des fonctions et classes ;
  • les instructions qui se poursuivent sur la ligne suivante.

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

  • les contenu des espaces de noms ;
  • les étiquettes de cas (case) ;
  • les spécificateurs de contrôle d'accès (public, private, protected).

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 :

  • autour de tous les opérateurs binaires (à deux opérandes), y compris les affectations ;
  • entre un mot-clé et les parenthèses qui le suivent ;
  • entre un identifiant ou mot-clé et une accolade ;
  • après les virgules et les points-virgules qui ne terminent pas une ligne ;
  • entre le mot-clé template et la liste des paramètres du patron.

Les espaces sont absentes aux endroits suivants :

  • avant les points-virgules et les virgules ;
  • du côté intérieur des parenthèses ;
  • entre le nom d'une fonction et la liste de ses arguments ;
  • entre les opérateurs unaires et leurs opérandes ;
  • dans une liste vide d'arguments ;
  • entre une étiquette et un deux-points ;
  • autour de l'opérateur de résolution de portée ::.

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 vraiment plus 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 représentatifs si vous devez lever 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 de la codebase d'Inkscape doivent utiliser la casse minuscule-avec-tirets. Les fichiers C++ doivent avoir l'extension .cpp, tandis que les fichiers d'en-tête doivent 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 a un effet sur ce qui le précède et non ce qui le suit. Ce fait est souvent oublié, donc afin que tout le monde le 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 elle dégrade fortement la qualité du code. Utilisez-la seulement lorsqu'il n'y a pas d'autre choix, 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.

Le code portable qui fonctionne de la même manière indépendamment de la plateforme est clairement préféré à du code spécifique à une plateforme utilisant de la compilation conditionnelle. Utiliser les bibliothèques GLib et GTK+ peut nettement aider à satisfaire cela. 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 fichier .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.