Add path helpers, normalise rom path from CLI, update readme

see #2077
This commit is contained in:
YoshiRulz 2021-05-05 06:08:47 +10:00
parent 3fee117c5f
commit 7a7522f282
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
4 changed files with 42 additions and 6 deletions

View File

@ -196,6 +196,7 @@ On Windows 8.1/10, it's easiest to use PowerShell for this. For example, to pass
```pwsh
(New-Object System.Diagnostics.Process -Property @{StartInfo=(New-Object System.Diagnostics.ProcessStartInfo -Property @{FileName="$PWD\EmuHawk.exe";Arguments='"--lua=C:\path\to\script.lua" "C:\path\to\rom.n64"'})}).Start()
```
Note: PowerShell's `cd` doesn't seem to change the CWD of child processes. Just open a shell from the install folder. Don't @ me.
For char escaping tips you're on your own. It might help to split up the command so you can identify syntax errors:
```pwsh
@ -205,8 +206,12 @@ $proc = New-Object System.Diagnostics.Process -Property @{StartInfo=$startInfo}
$proc.Start()
```
On Linux, you can pass arguments to `EmuHawkMono.sh` as expected and they will be forwarded to `mono`. (You can also `export` env. vars.) There is one exception: if you pass `--mono-no-redirect` as the *first argument* it will be eaten by the script itself, and stdout will *not* be redirected to a file.
The same example as above would be `./EmuHawkMono.sh --lua=/path/to/script.lua /path/to/rom.n64`.
On Linux, you can pass arguments to `EmuHawkMono.sh` as expected and they will be forwarded to `mono`. (You can also `export` env. vars.) All the arguments work as on Windows, with some caveats:
* Lua scripts are ignored;
* file paths must be absolute (or relative to the install dir, `EmuHawkMono.sh` changes the CWD to there);
* `--mono-no-redirect`: if you pass this flag *as the first argument*, it will be eaten by the script itself, and stdout will *not* be redirected to a file. (It's redirected by default.)
The same example as above would be `./EmuHawkMono.sh --lua=/path/to/script.lua /path/to/rom.n64` (but Lua is no-op).
For char escaping tips, see ~~Unix StackExchange~~ your shell's man/info page. BASH and Zsh have different rules!

View File

@ -497,8 +497,8 @@ namespace BizHawk.Client.EmuHawk
if (_argParser.cmdRom != null)
{
// Commandline should always override auto-load
var ioa = OpenAdvancedSerializer.ParseWithLegacy(_argParser.cmdRom);
LoadRom(_argParser.cmdRom, new LoadRomArgs { OpenAdvanced = ioa });
var romPath = _argParser.cmdRom.MakeAbsolute();
LoadRom(romPath, new LoadRomArgs { OpenAdvanced = OpenAdvancedSerializer.ParseWithLegacy(romPath) });
if (Game == null)
{
ShowMessageBox(owner: null, $"Failed to load {_argParser.cmdRom} specified on commandline");

View File

@ -48,6 +48,26 @@ namespace BizHawk.Common.PathExtensions
return false;
}
/// <returns><see langword="true"/> iff absolute (OS-dependent)</returns>
/// <seealso cref="IsRelative"/>
public static bool IsAbsolute(this string path)
{
if (OSTailoredCode.IsUnixHost) return path.Length >= 1 && path[0] == '/';
if (path.Contains('/')) return IsAbsolute(path.Replace('/', '\\'));
return path.Length >= 3
&& path[2] switch
{
'\\' => path[1] == '\\' && ('A'.RangeTo('Z').Contains(path[0]) || 'a'.RangeTo('z').Contains(path[0])),
'?' => path.StartsWith(@"\\?\"),
_ => false
};
}
/// <returns><see langword="false"/> iff absolute (OS-dependent)</returns>
/// <remarks>that means it may return <see langword="true"/> for invalid paths</remarks>
/// <seealso cref="IsAbsolute"/>
public static bool IsRelative(this string path) => !path.IsAbsolute();
/// <exception cref="ArgumentException">running on Windows host, and unmanaged call failed</exception>
/// <exception cref="FileNotFoundException">running on Windows host, and either path is not a regular file or directory</exception>
/// <remarks>
@ -87,6 +107,15 @@ namespace BizHawk.Common.PathExtensions
: throw new ArgumentException("Paths must have a common prefix");
}
/// <returns>absolute path (OS-dependent) equivalent to <paramref name="path"/></returns>
/// <remarks>
/// unless <paramref name="cwd"/> is given, uses <see cref="CWDHacks.Get">CWDHacks.Get</see>/<see cref="Environment.CurrentDirectory">Environment.CurrentDirectory</see>,
/// so take care when calling this after startup
/// </remarks>
public static string MakeAbsolute(this string path, string? cwd = null) => path.IsAbsolute()
? path
: new FileInfo($"{cwd ?? (OSTailoredCode.IsUnixHost ? Environment.CurrentDirectory : CWDHacks.Get())}/{path}").FullName; // FileInfo for normalisation ("C:\a\b\..\c" => "C:\a\c")
/// <returns>the absolute path equivalent to <paramref name="path"/> which contains <c>%exe%</c> (expanded) as a prefix</returns>
/// <remarks>
/// returned string omits trailing slash<br/>

View File

@ -5,6 +5,8 @@ using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Common
{
/// <summary>Implementors are able to provide pointers to functions in dynamically-linked libraries, which are loaded through some undefined mechanism.</summary>
@ -32,7 +34,7 @@ namespace BizHawk.Common
};
}
private static string UnixResolveFilePath(string orig) => orig[0] == '/'
private static string UnixResolveFilePath(string orig) => orig.IsAbsolute()
? orig
: UnixSearchPaths.Select(dir => dir + orig)
.FirstOrDefault(s =>
@ -40,7 +42,7 @@ namespace BizHawk.Common
var fi = new FileInfo(s);
return fi.Exists && (fi.Attributes & FileAttributes.Directory) != FileAttributes.Directory;
})
?? orig;
?? orig; // don't MakeAbsolute, just pass through and hope something lower-level magically makes it work
private IntPtr _p;