Skip to main content

The dm_set_time packages

·

dm_set_time is the tool that ships today. I keep shared UART settings and -d in the swiss_micros packages. This note is only the child parser and the four lines I send once the port is open.

I wanted a clock setter that I could call from Make without opening CoolTerm. The calculator already speaks ts and t. All I had to do was refuse a bad stamp, pick UTC or local when no stamp is given, and leave the console quickly afterwards.

Units #

Unit Role
DM_Set_Time Empty Pure parent.
DM_Set_Time.Command_Line GetOpt child: optional stamp and -u / --utc.
DM_Set_Time.Main Opens the port and runs the dialogue.

Command line #

Swiss_Micros.Command_Line.Object     --  -d / --device / DM_SERIAL_DEVICE
        ↑
DM_Set_Time.Command_Line.Object      --  -u / --utc ; operand YYYYMMDD HHMMSS

Pattern is the parent pattern with UTC_Short (u) appended. Parse installs that pattern, then calls Super.Parse. That is the whole hierarchical trick: I only add the letters I own.

Token Meaning
-d / --device / DM_SERIAL_DEVICE inherited; required
-? / --help inherited
-u / --utc when no stamp is given, Date_Time_Image uses UTC
operand one compact stamp YYYYMMDD HHMMSS

Analyze_File is the operand hook, not a file name. I demand length 15 and a Spitbol match:

Digit_Pattern     : constant SB_P.Pattern := SB_P.Any (S_MC.Decimal_Digit_Set);
Date_Pattern      : constant SB_P.Pattern := SB_P.Replicate (Digit_Pattern, 8);
Time_Pattern      : constant SB_P.Pattern := SB_P.Replicate (Digit_Pattern, 6);
Date_Time_Pattern : constant SB_P.Pattern :=
   SB_P.Pos (0) & Date_Pattern & " " & Time_Pattern;

Eight decimal digits, a space, six decimal digits. A second operand is Option_Wrong_Error (“Time already set”). A malformed stamp is Option_Parse_Error with the text Expected: YYYYMMDD HHMMSS. The negative tests I keep around are faulty_15 (right length, a letter in the date — Spitbol fails on the first B) and faulty_13 (wrong length).

Time returns the operand when Time (1) is not a space; otherwise it calls Swiss_Micros.Console_IO.Date_Time_Image (Use_UTC => This.Use_UTC). --utc is ignored once a stamp is present — the help text says so, because I kept tripping over that myself.

That stamp is what ts accepts. It is not what t prints (2026-09-22 18:09:26 TUE).

Help is printed child-first. I write the dm_set_time-main banner, the usage line, and the UTC flag, then I call Super.Write_Help so the device block and -? appear underneath, same as every other tool.

Dialogue (DM_Set_Time.Main) #

After Parse, and unless help was shown, I:

  1. Open Options.Device at the five Console_IO UART constants, blocking, 10 second timeout.
  2. Send a blank line so a console that was already awake still sees a delimiter.
  3. Put_Line (Console_Timeout & " 1") — shortest legal idle, so the calculator leaves SERIAL CONSOLE shortly after the programme exits. Wait for Console timeout set to 1 minutes, then Prompt.
  4. Put_Line (Set_Time & " " & Options.Time)ts plus the compact stamp. Wait for Prompt.
  5. Put_Line (Get_Time)t. Skip the echoed command, then read up to Prompt and print that buffer. The line in the buffer is the hyphenated form with weekday, not YYYYMMDD HHMMSS.
Port.Put_Line (SM_IO.Set_Time & " " & Options.Time);
Port.Expect (SM_IO.Prompt);

Port.Put_Line (SM_IO.Get_Time);
Port.Expect (SM_IO.Get_Time & ASCII.CR & ASCII.LF);   -- command echo
Port.Expect (SM_IO.Prompt, Text, Last);
Ada.Text_IO.Put_Line
   ("Time now shown on calculator: " & Text (Text'First .. Last));

Command-line errors (Option_Parse_Error, Option_Missing_Error, Option_Wrong_Error) print the message and point at --help. Anything else is traced and the process exits with Failure. I deliberately do not dump the call stack on the console. The full exception goes to the log with AdaCL.Trace.Write (AnException). --help shows how to turn that trace file on.

A small AdaCL detail: Write goes to the configured trace destinations (file, Standard_Output or Standard_Error). Write_Error also writes a simplified line to Standard_Error, so a failure is visible even when the file is off.

>bin/release/dm_set_time-main --TRACE=ON --TRACETO=STDOUT
 0   : 0   :! New Thread : main_task_00007FCBF1008C00
 1   : 0   :> Option          => TRACE
 2   : 0   :> Argument        => ON
 3   : 0   :> Option          => TRACETO
 4   : 0   :> Argument        => STDOUT
Error parsing command line options «ADACL.COMMAND_LINE.GETOPT.OPTION_MISSING_ERROR»
 5   : 0   :> Error parsing command line options «ADACL.COMMAND_LINE.GETOPT.OPTION_MISSING_ERROR»
Device not specified. Use '-d', '--device' or set the DM_SERIAL_DEVICE environment variable to specify the device.
 6   : 0   :> Device not specified. Use '-d', '--device' or set the DM_SERIAL_DEVICE environment variable to specify the device.
Use '--help' for help
 7   : 0   :> Use '--help' for help
 8   : 0   :! raised ADACL.COMMAND_LINE.GETOPT.OPTION_MISSING_ERROR : Device not specified. Use '-d', '--device' or set the DM_SERIAL_DEVICE environment variable to specify the device.
 8   : 0   :Load address: 0x1006eb000
 8   : 0   :Call stack traceback locations:
0x1006ee2dd 0x1006f04f1 0x1006ed27b 0x1007b595c 0x7ff8159c71c6

Make / ZShell #

dm_set_time-main -d $$(dm-get-serial-device.sh) "$$(date +'%Y%m%d %H%M%S')"

Two substitutions, not one quoted command. The date recipe is the compact ts layout; I do not use %Y-%m-%d here.