--------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Gnostic is Ada Generic Neural Object System Engineering.                                                                                                --
-- Gnostic (C) Copyright 2016 Manuel De Girardi.                                                                                                           --
--------------------------------------------------------------------------------------------------------------------------------------------------------------
  
--------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Date        := 2016-12-05 01:23:25 ; 
-- Description : Ada Generic Neural Object System Engineering.                                                                                              --
-- Version     := 2016.34.25a ; 
-- Authors     : Manuel De Girardi.                                                                                                                         --
--------------------------------------------------------------------------------------------------------------------------------------------------------------
with Gnat.OS_Lib;
use Gnat.Os_Lib;

with Ada.Strings.Fixed;
use Ada.Strings.Fixed;
use Ada.Strings;

with GNAT.Directory_Operations;
use GNAT.Directory_Operations;
with GNAT.Directory_Operations.Iteration;
with Gnat.Regexp;

use Gnat;
with Ada.Calendar.Formatting;
use Ada;

with Ada.Text_Io;
use Ada.Text_Io;
package body Gnos.Tools is


   
   function Integer_Image (Value : in Integer) return String is
   begin
      if Value < 0 then
	 return 
	   '-' & Integer'Image(Value)(Fixed.Index_Non_Blank(Integer'Image(Value)(2..Integer'Image(Value)'Last))..Integer'Image(Value)'Last);
      else
	 return 
	   Integer'Image(Value)(Fixed.Index_Non_Blank(Integer'Image(Value))..Integer'Image(Value)'Last);
      end if;
   end Integer_Image;
   
   
   function YMD_Elapsed_String(Years    : in Natural;
                               Months   : in Natural;
                               Days     : in Natural) return String is
   begin
      return Integer_Image(Years) &
        "y, " &
        Integer_Image(Months) &
        "m, " &
        Integer_Image(Days) &
        "d, ";        
   end YMD_Elapsed_String;
   
   
   
   procedure Difference_In_Years(Top_Date : in Time;
                                 Bot_Date : in Time;
                                 Years    : out Natural;
                                 Months   : out Natural;
                                 Days     : out Natural;
                                 Houres   : out Natural;
                                 Minutes  : out Natural;
                                 Second   : out Natural;
                                 Rest     : out Duration) is      
      
      function Is_Leap_Year (Year : Integer) return Boolean is
      begin
         return (Year rem 4 = 0) and ((Year rem 100 /= 0) or (Year rem 16 = 0));
      end Is_Leap_Year;
      
      pragma Inline (Is_Leap_Year);
      
      Days_Months_Count : constant array (Month_Number) of Day_Number := (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
      
      
      function Last_Days(Years , Months : in Natural) return Natural is         
      begin         
         if Months = 1 then
            return Days_Months_Count(12);
         elsif Months /= 3 then
            return Days_Months_Count(Months-1);
         end if;
         
         if Is_Leap_Year(Years) then
            return Days_Months_Count(2) + 1;
         else
            return Days_Months_Count(2);
         end if;
      end Last_Days;

      
      Top_Seconds : constant Day_Duration := Seconds(Top_Date);
      Bot_Seconds : constant Day_Duration := Seconds(Bot_Date);
      Top_Day     : constant Day_Number := Day(Top_Date);
      Bot_Day     : constant Day_Number := Day(Bot_Date);
      Top_Year    : constant Year_Number := Year(Top_Date);
      Bot_Year    : constant Year_Number := Year(Bot_Date);
      Top_Month   : constant Month_Number := Month(Top_Date);
      Bot_Month   : constant Month_Number := Month(Bot_Date);
      
      Years_Number  : Integer := 0;
      Months_Number : Integer := 0;
      Days_Number   : Integer := 0;            
      
      Total_Duration : Duration := Bot_Seconds - Top_Seconds;
   begin
      
      if Top_Date > Bot_Date then
         raise Constraint_Error;
      end if;
      
      Years    := 0;
      Months   := 0;
      Days     := 0;
      Houres   := 0;
      Minutes  := 0;
      Second   := 0;
      Rest     := 0.0;
      
      Years_Number := (Bot_Year - Top_Year - 1);
      
      Months_Number := Bot_Month;
      
      if (Bot_Month > Top_Month) or ((Bot_Month = Top_Month) and (Bot_Day >= Top_Day)) then         

         Years_Number := Years_Number + 1;
         
      else         
         Months_Number := Bot_Month + 12;
      end if;
      
      Months_Number := (Months_Number - Top_Month - 1);
      
      
      if Bot_Day > Top_Day then

         Months_Number := Months_Number + 1;
         Days_Number := Bot_Day - Top_Day;
	 
      elsif Bot_Day < Top_Day then
	 
         Days_Number := Last_Days (Bot_Year, Bot_Month) - Top_Day;
         if Days_Number < 0 then
            Days_Number := Days_Number + Bot_Day;
         end if;    
	 
      else
	 Months_Number := Months_Number + 1;	 
	 Days_Number := 0;
      end if;
      
      
      Days := Days_Number;
      Months := Months_Number;
      Years := Years_Number;
      
      if Bot_Seconds > Top_seconds then
         Total_Duration := (Bot_Seconds - Top_Seconds);	 
      elsif Bot_Seconds < Top_Seconds then
         Total_Duration := (86400.0 - Top_Seconds) + Bot_Seconds;         	 
	 Days := Days - 1;
      else
	 Total_Duration := 0.0;	 
      end if;
      Formatting.Split(Total_Duration, Houres, Minutes, Second, Rest);         
   end Difference_In_Years;

   
   
      function Normalize_Quoted_Argument(Arg : in String) return String is
      Local : String(1..Arg'Length) := Arg;
      Local_Index : Natural := 0;
   begin
      for I in Arg'First .. Arg'Last loop 
	 if Arg(i) /= '"' then
	    Local(Local_Index + 1) := Arg(I);
	    Local_Index := Local_Index + 1;
	 end if;
      end loop;
      if Local_Index /= 0 then
	 return Local(Local'First..Local_index);
      else
	 return Arg;
      end if;
   end Normalize_Quoted_Argument;

   
   Local_Prefix : constant String := "./";
   
   function Delete_Local_Prefix(Filename : in String) return String is
   begin
      if Filename'Length > 2 then
	 if Filename(Filename'First..Filename'First+1) = Local_Prefix then
	    return Filename(Filename'First+2..Filename'Last);
	 else
	    return Filename;
	 end if;
      else
	 return Filename;
      end if;
   end Delete_Local_Prefix;
   
   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 ' ("");
	 Tmp    : Os_Lib.String_Access := new String ' ("");
	 
	 Is_Out : Boolean := True;
	 Regular_Exp : Regexp.Regexp;
      begin
	 
	 --Text_Io.Put_line("File : "& Filename & "; Pattern : " & Pattern); 
	 Regular_Exp := Regexp.Compile("*" & Pattern, True, False);
	 
	 
	 if Regexp.Match(Filename, Regular_Exp) then
	    if Ada.Strings.Fixed.Index(Filename, " ") /= 0 then
	       
	       for I in Filename'First..Filename'Last-1 loop
		  if Filename(I) = Character'Val(32) then		     
		     Buffer := new String ' (Tmp.all & " ");
		     Free(Tmp);
		     Tmp := new String ' (Buffer.all);
		     Free(Buffer);
		  elsif Filename(I) = '/' then
		     if Ada.Strings.Fixed.Index(Filename, " ", I) > I and Ada.Strings.Fixed.Index(Filename, "/", I+1) > Ada.Strings.Fixed.Index(Filename, " ", I) then
			if Is_Out then
			   Buffer := new String ' (Tmp.all & Filename(I) & """");
			   Free(Tmp);
			   Tmp := new String ' (Buffer.all);
			   Free(Buffer);
			   Is_Out := False;
			else
			   Buffer := new String ' (Tmp.all & Filename(I));
			   Free(Tmp);
			   Tmp := new String ' (Buffer.all);
			   Free(Buffer);
			end if;
			
		     elsif Ada.Strings.Fixed.Index(Filename, " ", I) > I and Ada.Strings.Fixed.Index(Filename, "/", I+1) = 0 then
			
			if Is_Out then
			   Buffer := new String ' (Tmp.all & Filename(I) & """");
			   Free(Tmp);
			   Tmp := new String ' (Buffer.all);
			   Free(Buffer);
			   Is_Out := False;
			else
			   Buffer := new String ' (Tmp.all & Filename(I));
			   Free(Tmp);
			   Tmp := new String ' (Buffer.all);
			   Free(Buffer);
			end if;
		     else
			Buffer := new String ' (Tmp.all & Filename(I));
			Free(Tmp);
			Tmp := new String ' (Buffer.all);
			Free(Buffer);
		     end if;
		     
		  else
		     Buffer := new String ' (Tmp.all & Filename(I));
		     Free(Tmp);
		     Tmp := new String ' (Buffer.all);
		     Free(Buffer);
		  end if;
		  
	       end loop;
	       Buffer := new String ' (Tmp.all & Filename(Filename'Last));
	       if not Is_Out then		  
		  Buffer := new String ' (Tmp.all & """");
		  Free(Tmp);
		  Tmp := new String ' (Buffer.all);
		  Free(Buffer);
	       end if;
	       --Text_Io.Put_Line("Matched :" & Full_Line.all);
	       if Full_Line'Length > 0 then
		  Buffer := new String ' (Full_Line.all & ' ' & "" & Delete_Local_Prefix(Tmp.all) & "");
		  Free(Full_Line);
		  Full_Line := new String ' (Buffer.all);
		  Free(Buffer);
		  
	       else
		  Buffer := new String ' (Full_Line.all & "" & Delete_Local_Prefix(Tmp.all) & "");
		  Free(Full_Line);
		  Full_Line := new String ' (Buffer.all);
		  Free(Buffer);		  
	       end if;
	       --Text_Io.Put_Line("Matche :" & Tmp.all);
	    else
	       --Text_Io.Put_Line("Matched :" & filename);
	       if Full_Line'Length > 0 then
		  Buffer := new String ' (Full_Line.all & ' ' &  Delete_Local_Prefix(filename));
		  Free(Full_Line);
		  Full_Line := new String ' (Buffer.all);
		  Free(Buffer);		  
	       else
		  Buffer := new String ' (Full_Line.all & "" & Delete_Local_Prefix(filename) & "");
		  Free(Full_Line);
		  Full_Line := new String ' (Buffer.all);
		  Free(Buffer);
		  
	       end if;
	       --Text_Io.Put_Line("Matche :" & 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
	 declare
	    Result : constant String := Full_Line.all;
	 begin
	    Free(Full_Line);
	    return Result;
	 end;
      else
	 return Expand_Path(Pattern);
      end if;
   exception 
      when others =>
	 if Full_Line'Length > 0 then
	    declare
	       Result : constant String := Full_Line.all;
	    begin
	       Free(Full_Line);
	       return Result;
	    end;
	 else
	    return Expand_Path(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 := Ada.Strings.Fixed.Index(Line, " ", Start+1);
	    if Stop /= 0 then
	       if Line(Start) /= Absolute_Path then
		  
		  Result := new String ' (Result.all & ' ' & Search_Regexp(Expand_Path(Line(Start..Stop-1)), Line(Start..Stop-1)));
	       else		  
		  
		  Result := new String ' (Result.all & ' ' & Search_Regexp(Expand_Path(Line(Start..Stop-1)), Line(Start..Stop-1)));
	       end if;	 	
	       Recursive_Expand(Line(Stop+1..Line'last), Result);
	       
	       
	    else
	       
	       
	       if Line(Start) /= Absolute_Path then
		  
		  Result := new String ' (Result.all & ' ' & Search_Regexp(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(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(Ada.Strings.Fixed.Index_Non_Blank(Line)..Ada.Strings.Fixed.Index_Non_Blank(Line, Backward)), Full_Set);
      --Text_Io.Put_Line("Matched :" & Full_Set.all);      
      if Full_Set'Length > 0 then
	 declare
	    Result : constant String := Full_Set.all(Ada.Strings.Fixed.Index_Non_Blank(Full_Set.all)..Ada.Strings.Fixed.Index_Non_Blank(Full_Set.all, Backward));
	 begin
	    Free(Full_Set);
	    return Result;
	 end;	 	 
      else
	 return "";
      end if;
      
   end Expand_Filename;
   
   
   
   procedure Makefile(Filename : in String) is
      
      File : File_Type;
   begin
      Create(File, Out_File, Filename, Form => "WCEM=8");
      Put_Line(File, "");
      Put_Line(File, "#To make Ada projects.");
      Put_Line(File, "#2016-12-04");
      Put_Line(File, "#Makefile version 2.0.1");
      Put_Line(File, "");
      Put_Line(File, "Project_Name=`./head 1 Project.default`");
      Put_Line(File, "");
      Put_Line(File, "Sub_Projects_Names=`./tail 2 Project.default`");
      Put_Line(File, "");
      Put_Line(File, "libs=`for j in \`./tail 2 Project.default\`; do echo -aI\`./head 1 Project.default\`/$$j/src/lib; done`");
      Put_Line(File, "");
      Put_Line(File, "allsources=`for k in \`./tail 2 Project.default\`; do find \`./head 1 Project.default\`/$$k/src/lib -name ""*.ad?""; done`");
      Put_Line(File, "");
      
      Put_Line(File, "default:");
      Put_Line(File, Character'Val(9) & "@echo ""Par defaut, rien a faire pour etre bon.""");
      Put_Line(File, Character'Val(9) & "@echo ""Cibles restantes : """);
      Put_Line(File, Character'Val(9) & "@echo ""'info' pour avoir les informations sur le projet ;""");
      Put_Line(File, Character'Val(9) & "@echo ""'prepare' pour fabriquer les repertoires du projet ;""");
      Put_Line(File, Character'Val(9) & "@echo ""'update' pour updater la version Versions.default ;; et ranger le workspace (a la main).""");
      Put_Line(File, Character'Val(9) & "@echo ""'all' pour compiler le projet ;""");
      Put_Line(File, Character'Val(9) & "@echo ""'enlight-sources' pour collorier les sources en sequence d'echappement""");
      Put_Line(File, Character'Val(9) & "@echo ""'mrproper' pour supprimer les fichiers objets obtenus avec make all ;""");
      Put_Line(File, Character'Val(9) & "@echo ""'clean' pour supprimer les anciens fichiers sources et les fichier objets sauf le fichier programme principal ;""");
      Put_Line(File, Character'Val(9) & "@echo ""'help' appelle le programme with '-h' option ;""");
      Put_Line(File, Character'Val(9) & "@echo ""'version' appelle le program with '-v' option ;""");
      Put_Line(File, Character'Val(9) & "@echo ""'validate' appelle les cibles info, help and version.""");
      Put_Line(File, Character'Val(9) & "@echo ""'arch' pour archiver et compresser l'archive avec la derniere version dans Versions.default ;""");
      Put_Line(File, Character'Val(9) & "@echo """"");
      Put_Line(File, Character'Val(9) & "@echo ""'perfect' permet d'appeller la suite de cible suivante dans l'odre d'apparition :""");
      Put_Line(File, Character'Val(9) & "@echo """"");
      Put_Line(File, Character'Val(9) & "@echo """"");
      Put_Line(File, Character'Val(9) & "@echo ""all afin de produire le programme""");
      Put_Line(File, Character'Val(9) & "@echo ""clean afin de supprimer les vieux fichers si la compilation a produit le programme.""");
      Put_Line(File, Character'Val(9) & "@echo ""validate afin de pouvoir comparer la version du projet et la version du programme.""");  
      Put_Line(File, "");	 
      
      Put_Line(File, "tail:");
      Put_Line(File, Character'Val(9) & "gnatmake tail.adb -D obj");
      Put_Line(File, "head:");
      Put_Line(File, Character'Val(9) & "gnatmake head.adb -D obj");
      
      
      Put_Line(File, "info:");
      Put_Line(File, Character'Val(9) & "@echo Project Name = $(Project_Name) ;");
      Put_Line(File, Character'Val(9) & "@echo Sub Projects Names = $(Sub_Projects_Names) ;");
      Put_Line(File, Character'Val(9) & "@echo Project Version = `./tail -1 Versions.default`");
      Put_Line(File, "");

      Put_Line(File, "prepare:");
      
      Put_Line(File, Character'Val(9) & "@if [ ! -d $(Project_Name) ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "mkdir -p $(Project_Name)/bin; \");
      Put_Line(File, Character'Val(9) & "fi;");
      Put_Line(File, Character'Val(9) & "@mkdir -p Documentations/sources/enlighted;");
      Put_Line(File, Character'Val(9) & "@mkdir -p Documentations/sources/html;");
      Put_Line(File, Character'Val(9) & "@if [ -d $(Project_Name) ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "for i in $(Sub_Projects_Names) ; do \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "if [ ! -d  $(Project_Name)/$$i ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & Character'Val(9) & "mkdir -p $(Project_Name)/$$i; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & Character'Val(9) & "mkdir -p $(Project_Name)/$$i/src/lib; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & Character'Val(9) & "mkdir -p $(Project_Name)/$$i/obj; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "fi; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "done; \");
      Put_Line(File, Character'Val(9) & "fi");
      Put_Line(File, "");
      Put_Line(File, "all:");
      Put_Line(File, Character'Val(9) & "@echo ""Making graphical project : $(Project_Name)...""");
      Put_Line(File, Character'Val(9) & "@for i in $(Sub_Projects_Names) ; do \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "if [ -f $(Project_Name)/$$i/src/$$i.adb ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "gnatmake -Wall -gnatW8 -gnat12 -O3 $(Project_Name)/$$i/src/$$i.adb $(libs) \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "-aIPragmARC -aI/usr/share/ada/adainclude/aws -aO./AWS \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "-aI/usr/share/ada/adainclude/templates_parser -D $(Project_Name)/$$i/obj/ \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "-o $(Project_Name)/bin/$$i `gtkada-config` -L. -lgnutls -laws -lz; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "fi; \");
      Put_Line(File, Character'Val(9) & "done");
      Put_Line(File, "");
      Put_Line(File, "");
      Put_Line(File, Character'Val(9) & "if [ -x $(Project_Name)/bin/$(Project_Name) ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "strip $(Project_Name)/bin/$(Project_Name); \");
      Put_Line(File, Character'Val(9) & "fi;");
      Put_Line(File, Character'Val(9) & "@echo ""done.""");
      Put_Line(File, "");
      Put_Line(File, "");
      Put_Line(File, "enlight-sources:");
      Put_Line(File, Character'Val(9) & "@if [ -d $(Project_Name) ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "if [ -d Documentations/sources/enlighted ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "for l in $(allsources); do \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & Character'Val(9) & "echo $$l; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & Character'Val(9) & "source-highlight -s Ada -f ESC -o Documentations/sources/enlighted/`basename $$l`.txt -i $$l; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & Character'Val(9) & "source-highlight -s Ada -f html -o Documentations/sources/html/`basename $$l`.html -i $$l; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "done; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "fi; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "if [ -f $(Project_Name)/$(Project_Name)/src/$(Project_Name).adb ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "source-highlight -s Ada -f ESC -o Documentations/sources/enlighted/$(Project_Name).adb.txt \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "-i $(Project_Name)/$(Project_Name)/src/$(Project_Name).adb; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "source-highlight -s Ada -f html -o Documentations/sources/html/$(Project_Name).adb.html \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "-i $(Project_Name)/$(Project_Name)/src/$(Project_Name).adb; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "fi; \");
      Put_Line(File, Character'Val(9) & "fi;");
      Put_Line(File, "");
      
      Put_Line(File, "mrproper:");
      Put_Line(File, Character'Val(9) & "for i in $(Sub_Projects_Names) ; do \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "rm -f $(Project_Name)/$$i/obj/*; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "rm -f $(Project_Name)/$$i/src/lib/*~; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "rm -f $(Project_Name)/$$i/src/*~; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "rm -f $(Project_Name)/bin/$(Project_Name); \");
      Put_Line(File, Character'Val(9) & "done");
      Put_Line(File, "");
      
      Put_Line(File, "clean:");
      Put_Line(File, Character'Val(9) & "if [ -x ./$(Project_Name)/bin/$(Project_Name) ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "for i in $(Sub_Projects_Names) ; do \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & Character'Val(9) & "rm -f $(Project_Name)/$$i/obj/*; \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "done; \");
      Put_Line(File, Character'Val(9) & "fi;");
      Put_Line(File, "");
      Put_Line(File, "validate: info help version");
      Put_Line(File, "");
      
      Put_Line(File, "help:");
      Put_Line(File, Character'Val(9) & "if [ -x ./$(Project_Name)/bin/$(Project_Name) ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "$(Project_Name)/bin/$(Project_Name) -h; \");
      Put_Line(File, Character'Val(9) & "fi;");
      Put_Line(File, "version:");
      Put_Line(File, Character'Val(9) & "if [ -x ./$(Project_Name)/bin/$(Project_Name) ]; then \");
      Put_Line(File, Character'Val(9) & Character'Val(9) & "echo ""$(Project_Name) version : ""; $(Project_Name)/bin/$(Project_Name) -v; \");
      Put_Line(File, Character'Val(9) & "fi;");
      Put_Line(File, "");
      
      Put_Line(File, "update:");
      Put_Line(File, Character'Val(9) & "./tail -1 Versions.default >> History.txt");
      Put_Line(File, "");
      Put_Line(File, "arch:");
      Put_Line(File, Character'Val(9) & "tar -c -v -z -f $(Project_Name)-`./tail -1 Versions.default`.tgz \");
      Put_Line(File, Character'Val(9) & "$(Project_Name) \");
      Put_Line(File, Character'Val(9) & "Makefile Project.default Versions.default gpl.txt History.txt \");
      Put_Line(File, Character'Val(9) & "Documentations Howto.txt head.adb tail.adb");
      Put_Line(File, "");
      Put_Line(File, "perfect: all clean validate");      
      Close(File);
   
   end Makefile;
   

end Gnos.Tools;