|
1 | 1 | //! Module to factor out commandline interaction |
2 | 2 | //! This way we can use it in the regular OS commandline tool on Linux and Windows, |
3 | 3 | //! as well as on the UEFI shell tool. |
| 4 | +use clap::error::ErrorKind; |
4 | 5 | use clap::Parser; |
| 6 | +use clap::{arg, command, Arg, Args, FromArgMatches}; |
5 | 7 | use clap_num::maybe_hex; |
6 | 8 |
|
| 9 | +use crate::chromium_ec::commands::SetGpuSerialMagic; |
7 | 10 | use crate::chromium_ec::CrosEcDriverType; |
8 | 11 | use crate::commandline::{ |
9 | 12 | Cli, ConsoleArg, FpBrightnessArg, HardwareDeviceType, InputDeckModeArg, RebootEcArg, |
@@ -203,31 +206,71 @@ struct ClapCli { |
203 | 206 |
|
204 | 207 | /// Parse a list of commandline arguments and return the struct |
205 | 208 | pub fn parse(args: &[String]) -> Cli { |
206 | | - let args = ClapCli::parse_from(args); |
| 209 | + // Step 1 - Define args that can't be derived |
| 210 | + let cli = command!() |
| 211 | + .arg(Arg::new("fgd").long("flash-gpu-descriptor").num_args(2)) |
| 212 | + .disable_version_flag(true); |
| 213 | + // Step 2 - Define args from derived struct |
| 214 | + let mut cli = ClapCli::augment_args(cli); |
| 215 | + |
| 216 | + // Step 3 - Parse args that can't be derived |
| 217 | + let matches = cli.clone().get_matches_from(args); |
| 218 | + let fgd = matches |
| 219 | + .get_many::<String>("fgd") |
| 220 | + .unwrap_or_default() |
| 221 | + .map(|v| v.as_str()) |
| 222 | + .collect::<Vec<_>>(); |
| 223 | + let flash_gpu_descriptor = if !fgd.is_empty() { |
| 224 | + let hex_magic = if let Some(hex_magic) = fgd[0].strip_prefix("0x") { |
| 225 | + u8::from_str_radix(hex_magic, 16) |
| 226 | + } else { |
| 227 | + // Force parse error |
| 228 | + u8::from_str_radix("", 16) |
| 229 | + }; |
| 230 | + |
| 231 | + let magic = if let Ok(magic) = fgd[0].parse::<u8>() { |
| 232 | + magic |
| 233 | + } else if let Ok(hex_magic) = hex_magic { |
| 234 | + hex_magic |
| 235 | + } else if fgd[0].to_uppercase() == "GPU" { |
| 236 | + SetGpuSerialMagic::WriteGPUConfig as u8 |
| 237 | + } else if fgd[0].to_uppercase() == "SSD" { |
| 238 | + SetGpuSerialMagic::WriteSSDConfig as u8 |
| 239 | + } else { |
| 240 | + cli.error( |
| 241 | + ErrorKind::InvalidValue, |
| 242 | + "First argument of --flash-gpu-descriptor must be an integer or one of: 'GPU', 'SSD'", |
| 243 | + ) |
| 244 | + .exit(); |
| 245 | + }; |
| 246 | + if fgd[1].len() != 18 { |
| 247 | + cli.error( |
| 248 | + ErrorKind::InvalidValue, |
| 249 | + "Second argument of --flash-gpu-descriptor must be an 18 digit serial number", |
| 250 | + ) |
| 251 | + .exit(); |
| 252 | + } |
| 253 | + Some((magic, fgd[1].to_string())) |
| 254 | + } else { |
| 255 | + None |
| 256 | + }; |
| 257 | + |
| 258 | + // Step 4 - Parse from derived struct |
| 259 | + let args = ClapCli::from_arg_matches(&matches) |
| 260 | + .map_err(|err| err.exit()) |
| 261 | + .unwrap(); |
207 | 262 |
|
208 | 263 | let pd_addrs = match args.pd_addrs.len() { |
209 | 264 | 2 => Some((args.pd_addrs[0], args.pd_addrs[1])), |
210 | 265 | 0 => None, |
211 | | - _ => { |
212 | | - // Actually unreachable, checked by clap |
213 | | - println!( |
214 | | - "Must provide exactly to PD Addresses. Provided: {:?}", |
215 | | - args.pd_addrs |
216 | | - ); |
217 | | - std::process::exit(1); |
218 | | - } |
| 266 | + // Checked by clap |
| 267 | + _ => unreachable!(), |
219 | 268 | }; |
220 | 269 | let pd_ports = match args.pd_ports.len() { |
221 | 270 | 2 => Some((args.pd_ports[0], args.pd_ports[1])), |
222 | 271 | 0 => None, |
223 | | - _ => { |
224 | | - // Actually unreachable, checked by clap |
225 | | - println!( |
226 | | - "Must provide exactly to PD Ports. Provided: {:?}", |
227 | | - args.pd_ports |
228 | | - ); |
229 | | - std::process::exit(1); |
230 | | - } |
| 272 | + // Checked by clap |
| 273 | + _ => unreachable!(), |
231 | 274 | }; |
232 | 275 |
|
233 | 276 | Cli { |
@@ -299,6 +342,7 @@ pub fn parse(args: &[String]) -> Cli { |
299 | 342 | // UEFI only - every command needs to implement a parameter to enable the pager |
300 | 343 | paginate: false, |
301 | 344 | info: args.info, |
| 345 | + flash_gpu_descriptor, |
302 | 346 | raw_command: vec![], |
303 | 347 | } |
304 | 348 | } |
0 commit comments