IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

[XE2] Usage de l'unité CommandParser


Sujet :

Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut [XE2] Usage de l'unité CommandParser
    Bonjour !

    Je voudrais utiliser dans une application console l'unité CommandParser qui se trouve dans les démos de XE2 :

    http://sourceforge.net/p/radstudiode...RadStudio_XE2/

    J'ai téléchargé ce projet utilisant l'unité :

    http://bo.codeplex.com/SourceControl.../changes/71461

    J'avais trouvé le lien (avec des explications) dans un message de cette discussion :

    http://stackoverflow.com/questions/9...ine-parameters

    Mais avec tout ça je n'ai pas réussi à faire pour moi-même un petit exemple qui fonctionne. Enfin si, j'ai fait ça, qui est un début et qui montre déjà l'intérêt de cette unité :

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    program CommandParser1;
     
    {$APPTYPE CONSOLE}
     
    {$R *.res}
     
    uses
      System.SysUtils, CommandParser;
     
    var
      cp: TCommandParser;
     
    begin
      try
        // Paramètres :
        // /longnames /infile='1.txt' /outfile="2.txt"
     
        cp := TCommandParser.Create(FALSE, 'Unit names convertor');
     
        WriteLn(cp.SwitchChars = '/-');
     
        cp.AddSwitch('s', stBoolean, FALSE, '', 'Conversion to short names', 'shortnames');
        cp.AddSwitch('l', stBoolean, FALSE, '', 'Conversion to long names', 'longnames');
        cp.AddSwitch('i', stString, TRUE, '', 'Input file', 'infile');
        cp.AddSwitch('o', stString, FALSE, '', 'Output file', 'outfile');
     
        WriteLn(cp.Syntax);
        //WriteLn(cp.HelpText);
        //WriteLn(cp.Description);
     
        cp.ProcessCommandLine(CmdLine);
     
        WriteLn(cp.IndexOf('s') = 0);
        WriteLn(cp.IndexOf('l') = 1);
        WriteLn(cp.IndexOf('i') = 2);
        WriteLn(cp.IndexOf('o') = 3);
     
        WriteLn(cp.Switches[3].Name = 'o');
        WriteLn(cp.Switches[3].Value = '"2.txt"');
        WriteLn(cp.Switches[3].HasValue);
        WriteLn(cp.Switches[1].HasValue = FALSE);
     
        cp.Free;
     
        ReadLn;
      except
        on E: Exception do
          Writeln(E.ClassName, ': ', E.Message);
      end;
    end.
    Mais je ne vois pas comment récupérer les valeurs booléennes.

    J'ai essayé en m'inspirant du projet de suivre la méthode décrite dans la discussion mais c'est trop compliqué (pour moi). Doit-on nécessairement passer par un TComponent ? Si oui, cela peut-il se faire d'une façon relativement simple ?

  2. #2
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Par défaut
    Bonjour,
    Citation Envoyé par Roland Chastain Voir le message
    Mais je ne vois pas comment récupérer les valeurs booléennes.
    Personnellement, c'est cette remarque que je ne comprends pas...

    Les résultats fournis correspondent à ce qui est attendu, non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
        WriteLn(cp.SwitchChars = '/-');  // => TRUE car valeurs par défaut
     
        WriteLn(cp.IndexOf('s') = 0);  // => TRUE car 's' est le 1° paramètre défini
        WriteLn(cp.IndexOf('l') = 1);  // => TRUE car 'l' est le 2° paramètre défini
        WriteLn(cp.IndexOf('i') = 2);  // => TRUE car 'i' est le 3° paramètre défini
        WriteLn(cp.IndexOf('o') = 3);  // => TRUE car 'o' est le 4° paramètre défini
     
        WriteLn(cp.Switches[3].Name = 'o');  // => TRUE car le nom du 4° paramètre défini est 'o'
        WriteLn(cp.Switches[3].Value = '"2.txt"');  // => TRUE car 3° paramètre transmis correspondant au 4° paramètre défini est "2.txt"
        WriteLn(cp.Switches[3].HasValue);  // => TRUE car 3° paramètre transmis correspondant au 4° paramètre défini a une valeur
        WriteLn(cp.Switches[1].HasValue = FALSE);  // => TRUE car 1° paramètre transmis correspondant au 2° paramètre défini n'a pas de valeur

  3. #3
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    @Ph. B.

    Bonjour et merci pour l'intérêt porté à mon problème. Oui, il est possible que la solution soit sous mon nez, mais ces deux lignes (la deuxième n'était pas dans l'exemple donné plus haut) donnent le même résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        WriteLn(cp.Switches[1].HasValue = FALSE);
        WriteLn(cp.Switches[0].HasValue = FALSE);
    Si je comprends bien, ce résultat veut dire que ces options (contrairement aux deux autres) ne sont pas supposées avoir une valeur, mais sont simplement présentes ou absentes. Mais comment puis-je savoir si elles sont présentes, c'est ce que je ne vois pas encore.

  4. #4
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    ... mais ces deux lignes (la deuxième n'était pas dans l'exemple donné plus haut) donnent le même résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        WriteLn(cp.Switches[1].HasValue = FALSE);
        WriteLn(cp.Switches[0].HasValue = FALSE);
    Pour moi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        WriteLn(cp.Switches[1].HasValue = FALSE);  // => TRUE car 1° paramètre transmis correspondant au 2° paramètre défini n'a pas de valeur
        WriteLn(cp.Switches[0].HasValue = FALSE);  // => TRUE car 1° paramètre défini n'a pas de valeur puisque non transmis
    Citation Envoyé par Roland Chastain Voir le message
    Si je comprends bien, ce résultat veut dire que ces options (contrairement aux deux autres) ne sont pas supposées avoir une valeur, mais sont simplement présentes ou absentes. Mais comment puis-je savoir si elles sont présentes, c'est ce que je ne vois pas encore.
    AMHA, vu comme est construit le parseur, on ne peut pas déterminer si un paramètre est transmis ou non, mais seulement si il a une valeur ou pas.

    Il faut donc en l'état du parseur définir les paramètres différemment, en particulier ceux qui sont antagonistes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        cp.AddSwitch('s', stBoolean, FALSE, 'off', 'Conversion to short names', 'shortnames');
        cp.AddSwitch('l', stBoolean, FALSE, 'on', 'Conversion to long names', 'longnames');
        cp.AddSwitch('i', stString, TRUE, '', 'Input file', 'infile');
        cp.AddSwitch('o', stString, FALSE, '', 'Output file', 'outfile');
    En l'état, le paramètre 'Conversion to long names' sera activé par défaut.

  5. #5
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 173
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    AMHA, vu comme est construit le parseur, on ne peut pas déterminer si un paramètre est transmis ou non, mais seulement si il a une valeur ou pas.
    Merci pour ta réponse. Oui, tu as raison. Le switch booléen est fait pour avoir une valeur, une chaîne en fait. C'est ce que je n'avais pas compris.

    If a Boolean switch has a default value (as the code above sets), specifying that switch without a Boolean value will set the switch to the default value. You can use +, true, t, yes, y, or on to toggle a Boolean switch to true, and -, false, f, n, no, off to set it to false to avoid ambiguities.
    https://community.embarcadero.com/ar...th-delphi-2010

    Du coup je ne suis pas sûr qu'il y ait une vraie différence avec le switch de type chaîne.

    Citation Envoyé par Ph. B. Voir le message
    Il faut donc en l'état du parseur définir les paramètres différemment, en particulier ceux qui sont antagonistes :
    J'ai suivi ton conseil. Du coup je n'ai gardé que l'option "Conversion vers les noms courts", en considérant que par défaut le programme ferait la conversion vers les noms longs.

    Voilà, le code est opérationnel (mais peut-être améliorable).

    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    // https://community.embarcadero.com/article/technical-articles/149-tools/3589-writing-an-event-logger-with-delphi-2010
     
    program CommandParser2;
     
    {$APPTYPE CONSOLE}
    {$WARN SYMBOL_PLATFORM OFF}
     
    {$R *.res}
     
    uses
      System.SysUtils, CommandParser;
     
    procedure WriteLnFalse(const aAssertion: boolean);
    begin
      if not aAssertion then WriteLn(aAssertion);
    end;
     
    var
      cp: TCommandParser;
     
    begin
      try
        // Paramètres :
        // /shortnames=on /infile='1.txt' /outfile="2.txt"
        // ou
        // /shortnames /infile='1.txt' /outfile="2.txt"
     
        cp := TCommandParser.Create(
          FALSE,                        // ACaseInsensitive
          'Delphi unit names convertor' // ADescription
        );
     
        WriteLnFalse(cp.TrueValues = '|y|t|on|yes|true|+|');
        WriteLnFalse(cp.ArgChars = ':=');
        WriteLnFalse(cp.FalseValues = '|n|f|off|no|false|-|');
        WriteLnFalse(cp.SwitchChars = '/-');
     
        cp.AddSwitch('s', stBoolean, FALSE, 'on', 'Conversion to short names', 'shortnames');
        cp.AddSwitch('i', stString, TRUE, '', 'Input file name', 'infile');
        cp.AddSwitch('o', stString, FALSE, '', 'Output file name', 'outfile');
     
        WriteLn(cp.Syntax);
     
        cp.ProcessCommandLine(CmdLine);
     
        WriteLnFalse(cp.IndexOf('s') = 0);
        WriteLnFalse(cp.IndexOf('i') = 1);
        WriteLnFalse(cp.IndexOf('o') = 2);
     
        WriteLnFalse(cp.Switches[1].Name = 'i');
        WriteLnFalse(cp.Switches[1].HasValue);
        WriteLnFalse(cp.Switches[1].Value = '''1.txt''');
     
        WriteLnFalse(cp.Switches[2].Name = 'o');
        WriteLnFalse(cp.Switches[2].HasValue);
        WriteLnFalse(cp.Switches[2].Value = '"2.txt"');
     
        //WriteLnFalse(cp.Switches[0].HasValue);
        WriteLnFalse(cp.Switches[0].Value = 'on');
        WriteLnFalse(Pos('|' + cp.Switches[0].Value + '|', cp.TrueValues) > 0);
     
        cp.Free;
      except
        on E: Exception do
          WriteLn(E.ClassName, ': ', E.Message);
      end;
    end.
    J'ai testé le programme avec les commandes suivantes :

    Code Batch : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @echo off
     
    set exe="C:\Users\Roland\Documents\RAD Studio\Projects\UnitNames\CommandLine\CommandParser\Win32\Debug\CommandParser2.exe"
     
    %exe% /shortnames=on /infile='1.txt' /outfile="2.txt"
    %exe% /shortnames /infile='1.txt' /outfile="2.txt"
    %exe% /shortnames /outfile="2.txt" /infile='1.txt'
    %exe% /outfile="2.txt" /infile='1.txt'
    %exe% /shortnames /outfile="2.txt"
     
    pause

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

Discussions similaires

  1. [XL-2007] Une unité définit par l'usager dans un graph excel
    Par Alecks dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 24/05/2013, 14h21
  2. Fonctions de l'unité Crt pour Delphi XE2
    Par Roland Chastain dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 13/12/2012, 00h45
  3. Nom de portée de l'unité Windows dans Delphi XE2
    Par franckcl dans le forum Composants VCL
    Réponses: 6
    Dernier message: 15/06/2012, 20h12
  4. chemins de projets et unité avec XE2
    Par Pascal Fonteneau dans le forum EDI
    Réponses: 5
    Dernier message: 16/04/2012, 18h50
  5. Réponses: 1
    Dernier message: 14/07/2009, 10h48

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