@@ -56,7 +56,7 @@ fn expect_byte_string(it: &mut token_stream::IntoIter) -> String {
56
56
try_byte_string ( it) . expect ( "Expected byte string" )
57
57
}
58
58
59
- #[ derive( Clone , PartialEq ) ]
59
+ #[ derive( Debug , Clone , PartialEq ) ]
60
60
enum ParamType {
61
61
Ident ( String ) ,
62
62
Array { vals : String , max_length : usize } ,
@@ -285,6 +285,44 @@ fn generated_array_ops_name(vals: &str, max_length: usize) -> String {
285
285
)
286
286
}
287
287
288
+ #[ derive( Debug ) ]
289
+ struct ParamInfo {
290
+ name : String ,
291
+ type_ : ParamType ,
292
+ default : String ,
293
+ permission : String ,
294
+ description : String ,
295
+ }
296
+
297
+ impl ParamInfo {
298
+ fn try_parse ( it : & mut token_stream:: IntoIter ) -> Option < Self > {
299
+ let param_name = match it. next ( ) {
300
+ Some ( TokenTree :: Ident ( ident) ) => ident. to_string ( ) ,
301
+ Some ( _) => panic ! ( "Expected Ident or end" ) ,
302
+ None => return None ,
303
+ } ;
304
+
305
+ assert_eq ! ( expect_punct( it) , ':' ) ;
306
+ let param_type = expect_type ( it) ;
307
+ let group = expect_group ( it) ;
308
+ assert_eq ! ( group. delimiter( ) , Delimiter :: Brace ) ;
309
+
310
+ let mut param_it = group. stream ( ) . into_iter ( ) ;
311
+ let param_default = get_default ( & param_type, & mut param_it) ;
312
+ let param_permissions = get_literal ( & mut param_it, "permissions" ) ;
313
+ let param_description = get_byte_string ( & mut param_it, "description" ) ;
314
+ expect_end ( & mut param_it) ;
315
+
316
+ Some ( ParamInfo {
317
+ name : param_name,
318
+ type_ : param_type,
319
+ default : param_default,
320
+ permission : param_permissions,
321
+ description : param_description,
322
+ } )
323
+ }
324
+ }
325
+
288
326
#[ derive( Debug , Default ) ]
289
327
struct ModuleInfo {
290
328
type_ : String ,
@@ -293,7 +331,7 @@ struct ModuleInfo {
293
331
author : Option < String > ,
294
332
description : Option < String > ,
295
333
alias : Option < String > ,
296
- params : Option < Group > ,
334
+ params : Vec < ParamInfo > ,
297
335
}
298
336
299
337
impl ModuleInfo {
@@ -339,7 +377,17 @@ impl ModuleInfo {
339
377
"alias_rtnl_link" => {
340
378
info. alias = Some ( format ! ( "rtnl-link-{}" , expect_byte_string( it) ) )
341
379
}
342
- "params" => info. params = Some ( expect_group ( it) ) ,
380
+ "params" => {
381
+ let group = expect_group ( it) ;
382
+ assert_eq ! ( group. delimiter( ) , Delimiter :: Brace ) ;
383
+ let mut inner_it = group. stream ( ) . into_iter ( ) ;
384
+ let mut params = Vec :: new ( ) ;
385
+ while let Some ( param) = ParamInfo :: try_parse ( & mut inner_it) {
386
+ assert_eq ! ( expect_punct( & mut inner_it) , ',' ) ;
387
+ params. push ( param) ;
388
+ }
389
+ info. params = params;
390
+ }
343
391
_ => panic ! (
344
392
"Unknown key \" {}\" . Valid keys are: {:?}." ,
345
393
key, EXPECTED_KEYS
@@ -375,73 +423,46 @@ impl ModuleInfo {
375
423
376
424
info
377
425
}
378
- }
379
-
380
- pub fn module ( ts : TokenStream ) -> TokenStream {
381
- let mut it = ts. into_iter ( ) ;
382
-
383
- let info = ModuleInfo :: parse ( & mut it) ;
384
-
385
- let name = info. name . clone ( ) ;
386
-
387
- let mut modinfo = ModInfoBuilder :: new ( & name) ;
388
- if let Some ( author) = info. author {
389
- modinfo. emit ( "author" , & author) ;
390
- }
391
- if let Some ( description) = info. description {
392
- modinfo. emit ( "description" , & description) ;
393
- }
394
- modinfo. emit ( "license" , & info. license ) ;
395
- if let Some ( alias) = info. alias {
396
- modinfo. emit ( "alias" , & alias) ;
397
- }
398
-
399
- // Built-in modules also export the `file` modinfo string
400
- let file =
401
- std:: env:: var ( "RUST_MODFILE" ) . expect ( "Unable to fetch RUST_MODFILE environmental variable" ) ;
402
- modinfo. emit_only_builtin ( "file" , & file) ;
403
-
404
- let mut array_types_to_generate = Vec :: new ( ) ;
405
- if let Some ( params) = info. params {
406
- assert_eq ! ( params. delimiter( ) , Delimiter :: Brace ) ;
407
426
408
- let mut it = params . stream ( ) . into_iter ( ) ;
409
-
410
- loop {
411
- let param_name = match it . next ( ) {
412
- Some ( TokenTree :: Ident ( ident ) ) => ident . to_string ( ) ,
413
- Some ( _ ) => panic ! ( "Expected Ident or end" ) ,
414
- None => break ,
415
- } ;
416
-
417
- assert_eq ! ( expect_punct ( & mut it ) , ':' ) ;
418
- let param_type = expect_type ( & mut it ) ;
419
- let group = expect_group ( & mut it ) ;
420
- assert_eq ! ( expect_punct ( & mut it ) , ',' ) ;
427
+ fn generate ( & self ) -> TokenStream {
428
+ let name = & self . name ;
429
+ let mut modinfo = ModInfoBuilder :: new ( name ) ;
430
+ if let Some ( author ) = & self . author {
431
+ modinfo . emit ( "author" , author ) ;
432
+ }
433
+ if let Some ( description ) = & self . description {
434
+ modinfo . emit ( "description" , description ) ;
435
+ }
436
+ modinfo . emit ( "license" , & self . license ) ;
437
+ if let Some ( alias ) = & self . alias {
438
+ modinfo . emit ( "alias" , alias ) ;
439
+ }
421
440
422
- assert_eq ! ( group. delimiter( ) , Delimiter :: Brace ) ;
441
+ // Built-in modules also export the `file` modinfo string
442
+ let file = std:: env:: var ( "RUST_MODFILE" )
443
+ . expect ( "Unable to fetch RUST_MODFILE environmental variable" ) ;
444
+ modinfo. emit_only_builtin ( "file" , & file) ;
423
445
424
- let mut param_it = group. stream ( ) . into_iter ( ) ;
425
- let param_default = get_default ( & param_type, & mut param_it) ;
426
- let param_permissions = get_literal ( & mut param_it, "permissions" ) ;
427
- let param_description = get_byte_string ( & mut param_it, "description" ) ;
428
- expect_end ( & mut param_it) ;
446
+ let mut array_types_to_generate = Vec :: new ( ) ;
447
+ for param in self . params . iter ( ) {
448
+ let param_name = & param. name ;
449
+ let param_type = & param. type_ ;
450
+ let param_default = & param. default ;
451
+ let param_permissions = & param. permission ;
452
+ let param_description = & param. description ;
429
453
430
454
// TODO: more primitive types
431
455
// TODO: other kinds: unsafes, etc.
432
456
let ( param_kernel_type, ops) : ( String , _ ) = match param_type {
433
- ParamType :: Ident ( ref param_type) => (
457
+ ParamType :: Ident ( param_type) => (
434
458
param_type. to_string ( ) ,
435
459
param_ops_path ( param_type) . to_string ( ) ,
436
460
) ,
437
- ParamType :: Array {
438
- ref vals,
439
- max_length,
440
- } => {
441
- array_types_to_generate. push ( ( vals. clone ( ) , max_length) ) ;
461
+ ParamType :: Array { vals, max_length } => {
462
+ array_types_to_generate. push ( ( vals. clone ( ) , * max_length) ) ;
442
463
(
443
464
format ! ( "__rust_array_param_{}_{}" , vals, max_length) ,
444
- generated_array_ops_name ( vals, max_length) ,
465
+ generated_array_ops_name ( vals, * max_length) ,
445
466
)
446
467
}
447
468
} ;
@@ -465,10 +486,10 @@ pub fn module(ts: TokenStream) -> TokenStream {
465
486
let read_func = if permissions_are_readonly ( & param_permissions) {
466
487
format ! (
467
488
"
468
- fn read(&self) -> &<{param_type_internal} as kernel::module_param::ModuleParam>::Value {{
469
- // SAFETY: Parameters do not need to be locked because they are read only or sysfs is not enabled.
470
- unsafe {{ <{param_type_internal} as kernel::module_param::ModuleParam>::value(&__{name}_{param_name}_value) }}
471
- }}
489
+ fn read(&self) -> &<{param_type_internal} as kernel::module_param::ModuleParam>::Value {{
490
+ // SAFETY: Parameters do not need to be locked because they are read only or sysfs is not enabled.
491
+ unsafe {{ <{param_type_internal} as kernel::module_param::ModuleParam>::value(&__{name}_{param_name}_value) }}
492
+ }}
472
493
" ,
473
494
name = name,
474
495
param_name = param_name,
@@ -477,10 +498,10 @@ pub fn module(ts: TokenStream) -> TokenStream {
477
498
} else {
478
499
format ! (
479
500
"
480
- fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck <{param_type_internal} as kernel::module_param::ModuleParam>::Value {{
481
- // SAFETY: Parameters are locked by `KParamGuard`.
482
- unsafe {{ <{param_type_internal} as kernel::module_param::ModuleParam>::value(&__{name}_{param_name}_value) }}
483
- }}
501
+ fn read<'lck>(&self, lock: &'lck kernel::KParamGuard) -> &'lck <{param_type_internal} as kernel::module_param::ModuleParam>::Value {{
502
+ // SAFETY: Parameters are locked by `KParamGuard`.
503
+ unsafe {{ <{param_type_internal} as kernel::module_param::ModuleParam>::value(&__{name}_{param_name}_value) }}
504
+ }}
484
505
" ,
485
506
name = name,
486
507
param_name = param_name,
@@ -553,27 +574,26 @@ pub fn module(ts: TokenStream) -> TokenStream {
553
574
)
554
575
) ;
555
576
}
556
- }
557
577
558
- let mut generated_array_types = String :: new ( ) ;
578
+ let mut generated_array_types = String :: new ( ) ;
559
579
560
- for ( vals, max_length) in array_types_to_generate {
561
- let ops_name = generated_array_ops_name ( & vals, max_length) ;
562
- generated_array_types. push_str ( & format ! (
563
- "
580
+ for ( vals, max_length) in array_types_to_generate {
581
+ let ops_name = generated_array_ops_name ( & vals, max_length) ;
582
+ generated_array_types. push_str ( & format ! (
583
+ "
564
584
kernel::make_param_ops!(
565
585
{ops_name},
566
586
kernel::module_param::ArrayParam<{vals}, {{ {max_length} }}>
567
587
);
568
- " ,
569
- ops_name = ops_name,
570
- vals = vals,
571
- max_length = max_length,
572
- ) ) ;
573
- }
588
+ " ,
589
+ ops_name = ops_name,
590
+ vals = vals,
591
+ max_length = max_length,
592
+ ) ) ;
593
+ }
574
594
575
- format ! (
576
- "
595
+ format ! (
596
+ "
577
597
/// The module name.
578
598
///
579
599
/// Used by the printing macros, e.g. [`info!`].
@@ -659,69 +679,58 @@ pub fn module(ts: TokenStream) -> TokenStream {
659
679
{modinfo}
660
680
661
681
{generated_array_types}
662
- " ,
663
- type_ = info. type_,
664
- name = info. name,
665
- modinfo = modinfo. buffer,
666
- generated_array_types = generated_array_types,
667
- initcall_section = ".initcall6.init"
668
- ) . parse ( ) . expect ( "Error parsing formatted string into token stream." )
682
+ " ,
683
+ type_ = self . type_,
684
+ name = self . name,
685
+ modinfo = modinfo. buffer,
686
+ generated_array_types = generated_array_types,
687
+ initcall_section = ".initcall6.init"
688
+ ) . parse ( ) . expect ( "Error parsing formatted string into token stream." )
689
+ }
669
690
}
670
691
671
- pub fn module_misc_device ( ts : TokenStream ) -> TokenStream {
692
+ pub fn module ( ts : TokenStream ) -> TokenStream {
672
693
let mut it = ts. into_iter ( ) ;
673
-
674
694
let info = ModuleInfo :: parse ( & mut it) ;
695
+ info. generate ( )
696
+ }
675
697
676
- let module = format ! ( "__internal_ModuleFor{}" , info. type_) ;
698
+ pub fn module_misc_device ( ts : TokenStream ) -> TokenStream {
699
+ let mut it = ts. into_iter ( ) ;
677
700
678
- format ! (
679
- "
680
- #[doc(hidden)]
681
- struct {module} {{
682
- _dev: core::pin::Pin<alloc::boxed::Box<kernel::miscdev::Registration>>,
683
- }}
701
+ let mut info = ModuleInfo :: parse ( & mut it) ;
702
+ let type_ = info. type_ ;
684
703
685
- impl kernel::KernelModule for {module} {{
686
- fn init() -> kernel::Result<Self> {{
687
- Ok(Self {{
688
- _dev: kernel::miscdev::Registration::new_pinned::<{type_}>(
689
- kernel::c_str!(\" {name}\" ),
690
- None,
691
- (),
692
- )?,
693
- }})
694
- }}
695
- }}
704
+ let module = format ! ( "__internal_ModuleFor{}" , type_) ;
705
+ info. type_ = module. clone ( ) ;
696
706
697
- kernel::prelude::module! {{
698
- type: {module},
699
- name: b\" {name}\" ,
700
- {author}
701
- {description}
702
- license: b\" {license}\" ,
703
- {alias}
707
+ let extra = format ! (
708
+ "
709
+ #[doc(hidden)]
710
+ struct {module} {{
711
+ _dev: core::pin::Pin<alloc::boxed::Box<kernel::miscdev::Registration>>,
712
+ }}
713
+
714
+ impl kernel::KernelModule for {module} {{
715
+ fn init() -> kernel::Result<Self> {{
716
+ Ok(Self {{
717
+ _dev: kernel::miscdev::Registration::new_pinned::<{type_}>(
718
+ kernel::c_str!(\" {name}\" ),
719
+ None,
720
+ (),
721
+ )?,
722
+ }})
704
723
}}
724
+ }}
705
725
" ,
706
726
module = module,
707
727
type_ = info. type_,
708
728
name = info. name,
709
- author = info
710
- . author
711
- . map( |v| format!( "author: b\" {}\" ," , v) )
712
- . unwrap_or_else( || "" . to_string( ) ) ,
713
- description = info
714
- . description
715
- . map( |v| format!( "description: b\" {}\" ," , v) )
716
- . unwrap_or_else( || "" . to_string( ) ) ,
717
- alias = info
718
- . alias
719
- . map( |v| format!( "alias: b\" {}\" ," , v) )
720
- . unwrap_or_else( || "" . to_string( ) ) ,
721
- license = info. license
722
729
)
723
730
. parse ( )
724
- . expect ( "Error parsing formatted string into token stream." )
731
+ . expect ( "Error parsing formatted string into token stream." ) ;
732
+
733
+ vec ! [ extra, info. generate( ) ] . into_iter ( ) . collect ( )
725
734
}
726
735
727
736
#[ cfg( test) ]
0 commit comments