The dm_set_time packages
Table of Contents
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:
- Open
Options.Deviceat the fiveConsole_IOUART constants, blocking, 10 second timeout. - Send a blank line so a console that was already awake still sees a delimiter.
Put_Line (Console_Timeout & " 1")— shortest legal idle, so the calculator leaves SERIAL CONSOLE shortly after the programme exits. Wait forConsole timeout set to 1 minutes, thenPrompt.Put_Line (Set_Time & " " & Options.Time)—tsplus the compact stamp. Wait forPrompt.Put_Line (Get_Time)—t. Skip the echoed command, then read up toPromptand print that buffer. The line in the buffer is the hyphenated form with weekday, notYYYYMMDD 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.