with GNAT.Command_Line; with GNAT.Strings; with Ada.Command_Line; with Ada.Text_IO; use Ada.Text_IO; with Ada.Directories; with Ada.Strings.Unbounded; with Simple_Time; with CSV; with Candidates; procedure STV is package ACom renames Ada.Command_Line; package GCom renames GNAT.Command_Line; package GStr renames GNAT.Strings; package File renames Ada.Directories; package SU renames Ada.Strings.Unbounded; use type File.File_Kind; use type SU.Unbounded_String; Config : GCom.Command_Line_Configuration; Further_Help : String := "Try ""stv --help"" for more information."; Verbose : aliased Boolean; Version : aliased Boolean; Help : aliased Boolean; Candidate_File : aliased GStr.String_Access; Preference_File : aliased GStr.String_Access; Output_Dir : aliased GStr.String_Access; Number_To_Elect : aliased Integer; State_String : aliased GStr.String_Access; type State_Name is (ACT, NT, TAS, SA, WA, VIC, QLD, NSW); State : State_Name; Start_Time, Finish_Time : Simple_Time.Time; Main_Log, Log_Msg : SU.Unbounded_String; begin GCom.Define_Switch (Config => Config, Output => Verbose'Access, Switch => "-v", Long_Switch => "--verbose", Help => "chatty output on stderr"); GCom.Define_Switch (Config => Config, Output => Version'Access, Switch => "-V", Long_Switch => "--version", Help => "show version number"); -- technically not required, but included so -- it will show up in the help output GCom.Define_Switch (Config => Config, Output => Help'Access, Switch => "-h", Long_Switch => "--help", Help => "show this help information"); GCom.Define_Switch (Config => Config, Output => Candidate_File'Access, Switch => "-c:", Long_Switch => "--candidates=", Help => ".csv file containing AEC candidate data"); GCom.Define_Switch (Config => Config, Output => Preference_File'Access, Switch => "-p:", Long_Switch => "--preference=", Help => ".csv file containing AEC formal preferences"); GCom.Define_Switch (Config => Config, Output => Output_Dir'Access, Switch => "-o:", Long_Switch => "--outdir=", Help => "new directory to output count logging"); GCom.Define_Switch (Config => Config, Output => Number_To_Elect'Access, Switch => "-e:", Long_Switch => "--elect=", Help => "number of candidates to elect"); GCom.Define_Switch (Config => Config, Output => State_String'Access, Switch => "-s:", Long_Switch => "--state=", Help => "state or territory the data corresponds to"); GCom.Set_Usage (Config => Config, Usage => "[switches]", Help => "Note that the -c, -p, -o, -e, -s options are all" & ASCII.LF & "required for normal operation." & ASCII.LF); -- parse options begin GCom.Getopt (Config); exception when GCom.Exit_From_Command_Line => ACom.Set_Exit_Status (ACom.Failure); return; when GCom.Invalid_Switch => ACom.Set_Exit_Status (ACom.Failure); return; end; -- version display functionality if Version then Put_Line ("Australian STV Counter v0.2"); ACom.Set_Exit_Status (ACom.Failure); return; end if; -- check candidate data option is valid if Candidate_File.all = "" then Put_Line ("Candidate data file not provided." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; if not File.Exists (Candidate_File.all) then Put_Line ("Candidate data file does not exist." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; if File.Kind (Candidate_File.all) /= File.Ordinary_File then Put_Line ("Candidate data file name appears to refer to a directory or special file." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; -- check preference data option is valid if Preference_File.all = "" then Put_Line ("Preference data file not provided." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; if not File.Exists (Preference_File.all) then Put_Line ("Preference data file does not exist." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; if File.Kind (Preference_File.all) /= File.Ordinary_File then Put_Line ("Preference data file name appears to refer to a directory or special file." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; -- check output directory option is valid if Output_Dir.all = "" then Put_Line ("Output logging directory not provided." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; if File.Exists (Output_Dir.all) then Put_Line ("Output logging directory already exists." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end if; -- check state option is valid begin State := State_Name'Value (State_String.all); exception when Constraint_Error => Put_Line ("Invalid State/Territory or State/Territory not provided." & ASCII.LF & Further_Help); ACom.Set_Exit_Status (ACom.Failure); return; end; -- set up logging --File.Create_Directory (Output_Dir.all); Start_Time := Simple_Time.Now; Main_Log := SU.To_Unbounded_String (Output_Dir.all & "/" & "log.txt"); Log_Msg := SU.To_Unbounded_String ("Started election count at " & Simple_Time.To_String (Start_Time)); Put_Line (SU.To_String (Log_Msg)); Finish_Time := Simple_Time.Now; end STV;