@@ -113,91 +113,83 @@ fn get_string(it: &mut Cursor<'_>, expected_name: &str) -> String {
113
113
byte_string
114
114
}
115
115
116
- fn __build_modinfo_string_base (
117
- module : & str ,
118
- field : & str ,
119
- content : & str ,
120
- variable : & str ,
121
- builtin : bool ,
122
- ) -> String {
123
- let string = if builtin {
124
- // Built-in modules prefix their modinfo strings by `module.`.
125
- format ! (
126
- "{module}.{field}={content}\0 " ,
127
- module = module,
128
- field = field,
129
- content = content
130
- )
131
- } else {
132
- // Loadable modules' modinfo strings go as-is.
133
- format ! ( "{field}={content}\0 " , field = field, content = content)
134
- } ;
116
+ struct ModInfoBuilder < ' a > {
117
+ module : & ' a str ,
118
+ counter : usize ,
119
+ buffer : String ,
120
+ }
135
121
136
- format ! (
137
- "
138
- {cfg}
139
- #[link_section = \" .modinfo\" ]
140
- #[used]
141
- pub static {variable}: [u8; {length}] = *{string};
142
- " ,
143
- cfg = if builtin {
144
- "#[cfg(not(MODULE))]"
122
+ impl < ' a > ModInfoBuilder < ' a > {
123
+ fn new ( module : & ' a str ) -> Self {
124
+ ModInfoBuilder {
125
+ module,
126
+ counter : 0 ,
127
+ buffer : String :: new ( ) ,
128
+ }
129
+ }
130
+
131
+ fn emit_base ( & mut self , field : & str , content : & str , builtin : bool ) {
132
+ use std:: fmt:: Write ;
133
+
134
+ let string = if builtin {
135
+ // Built-in modules prefix their modinfo strings by `module.`.
136
+ format ! (
137
+ "{module}.{field}={content}\0 " ,
138
+ module = self . module,
139
+ field = field,
140
+ content = content
141
+ )
145
142
} else {
146
- "#[cfg(MODULE)]"
147
- } ,
148
- variable = variable,
149
- length = string. len( ) ,
150
- string = Literal :: byte_string( string. as_bytes( ) ) ,
151
- )
152
- }
143
+ // Loadable modules' modinfo strings go as-is.
144
+ format ! ( "{field}={content}\0 " , field = field, content = content)
145
+ } ;
153
146
154
- fn __build_modinfo_string_variable ( module : & str , field : & str ) -> String {
155
- format ! ( "__{module}_{field}" , module = module, field = field)
156
- }
147
+ write ! (
148
+ & mut self . buffer,
149
+ "
150
+ {cfg}
151
+ #[link_section = \" .modinfo\" ]
152
+ #[used]
153
+ pub static __{module}_{counter}: [u8; {length}] = *{string};
154
+ " ,
155
+ cfg = if builtin {
156
+ "#[cfg(not(MODULE))]"
157
+ } else {
158
+ "#[cfg(MODULE)]"
159
+ } ,
160
+ module = self . module,
161
+ counter = self . counter,
162
+ length = string. len( ) ,
163
+ string = Literal :: byte_string( string. as_bytes( ) ) ,
164
+ )
165
+ . unwrap ( ) ;
157
166
158
- fn build_modinfo_string_only_builtin ( module : & str , field : & str , content : & str ) -> String {
159
- __build_modinfo_string_base (
160
- module,
161
- field,
162
- content,
163
- & __build_modinfo_string_variable ( module, field) ,
164
- true ,
165
- )
166
- }
167
+ self . counter += 1 ;
168
+ }
167
169
168
- fn build_modinfo_string_only_loadable ( module : & str , field : & str , content : & str ) -> String {
169
- __build_modinfo_string_base (
170
- module,
171
- field,
172
- content,
173
- & __build_modinfo_string_variable ( module, field) ,
174
- false ,
175
- )
176
- }
170
+ fn emit_only_builtin ( & mut self , field : & str , content : & str ) {
171
+ self . emit_base ( field, content, true )
172
+ }
177
173
178
- fn build_modinfo_string ( module : & str , field : & str , content : & str ) -> String {
179
- build_modinfo_string_only_builtin ( module, field, content)
180
- + & build_modinfo_string_only_loadable ( module, field, content)
181
- }
174
+ fn emit_only_loadable ( & mut self , field : & str , content : & str ) {
175
+ self . emit_base ( field, content, false )
176
+ }
182
177
183
- fn build_modinfo_string_optional ( module : & str , field : & str , content : Option < & str > ) -> String {
184
- if let Some ( content) = content {
185
- build_modinfo_string ( module, field, content)
186
- } else {
187
- "" . to_string ( )
178
+ fn emit ( & mut self , field : & str , content : & str ) {
179
+ self . emit_only_builtin ( field, content) ;
180
+ self . emit_only_loadable ( field, content) ;
188
181
}
189
- }
190
182
191
- fn build_modinfo_string_param ( module : & str , field : & str , param : & str , content : & str ) -> String {
192
- let variable = format ! (
193
- "__{module}_{ field}_{param}" ,
194
- module = module ,
195
- field = field ,
196
- param = param
197
- ) ;
198
- let content = format ! ( "{param}:{content}" , param = param, content = content) ;
199
- __build_modinfo_string_base ( module , field, & content, & variable , true )
200
- + & __build_modinfo_string_base ( module , field , & content , & variable , false )
183
+ fn emit_optional ( & mut self , field : & str , content : Option < & str > ) {
184
+ if let Some ( content ) = content {
185
+ self . emit ( field, content ) ;
186
+ }
187
+ }
188
+
189
+ fn emit_param ( & mut self , field : & str , param : & str , content : & str ) {
190
+ let content = format ! ( "{param}:{content}" , param = param, content = content) ;
191
+ self . emit ( field, & content) ;
192
+ }
201
193
}
202
194
203
195
fn permissions_are_readonly ( perms : & str ) -> bool {
@@ -395,8 +387,18 @@ pub fn module(ts: TokenStream) -> TokenStream {
395
387
396
388
let name = info. name . clone ( ) ;
397
389
390
+ let mut modinfo = ModInfoBuilder :: new ( & name) ;
391
+ modinfo. emit_optional ( "author" , info. author . as_deref ( ) ) ;
392
+ modinfo. emit_optional ( "description" , info. description . as_deref ( ) ) ;
393
+ modinfo. emit ( "license" , & info. license ) ;
394
+ modinfo. emit_optional ( "alias" , info. alias . as_deref ( ) ) ;
395
+
396
+ // Built-in modules also export the `file` modinfo string
397
+ let file =
398
+ std:: env:: var ( "RUST_MODFILE" ) . expect ( "Unable to fetch RUST_MODFILE environmental variable" ) ;
399
+ modinfo. emit_only_builtin ( "file" , & file) ;
400
+
398
401
let mut array_types_to_generate = Vec :: new ( ) ;
399
- let mut params_modinfo = String :: new ( ) ;
400
402
if let Some ( params) = info. params {
401
403
let mut it = params;
402
404
@@ -436,18 +438,8 @@ pub fn module(ts: TokenStream) -> TokenStream {
436
438
}
437
439
} ;
438
440
439
- params_modinfo. push_str ( & build_modinfo_string_param (
440
- & name,
441
- "parmtype" ,
442
- & param_name,
443
- & param_kernel_type,
444
- ) ) ;
445
- params_modinfo. push_str ( & build_modinfo_string_param (
446
- & name,
447
- "parm" ,
448
- & param_name,
449
- & param_description,
450
- ) ) ;
441
+ modinfo. emit_param ( "parmtype" , & param_name, & param_kernel_type) ;
442
+ modinfo. emit_param ( "parm" , & param_name, & param_description) ;
451
443
let param_type_internal = match param_type {
452
444
ParamType :: Ident ( ref param_type) => match param_type. as_ref ( ) {
453
445
"str" => "kernel::module_param::StringParam" . to_string ( ) ,
@@ -496,7 +488,7 @@ pub fn module(ts: TokenStream) -> TokenStream {
496
488
name = name,
497
489
param_name = param_name,
498
490
) ;
499
- params_modinfo . push_str (
491
+ modinfo . buffer . push_str (
500
492
& format ! (
501
493
"
502
494
static mut __{name}_{param_name}_value: {param_type_internal} = {param_default};
@@ -572,9 +564,6 @@ pub fn module(ts: TokenStream) -> TokenStream {
572
564
) ) ;
573
565
}
574
566
575
- let file =
576
- std:: env:: var ( "RUST_MODFILE" ) . expect ( "Unable to fetch RUST_MODFILE environmental variable" ) ;
577
-
578
567
format ! (
579
568
"
580
569
/// The module name.
@@ -654,26 +643,13 @@ pub fn module(ts: TokenStream) -> TokenStream {
654
643
}}
655
644
}}
656
645
657
- {author}
658
- {description}
659
- {license}
660
- {alias}
661
-
662
- // Built-in modules also export the `file` modinfo string
663
- {file}
664
-
665
- {params_modinfo}
646
+ {modinfo}
666
647
667
648
{generated_array_types}
668
649
" ,
669
650
type_ = info. type_,
670
651
name = info. name,
671
- author = & build_modinfo_string_optional( & name, "author" , info. author. as_deref( ) ) ,
672
- description = & build_modinfo_string_optional( & name, "description" , info. description. as_deref( ) ) ,
673
- license = & build_modinfo_string( & name, "license" , & info. license) ,
674
- alias = & build_modinfo_string_optional( & name, "alias" , info. alias. as_deref( ) ) ,
675
- file = & build_modinfo_string_only_builtin( & name, "file" , & file) ,
676
- params_modinfo = params_modinfo,
652
+ modinfo = modinfo. buffer,
677
653
generated_array_types = generated_array_types,
678
654
initcall_section = ".initcall6.init"
679
655
) . parse ( ) . expect ( "Error parsing formatted string into token stream." )
0 commit comments