From 4054443a7268bba90e5063ef5ebfebbc087e5c39 Mon Sep 17 00:00:00 2001 From: GenevensiS <66968533+G-e-n-e-v-e-n-s-i-S@users.noreply.github.com> Date: Tue, 17 Sep 2024 06:13:01 +0200 Subject: [PATCH 1/2] add exists_in_package script function --- doc/function/exists_in_package.txt | 13 +++++++++ src/script/functions/basic.cpp | 10 ++++++- src/util/io/package.cpp | 29 +++++++++++++++++++ src/util/io/package.hpp | 8 ++++- src/util/io/package_manager.cpp | 14 +++++++++ src/util/io/package_manager.hpp | 7 +++-- .../drupal/mse-drupal-modules/highlight.inc | 3 +- 7 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 doc/function/exists_in_package.txt diff --git a/doc/function/exists_in_package.txt b/doc/function/exists_in_package.txt new file mode 100644 index 00000000..20f8d096 --- /dev/null +++ b/doc/function/exists_in_package.txt @@ -0,0 +1,13 @@ +Function: exists_in_package + +--Usage-- +> exists_in_package("/package/filename") + +Check if a file exists in a given package. + +--Parameters-- +! Parameter Type Description +| @input@ [[type:string]] Path of the file, starting from the data directory. + +--Examples-- +> exists_in_package("/magic-modules.mse-include/watermarks/custom_user_watermark.png") == true diff --git a/src/script/functions/basic.cpp b/src/script/functions/basic.cpp index 751b77de..d59beea4 100644 --- a/src/script/functions/basic.cpp +++ b/src/script/functions/basic.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +63,13 @@ SCRIPT_FUNCTION(error) { queue_message(MESSAGE_ERROR, input); } return script_nil; -} +} + +SCRIPT_FUNCTION(exists_in_package) { + SCRIPT_PARAM_C(String, input); + bool result = package_manager.existsInPackage(input); + SCRIPT_RETURN(result); +} // ----------------------------------------------------------------------------- : Conversion @@ -738,6 +745,7 @@ void init_script_basic_functions(Context& ctx) { ctx.setVariable(_("trace"), script_trace); ctx.setVariable(_("warning"), script_warning); ctx.setVariable(_("error"), script_error); + ctx.setVariable(_("exists_in_package"), script_exists_in_package); // conversion ctx.setVariable(_("to_string"), script_to_string); ctx.setVariable(_("to_int"), script_to_int); diff --git a/src/util/io/package.cpp b/src/util/io/package.cpp index 272cfa52..895fa60a 100644 --- a/src/util/io/package.cpp +++ b/src/util/io/package.cpp @@ -186,6 +186,35 @@ public: // ----------------------------------------------------------------------------- : Package : inside +bool Package::existsIn(const String& file) { + FileInfos::iterator it = files.find(normalize_internal_filename(file)); + if (it == files.end()) { + // does it look like a relative filename? + if (filename.find(_(".mse-")) != String::npos) { + return false; + } + } + + unique_ptr stream; + if (it != files.end() && it->second.wasWritten()) { + // written to this file, open the temp file + stream = make_unique(it->second.tempName); + } + else if (wxFileExists(filename + _("/") + file)) { + // a file in directory package + stream = make_unique(filename + _("/") + file); + } + else if (wxFileExists(filename) && it != files.end() && it->second.zipEntry) { + // a file in a zip archive + stream = make_unique(filename, it->second.zipEntry); + } + else { + // shouldn't happen, packaged changed by someone else since opening it + return false; + } + return stream && stream->IsOk(); +} + unique_ptr Package::openIn(const String& file) { if (!file.empty() && file.GetChar(0) == _('/')) { // absolute path, open file from another package diff --git a/src/util/io/package.hpp b/src/util/io/package.hpp index 6d15df9c..eee03149 100644 --- a/src/util/io/package.hpp +++ b/src/util/io/package.hpp @@ -132,10 +132,16 @@ public: // --------------------------------------------------- : Managing the inside of the package + /// Check if a file is in the package. + bool existsIn(const String& file); + inline bool existsIn(const LocalFileName& file) { + return existsIn(file.fn); + } + /// Open an input stream for a file in the package. unique_ptr openIn(const String& file); inline unique_ptr openIn(const LocalFileName& file) { - return openIn(file.fn); + return openIn(file.fn); } /// Open an output stream for a file in the package. diff --git a/src/util/io/package_manager.cpp b/src/util/io/package_manager.cpp index 2f368ad0..9eeca4f2 100644 --- a/src/util/io/package_manager.cpp +++ b/src/util/io/package_manager.cpp @@ -95,6 +95,20 @@ void PackageManager::findMatching(const String& pattern, vector& out) } } +bool PackageManager::existsInPackage(const String& name) { + if (!name.empty() && name.GetChar(0) == _('/')) { + // break name + size_t start = name.find_first_not_of(_("/\\"), 1); // allow "//package/name" from incorrect scripts + size_t pos = name.find_first_of(_("/\\"), start); + if (start < pos && pos != String::npos) { + // open package + PackagedP p = openAny(name.substr(start, pos - start)); + return p->existsIn(name.substr(pos + 1)); + } + } + throw FileNotFoundError(name, _("No package name specified, use '/package/filename'")); +} + pair,Packaged*> PackageManager::openFileFromPackage(Packaged* package, const String& name) { if (!name.empty() && name.GetChar(0) == _('/')) { // absolute name; break name diff --git a/src/util/io/package_manager.hpp b/src/util/io/package_manager.hpp index 4178d310..7e6037c4 100644 --- a/src/util/io/package_manager.hpp +++ b/src/util/io/package_manager.hpp @@ -139,7 +139,10 @@ public: /// Find all packages that match a filename pattern, store them in out /** Only reads the package headers */ void findMatching(const String& pattern, vector& out); - + + /// Check if a file exists in a package + bool existsInPackage(const String& name); + /// Open a file from a package, with a name encoded as "/package/file" /** If 'package' is set then: * - tries to open a relative file from the package if the name is "file" @@ -148,7 +151,7 @@ public: * Returns the opened file and the package it is in */ pair,Packaged*> openFileFromPackage(Packaged* package, const String& name); - + /// Get a filename to open from a package /** WARNING: this is a bit of a hack, since not all package types support names in this way. * It is needed for third party libraries (i.e. hunspell) that load stuff from files. diff --git a/tools/website/drupal/mse-drupal-modules/highlight.inc b/tools/website/drupal/mse-drupal-modules/highlight.inc index c34c41c4..dca657e8 100644 --- a/tools/website/drupal/mse-drupal-modules/highlight.inc +++ b/tools/website/drupal/mse-drupal-modules/highlight.inc @@ -101,6 +101,7 @@ $built_in_functions = array( // other 'trace' =>'', 'assert' =>'', + 'exists_in_package' =>'', ); @@ -232,4 +233,4 @@ function highlight_script_string($code) { return $code; } -?> \ No newline at end of file +?> From 28dd64ddebfb356ce63cdab813f43ca08a914afd Mon Sep 17 00:00:00 2001 From: GenevensiS <66968533+G-e-n-e-v-e-n-s-i-S@users.noreply.github.com> Date: Tue, 17 Sep 2024 06:30:17 +0200 Subject: [PATCH 2/2] Update index.txt --- doc/function/index.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/function/index.txt b/doc/function/index.txt index 700fdf7d..4d6dbc8f 100644 --- a/doc/function/index.txt +++ b/doc/function/index.txt @@ -112,3 +112,4 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:assert]] Check a condition for debugging purposes. | [[fun:warning]] Output a warning message. | [[fun:error]] Output an error message. +| [[fun:exists_in_package]] Checks if a file exists in a package.