PostgreSQLLa base de données la plus sophistiquée au monde.

46.2. Pour le développeur

46.2.1. Mécaniques

Cette section explique comment implémenter le support natif d'une langue dans un programme ou dans une bibliothèque qui fait partie de la distribution PostgreSQL™. Actuellement, cela s'applique uniquement aux programmes C.

Procédure 46.1. Ajouter le support NLS à un programme

  1. Le code suivant est inséré dans la séquence initiale du programme :

    #ifdef ENABLE_NLS
    #include <locale.h>
    #endif
    
    ...
    
    #ifdef ENABLE_NLS
    setlocale(LC_ALL, "");
    bindtextdomain("nomprog", LOCALEDIR);
    textdomain("nomprog");
    #endif
    

    (nomprog peut être choisi tout à fait librement).

  2. Partout où un message candidat à la traduction est trouvé, un appel à gettext() doit être inséré. Par exemple :

    fprintf(stderr, "panic level %d\n", lvl);
    

    devra être changé avec

    fprintf(stderr, gettext("panic level %d\n"), lvl);
    

    (gettext est défini comme une opération nulle si NLS n'est pas configuré).

    Cela peut engendrer du fouillis. Un raccourci habituel consiste à utiliser

    #define _(x) gettext(x)
    

    Une autre solution est envisageable si le programme effectue la plupart de ses communications via une fonction ou un nombre restreint de fonctions, telle ereport() pour le moteur. Le fonctionnement interne de cette fonction peut alors être modifiée pour qu'elle appelle gettext pour toutes les chaînes en entrée.

  3. Un fichier nls.mk est ajouté dans le répertoire des sources du programme. Ce fichier sera lu comme un makefile. Les affectations des variables suivantes doivent être réalisées ici :

    CATALOG_NAME

    Le nom du programme tel que fourni lors de l'appel à textdomain().

    AVAIL_LANGUAGES

    Liste des traductions fournies -- initialement vide.

    GETTEXT_FILES

    Liste des fichiers contenant les chaînes traduisibles, c'est-à-dire celles marquées avec gettext ou avec une solution alternative. Il se peut que cette liste inclut pratiquement tous les fichiers sources du programme. Si cette liste est trop longue, le premier « fichier » peut être remplacé par un + et le deuxième mot représenter un fichier contenant un nom de fichier par ligne.

    GETTEXT_TRIGGERS

    Les outils qui engendrent des catalogues de messages pour les traducteurs ont besoin de connaître les appels de fonction contenant des chaînes à traduire. Par défaut, seuls les appels à gettext() sont reconnus. Si _ ou d'autres identifiants sont utilisés, il est nécessaire de les lister ici. Si la chaîne traduisible n'est pas le premier argument, l'élément a besoin d'être de la forme func:2 (pour le second argument).

Le système de construction s'occupera automatiquement de construire et installer les catalogues de messages.

46.2.2. Guide d'écriture des messages

Voici quelques lignes de conduite pour l'écriture de messages facilement traduisibles.

  • Ne pas construire de phrases à l'exécution, telles que

    printf("Files were %s.\n", flag ? "copied" : "removed");
    

    L'ordre des mots d'une phrase peut être différent dans d'autres langues. De plus, même si gettext() est correctement appelé sur chaque fragment, il pourrait être difficile de traduire séparément les fragments. Il est préférable de dupliquer un peu de code de façon à ce que chaque message à traduire forme un tout cohérent. Seuls les nombres, noms de fichiers et autres variables d'exécution devraient être insérés au moment de l'exécution dans le texte d'un message.

  • Pour des raisons similaires, ceci ne fonctionnera pas :

    printf("copied %d file%s", n, n!=1 ? "s" : "");
    

    parce que cette forme présume de la façon dont la forme plurielle est obtenue. L'idée de résoudre ce cas de la façon suivante :

    if (n==1)
        printf("copied 1 file");
    else
        printf("copied %d files", n):
    

    sera source de déception. Certaines langues ont plus de deux formes avec des règles particulières. Il se pourrait qu'une solution à ce problème soit trouvée dans le futur, mais actuellement le mieux est encore de l'éviter. Il est préférable d'écrire :

    printf("number of copied files: %d", n);
    
  • Lorsque quelque chose doit être communiqué au traducteur, telle que la façon dont un message doit être aligné avec quelque autre sortie, on pourra faire précéder l'occurrence de la chaîne d'un commentaire commençant par translator, par exemple

    /* translator: This message is not what it seems to be. */
    

    Ces commentaires sont copiés dans les catalogues de messages de façon à ce que les traducteurs les voient.