@@ -21,8 +21,8 @@ pub struct SimArgs {
2121 #[ arg( long, value_hint = clap:: ValueHint :: FilePath ) ]
2222 pub setup : Option < PathBuf > ,
2323
24- /// Write .cir to a specific file (ngspice still runs on it ). Only valid when simulating a single file.
25- #[ arg( short, long, value_hint = clap:: ValueHint :: FilePath ) ]
24+ /// Write .cir to a file and exit (ngspice is not run ). Only valid when simulating a single file.
25+ #[ arg( short, long, value_hint = clap:: ValueHint :: FilePath , conflicts_with = "netlist" ) ]
2626 pub output : Option < PathBuf > ,
2727
2828 /// Disable network access (offline mode) - only use vendored dependencies
@@ -94,28 +94,28 @@ fn simulate_one(
9494 writeln ! ( buf, "{setup}" ) ?;
9595 }
9696
97- // --netlist or `-o -`: print to stdout and return
98- let print_to_stdout = args. netlist || args. output . as_deref ( ) == Some ( std:: path:: Path :: new ( "-" ) ) ;
99- if print_to_stdout {
97+ // --netlist: print to stdout and return (skip ngspice)
98+ if args. netlist {
10099 std:: io:: stdout ( ) . write_all ( & buf) ?;
101100 return Ok ( true ) ;
102101 }
103102
103+ // --output: write .cir to file and return (skip ngspice)
104+ if let Some ( output_path) = & args. output {
105+ File :: create ( output_path) ?. write_all ( & buf) ?;
106+ return Ok ( true ) ;
107+ }
108+
104109 // Write .cir next to the zen file so ngspice resolves relative paths correctly
105110 let zen_dir = zen_path. parent ( ) . unwrap_or ( std:: path:: Path :: new ( "." ) ) ;
106- let cir_path: Box < dyn AsRef < std:: path:: Path > > = if let Some ( output_path) = & args. output {
107- File :: create ( output_path) ?. write_all ( & buf) ?;
108- Box :: new ( output_path. clone ( ) )
109- } else {
110- let mut tmp = tempfile:: Builder :: new ( )
111- . suffix ( ".cir" )
112- . tempfile_in ( zen_dir) ?;
113- tmp. write_all ( & buf) ?;
114- tmp. flush ( ) ?;
115- Box :: new ( tmp. into_temp_path ( ) )
116- } ;
111+ let mut tmp = tempfile:: Builder :: new ( )
112+ . suffix ( ".cir" )
113+ . tempfile_in ( zen_dir) ?;
114+ tmp. write_all ( & buf) ?;
115+ tmp. flush ( ) ?;
116+ let cir_path = tmp. into_temp_path ( ) ;
117117
118- let result = run_ngspice_captured ( ( * cir_path) . as_ref ( ) , zen_dir) ?;
118+ let result = run_ngspice_captured ( cir_path. as_ref ( ) , zen_dir) ?;
119119
120120 if result. success {
121121 if args. verbose {
@@ -150,8 +150,10 @@ pub fn execute(args: SimArgs) -> Result<()> {
150150 }
151151
152152 // Directory / workspace mode — behave like `pcb build`
153- if args. setup . is_some ( ) || args. output . is_some ( ) {
154- anyhow:: bail!( "--setup and --output are only supported when simulating a single file" ) ;
153+ if args. setup . is_some ( ) || args. output . is_some ( ) || args. netlist {
154+ anyhow:: bail!(
155+ "--setup, --output, and --netlist are only supported when simulating a single file"
156+ ) ;
155157 }
156158
157159 let resolution_result =
0 commit comments