11use alloc:: string:: { String , ToString } ;
2- use anyhow:: { Context , Result , bail } ;
2+ use anyhow:: Result ;
33use core:: ptr:: null_mut;
4- use jaarg:: alloc:: ParseMapResult ;
54use jaarg:: {
65 ErrorUsageWriter , ErrorUsageWriterContext , HelpWriter , HelpWriterContext , Opt , Opts ,
7- StandardErrorUsageWriter , StandardFullHelpWriter ,
6+ ParseControl , ParseResult , StandardErrorUsageWriter , StandardFullHelpWriter ,
87} ;
98use log:: { error, info} ;
109use uefi_raw:: Status ;
@@ -45,32 +44,71 @@ impl SproutOptions {
4544 /// Produces [SproutOptions] from the arguments provided by the UEFI core.
4645 /// Internally we utilize the `jaarg` argument parser which has excellent no_std support.
4746 pub fn parse ( ) -> Result < Self > {
47+ enum ArgID {
48+ Help ,
49+ AutoConfigure ,
50+ Config ,
51+ Boot ,
52+ ForceMenu ,
53+ MenuTimeout ,
54+ }
55+
4856 // All the options for the Sprout executable.
49- const OPTIONS : Opts < & str > = Opts :: new ( & [
50- Opt :: help_flag ( "help" , & [ "--help" ] ) . help_text ( "Display Sprout Help" ) ,
51- Opt :: flag ( "autoconfigure" , & [ "--autoconfigure" ] )
57+ const OPTIONS : Opts < ArgID > = Opts :: new ( & [
58+ Opt :: help_flag ( ArgID :: Help , & [ "--help" ] ) . help_text ( "Display Sprout Help" ) ,
59+ Opt :: flag ( ArgID :: AutoConfigure , & [ "--autoconfigure" ] )
5260 . help_text ( "Enable Sprout autoconfiguration" ) ,
53- Opt :: value ( "config" , & [ "--config" ] , "PATH" )
61+ Opt :: value ( ArgID :: Config , & [ "--config" ] , "PATH" )
5462 . help_text ( "Path to Sprout configuration file" ) ,
55- Opt :: value ( "boot" , & [ "--boot" ] , "ENTRY" ) . help_text ( "Entry to boot, bypassing the menu" ) ,
56- Opt :: flag ( "force-menu" , & [ "--force-menu" ] ) . help_text ( "Force showing the boot menu" ) ,
57- Opt :: value ( "menu-timeout" , & [ "--menu-timeout" ] , "TIMEOUT" )
63+ Opt :: value ( ArgID :: Boot , & [ "--boot" ] , "ENTRY" )
64+ . help_text ( "Entry to boot, bypassing the menu" ) ,
65+ Opt :: flag ( ArgID :: ForceMenu , & [ "--force-menu" ] ) . help_text ( "Force showing the boot menu" ) ,
66+ Opt :: value ( ArgID :: MenuTimeout , & [ "--menu-timeout" ] , "TIMEOUT" )
5867 . help_text ( "Boot menu timeout, in seconds" ) ,
5968 ] ) ;
6069
6170 // Acquire the arguments as determined by the UEFI core.
6271 let args = eficore:: env:: args ( ) ?;
6372
73+ // Use the default value of sprout options and have the raw options be parsed into it.
74+ let mut result = Self :: default ( ) ;
75+
6476 // Parse the OPTIONS into a map using jaarg.
65- let parsed = match OPTIONS . parse_map (
77+ match OPTIONS . parse (
6678 "sprout" ,
6779 args. iter ( ) ,
68- |program_name| {
69- let ctx = HelpWriterContext {
70- options : & OPTIONS ,
71- program_name,
72- } ;
73- info ! ( "{}" , StandardFullHelpWriter :: new( ctx) ) ;
80+ |program_name, id, _opt, _name, value| {
81+ match id {
82+ ArgID :: AutoConfigure => {
83+ // Enable autoconfiguration.
84+ result. autoconfigure = true ;
85+ }
86+ ArgID :: Config => {
87+ // The configuration file to load.
88+ result. config = value. into ( ) ;
89+ }
90+ ArgID :: Boot => {
91+ // The entry to boot.
92+ result. boot = Some ( value. into ( ) ) ;
93+ }
94+ ArgID :: ForceMenu => {
95+ // Force showing of the boot menu.
96+ result. force_menu = true ;
97+ }
98+ ArgID :: MenuTimeout => {
99+ // The timeout for the boot menu in seconds.
100+ result. menu_timeout = Some ( value. parse :: < u64 > ( ) ?) ;
101+ }
102+ ArgID :: Help => {
103+ let ctx = HelpWriterContext {
104+ options : & OPTIONS ,
105+ program_name,
106+ } ;
107+ info ! ( "{}" , StandardFullHelpWriter :: new( ctx) ) ;
108+ return Ok ( ParseControl :: Quit ) ;
109+ }
110+ }
111+ Ok ( ParseControl :: Continue )
74112 } ,
75113 |program_name, error| {
76114 let ctx = ErrorUsageWriterContext {
@@ -81,52 +119,14 @@ impl SproutOptions {
81119 error ! ( "{}" , StandardErrorUsageWriter :: new( ctx) ) ;
82120 } ,
83121 ) {
84- ParseMapResult :: Map ( map ) => map ,
85- ParseMapResult :: ExitSuccess => unsafe {
122+ ParseResult :: ContinueSuccess => Ok ( result ) ,
123+ ParseResult :: ExitSuccess => unsafe {
86124 uefi:: boot:: exit ( uefi:: boot:: image_handle ( ) , Status :: SUCCESS , 0 , null_mut ( ) ) ;
87125 } ,
88126
89- ParseMapResult :: ExitFailure => unsafe {
127+ ParseResult :: ExitError => unsafe {
90128 uefi:: boot:: exit ( uefi:: boot:: image_handle ( ) , Status :: ABORTED , 0 , null_mut ( ) ) ;
91129 } ,
92- } ;
93-
94- // Use the default value of sprout options and have the raw options be parsed into it.
95- let mut result = Self :: default ( ) ;
96-
97- for ( key, value) in parsed {
98- match key {
99- "autoconfigure" => {
100- // Enable autoconfiguration.
101- result. autoconfigure = true ;
102- }
103-
104- "config" => {
105- // The configuration file to load.
106- result. config = value;
107- }
108-
109- "boot" => {
110- // The entry to boot.
111- result. boot = Some ( value) ;
112- }
113-
114- "force-menu" => {
115- // Force showing of the boot menu.
116- result. force_menu = true ;
117- }
118-
119- "menu-timeout" => {
120- // The timeout for the boot menu in seconds.
121- let value = value
122- . parse :: < u64 > ( )
123- . context ( "menu-timeout must be a number" ) ?;
124- result. menu_timeout = Some ( value) ;
125- }
126-
127- _ => bail ! ( "unknown option: --{key}" ) ,
128- }
129130 }
130- Ok ( result)
131131 }
132132}
0 commit comments