From c2f324ac23ea143dfea308229f0ac0376ed4f745 Mon Sep 17 00:00:00 2001 From: Jed Barber Date: Mon, 6 Feb 2017 02:32:14 +1100 Subject: Most of the Main procedure done, a Simple Time package added --- src/simple_time.adb | 32 +++++++++ src/simple_time.ads | 21 ++++++ src/stv.adb | 184 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 228 insertions(+), 9 deletions(-) create mode 100644 src/simple_time.adb create mode 100644 src/simple_time.ads diff --git a/src/simple_time.adb b/src/simple_time.adb new file mode 100644 index 0000000..cf1995c --- /dev/null +++ b/src/simple_time.adb @@ -0,0 +1,32 @@ + + +with Ada.Calendar; use Ada.Calendar; +with Ada.Strings; use Ada.Strings; +with Ada.Strings.Fixed; use Ada.Strings.Fixed; + + +package body Simple_Time is + + + function To_String + (Moment : in Time) + return String + is + Raw_Secs : Day_Duration := Seconds (Moment); + + Hours : Integer := Integer (Raw_Secs) / 3600; + Minutes : Integer := (Integer (Raw_Secs) - Hours * 3600) / 60; + Seconds : Duration := Raw_Secs - Duration (Hours) * 3600 - Duration (Minutes) * 60; + begin + return Trim (Year_Number'Image (Year (Moment)), Both) & "-" & + Trim (Month_Number'Image (Month (Moment)), Both) & "-" & + Trim (Day_Number'Image (Day (Moment)), Both) & " " & + Trim (Integer'Image (Hours), Both) & ":" & + Trim (Integer'Image (Minutes), Both) & ":" & + Trim (Duration'Image (Seconds), Both); + end To_String; + + +end Simple_Time; + + diff --git a/src/simple_time.ads b/src/simple_time.ads new file mode 100644 index 0000000..01aaa23 --- /dev/null +++ b/src/simple_time.ads @@ -0,0 +1,21 @@ + + +with Ada.Calendar; + + +package Simple_Time is + + + subtype Time is Ada.Calendar.Time; + + + function Now return Time renames Ada.Calendar.Clock; + function To_String (Moment : in Time) return String; + + + function "-" (Left, Right : in Time) return Duration renames Ada.Calendar."-"; + + +end Simple_Time; + + diff --git a/src/stv.adb b/src/stv.adb index a7d6c6d..01c7a38 100644 --- a/src/stv.adb +++ b/src/stv.adb @@ -1,7 +1,12 @@ -with Ada.Text_IO; +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; @@ -9,24 +14,185 @@ with Candidates; procedure STV is - package My_CSV is new CSV; + 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; - Result : My_CSV.CSV_Record; + use type File.File_Kind; + use type SU.Unbounded_String; -begin + 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; - Result := My_CSV.Parse_Line ("123,4""56,78""9764,3,""4,5"","); + type State_Name is (ACT, NT, TAS, SA, WA, VIC, QLD, NSW); + State : State_Name; - for Item of Result loop - Ada.Text_IO.Put_Line (Ada.Strings.Unbounded.To_String (Item)); - end loop; + 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; - Ada.Text_IO.Put_Line (My_CSV.Unparse_Record (Result)); end STV; -- cgit