Discussion: Effet magique de l'unité LConvEncoding [Free Pascal]

  1. #1
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    2 990
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Sénégal

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 2 990
    Points : 10 747
    Points
    10 747
    Billets dans le blog
    4

    Par défaut Effet magique de l'unité LConvEncoding

    Bonjour !

    Je poste cette question dans le sous-forum Free Pascal, parce que j'utilise l'unité LConvEncoding de Lazarus dans une application console compilée directement par Free Pascal.

    J'étais en train de faire des recherches sur l'encodage du symbole euro (€) et sur la variable FormatSettings.CurrencyString.

    J'ai observé quelque chose que je ne m'explique pas, à savoir que le simple fait de déclarer l'unité LConvEncoding en tête de mon programme a un effet que l'exemple suivant met en évidence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    {$ASSERTIONS ON}
    {.$DEFINE USELCONVENCODING}
     
    uses
      sysutils
    {$IFDEF USELCONVENCODING}
      , lconvencoding
    {$ENDIF}
      ;
     
    begin
    {$IFDEF USELCONVENCODING}
      Assert(Length(FormatSettings.CurrencyString) = 3);
      //Assert(FormatSettings.CurrencyString = #8364); // Warning: Implicit string type conversion from "AnsiString" to "WideString"
      Assert(FormatSettings.CurrencyString = AnsiString(#8364));
    {$ELSE}
      Assert(Length(FormatSettings.CurrencyString) = 1);
      //Assert(FormatSettings.CurrencyString = #128); // Assertion failed
      Assert(FormatSettings.CurrencyString[1] = #128);
    {$ENDIF}
      WriteLn('ok');
      ReadLn;
    end.
    Sauriez-vous comment le simple fait de déclarer l'unité peut produire cet effet ? Et quel est cet effet justement ?

    Question subsidiaire, pourquoi l'assertion FormatSettings.CurrencyString = #128 échoue-t-elle ?

    Je me sers pour compiler mon programme (c'est sous Windows) du script suivant :

    Code Batch : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    set ver=3.0.2
    set path=c:\fpc\%ver%\bin\i386-win32
     
    if not exist .\units md .\units
     
    fpc.exe -Mdelphi -Fuc:\lazarus\components\lazutils -FU.\units %1

  2. #2
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Traqueur de tritons et autres bestioles
    Inscrit en
    mars 2002
    Messages
    1 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Traqueur de tritons et autres bestioles

    Informations forums :
    Inscription : mars 2002
    Messages : 1 481
    Points : 3 592
    Points
    3 592

    Par défaut

    Salut Roland,

    En consultant le code de la RTL, l'ajout de l'unité lconvencoding dans la clause Uses de ton unité déclenche certaines initialisations notamment dans l'unité FPCAdds, ces initialisations modifient les pages de code par défaut et les fixent à UTF-8.

    FormatSettings.CurrencyString est une chaîne de caractères, il serait bon de regarder sa taille pour vérifier si elle ne fait qu'un seul caractère.

    Cdlt

    M E N S . A G I T A T . M O L E M
    Debian 8.x 64bit, Lazarus 1.6 (FPC 3.0), Python 3

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    2 990
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Sénégal

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 2 990
    Points : 10 747
    Points
    10 747
    Billets dans le blog
    4

    Par défaut

    Citation Envoyé par e-ric Voir le message
    En consultant le code de la RTL, l'ajout de l'unité lconvencoding dans la clause Uses de ton unité déclenche certaines initialisations notamment dans l'unité FPCAdds, ces initialisations modifient les pages de code par défaut et les fixent à UTF-8.
    Merci pour ta réponse. Bien vu !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {$ifdef UTF8_RTL}
    initialization
      SetMultiByteConversionCodePage(CP_UTF8);
      // SetMultiByteFileSystemCodePage(CP_UTF8); not needed, this is the default under Windows
      SetMultiByteRTLFileSystemCodePage(CP_UTF8);
    {$IFEND}
    Maintenant je cherche les options de ligne de commande qui me permettraient d'obtenir ce même effet mais jusqu'à présent je n'ai pas trouvé.

    Si UTF-8 est l'avenir, j'aime autant m'y mettre définitivement pour tout le code que j'écrirai désormais, même quand j'utilise FPC tout seul.

    Sur cette page, il est dit une chose intéressante :

    If you want to use the new UTF-8 strings in your non LCL programs, add dependency for LazUtils package. Then add LazUTF8 unit in the uses section of main program file. It must be near the beginning, just after the critical memorymanagers and threading stuff (e.g. cmem, heaptrc, cthreads).
    C'est bon à savoir mais ça ne fait pas vraiment mon affaire. Je suppose qu'il doit être possible de configurer FPC pour qu'il fonctionne en mode UTF-8, sans ajouter forcément le paquet LazUtils. J'ai essayé de compiler avec l'option -mDelphiUnicode le programme suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    uses
      sysutils;
     
    begin
      WriteLn(Length(FormatSettings.CurrencyString));
      ReadLn;
    end.
    J'obtiens toujours "1" comme longueur de la chaîne (au lieu de "3" si je déclare l'unité lconvencoding).

  4. #4
    Membre averti

    Homme Profil pro
    Autre
    Inscrit en
    novembre 2015
    Messages
    99
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : novembre 2015
    Messages : 99
    Points : 420
    Points
    420

    Par défaut

    Je me permets d'intervenir dans votre discussion ...


    Pour dire les choses franchement, Free Pascal (j'entends ici le compilateur Free Pascal uniquement, sans Lazarus et sans la LCL) "n'utilise" pas à proprement parler l'UTF-8. Ce que je veux dire, c'est qu'il faut plutôt le mettre en parallèle avec l'évolution de Delphi historiquement: d'abord de l'Ansi uniquement puis, depuis les versions FPC 3.x, un passage à l'Unicode (mais de type UTF-16).

    Donc, Free Pascal a maintenant (comme Delphi) des chaînes de caractères de type Ansi (avec 1 caractère = 1 octet, même si c'est très abusif -voire faux- de dire cela): les "rawbytestring"; et des chaînes de caractères de type Unicode UTF-16/Wide (avec 1 caractère = 2 octets, même terme abusif, mais cela permet d'avoir une "image simple" à l'esprit): les "unicodestring". Et l'UTF-8 utilisé en standard par Lazarus et la LCL tombe dans la première catégorie (i.e. le type Ansi = 1 octet).


    L'utilisation de l'UTF-8 par Lazarus correspond plutôt à un "hack" des chaînes de caractères de type Ansi, pour lequel le code page système par défaut est défini comme étant l'UTF-8. Ce n'est d'ailleurs pas vraiment ce que l'équipe de Free Pascal avait en tête au départ, quand ils ont implémenté le support de l'Unicode dans les versions 3.x.

    C'est la raison des instructions SetMultiByteConversionCodePage/SetMultiByteRTLFileSystemCodePage.


    Il ressort de tout cela qu'il n'y a pas "d'options de ligne de commande" pour Free pascal permettant de réaliser l'équivalent de ces instructions. Le mode de fonctionnement "UTF-8" utilisé par Lazarus/la LCL est spécifique à ce dernier; Free Pascal peut bien entendu s'en "accommoder", mais on ne peut pas vraiment dire qu'une "option" existerait et permettrait de définir l'UTF-8 comme étant "au cœur" des chaînes de caractères utilisées au sein de Free Pascal (système, RTL, ...).


    Plus concrètement:

    Je suppose qu'il doit être possible de configurer FPC pour qu'il fonctionne en mode UTF-8, sans ajouter forcément le paquet LazUtils
    Ajoutez vous-même les instructions citées dans votre code, si c'est le mode Ansi/UTF-8 de la LCL que vous désirez émuler/utiliser.

    J'ai essayé de compiler avec l'option -mDelphiUnicode
    Cette option permet (en plus du mode Delphi) d'indiquer que les chaînes de caractères (i.e. les "string") sont par défaut des chaînes de caractères de type Unicode UTF-16 (i.e. 1 caractère = 2 octets). Elles ne permettent en aucun cas une définition par défaut à de l'UTF-8.

    En fait, d'après ce qui précède, ce mode est incompatible avec le mode Ansi/UTF-8 (i.e. UTF8RTL) utilisé par Lazarus/la LCL: enfin, pas incompatible au sens "ne fonctionne pas", mais plutôt au sens "ne correspond pas au mode de fonctionnement".

    Par ailleurs, la RTL et la partie système de FPC ne sont actuellement pas compilées par défaut en mode Unicode/UTF-16 (bien qu'il me semble qu'il y a maintenant une option de compilation prévue pour les recompiler dans ce mode, sur demande de l'utilisateur). Donc pour le moment, les chaînes de caractères au sein des "TFormatSettings" sont toujours de type Ansi (ou Ansi/UTF-8 si l'on applique le "hack" de Lazarus/la LCL).

  5. #5
    Membre expert
    Avatar de e-ric
    Homme Profil pro
    Traqueur de tritons et autres bestioles
    Inscrit en
    mars 2002
    Messages
    1 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Traqueur de tritons et autres bestioles

    Informations forums :
    Inscription : mars 2002
    Messages : 1 481
    Points : 3 592
    Points
    3 592

    Par défaut

    Citation Envoyé par Roland Chastain Voir le message
    Merci pour ta réponse. Bien vu !
    Maintenant je cherche les options de ligne de commande qui me permettraient d'obtenir ce même effet mais jusqu'à présent je n'ai pas trouvé.
    Peut-être que l'option -d du compilateur te rendra service ainsi que la lecture du wiki (http://wiki.freepascal.org/Conditional_compilation/fr) et articles connexes (traduits par mes soins et en attente de relecture par de bonnes volontés ).

    Cdlt

    M E N S . A G I T A T . M O L E M
    Debian 8.x 64bit, Lazarus 1.6 (FPC 3.0), Python 3

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  6. #6
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    décembre 2011
    Messages
    2 990
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Sénégal

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : décembre 2011
    Messages : 2 990
    Points : 10 747
    Points
    10 747
    Billets dans le blog
    4

    Par défaut

    Merci pour vos réponses.

    Citation Envoyé par FChrisF Voir le message
    L'utilisation de l'UTF-8 par Lazarus correspond plutôt à un "hack" des chaînes de caractères de type Ansi, pour lequel le code page système par défaut est défini comme étant l'UTF-8.
    D'accord, je vois. J'avais donc confondu "UTF-8" et "Unicode".

    Ce n'est quand même pas simple tout ça... Avec les problèmes de terminologie en plus...

    @e-ric

    Bravo pour ton travail de traduction. J'ai relu la page en question : je n'y ai rien vu à corriger.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. TTreeView -> Comment ouvrir une unité ?
    Par DaLove dans le forum C++Builder
    Réponses: 2
    Dernier message: 08/12/2002, 11h30
  2. Sans effet: StringGrid1->Cells[1][1][2] = c ?
    Par Xavier dans le forum C++Builder
    Réponses: 3
    Dernier message: 27/11/2002, 10h32
  3. [VB6][impression]Comment faire des effets sur les polices ?
    Par le.dod dans le forum VB 6 et antérieur
    Réponses: 11
    Dernier message: 08/11/2002, 10h31
  4. Effet Fade In / Fade Out sur une surface DirectDraw
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 08/09/2002, 17h37
  5. Connaitre l'unitée à ajouter dans USES
    Par DelphiCool dans le forum Langage
    Réponses: 7
    Dernier message: 01/08/2002, 13h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo