@@ -104,7 +104,10 @@ fn parse_args() -> Vec<(PathBuf, Option<PathBuf>)> {
104104 let mut args_it = std:: env:: args ( ) . skip ( 1 ) ;
105105 assert ! (
106106 1 <= args_it. len( ) && args_it. len( ) <= 2 ,
107- "Usage: cargo run -p stdarch-gen2 -- INPUT_DIR [OUTPUT_DIR]"
107+ "Usage: cargo run -p stdarch-gen-arm -- INPUT_DIR [OUTPUT_DIR]\n \
108+ where:\n \
109+ - INPUT_DIR contains a tree like: INPUT_DIR/<feature>/<arch>.spec.yml\n \
110+ - OUTPUT_DIR is a directory like: crates/core_arch/src/"
108111 ) ;
109112
110113 let in_path = Path :: new ( args_it. next ( ) . unwrap ( ) . as_str ( ) ) . to_path_buf ( ) ;
@@ -124,7 +127,7 @@ fn parse_args() -> Vec<(PathBuf, Option<PathBuf>)> {
124127 std:: env:: current_exe ( )
125128 . map ( |mut f| {
126129 f. pop ( ) ;
127- f. push ( "../../crates/core_arch/src/aarch64/ " ) ;
130+ f. push ( "../../crates/core_arch/src/" ) ;
128131 f. exists ( ) . then_some ( f)
129132 } )
130133 . ok ( )
@@ -147,10 +150,10 @@ fn generate_file(
147150 out,
148151 r#"// This code is automatically generated. DO NOT MODIFY.
149152//
150- // Instead, modify `crates/stdarch-gen2 /spec/` and run the following command to re-generate this file:
153+ // Instead, modify `crates/stdarch-gen-arm /spec/` and run the following command to re-generate this file:
151154//
152155// ```
153- // cargo run --bin=stdarch-gen2 -- crates/stdarch-gen2 /spec
156+ // cargo run --bin=stdarch-gen-arm -- crates/stdarch-gen-arm /spec
154157// ```
155158#![allow(improper_ctypes)]
156159
@@ -183,17 +186,19 @@ pub fn format_code(
183186 output. write_all ( proc. wait_with_output ( ) ?. stdout . as_slice ( ) )
184187}
185188
186- /// Derive an output file name from an input file and an output directory.
189+ /// Derive an output file path from an input file path and an output directory.
187190///
188- /// The name is formed by:
191+ /// `in_filepath` is expected to have a structure like:
192+ /// .../<feature>/<arch>.spec.yml
189193///
190- /// - ... taking in_filepath.file_name() (dropping all directory components),
191- /// - ... dropping a .yml or .yaml extension (if present),
192- /// - ... then dropping a .spec extension (if present).
194+ /// The resulting output path will have a structure like:
195+ /// <out_dirpath>/<arch>/<feature>/generated.rs
193196///
194197/// Panics if the resulting name is empty, or if file_name() is not UTF-8.
195198fn make_output_filepath ( in_filepath : & Path , out_dirpath : & Path ) -> PathBuf {
196- make_filepath ( in_filepath, out_dirpath, |name : & str | format ! ( "{name}.rs" ) )
199+ make_filepath ( in_filepath, out_dirpath, |_name : & str | {
200+ format ! ( "generated.rs" )
201+ } )
197202}
198203
199204fn make_tests_filepath ( in_filepath : & Path , out_dirpath : & Path ) -> PathBuf {
@@ -207,22 +212,27 @@ fn make_filepath<F: FnOnce(&str) -> String>(
207212 out_dirpath : & Path ,
208213 name_formatter : F ,
209214) -> PathBuf {
210- let mut parts = in_filepath. iter ( ) ;
211- let name = parts
212- . next_back ( )
213- . and_then ( |f| f. to_str ( ) )
214- . expect ( "Inputs must have valid, UTF-8 file_name()" ) ;
215- let dir = parts. next_back ( ) . unwrap ( ) ;
215+ let mut parts = in_filepath. components ( ) . rev ( ) . map ( |f| {
216+ f. as_os_str ( )
217+ . to_str ( )
218+ . expect ( "Inputs must have valid, UTF-8 file_name()" )
219+ } ) ;
220+ let yml = parts. next ( ) . expect ( "Not enough input path elements." ) ;
221+ let feature = parts. next ( ) . expect ( "Not enough input path elements." ) ;
216222
217- let name = name
218- . trim_end_matches ( ".yml" )
219- . trim_end_matches ( ".yaml" )
220- . trim_end_matches ( ".spec" ) ;
221- assert ! ( !name. is_empty( ) ) ;
223+ let arch = yml
224+ . strip_suffix ( ".yml" )
225+ . expect ( "Expected .yml file input." )
226+ . strip_suffix ( ".spec" )
227+ . expect ( "Expected .spec.yml file input." ) ;
228+ if arch. is_empty ( ) {
229+ panic ! ( "Extended ARCH.spec.yml file input." ) ;
230+ }
222231
223232 let mut output = out_dirpath. to_path_buf ( ) ;
224- output. push ( dir) ;
225- output. push ( name_formatter ( name) ) ;
233+ output. push ( arch) ;
234+ output. push ( feature) ;
235+ output. push ( name_formatter ( arch) ) ;
226236 output
227237}
228238
@@ -233,47 +243,68 @@ mod tests {
233243 #[ test]
234244 fn infer_output_file ( ) {
235245 macro_rules! t {
236- ( $src: expr, $outdir: expr, $dst: expr) => {
246+ ( $src: expr, $outdir: expr, $dst: expr, $ldst : expr ) => {
237247 let src: PathBuf = $src. iter( ) . collect( ) ;
238248 let outdir: PathBuf = $outdir. iter( ) . collect( ) ;
239249 let dst: PathBuf = $dst. iter( ) . collect( ) ;
250+ let ldst: PathBuf = $ldst. iter( ) . collect( ) ;
240251 assert_eq!( make_output_filepath( & src, & outdir) , dst) ;
252+ assert_eq!( make_tests_filepath( & src, & outdir) , ldst) ;
241253 } ;
242254 }
243255 // Documented usage.
244- t ! ( [ "x" , "NAME.spec.yml" ] , [ "" ] , [ "x" , "NAME.rs" ] ) ;
245256 t ! (
246- [ "x" , "NAME.spec.yml" ] ,
247- [ "a" , "b" ] ,
248- [ "a" , "b" , "x" , "NAME.rs" ]
257+ [ "FEAT" , "ARCH.spec.yml" ] ,
258+ [ "" ] ,
259+ [ "ARCH" , "FEAT" , "generated.rs" ] ,
260+ [ "ARCH" , "FEAT" , "ld_st_tests_ARCH.rs" ]
249261 ) ;
250262 t ! (
251- [ "x" , "y" , "NAME .spec.yml" ] ,
263+ [ "x" , "y" , "FEAT" , "ARCH .spec.yml"] ,
252264 [ "out" ] ,
253- [ "out" , "y" , "NAME.rs" ]
265+ [ "out" , "ARCH" , "FEAT" , "generated.rs" ] ,
266+ [ "out" , "ARCH" , "FEAT" , "ld_st_tests_ARCH.rs" ]
254267 ) ;
255- t ! ( [ "x" , "NAME.spec.yaml" ] , [ "out" ] , [ "out" , "x" , "NAME.rs" ] ) ;
256- t ! ( [ "x" , "NAME.spec" ] , [ "out" ] , [ "out" , "x" , "NAME.rs" ] ) ;
257- t ! ( [ "x" , "NAME.yml" ] , [ "out" ] , [ "out" , "x" , "NAME.rs" ] ) ;
258- t ! ( [ "x" , "NAME.yaml" ] , [ "out" ] , [ "out" , "x" , "NAME.rs" ] ) ;
259- // Unrecognised extensions get treated as part of the stem.
260268 t ! (
261- [ "x" , "NAME.spac.yml" ] ,
262- [ "out" ] ,
263- [ "out" , "x" , "NAME.spac.rs" ]
269+ [ "p" , "q" , "FEAT" , "ARCH.spec.yml" ] ,
270+ [ "a" , "b" ] ,
271+ [ "a" , "b" , "ARCH" , "FEAT" , "generated.rs" ] ,
272+ [ "a" , "b" , "ARCH" , "FEAT" , "ld_st_tests_ARCH.rs" ]
264273 ) ;
265- t ! ( [ "x" , "NAME.txt" ] , [ "out" ] , [ "out" , "x" , "NAME.txt.rs" ] ) ;
266- // Always take the top-level directory from the input path
274+ // Extra extensions get treated as part of the stem.
267275 t ! (
268- [ "x " , "y" , "z" , "NAME .spec.yml"] ,
276+ [ "FEAT " , "ARCH.variant .spec.yml" ] ,
269277 [ "out" ] ,
270- [ "out" , "z" , "NAME.rs" ]
278+ [ "out" , "ARCH.variant" , "FEAT" , "generated.rs" ] ,
279+ [ "out" , "ARCH.variant" , "FEAT" , "ld_st_tests_ARCH.variant.rs" ]
271280 ) ;
272281 }
273282
274283 #[ test]
275284 #[ should_panic]
276285 fn infer_output_file_no_stem ( ) {
277- make_output_filepath ( Path :: new ( ".spec.yml" ) , Path :: new ( "" ) ) ;
286+ let src = PathBuf :: from ( "FEAT/.spec.yml" ) ;
287+ make_output_filepath ( & src, Path :: new ( "" ) ) ;
288+ }
289+
290+ #[ test]
291+ #[ should_panic]
292+ fn infer_output_file_no_feat ( ) {
293+ let src = PathBuf :: from ( "ARCH.spec.yml" ) ;
294+ make_output_filepath ( & src, Path :: new ( "" ) ) ;
295+ }
296+
297+ #[ test]
298+ #[ should_panic]
299+ fn infer_output_file_ldst_no_stem ( ) {
300+ let src = PathBuf :: from ( "FEAT/.spec.yml" ) ;
301+ make_tests_filepath ( & src, Path :: new ( "" ) ) ;
302+ }
303+
304+ #[ test]
305+ #[ should_panic]
306+ fn infer_output_file_ldst_no_feat ( ) {
307+ let src = PathBuf :: from ( "ARCH.spec.yml" ) ;
308+ make_tests_filepath ( & src, Path :: new ( "" ) ) ;
278309 }
279310}
0 commit comments