The 'Big Whine' patch:

Any use of a file from another package without a declared dependency will give a warning;

Also added some more _LOCALE_123_ macros so we need less format_string calls

git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@753 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
twanvl
2007-09-24 20:24:22 +00:00
parent efcccb79c4
commit 36a36356c5
51 changed files with 246 additions and 132 deletions
+27 -3
View File
@@ -178,10 +178,15 @@ class BufferedFileInputStream : private BufferedFileInputStream_aux, public wxBu
InputStreamP Package::openIn(const String& file) {
if (!file.empty() && file.GetChar(0) == _('/')) {
// absolute path, open file from another package
return packages.openFileFromPackage(file);
Packaged* p = dynamic_cast<Packaged*>(this);
return packages.openFileFromPackage(p, file);
}
FileInfos::iterator it = files.find(toStandardName(file));
if (it == files.end()) {
// does it look like a relative filename?
if (filename.find(_(".mse-")) != String::npos) {
throw PackageError(_ERROR_2_("file not found package like", file, filename));
}
throw FileNotFoundError(file, filename);
}
InputStreamP stream;
@@ -442,6 +447,7 @@ IMPLEMENT_REFLECTION(Packaged) {
REFLECT_N("icon", icon_filename);
REFLECT_NO_SCRIPT(position_hint);
REFLECT(version);
REFLECT(compatible_version);
REFLECT_NO_SCRIPT_N("depends ons", dependencies); // hack for singular_form
}
@@ -472,7 +478,7 @@ void Packaged::open(const String& package, bool just_header) {
fully_loaded = false;
if (just_header) {
// Read just the header (the part common to all Packageds)
Reader reader(openIn(typeName()), absoluteFilename() + _("/") + typeName(), true);
Reader reader(openIn(typeName()), this, absoluteFilename() + _("/") + typeName(), true);
try {
JustAsPackageProxy proxy(this);
reader.handle_greedy(proxy);
@@ -487,7 +493,7 @@ void Packaged::open(const String& package, bool just_header) {
void Packaged::loadFully() {
if (fully_loaded) return;
fully_loaded = true;
Reader reader(openIn(typeName()), absoluteFilename() + _("/") + typeName());
Reader reader(openIn(typeName()), this, absoluteFilename() + _("/") + typeName());
try {
reader.handle_greedy(*this);
validate(reader.file_app_version);
@@ -518,6 +524,24 @@ void Packaged::validate(Version) {
}
}
void Packaged::requireDependency(Packaged* package) {
if (package == this) return; // dependency on self
String n = package->relativeFilename();
FOR_EACH(dep, dependencies) {
if (dep->package == n) {
if (package->version < dep->version) {
handle_warning(_ERROR_3_("package out of date", n, package->version.toString(), dep->version.toString()), false);
} else if (package->compatible_version > dep->version) {
handle_warning(_ERROR_4_("package too new", n, package->version.toString(), dep->version.toString(), relativeFilename()), false);
} else {
return; // ok
}
}
}
// dependency not found
handle_warning(_ERROR_4_("dependency not given", name(), package->relativeFilename(), package->relativeFilename(), package->version.toString()), false);
}
// ----------------------------------------------------------------------------- : IncludePackage
String IncludePackage::typeName() const { return _("include"); }
+11 -6
View File
@@ -117,7 +117,7 @@ class Package : public IntrusivePtrVirtualBase {
template <typename T>
void readFile(const String& file, T& obj) {
Reader reader(openIn(file), absoluteFilename() + _("/") + file);
Reader reader(openIn(file), dynamic_cast<Packaged*>(this), absoluteFilename() + _("/") + file);
try {
reader.handle_greedy(obj);
} catch (const ParseError& err) {
@@ -196,12 +196,13 @@ class Packaged : public Package {
Packaged();
virtual ~Packaged() {}
Version version; ///< Version number of this package
String short_name; ///< Short name of this package
String full_name; ///< Name of this package, for menus etc.
String icon_filename; ///< Filename of icon to use in package lists
Version version; ///< Version number of this package
Version compatible_version; ///< Earliest version number this package is compatible with
String short_name; ///< Short name of this package
String full_name; ///< Name of this package, for menus etc.
String icon_filename; ///< Filename of icon to use in package lists
vector<PackageDependencyP> dependencies; ///< Dependencies of this package
int position_hint; ///< A hint for the package list
int position_hint; ///< A hint for the package list
/// Get an input stream for the package icon, if there is any
InputStreamP openIconFile();
@@ -215,6 +216,10 @@ class Packaged : public Package {
void save();
void saveAs(const String& package, bool remove_unused = true);
/// Check if this package lists a dependency on the given package
/** This is done to force people to fill in the dependencies */
void requireDependency(Packaged* package);
protected:
/// filename of the data file, and extension of the package file
virtual String typeName() const = 0;
+18 -11
View File
@@ -101,17 +101,24 @@ void PackageManager::findMatching(const String& pattern, vector<PackagedP>& out)
}
}
InputStreamP PackageManager::openFileFromPackage(const String& name) {
// we don't want an absolute path (for security reasons)
String n;
if (!name.empty() && name.GetChar(0) == _('/')) n = name.substr(1);
else n = name;
// break
size_t pos = n.find_first_of(_("/\\"));
if (pos == String::npos) throw FileNotFoundError(n, _("No package name specified, use 'package/filename'"));
// open package and file
PackagedP p = openAny(n.substr(0, pos));
return p->openIn(n.substr(pos+1));
InputStreamP PackageManager::openFileFromPackage(Packaged*& package, const String& name) {
if (!name.empty() && name.GetChar(0) == _('/')) {
// absolute name; break name
size_t pos = name.find_first_of(_("/\\"), 1);
if (pos != String::npos) {
// open package
PackagedP p = openAny(name.substr(1, pos-1));
if (package) {
package->requireDependency(p.get());
}
package = p.get();
return p->openIn(name.substr(pos + 1));
}
} else if (package) {
// relative name
return package->openIn(name);
}
throw FileNotFoundError(name, _("No package name specified, use '/package/filename'"));
}
bool PackageManager::checkDependency(const PackageDependency& dep, bool report_errors) {
+10 -4
View File
@@ -66,12 +66,18 @@ class PackageManager {
/** Only reads the package headers */
void findMatching(const String& pattern, vector<PackagedP>& out);
/// Open a file from a package, with a name encoded as "package/file"
InputStreamP openFileFromPackage(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"
* - verifies a dependency from that package if an absolute filename is used
* this is to force people to fill in the dependencies
* Afterwards, package will be set to the package the file is opened from
*/
InputStreamP openFileFromPackage(Packaged*& package, const String& name);
/// Check if the given dependency is currently installed
bool checkDependency(const PackageDependency& dep, bool report_errors = false);
bool checkDependency(const PackageDependency& dep, bool report_errors = true);
inline String getGlobalDataDir() const { return global_data_directory; }
inline String getLocalDataDir() const { return local_data_directory; }
+5 -5
View File
@@ -14,9 +14,9 @@
// ----------------------------------------------------------------------------- : Reader
Reader::Reader(const InputStreamP& input, const String& filename, bool ignore_invalid)
Reader::Reader(const InputStreamP& input, Packaged* package, const String& filename, bool ignore_invalid)
: indent(0), expected_indent(0), state(OUTSIDE)
, filename(filename), line_number(0), previous_line_number(0)
, package(package), filename(filename), line_number(0), previous_line_number(0)
, ignore_invalid(ignore_invalid)
, input(input)
{
@@ -24,12 +24,12 @@ Reader::Reader(const InputStreamP& input, const String& filename, bool ignore_in
handleAppVersion();
}
Reader::Reader(const String& filename)
Reader::Reader(Packaged* pkg, const String& filename)
: indent(0), expected_indent(0), state(OUTSIDE)
, filename(filename), line_number(0), previous_line_number(0)
, package(pkg), filename(filename), line_number(0), previous_line_number(0)
, ignore_invalid(false)
, input(packages.openFileFromPackage(filename))
{
input = packages.openFileFromPackage(package, filename);
moveNext();
handleAppVersion();
}
+12 -4
View File
@@ -16,6 +16,7 @@ template <typename T> class Defaultable;
template <typename T> class Scriptable;
DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(StyleSheet);
class Packaged;
// ----------------------------------------------------------------------------- : Reader
@@ -35,11 +36,13 @@ class Reader {
/// Construct a reader that reads from the given input stream
/** filename is used only for error messages
*/
Reader(const InputStreamP& input, const String& filename = wxEmptyString, bool ignore_invalid = false);
Reader(const InputStreamP& input, Packaged* package = nullptr, const String& filename = wxEmptyString, bool ignore_invalid = false);
/// Construct a reader that reads a file in a package
/** Used for "include file" keys. */
Reader(const String& filename);
/** Used for "include file" keys.
* package can be nullptr
*/
Reader(Packaged* package, const String& filename);
~Reader() { showWarnings(); }
@@ -108,6 +111,9 @@ class Reader {
/// Indicate that the last value from getValue() was not handled, allowing it to be handled again
void unhandle();
/// The package being read from
inline Packaged* getPackage() const { return package; }
// --------------------------------------------------- : Data
/// App version this file was made with
Version file_app_version;
@@ -141,6 +147,8 @@ class Reader {
/// Filename for error messages
String filename;
/// Package this file is from, if any
Packaged* package;
/// Line number of the current line for error messages
int line_number;
/// Line number of the previous_line
@@ -172,7 +180,7 @@ class Reader {
template <typename T>
void unknownKey(T& v) {
if (key == _("include file")) {
Reader reader(value);
Reader reader(package, value);
reader.handle_greedy(v);
moveNext();
} else {