@@ -13,12 +13,13 @@ use crossbeam_channel::{select, Receiver, Sender};
1313use eframe:: egui:: { vec2, ViewportBuilder } ;
1414use eframe:: { egui, icon_data} ;
1515use egui_plot:: PlotPoint ;
16+ pub use gumdrop:: Options ;
1617use preferences:: AppInfo ;
1718use std:: cmp:: max;
1819use std:: path:: PathBuf ;
1920use std:: sync:: { Arc , RwLock } ;
21+ use std:: thread;
2022use std:: time:: Duration ;
21- use std:: { env, thread} ;
2223
2324mod color_picker;
2425mod custom_highlighter;
@@ -262,13 +263,100 @@ fn main_thread(
262263 }
263264}
264265
266+ fn parse_databits ( s : & str ) -> Result < serialport:: DataBits , String > {
267+ let d: u8 = s
268+ . parse ( )
269+ . map_err ( |_e| format ! ( "databits not a number: {s}" ) ) ?;
270+ Ok ( serialport:: DataBits :: try_from ( d) . map_err ( |_e| format ! ( "invalid databits: {s}" ) ) ?)
271+ }
272+
273+ fn parse_flow ( s : & str ) -> Result < serialport:: FlowControl , String > {
274+ match s {
275+ "none" => Ok ( serialport:: FlowControl :: None ) ,
276+ "soft" => Ok ( serialport:: FlowControl :: Software ) ,
277+ "hard" => Ok ( serialport:: FlowControl :: Hardware ) ,
278+ _ => Err ( format ! ( "invalid flow-control: {s}" ) ) ,
279+ }
280+ }
281+
282+ fn parse_stopbits ( s : & str ) -> Result < serialport:: StopBits , String > {
283+ let d: u8 = s
284+ . parse ( )
285+ . map_err ( |_e| format ! ( "stopbits not a number: {s}" ) ) ?;
286+ Ok ( serialport:: StopBits :: try_from ( d) . map_err ( |_e| format ! ( "invalid stopbits: {s}" ) ) ?)
287+ }
288+
289+ fn parse_parity ( s : & str ) -> Result < serialport:: Parity , String > {
290+ match s {
291+ "none" => Ok ( serialport:: Parity :: None ) ,
292+ "odd" => Ok ( serialport:: Parity :: Odd ) ,
293+ "even" => Ok ( serialport:: Parity :: Even ) ,
294+ _ => Err ( format ! ( "invalid parity setting: {s}" ) ) ,
295+ }
296+ }
297+
298+ #[ derive( Debug , Options ) ]
299+ struct CliOptions {
300+ /// Serial port device to open on startup
301+ #[ options( free) ]
302+ device : Option < String > ,
303+
304+ /// Baudrate (default=9600)
305+ #[ options( short = "b" ) ]
306+ baudrate : Option < u32 > ,
307+
308+ /// Data bits (5, 6, 7, default=8)
309+ #[ options( short = "d" , parse( try_from_str = "parse_databits" ) ) ]
310+ databits : Option < serialport:: DataBits > ,
311+
312+ /// Flow conrol (hard, soft, default=none)
313+ #[ options( short = "f" , parse( try_from_str = "parse_flow" ) ) ]
314+ flow : Option < serialport:: FlowControl > ,
315+
316+ /// Stop bits (default=1, 2)
317+ #[ options( short = "s" , parse( try_from_str = "parse_stopbits" ) ) ]
318+ stopbits : Option < serialport:: StopBits > ,
319+
320+ /// Parity (odd, even, default=none)
321+ #[ options( short = "p" , parse( try_from_str = "parse_parity" ) ) ]
322+ parity : Option < serialport:: Parity > ,
323+
324+ /// Load data from a file instead of a serial port
325+ #[ options( short = "F" ) ]
326+ file : Option < std:: path:: PathBuf > ,
327+
328+ help : bool ,
329+ }
330+
265331fn main ( ) {
266332 egui_logger:: builder ( ) . init ( ) . unwrap ( ) ;
267333
334+ let args = CliOptions :: parse_args_default_or_exit ( ) ;
335+
268336 let gui_settings = load_gui_settings ( ) ;
269337 let saved_serial_device_configs = load_serial_settings ( ) ;
270338
271- let device_lock = Arc :: new ( RwLock :: new ( Device :: default ( ) ) ) ;
339+ let mut device = Device :: default ( ) ;
340+ if let Some ( name) = args. device {
341+ device. name = name;
342+ }
343+ if let Some ( baudrate) = args. baudrate {
344+ device. baud_rate = baudrate;
345+ }
346+ if let Some ( databits) = args. databits {
347+ device. data_bits = databits;
348+ }
349+ if let Some ( flow) = args. flow {
350+ device. flow_control = flow;
351+ }
352+ if let Some ( stopbits) = args. stopbits {
353+ device. stop_bits = stopbits;
354+ }
355+ if let Some ( parity) = args. parity {
356+ device. parity = parity;
357+ }
358+
359+ let device_lock = Arc :: new ( RwLock :: new ( device) ) ;
272360 let devices_lock = Arc :: new ( RwLock :: new ( vec ! [ gui_settings. device. clone( ) ] ) ) ;
273361 let data_lock = Arc :: new ( RwLock :: new ( GuiOutputDataContainer :: default ( ) ) ) ;
274362 let connected_lock = Arc :: new ( RwLock :: new ( false ) ) ;
@@ -319,11 +407,8 @@ fn main() {
319407 ) ;
320408 } ) ;
321409
322- let args: Vec < String > = env:: args ( ) . collect ( ) ;
323- if args. len ( ) > 1 {
324- load_tx
325- . send ( PathBuf :: from ( & args[ 1 ] ) )
326- . expect ( "failed to send file" ) ;
410+ if let Some ( file) = args. file {
411+ load_tx. send ( file) . expect ( "failed to send file" ) ;
327412 }
328413
329414 let options = eframe:: NativeOptions {
0 commit comments