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

Ada Discussion :

Analyser une ligne de commande


Sujet :

Ada

  1. #1
    Invité
    Invité(e)
    Par défaut Analyser une ligne de commande
    Bonjour,
    J'essaie de parsser une ligne de commande, mais je ne parviens pas à retrouver pourquoi je n'assume pas le "/" de fin de chemin de répertoire.

    Je préviens dans le code qui suit, j'effecue une recherche des ficher correspondant à une expression régulière pour remplacer les "*" et les "?" ; j'utilise Gnat.Regexp.Match (String, Regular_Expression) pour le faire.

    De plus j'ai un problème avec les espaces dans les noms de fichier que j'essaie de protéger.

    Voivi ma fonction exploitant du code récursif.

    Code ada : 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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
     
    with GNAT.Directory_Operations;
    use GNAT.Directory_Operations;
    with GNAT.Directory_Operations.Iteration;
    with Gnat.Regexp;
    use Gnat;
    with Ada.Text_Io;
    use Ada;
    with Ada.Strings.Fixed;
    use Ada.Strings;
    with Gnat.Os_Lib;
     
    function Search_Regexp (Path : in String;
    			   Pattern : in String) return String is
     
          Full_Line : OS_Lib.String_Access := new String ' ("");
     
     
          procedure Action (Filename : in String;
    			Index    : in Positive;
    			Verax    : in out Boolean) is
     
    	 Buffer : Os_Lib.String_Access := new String ' ("");
    	 Is_Out : Boolean := True;
          begin
     
    	 --Text_Io.Put_Line(filename);
    	 if Regexp.Match(Dir_name(Filename), Regexp.Compile(Base_Name(Pattern), True, False)) then
    	    if Fixed.Index(Filename, " ") /= 0 then
     
    	       for I in Filename'Range loop
    		  if Filename(I) = Character'Val(32) then
    		     Buffer := new String ' (Buffer.all & "\ ");
    		  elsif Filename(I) = '/' then
    		     if Fixed.Index(Filename, " ", I) > I and Fixed.Index(Filename, "/", I+1) > Fixed.Index(Filename, " ", I) then
    			if Is_Out then
    			   Buffer := new String ' (Buffer.all & Filename(I) & "\""");
    			   Is_Out := False;
    			else
    			   Buffer := new String ' (Buffer.all & Filename(I));
    			end if;
     
    		     elsif Fixed.Index(Filename, " ", I) > I and Fixed.Index(Filename, "/", I+1) = 0 then
     
    			if Is_Out then
    			   Buffer := new String ' (Buffer.all & Filename(I) & "\""");
    			   Is_Out := False;
    			else
    			   Buffer := new String ' (Buffer.all & Filename(I));
    			end if;
    		     else
    			Buffer := new String ' (Buffer.all & Filename(I));
     
     
    		     end if;
     
    		  else
    		     Buffer := new String ' (Buffer.all & Filename(I));
     
    		  end if;
     
    	       end loop;
    	       if not Is_Out then
    		  Buffer := new String ' (Buffer.all & "\""");
    	       end if;
     
    	       Full_Line := new String ' (Full_Line.all & ' ' & "" & Buffer.all & "");
    	    else
     
    	       Full_Line := new String ' (Full_Line.all & ' ' &  Filename);
    	    end if;
    	 end if;
    	 Verax := False;
          end Action;
     
     
          procedure File_Search is
    	 new Iteration.Wildcard_iterator(Action);
     
     
       begin
     
          Text_Io.Put_Line("pattern for : " & Expand_Path(Pattern));
          if Expand_Path(Pattern) /= "" then
     
    	 File_Search(Dir_Name(Expand_Path(Path)));
          end if;
          if Full_Line'Length > 0 then
    	 return Full_Line.all;
          else
    	 return Pattern;
          end if;
       end Search_Regexp;
     
     
     
       function Expand_filename (Line : in String) return String is
     
     
          Current_Dir : constant String := ".";
          Absolute_Path : constant Character := '/';
     
     
          procedure Recursive_Expand (Line : in String; Result : in out Os_Lib.String_Access) is
     
    	 Start, Stop : Natural := 0;
          begin
     
    	 if Line'Length > 1 then	    
    	    if Start = 0 then
    	       Start := Line'First;
    	    end if;
    	    if Line(Start) /= Absolute_Path then
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Dir_Name(Current_Dir), Line(Start..Line'Last)));
    	    else		  
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Dir_Name(Line(Start..Line'last)), Line(Start..Line'Last)));
    	    end if;	 	
    	    Start := Fixed.Index(Line, " ", Line'First+1);	    
    	    if Start = 0 then
    	       start := Line'Last;	       	    	       
    	    end if;
    	    if Start < Line'Last then
    	       Stop := Fixed.Index(Line, " ", Start+1);
    	       if Stop /= 0 then
    		  Recursive_Expand(Line(start..stop), Result);
    	       else
    		  Recursive_Expand(Line(Start..Line'Last), Result);
    	       end if;
    	    end if;
    	 else
    	    if Start = 0 then
    	       Start := Line'First;
    	    end if;
    	    if Line(Start) /= Absolute_Path then
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Dir_Name(Current_Dir), Line(Start..Line'Last)));
    	    else		  
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Dir_Name(Line(Start..Line'last)), Line(Start..Line'Last)));
    	    end if;	 		  
     
    	 end if;
          end Recursive_Expand;
          Full_Set : Os_Lib.String_Access := new String ' ("");
       begin
     
          Recursive_Expand(Line, Full_Set);
          return Full_Set.all;
     
       end Expand_Filename;

    Donc, Expand_Filename appelle Recursive_Expand qui appelle Search_Regexp qui appelle File_Search qui appelle Action.
    Normalement le code à calculer est celui de Recursive_Expand.

    Merci pour votre Aide.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Oups, en fait ce code semble fonctionner.
    Désolé.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Ah ben tiens, puisque je suis là.

    Correction et préconditions :

    Code ada : 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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
     
    with GNAT.Directory_Operations;
    use GNAT.Directory_Operations;
    with GNAT.Directory_Operations.Iteration;
    with Gnat.Regexp;
     
    use Gnat;
    with Ada.Text_Io;
    use Ada;
    with Ada.Strings.Fixed;
    use Ada.Strings;
    with Gnat.Os_Lib;
    with Ada.Text_Io;
    use Ada;
    procedure adaRegexp is
       function Search_Regexp (Path : in String;
    			   Pattern : in String) return String is
     
          Full_Line : OS_Lib.String_Access := new String ' ("");
     
     
          procedure Action (Filename : in String;
    			Index    : in Positive;
    			Verax    : in out Boolean) is
     
    	 Buffer : Os_Lib.String_Access := new String ' ("");
    	 Is_Out : Boolean := True;
          begin
     
    	 --Text_Io.Put_Line(filename);
    	 if Regexp.Match(Dir_name(Filename), Regexp.Compile(Base_Name(Pattern), True, False)) then
    	    if Fixed.Index(Filename, " ") /= 0 then
     
    	       for I in Filename'Range loop
    		  if Filename(I) = Character'Val(32) then
    		     Buffer := new String ' (Buffer.all & "\ ");
    		  elsif Filename(I) = '/' then
    		     if Fixed.Index(Filename, " ", I) > I and Fixed.Index(Filename, "/", I+1) > Fixed.Index(Filename, " ", I) then
    			if Is_Out then
    			   Buffer := new String ' (Buffer.all & Filename(I) & "\""");
    			   Is_Out := False;
    			else
    			   Buffer := new String ' (Buffer.all & Filename(I));
    			end if;
     
    		     elsif Fixed.Index(Filename, " ", I) > I and Fixed.Index(Filename, "/", I+1) = 0 then
     
    			if Is_Out then
    			   Buffer := new String ' (Buffer.all & Filename(I) & "\""");
    			   Is_Out := False;
    			else
    			   Buffer := new String ' (Buffer.all & Filename(I));
    			end if;
    		     else
    			Buffer := new String ' (Buffer.all & Filename(I));
     
     
    		     end if;
     
    		  else
    		     Buffer := new String ' (Buffer.all & Filename(I));
     
    		  end if;
     
    	       end loop;
    	       if not Is_Out then
    		  Buffer := new String ' (Buffer.all & "\""");
    	       end if;
     
    	       Full_Line := new String ' (Full_Line.all & ' ' & "" & Buffer.all & "");
    	    else
     
    	       Full_Line := new String ' (Full_Line.all & ' ' &  Filename);
    	    end if;
    	 end if;
    	 Verax := False;
          end Action;
     
     
          procedure File_Search is
    	 new Iteration.Wildcard_iterator(Action);
     
     
       begin
     
          Text_Io.Put_Line("pattern for : " & Expand_Path(Pattern));
          if Expand_Path(Pattern) /= "" then
     
    	 File_Search(Dir_Name(Path));
          end if;
          if Full_Line'Length > 0 then
    	 return Full_Line.all;
          else
    	 return Pattern;
          end if;
       end Search_Regexp;
     
     
     
       function Expand_filename (Line : in String) return String is
     
     
          Current_Dir : constant String := ".";
          Absolute_Path : constant Character := '/';
     
     
          procedure Recursive_Expand (Line : in String; Result : in out Os_Lib.String_Access) is
     
    	 Start, Stop : Natural := 0;
          begin
     
    	 if Line'Length > 1 then	    
    	    if Start = 0 then
    	       Start := Line'First;
    	    end if;
    	    if Line(Start) /= Absolute_Path then
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Base_Name(Expand_Path(Line(Start..Line'last))), Line(Start..Line'Last)));
    	    else		  
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Dir_Name(Expand_Path(Line(Start..Line'last))), Line(Start..Line'Last)));
    	    end if;	 	
    	    Start := Fixed.Index(Line, " ", Line'First+1);	    
    	    if Start = 0 then
    	       start := Line'Last;	       	    	       
    	    end if;
    	    if Start < Line'Last then
    	       Stop := Fixed.Index(Line, " ", Start+1);
    	       if Stop /= 0 then
    		  Recursive_Expand(Line(start..stop), Result);
    	       else
    		  Recursive_Expand(Line(Start..Line'Last), Result);
    	       end if;
    	    end if;
    	 else
    	    if Start = 0 then
    	       Start := Line'First;
    	    end if;
    	    if Line(Start) /= Absolute_Path then
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Base_name(Expand_Path(Line(Start..Line'Last))), Line(Start..Line'Last)));
    	    else		  
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Dir_Name(Expand_Path(Line(Start..Line'last))), Line(Start..Line'Last)));
    	    end if;	 		  
     
    	 end if;
          end Recursive_Expand;
          Full_Set : Os_Lib.String_Access := new String ' ("");
       begin
     
          Recursive_Expand(Line, Full_Set);
          return Full_Set.all;
     
       end Expand_Filename;
    begin
        --Accept $HOME/ mais pas $HOME ni /$HOME ni /$HOME/
       Text_Io.Put(Expand_Filename("$HOME/"));
    end adaRegexp;

  4. #4
    Membre actif

    Homme Profil pro
    Mathématicien et développeur
    Inscrit en
    Mars 2012
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Mathématicien et développeur
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2012
    Messages : 132
    Points : 241
    Points
    241
    Billets dans le blog
    3
    Par défaut Grain de sel...
    Dans un code appelé souvent (ce qui n'est probablement pas le cas ici) tu aurais une fuite de mémoire avec tous ces "new" sans désallocation. Une solution simple serait d'utiliser des Unbounded_String à la place des OS_Lib.String_Access.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Oui, merci zerte.

  6. #6
    Invité
    Invité(e)
    Par défaut
    Accept les option en ligne de commande avant de résoudre les caractères joker.
    Multiple correction mais toujours pas de libération de la mémoire.
    Code ada : 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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
     
    function Search_Regexp (Path : in String;
    			   Pattern : in String) return String is
     
          Full_Line : OS_Lib.String_Access := new String ' ("");
     
     
          procedure Action (Filename : in String;
    			Index    : in Positive;
    			Verax    : in out Boolean) is
     
    	 Buffer : Os_Lib.String_Access := new String ' ("");
    	 Is_Out : Boolean := True;
          begin
    	 if Regexp.Match(Filename, Regexp.Compile(Pattern, True, False)) then
    	    if Fixed.Index(Filename, " ") /= 0 then
     
    	       for I in Filename'Range loop
    		  if Filename(I) = Character'Val(32) then
    		     Buffer := new String ' (Buffer.all & "\ ");
    		  elsif Filename(I) = '/' then
    		     if Fixed.Index(Filename, " ", I) > I and Fixed.Index(Filename, "/", I+1) > Fixed.Index(Filename, " ", I) then
    			if Is_Out then
    			   Buffer := new String ' (Buffer.all & Filename(I) & "\""");
    			   Is_Out := False;
    			else
    			   Buffer := new String ' (Buffer.all & Filename(I));
    			end if;
     
    		     elsif Fixed.Index(Filename, " ", I) > I and Fixed.Index(Filename, "/", I+1) = 0 then
     
    			if Is_Out then
    			   Buffer := new String ' (Buffer.all & Filename(I) & "\""");
    			   Is_Out := False;
    			else
    			   Buffer := new String ' (Buffer.all & Filename(I));
    			end if;
    		     else
    			Buffer := new String ' (Buffer.all & Filename(I));
     
     
    		     end if;
     
    		  else
    		     Buffer := new String ' (Buffer.all & Filename(I));
     
    		  end if;
     
    	       end loop;
    	       if not Is_Out then
    		  Buffer := new String ' (Buffer.all & "\""");
    	       end if;
     
    	       Full_Line := new String ' (Full_Line.all & ' ' & "" & Buffer.all & "");
    	    else
     
    	       Full_Line := new String ' (Full_Line.all & ' ' &  Filename);
    	    end if;
    	 end if;
    	 Verax := False;
          end Action;
     
     
          procedure File_Search is
    	 new Iteration.Wildcard_iterator(Action);
     
     
       begin
     
          Text_Io.Put_Line("pattern for : " & Expand_Path(Pattern));
          if Expand_Path(Pattern) /= "" then
     
    	 File_Search(Path);
          end if;
          if Full_Line'Length > 0 then
    	 return Full_Line.all;
          else
    	 return Pattern;
          end if;
       end Search_Regexp;
     
     
     
       function Expand_filename (Line : in String) return String is
     
     
          Current_Dir : constant String := ".";
          Absolute_Path : constant Character := '/';
     
     
          procedure Recursive_Expand (Line : in String; Result : in out Os_Lib.String_Access) is
     
    	 Start, Stop : Natural := 0;
          begin
    	 if Line'Length > 1 then	    
    	    if Start = 0 then
    	       Start := Line'First;
    	    end if;
     
    	    Stop := Fixed.Index(Line, " ", Start+1);
    	    if Stop /= 0 then
    	       if Line(Start) /= Absolute_Path then
     
    		  Result := new String ' (Result.all & ' ' & Search_Regexp(Base_Name(Expand_Path(Line(Start..Stop))), Line(Start..Stop)));
    	       else		  
     
    		  Result := new String ' (Result.all & ' ' & Search_Regexp(Expand_Path(Line(Start..Stop)), Line(Start..Stop)));
    	       end if;	 	
    	       Recursive_Expand(Line(Stop+1..Line'last), Result);
     
     
    	    else
     
     
    	       if Line(Start) /= Absolute_Path then
     
    		  Result := new String ' (Result.all & ' ' & Search_Regexp(Base_Name(Expand_Path(Line(Start..Line'last))), Line(Start..Line'Last)));
    	       else		  
     
    		  Result := new String ' (Result.all & ' ' & Search_Regexp(Expand_Path(Line(Start..Line'last)), Line(Start..Line'Last)));
    	       end if;	 	
     
     
    	    end if;
     
    	 else
    	    if Start = 0 then
    	       Start := Line'First;
    	    end if;
    	    if Line(Start) /= Absolute_Path then
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Base_name(Expand_Path(Line(Start..Line'Last))), Line(Start..Line'Last)));
    	    else		  
     
    	       Result := new String ' (Result.all & ' ' & Search_Regexp(Expand_Path(Line(Start..Line'last)), Line(Start..Line'Last)));
    	    end if;	 		  
     
    	 end if;
          end Recursive_Expand;
          Full_Set : Os_Lib.String_Access := new String ' ("");
       begin
     
          Recursive_Expand(Line, Full_Set);
          return Full_Set.all;
     
       end Expand_Filename;


    Tiens d'ailleurs, je croyais qu'Ada gérait la mèmoire lui même...
    Il doit y avoir excpetion.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Pour bien faire, il faudrait ajouter "*" & au debut de Pattern passé à Compile.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 13/06/2008, 11h56
  2. Réponses: 11
    Dernier message: 20/12/2005, 16h29
  3. [OCaml] Parser une ligne de commande
    Par Thanatos dans le forum Caml
    Réponses: 4
    Dernier message: 10/12/2004, 10h11
  4. lancer une mdb a partir d'une ligne de commande
    Par dpie dans le forum Access
    Réponses: 5
    Dernier message: 30/11/2004, 15h01
  5. Analyser la ligne de commande
    Par benj29 dans le forum C
    Réponses: 14
    Dernier message: 19/11/2002, 04h13

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