[Scummvm-git-logs] scummvm master -> 96bc15af33008f869d70bcb7b1b22312b81193c2

sev- noreply at scummvm.org
Mon May 23 22:38:05 UTC 2022


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
cb8718dcdc BASE: Fix md5 commandline command on Windows
f2849282a6 Common: Add functions to decompose a Path into its components
96bc15af33 BASE: Add md5mac command to compute MD5 hash from data and rsc fork


Commit: cb8718dcdc1d2e3d280226f55d6c9e88289479a8
    https://github.com/scummvm/scummvm/commit/cb8718dcdc1d2e3d280226f55d6c9e88289479a8
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-05-24T00:38:02+02:00

Commit Message:
BASE: Fix md5 commandline command on Windows

Changed paths:
    base/commandLine.cpp


diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 747e2f21cc0..06e25edb7f1 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -1695,7 +1695,13 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
 		return true;
 	} else if (command == "md5") {
 		Common::String filename = settings.getValOrDefault("md5-path", "scummvm");
-		Common::Path Filename(filename, '/');
+		// Assume '/' separator except on Windows if the path contain at least one `\`
+		char sep = '/';
+#if WIN32
+		if (filename.contains('\\'))
+			sep = '\\';
+#endif
+		Common::Path Filename(filename, sep);
 		Common::FSNode path(Filename);
 		int32 md5Length = 0;
 


Commit: f2849282a67895313d15cfe95f77138e053aa094
    https://github.com/scummvm/scummvm/commit/f2849282a67895313d15cfe95f77138e053aa094
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-05-24T00:38:02+02:00

Commit Message:
Common: Add functions to decompose a Path into its components

Changed paths:
    common/path.cpp
    common/path.h


diff --git a/common/path.cpp b/common/path.cpp
index b2a5f3c6f86..e152fa3f80b 100644
--- a/common/path.cpp
+++ b/common/path.cpp
@@ -32,7 +32,10 @@ Path::Path(const char *str, char separator) {
 }
 
 Path::Path(const String &str, char separator) {
-	set(str.c_str(), separator);
+	if (separator == DIR_SEPARATOR)
+		_str = str;
+	else
+		set(str.c_str(), separator);
 }
 
 String Path::toString(char separator) const {
@@ -46,6 +49,24 @@ String Path::toString(char separator) const {
 	return res;
 }
 
+Path Path::getParent() const {
+	if (_str.size() < 2)
+		return Path();
+	size_t separatorPos = _str.findLastOf(DIR_SEPARATOR, _str.size() - 2);
+	if (separatorPos == Common::String::npos)
+		return Path();
+	return Path(_str.substr(0, separatorPos + 1), DIR_SEPARATOR);
+}
+
+Path Path::getLastComponent() const {
+	if (_str.size() < 2)
+		return *this;
+	size_t separatorPos = _str.findLastOf(DIR_SEPARATOR, _str.size() - 2);
+	if (separatorPos == Common::String::npos)
+		return *this;
+	return Path(_str.substr(separatorPos + 1), DIR_SEPARATOR);
+}
+
 bool Path::operator==(const Path &x) const {
 	return _str == x.rawString();
 }
@@ -84,7 +105,10 @@ Path &Path::appendInPlace(const Path &x) {
 }
 
 Path &Path::appendInPlace(const String &str, char separator) {
-	appendInPlace(str.c_str(), separator);
+	if (separator == DIR_SEPARATOR)
+		_str += str;
+	else
+		appendInPlace(str.c_str(), separator);
 	return *this;
 }
 
diff --git a/common/path.h b/common/path.h
index 10e1d0d27b8..cc5b214d394 100644
--- a/common/path.h
+++ b/common/path.h
@@ -91,6 +91,22 @@ public:
 	 */
 	String toString(char separator = '/') const;
 
+	/**
+	 * Returns the Path for the parent directory of this path.
+	 *
+	 * Appending the getLastComponent() of a path to getParent() returns a path
+	 * identical to the original path.
+	 */
+	Path getParent() const;
+
+	/**
+	 * Returns the last component of this path.
+	 *
+	 * Appending the getLastComponent() of a path to getParent() returns a path
+	 * identical to the original path.
+	 */
+	Path getLastComponent() const;
+
 	/** Check whether this path is identical to path @p x. */
 	bool operator==(const Path &x) const;
 


Commit: 96bc15af33008f869d70bcb7b1b22312b81193c2
    https://github.com/scummvm/scummvm/commit/96bc15af33008f869d70bcb7b1b22312b81193c2
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-05-24T00:38:02+02:00

Commit Message:
BASE: Add md5mac command to compute MD5 hash from data and rsc fork

Changed paths:
    base/commandLine.cpp
    doc/docportal/advanced_topics/command_line.rst


diff --git a/base/commandLine.cpp b/base/commandLine.cpp
index 06e25edb7f1..fb5398480e7 100644
--- a/base/commandLine.cpp
+++ b/base/commandLine.cpp
@@ -34,6 +34,7 @@
 
 #include "common/config-manager.h"
 #include "common/fs.h"
+#include "common/macresman.h"
 #include "common/md5.h"
 #include "common/rendermode.h"
 #include "common/savefile.h"
@@ -211,12 +212,17 @@ static const char HELP_STRING[] =
 	"                           Grim Fandango or Escape from Monkey Island\n"
 	"  --md5                    Shows MD5 hash of the file given by --md5-path=PATH\n"
 	"                           If --md5-length=NUM is passed then it shows the MD5 hash of\n"
-	"                           the first NUM bytes of the file given by PATH\n"
+	"                           the first or last NUM bytes of the file given by PATH\n"
 	"                           If --md5-engine=ENGINE_ID is passed, it fetches the MD5 length\n"
 	"                           automatically, overriding --md5-length\n"
-	"  --md5-path=PATH          Used with --md5 to specify path of file to calculate MD5 hash of\n"
-	"  --md5-length=NUM         Used with --md5 to specify the number of bytes to be hashed.\n"
-	"                           Use negative number for calculating tail md5.\n"
+	"  --md5mac                 Shows MD5 hash for both the resource fork and data fork of the\n"
+	"                           mac file given by --md5-path=PATH. If --md5-length=NUM is passed\n"
+	"                           then it shows the MD5 hash of the first or last NUM bytes of each\n"
+	"                           fork.\n"
+	"  --md5-path=PATH          Used with --md5 or --md5mac to specify path of file to calculate\n"
+	"                           MD5 hash of\n"
+	"  --md5-length=NUM         Used with --md5 or --md5mac to specify the number of bytes to be\n"
+	"                           hashed. Use negative number for calculating tail md5.\n"
 	"                           Is overriden when used with --md5-engine\n"
 	"  --md5-engine=ENGINE_ID   Used with --md5 to specify the engine for which number of bytes\n"
 	"                           to be hashed must be calculated. This option overrides --md5-length\n"
@@ -598,6 +604,9 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
 			DO_LONG_COMMAND("md5")
 			END_COMMAND
 
+			DO_LONG_COMMAND("md5mac")
+			END_COMMAND
+
 #ifdef DETECTOR_TESTING_HACK
 			// HACK FIXME TODO: This command is intentionally *not* documented!
 			DO_LONG_COMMAND("test-detector")
@@ -827,14 +836,8 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
 			END_OPTION
 
 			DO_LONG_OPTION("md5-path")
-				Common::FSNode path(option);
-				if (!path.exists()) {
-					usage("Non-existent file path '%s'", option);
-				} else if (path.isDirectory()) {
-					usage("'%s' is a directory, not a file path!", option);
-				} else if (!path.isReadable()) {
-					usage("Non-readable file path '%s'", option);
-				}
+				// While the --md5 command expect a file name, the --md5mac may take a base name.
+				// Thus we do not check that the file exists here.
 			END_OPTION
 
 			DO_LONG_OPTION("md5-engine")
@@ -1374,6 +1377,12 @@ static int recAddGames(const Common::FSNode &dir, const Common::String &engineId
 }
 
 static void calcMD5(Common::FSNode &path, int32 length) {
+	if (!path.exists()) {
+		usage("File '%s' does not exist", path.getName().c_str());
+		return;
+	} else if (!path.isReadable()) {
+		usage("Non-readable file path '%s'", path.getName().c_str());
+	}
 	Common::SeekableReadStream *stream = path.createReadStream();
 
 	if (stream) {
@@ -1397,6 +1406,55 @@ static void calcMD5(Common::FSNode &path, int32 length) {
 	}
 }
 
+static void calcMD5Mac(Common::Path &filePath, int32 length) {
+	// We need to split the path into the file name and a SearchSet
+	Common::SearchSet dir;
+	char nativeSeparator = '/';
+#if WIN32
+	nativeSeparator = '\\';
+#endif
+	Common::FSNode dirNode(filePath.getParent().toString(nativeSeparator));
+	dir.addDirectory(dirNode.getPath(), dirNode);
+	Common::String fileName = filePath.getLastComponent().toString();
+
+	Common::MacResManager macResMan;
+	// FIXME: There currently isn't any way to tell the Mac resource
+	// manager to open a specific file. Instead, it takes a "base name"
+	// and constructs a file name out of that. While usually a desirable
+	// thing, it's not ideal here.
+	if (!macResMan.open(fileName, dir)) {
+		printf("Mac resource file '%s' not found or could not be open\n", filePath.toString(nativeSeparator).c_str());
+	} else {
+		if (!macResMan.hasResFork() && !macResMan.hasDataFork()) {
+			printf("'%s' has neither data not resource fork\n", macResMan.getBaseFileName().toString().c_str());
+		} else {
+			bool tail = false;
+			if (length < 0) {// Tail md5 is requested
+				length = -length;
+				tail = true;
+			}
+
+			// The resource fork is probably the most relevant one.
+			if (macResMan.hasResFork()) {
+				Common::String md5 = macResMan.computeResForkMD5AsString(length, tail);
+				if (length != 0 && length < (int32)macResMan.getResForkDataSize())
+					md5 += Common::String::format(" (%s %d bytes)", tail ? "last" : "first", length);
+				printf("%s (resource): %s, %llu bytes\n", macResMan.getBaseFileName().toString().c_str(), md5.c_str(), (unsigned long long)macResMan.getResForkDataSize());
+			}
+			if (macResMan.hasDataFork()) {
+				Common::SeekableReadStream *stream = macResMan.getDataFork();
+				if (tail && stream->size() > length)
+					stream->seek(-length, SEEK_END);
+				Common::String md5 = Common::computeStreamMD5AsString(*stream, length);
+				if (length != 0 && length < stream->size())
+					md5 += Common::String::format(" (%s %d bytes)", tail ? "last" : "first", length);
+				printf("%s (data): %s, %llu bytes\n", macResMan.getBaseFileName().toString().c_str(), md5.c_str(), (unsigned long long)stream->size());
+			}
+		}
+		macResMan.close();
+	}
+}
+
 static bool addGames(const Common::String &path, const Common::String &engineId, const Common::String &gameId, bool recursive) {
 	//Current directory
 	Common::FSNode dir(path);
@@ -1693,7 +1751,7 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
 	} else if (command == "add") {
 		addGames(settings["path"], gameOption.engineId, gameOption.gameId, settings["recursive"] == "true");
 		return true;
-	} else if (command == "md5") {
+	} else if (command == "md5" || command == "md5mac") {
 		Common::String filename = settings.getValOrDefault("md5-path", "scummvm");
 		// Assume '/' separator except on Windows if the path contain at least one `\`
 		char sep = '/';
@@ -1702,13 +1760,12 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
 			sep = '\\';
 #endif
 		Common::Path Filename(filename, sep);
-		Common::FSNode path(Filename);
 		int32 md5Length = 0;
 
 		if (settings.contains("md5-length"))
 			md5Length = strtol(settings["md5-length"].c_str(), nullptr, 10);
 
-		if (settings.contains("md5-engine")) {
+		if (command == "md5" && settings.contains("md5-engine")) {
 			Common::String engineID = settings["md5-engine"];
 			if (engineID == "scumm") {
 				// Hardcoding value as scumm doesn't use AdvancedMetaEngineDetection
@@ -1729,7 +1786,11 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
 			}
 		}
 
-		calcMD5(path, md5Length);
+		if (command == "md5") {
+			Common::FSNode path(Filename);
+			calcMD5(path, md5Length);
+		} else
+			calcMD5Mac(Filename, md5Length);
 
 		return true;
 #ifdef DETECTOR_TESTING_HACK
diff --git a/doc/docportal/advanced_topics/command_line.rst b/doc/docportal/advanced_topics/command_line.rst
index 293b3509d30..646ebf9e7ce 100755
--- a/doc/docportal/advanced_topics/command_line.rst
+++ b/doc/docportal/advanced_topics/command_line.rst
@@ -166,7 +166,8 @@ Short options are listed where they are available.
         ``--tempo=NUM``,,"Sets music tempo (in percent, 50-200) for SCUMM games (default: 100)"
         ``--themepath=PATH``,,":ref:`Specifies path to where GUI themes are stored <themepath>`"
         ``--version``,``-v``,"Displays ScummVM version information and exits"
-        ``--md5``,,"Shows MD5 hash of the file given by ``--md5-path=PATH``. If ``--md5-length=NUM`` is passed then it shows the MD5 hash of the first ``NUM`` bytes of the file given by ``PATH``. If ``--md5-engine=ENGINE_ID`` option is passed then it auto-calculates the required bytes and its hash, overriding ``--md5-length``"
-        ``--md5-path=PATH``,,"Used with ``--md5`` to specify path of file to calculate MD5 hash of (default: ./scummvm)"
-        ``--md5-length=NUM``,,"Used with ``--md5`` to specify the number of bytes to be hashed. If ``NUM`` is 0, MD5 hash of the whole file is calculated. Of ``NUM`` is negative, the MD5 hash is calculated from the tail. Is overriden if passed with ``--md5-engine`` option. (default: 0)"
+        ``--md5``,,"Shows MD5 hash of the file given by ``--md5-path=PATH``. If ``--md5-length=NUM`` is passed then it shows the MD5 hash of the first or last ``NUM`` bytes of the file given by ``PATH``. If ``--md5-engine=ENGINE_ID`` option is passed then it auto-calculates the required bytes and its hash, overriding ``--md5-length``"
+        ``--md5mac``,,"Shows MD5 hash for both the resource fork and data fork of the file given by ``--md5-path=PATH``. If ``--md5-length=NUM`` is passed then it shows the MD5 hash of the first or last ``NUM`` bytes of each fork."
+        ``--md5-path=PATH``,,"Used with ``--md5`` or ```--md5mac`` to specify path of file to calculate MD5 hash of (default: ./scummvm)"
+        ``--md5-length=NUM``,,"Used with ``--md5`` or ```--md5mac`` to specify the number of bytes to be hashed. If ``NUM`` is 0, MD5 hash of the whole file is calculated. Of ``NUM`` is negative, the MD5 hash is calculated from the tail. Is overriden if passed with ``--md5-engine`` option. (default: 0)"
         ``--md5-engine=ENGINE_ID``,,"Used with ``--md5`` to specify engine of game for which hash is to be calculated. Overrides ``--md5-length`` if passed with it"




More information about the Scummvm-git-logs mailing list