|
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, |
@@ -208,31 +211,71 @@ struct ClapCli { |
208 | 211 |
|
209 | 212 | /// Parse a list of commandline arguments and return the struct |
210 | 213 | pub fn parse(args: &[String]) -> Cli { |
211 | | - let args = ClapCli::parse_from(args); |
| 214 | + // Step 1 - Define args that can't be derived |
| 215 | + let cli = command!() |
| 216 | + .arg(Arg::new("fgd").long("flash-gpu-descriptor").num_args(2)) |
| 217 | + .disable_version_flag(true); |
| 218 | + // Step 2 - Define args from derived struct |
| 219 | + let mut cli = ClapCli::augment_args(cli); |
| 220 | + |
| 221 | + // Step 3 - Parse args that can't be derived |
| 222 | + let matches = cli.clone().get_matches_from(args); |
| 223 | + let fgd = matches |
| 224 | + .get_many::<String>("fgd") |
| 225 | + .unwrap_or_default() |
| 226 | + .map(|v| v.as_str()) |
| 227 | + .collect::<Vec<_>>(); |
| 228 | + let flash_gpu_descriptor = if !fgd.is_empty() { |
| 229 | + let hex_magic = if let Some(hex_magic) = fgd[0].strip_prefix("0x") { |
| 230 | + u8::from_str_radix(hex_magic, 16) |
| 231 | + } else { |
| 232 | + // Force parse error |
| 233 | + u8::from_str_radix("", 16) |
| 234 | + }; |
| 235 | + |
| 236 | + let magic = if let Ok(magic) = fgd[0].parse::<u8>() { |
| 237 | + magic |
| 238 | + } else if let Ok(hex_magic) = hex_magic { |
| 239 | + hex_magic |
| 240 | + } else if fgd[0].to_uppercase() == "GPU" { |
| 241 | + SetGpuSerialMagic::WriteGPUConfig as u8 |
| 242 | + } else if fgd[0].to_uppercase() == "SSD" { |
| 243 | + SetGpuSerialMagic::WriteSSDConfig as u8 |
| 244 | + } else { |
| 245 | + cli.error( |
| 246 | + ErrorKind::InvalidValue, |
| 247 | + "First argument of --flash-gpu-descriptor must be an integer or one of: 'GPU', 'SSD'", |
| 248 | + ) |
| 249 | + .exit(); |
| 250 | + }; |
| 251 | + if fgd[1].len() != 18 { |
| 252 | + cli.error( |
| 253 | + ErrorKind::InvalidValue, |
| 254 | + "Second argument of --flash-gpu-descriptor must be an 18 digit serial number", |
| 255 | + ) |
| 256 | + .exit(); |
| 257 | + } |
| 258 | + Some((magic, fgd[1].to_string())) |
| 259 | + } else { |
| 260 | + None |
| 261 | + }; |
| 262 | + |
| 263 | + // Step 4 - Parse from derived struct |
| 264 | + let args = ClapCli::from_arg_matches(&matches) |
| 265 | + .map_err(|err| err.exit()) |
| 266 | + .unwrap(); |
212 | 267 |
|
213 | 268 | let pd_addrs = match args.pd_addrs.len() { |
214 | 269 | 2 => Some((args.pd_addrs[0], args.pd_addrs[1])), |
215 | 270 | 0 => None, |
216 | | - _ => { |
217 | | - // Actually unreachable, checked by clap |
218 | | - println!( |
219 | | - "Must provide exactly to PD Addresses. Provided: {:?}", |
220 | | - args.pd_addrs |
221 | | - ); |
222 | | - std::process::exit(1); |
223 | | - } |
| 271 | + // Checked by clap |
| 272 | + _ => unreachable!(), |
224 | 273 | }; |
225 | 274 | let pd_ports = match args.pd_ports.len() { |
226 | 275 | 2 => Some((args.pd_ports[0], args.pd_ports[1])), |
227 | 276 | 0 => None, |
228 | | - _ => { |
229 | | - // Actually unreachable, checked by clap |
230 | | - println!( |
231 | | - "Must provide exactly to PD Ports. Provided: {:?}", |
232 | | - args.pd_ports |
233 | | - ); |
234 | | - std::process::exit(1); |
235 | | - } |
| 277 | + // Checked by clap |
| 278 | + _ => unreachable!(), |
236 | 279 | }; |
237 | 280 |
|
238 | 281 | Cli { |
@@ -305,6 +348,7 @@ pub fn parse(args: &[String]) -> Cli { |
305 | 348 | // UEFI only - every command needs to implement a parameter to enable the pager |
306 | 349 | paginate: false, |
307 | 350 | info: args.info, |
| 351 | + flash_gpu_descriptor, |
308 | 352 | raw_command: vec![], |
309 | 353 | } |
310 | 354 | } |
0 commit comments