@@ -177,72 +177,77 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
177
177
' mir : ' a ,
178
178
{
179
179
let this = self . eval_context_ref ( ) ;
180
- let os_str = this. read_os_str_from_c_str ( scalar) ?;
180
+ let os_str: & ' a OsStr = this. read_os_str_from_c_str ( scalar) ?;
181
181
182
- #[ cfg( windows) ]
183
- return Ok ( if this. tcx . sess . target . target . target_os == "windows" {
184
- // Windows-on-Windows, all fine.
185
- Cow :: Borrowed ( Path :: new ( os_str) )
186
- } else {
187
- // Unix target, Windows host. Need to convert target '/' to host '\'.
188
- let converted = os_str
189
- . encode_wide ( )
190
- . map ( |wchar| if wchar == '/' as u16 { '\\' as u16 } else { wchar } )
191
- . collect :: < Vec < _ > > ( ) ;
192
- Cow :: Owned ( PathBuf :: from ( OsString :: from_wide ( & converted) ) )
193
- } ) ;
194
- #[ cfg( unix) ]
195
- return Ok ( if this. tcx . sess . target . target . target_os == "windows" {
196
- // Windows target, Unix host. Need to convert target '\' to host '/'.
197
- let converted = os_str
198
- . as_bytes ( )
199
- . iter ( )
200
- . map ( |& wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar } )
201
- . collect :: < Vec < _ > > ( ) ;
202
- Cow :: Owned ( PathBuf :: from ( OsString :: from_vec ( converted) ) )
203
- } else {
204
- // Unix-on-Unix, all is fine.
205
- Cow :: Borrowed ( Path :: new ( os_str) )
206
- } ) ;
182
+ Ok ( match convert_path_separator ( os_str, & this. tcx . sess . target . target . target_os ) {
183
+ Cow :: Borrowed ( x) => Cow :: Borrowed ( Path :: new ( x) ) ,
184
+ Cow :: Owned ( y) => Cow :: Owned ( PathBuf :: from ( y) ) ,
185
+ } )
186
+ }
187
+
188
+ /// Read a null-terminated sequence of `u16`s, and perform path separator conversion if needed.
189
+ fn read_path_from_wide_str ( & self , scalar : Scalar < Tag > ) -> InterpResult < ' tcx , PathBuf > {
190
+ let this = self . eval_context_ref ( ) ;
191
+ let os_str: OsString = this. read_os_str_from_wide_str ( scalar) ?;
192
+
193
+ Ok ( PathBuf :: from ( & convert_path_separator ( & os_str, & this. tcx . sess . target . target . target_os ) ) )
207
194
}
208
195
209
- /// Write a Path to the machine memory, adjusting path separators if needed.
196
+ /// Write a Path to the machine memory (as a null-terminated sequence of bytes),
197
+ /// adjusting path separators if needed.
210
198
fn write_path_to_c_str (
211
199
& mut self ,
212
200
path : & Path ,
213
201
scalar : Scalar < Tag > ,
214
202
size : u64 ,
215
203
) -> InterpResult < ' tcx , ( bool , u64 ) > {
216
204
let this = self . eval_context_mut ( ) ;
217
-
218
- #[ cfg( windows) ]
219
- let os_str = if this. tcx . sess . target . target . target_os == "windows" {
220
- // Windows-on-Windows, all fine.
221
- Cow :: Borrowed ( path. as_os_str ( ) )
222
- } else {
223
- // Unix target, Windows host. Need to convert host '\\' to target '/'.
224
- let converted = path
225
- . as_os_str ( )
226
- . encode_wide ( )
227
- . map ( |wchar| if wchar == '\\' as u16 { '/' as u16 } else { wchar } )
228
- . collect :: < Vec < _ > > ( ) ;
229
- Cow :: Owned ( OsString :: from_wide ( & converted) )
230
- } ;
231
- #[ cfg( unix) ]
232
- let os_str = if this. tcx . sess . target . target . target_os == "windows" {
233
- // Windows target, Unix host. Need to convert host '/' to target '\'.
234
- let converted = path
235
- . as_os_str ( )
236
- . as_bytes ( )
237
- . iter ( )
238
- . map ( |& wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar } )
239
- . collect :: < Vec < _ > > ( ) ;
240
- Cow :: Owned ( OsString :: from_vec ( converted) )
241
- } else {
242
- // Unix-on-Unix, all is fine.
243
- Cow :: Borrowed ( path. as_os_str ( ) )
244
- } ;
245
-
205
+ let os_str = convert_path_separator ( path. as_os_str ( ) , & this. tcx . sess . target . target . target_os ) ;
246
206
this. write_os_str_to_c_str ( & os_str, scalar, size)
247
207
}
208
+
209
+ /// Write a Path to the machine memory (as a null-terminated sequence of `u16`s),
210
+ /// adjusting path separators if needed.
211
+ fn write_path_to_wide_str (
212
+ & mut self ,
213
+ path : & Path ,
214
+ scalar : Scalar < Tag > ,
215
+ size : u64 ,
216
+ ) -> InterpResult < ' tcx , ( bool , u64 ) > {
217
+ let this = self . eval_context_mut ( ) ;
218
+ let os_str = convert_path_separator ( path. as_os_str ( ) , & this. tcx . sess . target . target . target_os ) ;
219
+ this. write_os_str_to_wide_str ( & os_str, scalar, size)
220
+ }
221
+ }
222
+
223
+ /// Perform path separator conversion if needed.
224
+ fn convert_path_separator < ' a > (
225
+ os_str : & ' a OsStr ,
226
+ target_os : & str ,
227
+ ) -> Cow < ' a , OsStr > {
228
+ #[ cfg( windows) ]
229
+ return if target_os == "windows" {
230
+ // Windows-on-Windows, all fine.
231
+ Cow :: Borrowed ( os_str)
232
+ } else {
233
+ // Unix target, Windows host. Need to convert host '\\' to target '/'.
234
+ let converted = os_str
235
+ . encode_wide ( )
236
+ . map ( |wchar| if wchar == '\\' as u16 { '/' as u16 } else { wchar } )
237
+ . collect :: < Vec < _ > > ( ) ;
238
+ Cow :: Owned ( OsString :: from_wide ( & converted) )
239
+ } ;
240
+ #[ cfg( unix) ]
241
+ return if target_os == "windows" {
242
+ // Windows target, Unix host. Need to convert host '/' to target '\'.
243
+ let converted = os_str
244
+ . as_bytes ( )
245
+ . iter ( )
246
+ . map ( |& wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar } )
247
+ . collect :: < Vec < _ > > ( ) ;
248
+ Cow :: Owned ( OsString :: from_vec ( converted) )
249
+ } else {
250
+ // Unix-on-Unix, all is fine.
251
+ Cow :: Borrowed ( os_str)
252
+ } ;
248
253
}
0 commit comments