diff --git a/pandatool/src/converter/somethingToEggConverter.I b/pandatool/src/converter/somethingToEggConverter.I index b45d16b7d1..00f506dc7c 100644 --- a/pandatool/src/converter/somethingToEggConverter.I +++ b/pandatool/src/converter/somethingToEggConverter.I @@ -17,6 +17,30 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::clear_error +// Access: Public +// Description: Resets the error flag to the no-error state. +// had_error() will return false until a new error is +// generated. +//////////////////////////////////////////////////////////////////// +INLINE void SomethingToEggConverter:: +clear_error() { + _error = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: SomethingToEggConverter::had_error +// Access: Public +// Description: Returns true if an error was detected during the +// conversion process (unless _allow_errors is true), +// false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool SomethingToEggConverter:: +had_error() const { + return !_allow_errors && (_error || _path_replace->had_error()); +} + //////////////////////////////////////////////////////////////////// // Function: SomethingToEggConverter::set_path_replace // Access: Public diff --git a/pandatool/src/converter/somethingToEggConverter.cxx b/pandatool/src/converter/somethingToEggConverter.cxx index 5d58aed508..fb249117d5 100644 --- a/pandatool/src/converter/somethingToEggConverter.cxx +++ b/pandatool/src/converter/somethingToEggConverter.cxx @@ -144,9 +144,7 @@ handle_external_reference(EggGroupNode *egg_parent, if (!ext->convert_file(ref_filename)) { delete ext; nout << "Unable to read external reference: " << ref_filename << "\n"; - if (!_allow_errors) { - _error = true; - } + _error = true; return false; } diff --git a/pandatool/src/converter/somethingToEggConverter.h b/pandatool/src/converter/somethingToEggConverter.h index 9e84a99dda..2a7024b9d8 100644 --- a/pandatool/src/converter/somethingToEggConverter.h +++ b/pandatool/src/converter/somethingToEggConverter.h @@ -49,6 +49,9 @@ public: virtual SomethingToEggConverter *make_copy()=0; + INLINE void clear_error(); + INLINE bool had_error() const; + INLINE void set_path_replace(PathReplace *path_replace); INLINE PathReplace *get_path_replace(); INLINE const PathReplace *get_path_replace() const; diff --git a/pandatool/src/dxfegg/dxfToEggConverter.cxx b/pandatool/src/dxfegg/dxfToEggConverter.cxx index 62266837ad..54e1ea9bac 100644 --- a/pandatool/src/dxfegg/dxfToEggConverter.cxx +++ b/pandatool/src/dxfegg/dxfToEggConverter.cxx @@ -91,14 +91,14 @@ get_extension() const { //////////////////////////////////////////////////////////////////// bool DXFToEggConverter:: convert_file(const Filename &filename) { - _error = false; + clear_error(); if (_egg_data->get_coordinate_system() == CS_default) { _egg_data->set_coordinate_system(CS_zup_right); } process(filename); - return !_error; + return !had_error(); } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/egg-palettize/eggPalettize.cxx b/pandatool/src/egg-palettize/eggPalettize.cxx index d1ecca4bec..71e378e7d9 100644 --- a/pandatool/src/egg-palettize/eggPalettize.cxx +++ b/pandatool/src/egg-palettize/eggPalettize.cxx @@ -657,6 +657,8 @@ run() { } } + pal->set_noabs(_noabs); + if (_report_pi) { pal->report_pi(); exit(0); @@ -724,6 +726,8 @@ run() { } // And process the egg files named for addition. + bool all_eggs_valid = true; + string egg_comment = get_exec_command(); Eggs::const_iterator ei; for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { @@ -733,10 +737,18 @@ run() { string name = source_filename.get_basename(); EggFile *egg_file = pal->get_egg_file(name); - egg_file->from_command_line(egg_data, source_filename, dest_filename, - egg_comment); + if (!egg_file->from_command_line(egg_data, source_filename, dest_filename, + egg_comment)) { + all_eggs_valid = false; - pal->add_command_line_egg(egg_file); + } else { + pal->add_command_line_egg(egg_file); + } + } + + if (!all_eggs_valid) { + nout << "Errors reading egg file(s).\n"; + exit(1); } if (_optimal) { @@ -767,10 +779,12 @@ run() { } } - pal->generate_images(_redo_all); - - if (!pal->write_eggs()) { - okflag = false; + if (okflag) { + pal->generate_images(_redo_all); + + if (!pal->write_eggs()) { + okflag = false; + } } if (!_nodb) { diff --git a/pandatool/src/eggbase/eggBase.cxx b/pandatool/src/eggbase/eggBase.cxx index 0909a43889..83565403a4 100644 --- a/pandatool/src/eggbase/eggBase.cxx +++ b/pandatool/src/eggbase/eggBase.cxx @@ -39,13 +39,16 @@ EggBase() { &EggBase::dispatch_coordinate_system, &_got_coordinate_system, &_coordinate_system); - _coordinate_system = CS_yup_right; - _normals_mode = NM_preserve; _normals_threshold = 0.0; _got_transform = false; _transform = LMatrix4d::ident_mat(); + + _got_coordinate_system = false; + _coordinate_system = CS_yup_right; + + _noabs = false; } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/eggbase/eggBase.h b/pandatool/src/eggbase/eggBase.h index 2872a27d03..df9574d39e 100644 --- a/pandatool/src/eggbase/eggBase.h +++ b/pandatool/src/eggbase/eggBase.h @@ -72,6 +72,8 @@ protected: bool _got_coordinate_system; CoordinateSystem _coordinate_system; + + bool _noabs; }; #endif diff --git a/pandatool/src/eggbase/eggMultiBase.cxx b/pandatool/src/eggbase/eggMultiBase.cxx index 50b8489c56..c68e5673a3 100644 --- a/pandatool/src/eggbase/eggMultiBase.cxx +++ b/pandatool/src/eggbase/eggMultiBase.cxx @@ -35,6 +35,14 @@ EggMultiBase() { "Force complete loading: load up the egg file along with all of its " "external references.", &EggMultiBase::dispatch_none, &_force_complete); + + add_option + ("noabs", "", 0, + "Don't allow any of the named egg files to have absolute pathnames. " + "If any do, abort with an error. This option is designed to help " + "detect errors when populating or building a standalone model tree, " + "which should be self-contained and include only relative pathnames.", + &EggReader::dispatch_none, &_noabs); } //////////////////////////////////////////////////////////////////// @@ -124,6 +132,12 @@ read_egg(const Filename &filename) { return (EggData *)NULL; } + if (_noabs && data->original_had_absolute_pathnames()) { + nout << filename.get_basename() + << " includes absolute pathnames!\n"; + return (EggData *)NULL; + } + DSearchPath file_path; file_path.append_directory(filename.get_dirname()); diff --git a/pandatool/src/eggbase/eggReader.cxx b/pandatool/src/eggbase/eggReader.cxx index aebaef1c28..cf85093387 100644 --- a/pandatool/src/eggbase/eggReader.cxx +++ b/pandatool/src/eggbase/eggReader.cxx @@ -49,6 +49,14 @@ EggReader() { "external references.", &EggReader::dispatch_none, &_force_complete); + add_option + ("noabs", "", 0, + "Don't allow the input egg file to have absolute pathnames. " + "If it does, abort with an error. This option is designed to help " + "detect errors when populating or building a standalone model tree, " + "which should be self-contained and include only relative pathnames.", + &EggReader::dispatch_none, &_noabs); + _tex_type = (PNMFileType *)NULL; _delod = -1.0; } @@ -174,6 +182,12 @@ handle_args(ProgramBase::Args &args) { exit(1); } + if (_noabs && file_data.original_had_absolute_pathnames()) { + nout << filename.get_basename() + << " includes absolute pathnames!\n"; + exit(1); + } + DSearchPath file_path; file_path.append_directory(filename.get_dirname()); diff --git a/pandatool/src/eggbase/somethingToEgg.cxx b/pandatool/src/eggbase/somethingToEgg.cxx index 41be3cccef..60775fffdf 100644 --- a/pandatool/src/eggbase/somethingToEgg.cxx +++ b/pandatool/src/eggbase/somethingToEgg.cxx @@ -52,6 +52,14 @@ SomethingToEgg(const string &format_name, "Specify the coordinate system of the input " + _format_name + " file. Normally, this can inferred from the file itself."); + add_option + ("noabs", "", 0, + "Don't allow the input " + _format_name + " file to have absolute pathnames. " + "If it does, abort with an error. This option is designed to help " + "detect errors when populating or building a standalone model tree, " + "which should be self-contained and include only relative pathnames.", + &SomethingToEgg::dispatch_none, &_noabs); + add_option ("ignore", "", 0, "Ignore non-fatal errors and generate an egg file anyway.", @@ -200,6 +208,8 @@ apply_units_scale(EggData &data) { //////////////////////////////////////////////////////////////////// void SomethingToEgg:: apply_parameters(SomethingToEggConverter &converter) { + _path_replace->_noabs = _noabs; + _path_replace->_exists = true; converter.set_path_replace(_path_replace); converter.set_animation_convert(_animation_convert); diff --git a/pandatool/src/fltegg/fltToEggConverter.cxx b/pandatool/src/fltegg/fltToEggConverter.cxx index 60188ca38d..4bb5884deb 100644 --- a/pandatool/src/fltegg/fltToEggConverter.cxx +++ b/pandatool/src/fltegg/fltToEggConverter.cxx @@ -163,7 +163,7 @@ convert_flt(const FltHeader *flt_header) { _egg_data->set_coordinate_system(CS_zup_right); } - _error = false; + clear_error(); _flt_header = flt_header; // Generate a default vertex pool. @@ -188,7 +188,7 @@ convert_flt(const FltHeader *flt_header) { cleanup(); - return !_error; + return !had_error(); } //////////////////////////////////////////////////////////////////// @@ -681,9 +681,7 @@ parse_comment(const string &comment, const string &name, if (p >= comment.length() || comment[p] != '{') { nout << "No opening brace in comment for " << name << "\n\n"; - if (!_allow_errors) { - _error = true; - } + _error = true; return false; } @@ -697,9 +695,7 @@ parse_comment(const string &comment, const string &name, if (q == p) { nout << "No closing brace in comment for " << name << "\n\n"; - if (!_allow_errors) { - _error = true; - } + _error = true; return false; } @@ -708,9 +704,7 @@ parse_comment(const string &comment, const string &name, if (!egg_node->parse_egg(egg_syntax)) { nout << "Syntax error in comment for " << name << "\n\n"; - if (!_allow_errors) { - _error = true; - } + _error = true; return false; } diff --git a/pandatool/src/fltprogs/fltToEgg.cxx b/pandatool/src/fltprogs/fltToEgg.cxx index c26dffe137..946738df48 100644 --- a/pandatool/src/fltprogs/fltToEgg.cxx +++ b/pandatool/src/fltprogs/fltToEgg.cxx @@ -68,6 +68,17 @@ FltToEgg() : //////////////////////////////////////////////////////////////////// void FltToEgg:: run() { + _data.set_coordinate_system(_coordinate_system); + + FltToEggConverter converter; + converter.set_merge_externals(_merge_externals); + converter.set_egg_data(&_data, false); + converter._compose_transforms = _compose_transforms; + converter._allow_errors = _allow_errors; + + apply_parameters(converter); + + PT(FltHeader) header = new FltHeader(_path_replace); nout << "Reading " << _input_filename << "\n"; @@ -79,15 +90,6 @@ run() { header->check_version(); - _data.set_coordinate_system(_coordinate_system); - - FltToEggConverter converter; - converter.set_merge_externals(_merge_externals); - converter.set_egg_data(&_data, false); - converter._compose_transforms = _compose_transforms; - converter._allow_errors = _allow_errors; - - apply_parameters(converter); if (!converter.convert_flt(header)) { nout << "Errors in conversion.\n"; diff --git a/pandatool/src/lwoegg/lwoToEggConverter.cxx b/pandatool/src/lwoegg/lwoToEggConverter.cxx index 6faf7fab5b..056c10ea0b 100644 --- a/pandatool/src/lwoegg/lwoToEggConverter.cxx +++ b/pandatool/src/lwoegg/lwoToEggConverter.cxx @@ -167,7 +167,7 @@ convert_lwo(const LwoHeader *lwo_header) { _egg_data->remove_unused_vertices(); cleanup(); - return !_error; + return !had_error(); } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index 9f131367f5..f125d6334b 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -272,6 +272,7 @@ get_input_units() { bool MayaToEggConverter:: convert_maya() { clear(); + clear_error(); if (!open_api()) { mayaegg_cat.error() @@ -391,6 +392,10 @@ convert_maya() { reparent_decals(&get_egg_data()); } + if (had_error()) { + all_ok = false; + } + if (all_ok) { mayaegg_cat.info() << "Converted, no errors.\n"; diff --git a/pandatool/src/mayaprogs/mayaToEgg.cxx b/pandatool/src/mayaprogs/mayaToEgg.cxx index d32ba574be..350b6e1b60 100644 --- a/pandatool/src/mayaprogs/mayaToEgg.cxx +++ b/pandatool/src/mayaprogs/mayaToEgg.cxx @@ -99,6 +99,12 @@ MayaToEgg() : "Increase verbosity. More v's means more verbose.", &MayaToEgg::dispatch_count, NULL, &_verbose); + // Unfortunately, the Maya API doesn't allow us to differentiate + // between relative and absolute pathnames--everything comes out as + // an absolute pathname, even if it is stored in the Maya file as a + // relative path. So we can't support -noabs. + remove_option("noabs"); + _verbose = 0; _polygon_tolerance = 0.01; _transform_type = MayaToEggConverter::TT_model; @@ -159,7 +165,6 @@ run() { _data.set_coordinate_system(_coordinate_system); converter.set_egg_data(&_data, false); - apply_parameters(converter); if (!converter.convert_file(_input_filename)) { nout << "Errors in conversion.\n"; diff --git a/pandatool/src/palettizer/eggFile.cxx b/pandatool/src/palettizer/eggFile.cxx index 560b602eb4..f852818031 100644 --- a/pandatool/src/palettizer/eggFile.cxx +++ b/pandatool/src/palettizer/eggFile.cxx @@ -60,9 +60,10 @@ EggFile() { // Function: EggFile::from_command_line // Access: Public // Description: Accepts the information about the egg file as -// supplied from the command line. +// supplied from the command line. Returns true if the +// egg file is valid, false otherwise. //////////////////////////////////////////////////////////////////// -void EggFile:: +bool EggFile:: from_command_line(EggData *data, const Filename &source_filename, const Filename &dest_filename, @@ -90,8 +91,21 @@ from_command_line(EggData *data, // file inherits the default group that was in effect when it was // specified on the command line. _default_group = pal->get_default_group(); + + return true; } +//////////////////////////////////////////////////////////////////// +// Function: EggFile::get_source_filename +// Access: Public +// Description: Returns the filename this egg file was read from. +//////////////////////////////////////////////////////////////////// +const Filename &EggFile:: +get_source_filename() const { + return _source_filename; +} + + //////////////////////////////////////////////////////////////////// // Function: EggFile::scan_textures // Access: Public @@ -536,7 +550,7 @@ remove_egg() { // file. //////////////////////////////////////////////////////////////////// bool EggFile:: -read_egg() { +read_egg(bool noabs) { nassertr(_data == (EggData *)NULL, false); nassertr(!_source_filename.empty(), false); @@ -554,10 +568,15 @@ read_egg() { return false; } + if (noabs && data->original_had_absolute_pathnames()) { + nout << _source_filename.get_basename() + << " references textures using absolute pathnames!\n"; + return false; + } // Extract the set of textures referenced by this egg file. EggTextureCollection tc; - tc.find_used_textures(_data); + tc.find_used_textures(data); // Make sure each tref name is unique within a given file. tc.uniquify_trefs(); @@ -850,7 +869,7 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) { //////////////////////////////////////////////////////////////////// TypedWritable* EggFile:: make_EggFile(const FactoryParams ¶ms) { - EggFile *me = new EggFile; + EggFile *me = new EggFile(); DatagramIterator scan; BamReader *manager; diff --git a/pandatool/src/palettizer/eggFile.h b/pandatool/src/palettizer/eggFile.h index 7a9e71fa9c..2d3e1c29b1 100644 --- a/pandatool/src/palettizer/eggFile.h +++ b/pandatool/src/palettizer/eggFile.h @@ -44,11 +44,13 @@ class EggFile : public TypedWritable, public Namable { public: EggFile(); - void from_command_line(EggData *data, + bool from_command_line(EggData *data, const Filename &source_filename, const Filename &dest_filename, const string &egg_comment); + const Filename &get_source_filename() const; + void scan_textures(); void get_textures(pset &result) const; @@ -74,7 +76,7 @@ public: void update_egg(); void remove_egg(); - bool read_egg(); + bool read_egg(bool noabs); void release_egg_data(); bool write_egg(); @@ -95,6 +97,7 @@ private: typedef pvector Textures; Textures _textures; + bool _noabs; bool _first_txa_match; PaletteGroups _explicitly_assigned_groups; PaletteGroup *_default_group; diff --git a/pandatool/src/palettizer/paletteImage.cxx b/pandatool/src/palettizer/paletteImage.cxx index e9c54bdab2..20c12d051f 100644 --- a/pandatool/src/palettizer/paletteImage.cxx +++ b/pandatool/src/palettizer/paletteImage.cxx @@ -738,12 +738,12 @@ get_image() { if (!_new_image) { if (pal->_shadow_color_type != (PNMFileType *)NULL) { - if (_shadow_image.read(_image)) { + if (_shadow_image.get_filename().exists() && _shadow_image.read(_image)) { _got_image = true; return; } } else { - if (read(_image)) { + if (get_filename().exists() && read(_image)) { _got_image = true; return; } diff --git a/pandatool/src/palettizer/palettizer.cxx b/pandatool/src/palettizer/palettizer.cxx index 80b1feb7f9..0276333862 100644 --- a/pandatool/src/palettizer/palettizer.cxx +++ b/pandatool/src/palettizer/palettizer.cxx @@ -102,6 +102,7 @@ public: Palettizer:: Palettizer() { _is_valid = true; + _noabs = false; _generated_image_pattern = "%g_palette_%p_%i"; _map_dirname = "%g"; @@ -125,6 +126,36 @@ Palettizer() { _remap_char_uv = RU_poly; } +//////////////////////////////////////////////////////////////////// +// Function: Palettizer::get_noabs +// Access: Public +// Description: Returns the current setting of the noabs flag. See +// set_noabs(). +//////////////////////////////////////////////////////////////////// +bool Palettizer:: +get_noabs() const { + return _noabs; +} + +//////////////////////////////////////////////////////////////////// +// Function: Palettizer::set_noabs +// Access: Public +// Description: Changes the current setting of the noabs flag. +// +// If this flag is true, then it is an error to process +// an egg file that contains absolute pathname +// references. This flag is intended to help detect egg +// files that are incorrectly built within a model tree +// (which should use entirely relative pathnames). +// +// This flag must be set before any egg files are +// processed. +//////////////////////////////////////////////////////////////////// +void Palettizer:: +set_noabs(bool noabs) { + _noabs = noabs; +} + //////////////////////////////////////////////////////////////////// // Function: Palettizer::is_valid // Access: Public @@ -660,7 +691,7 @@ read_stale_eggs(bool redo_all) { EggFile *egg_file = (*ei).second; if (!egg_file->has_data() && (egg_file->is_stale() || redo_all)) { - if (!egg_file->read_egg()) { + if (!egg_file->read_egg(_noabs)) { invalid_eggs.push_back(ei); } else { @@ -676,9 +707,28 @@ read_stale_eggs(bool redo_all) { for (ii = invalid_eggs.begin(); ii != invalid_eggs.end(); ++ii) { EggFiles::iterator ei = (*ii); EggFile *egg_file = (*ei).second; - nout << "Removing " << (*ei).first << "\n"; - egg_file->remove_egg(); - _egg_files.erase(ei); + if (egg_file->get_source_filename().exists()) { + // If there is an invalid egg file, remove it; hopefully it will + // get rebuilt properly next time. + nout << "Removing invalid egg file: " + << FilenameUnifier::make_user_filename(egg_file->get_source_filename()) + << "\n"; + + egg_file->get_source_filename().unlink(); + okflag = false; + + } else { + // If the egg file is simply missing, quietly remove any record + // of it from the database. + egg_file->remove_egg(); + _egg_files.erase(ei); + } + } + + if (!okflag) { + nout << "\n" + << "Some errors in egg files encountered.\n" + << "Re-run make install or make opt-pal to try to regenerate these.\n\n"; } return okflag; @@ -701,7 +751,7 @@ write_eggs() { if (egg_file->had_data()) { if (!egg_file->has_data()) { // Re-read the egg file. - bool read_ok = egg_file->read_egg(); + bool read_ok = egg_file->read_egg(_noabs); if (!read_ok) { nout << "Error! Unable to re-read egg file.\n"; okflag = false; diff --git a/pandatool/src/palettizer/palettizer.h b/pandatool/src/palettizer/palettizer.h index 2195260778..7135683eda 100644 --- a/pandatool/src/palettizer/palettizer.h +++ b/pandatool/src/palettizer/palettizer.h @@ -48,6 +48,9 @@ class Palettizer : public TypedWritable { public: Palettizer(); + bool get_noabs() const; + void set_noabs(bool noabs); + bool is_valid() const; void report_pi() const; void report_statistics() const; @@ -91,15 +94,16 @@ public: bool _is_valid; - // These values are not stored in the bam file, but are specific to - // each session. + // These values are not stored in the textures.boo file, but are + // specific to each session. TxaFile _txa_file; string _default_groupname; string _default_groupdir; + bool _noabs; // The following parameter values specifically relate to textures - // and palettes. These values are stored in the bam file for future - // reference. + // and palettes. These values are stored in the textures.boo file + // for future reference. string _generated_image_pattern; string _map_dirname; Filename _shadow_dirname; diff --git a/pandatool/src/pandatoolbase/Sources.pp b/pandatool/src/pandatoolbase/Sources.pp index 7b9b3489a1..4cfb67424b 100644 --- a/pandatool/src/pandatoolbase/Sources.pp +++ b/pandatool/src/pandatoolbase/Sources.pp @@ -6,6 +6,7 @@ #define SOURCES \ animationConvert.cxx animationConvert.h \ + config_pandatoolbase.cxx config_pandatoolbase.h \ distanceUnit.cxx distanceUnit.h \ pandatoolbase.cxx pandatoolbase.h pandatoolsymbols.h \ pathReplace.cxx pathReplace.I pathReplace.h \ @@ -13,6 +14,7 @@ #define INSTALL_HEADERS \ animationConvert.h \ + config_pandatoolbase.h \ distanceUnit.h \ pandatoolbase.h pandatoolsymbols.h \ pathReplace.I pathReplace.h \ diff --git a/pandatool/src/pandatoolbase/config_pandatoolbase.cxx b/pandatool/src/pandatoolbase/config_pandatoolbase.cxx new file mode 100644 index 0000000000..382e4d1546 --- /dev/null +++ b/pandatool/src/pandatoolbase/config_pandatoolbase.cxx @@ -0,0 +1,39 @@ +// Filename: config_pandatoolbase.cxx +// Created by: drose (29Nov04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#include "config_pandatoolbase.h" + +NotifyCategoryDef(pandatoolbase, ""); + +//////////////////////////////////////////////////////////////////// +// Function: init_libpandatoolbase +// Description: Initializes the library. This must be called at +// least once before any of the functions or classes in +// this library can be used. Normally it will be +// called by the static initializers and need not be +// called explicitly, but special cases exist. +//////////////////////////////////////////////////////////////////// +void +init_libpandatoolbase() { + static bool initialized = false; + if (initialized) { + return; + } + initialized = true; +} + diff --git a/pandatool/src/pandatoolbase/config_pandatoolbase.h b/pandatool/src/pandatoolbase/config_pandatoolbase.h new file mode 100644 index 0000000000..172776ac7d --- /dev/null +++ b/pandatool/src/pandatoolbase/config_pandatoolbase.h @@ -0,0 +1,30 @@ +// Filename: config_pandatoolbase.h +// Created by: drose (29Nov04) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://etc.cmu.edu/panda3d/docs/license/ . +// +// To contact the maintainers of this program write to +// panda3d-general@lists.sourceforge.net . +// +//////////////////////////////////////////////////////////////////// + +#ifndef CONFIG_PANDATOOLBASE_H +#define CONFIG_PANDATOOLBASE_H + +#include "pandatoolbase.h" + +#include "notifyCategoryProxy.h" + +NotifyCategoryDeclNoExport(pandatoolbase); + +extern void init_libpandatoolbase(); + +#endif diff --git a/pandatool/src/pandatoolbase/pathReplace.I b/pandatool/src/pandatoolbase/pathReplace.I index f7389b4157..0542f8b55f 100755 --- a/pandatool/src/pandatoolbase/pathReplace.I +++ b/pandatool/src/pandatoolbase/pathReplace.I @@ -17,6 +17,29 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: PathReplace::clear_error +// Access: Public +// Description: Resets the error flag to the no-error state. +// had_error() will return false until a new error is +// generated. +//////////////////////////////////////////////////////////////////// +INLINE void PathReplace:: +clear_error() { + _error_flag = false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PathReplace::had_error +// Access: Public +// Description: Returns true if an error was detected since the last +// call to clear_error(), false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool PathReplace:: +had_error() const { + return _error_flag; +} + //////////////////////////////////////////////////////////////////// // Function: PathReplace::clear // Access: Public @@ -24,6 +47,7 @@ //////////////////////////////////////////////////////////////////// INLINE void PathReplace:: clear() { + clear_error(); _entries.clear(); } diff --git a/pandatool/src/pandatoolbase/pathReplace.cxx b/pandatool/src/pandatoolbase/pathReplace.cxx index 88107e454b..082af92489 100755 --- a/pandatool/src/pandatoolbase/pathReplace.cxx +++ b/pandatool/src/pandatoolbase/pathReplace.cxx @@ -18,6 +18,7 @@ #include "pathReplace.h" #include "config_util.h" +#include "config_pandatoolbase.h" #include "indent.h" //////////////////////////////////////////////////////////////////// @@ -28,6 +29,9 @@ PathReplace:: PathReplace() { _path_store = PS_keep; + _noabs = false; + _exists = false; + _error_flag = false; } //////////////////////////////////////////////////////////////////// @@ -96,9 +100,31 @@ match_path(const Filename &orig_filename, // The file couldn't be found anywhere. Did we at least get any // prefix match? if (got_match) { + if (_exists) { + _error_flag = true; + pandatoolbase_cat.error() + << "File does not exist: " << match << "\n"; + } else if (pandatoolbase_cat.is_debug()) { + pandatoolbase_cat.debug() + << "File does not exist: " << match << "\n"; + } + return match; } + if (!orig_filename.is_local()) { + // Ok, we didn't match any specified prefixes. If the file is an + // absolute pathname and we have _noabs set, that's an error. + if (_noabs) { + _error_flag = true; + pandatoolbase_cat.error() + << "Absolute pathname: " << orig_filename << "\n"; + } else if (pandatoolbase_cat.is_debug()) { + pandatoolbase_cat.debug() + << "Absolute pathname: " << orig_filename << "\n"; + } + } + // Well, we still haven't found it; look it up on the search path as // is. if (_path_store != PS_keep) { @@ -111,7 +137,16 @@ match_path(const Filename &orig_filename, } } - // Nope, couldn't find anything. Just return the original filename. + // Nope, couldn't find anything. This is an error, but just return + // the original filename. + if (_exists) { + _error_flag = true; + pandatoolbase_cat.error() + << "File does not exist: " << orig_filename << "\n"; + } else if (pandatoolbase_cat.is_debug()) { + pandatoolbase_cat.debug() + << "File does not exist: " << orig_filename << "\n"; + } return orig_filename; } @@ -125,6 +160,10 @@ match_path(const Filename &orig_filename, //////////////////////////////////////////////////////////////////// Filename PathReplace:: store_path(const Filename &orig_filename) { + if (orig_filename.empty()) { + return orig_filename; + } + if (_path_directory.is_local()) { _path_directory.make_absolute(); } @@ -190,6 +229,11 @@ write(ostream &out, int indent_level) const { default: break; } + + if (_noabs) { + indent(out, indent_level) + << "-noabs\n"; + } } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/pandatoolbase/pathReplace.h b/pandatool/src/pandatoolbase/pathReplace.h index 5e4db9a10e..e5fbdc47fd 100755 --- a/pandatool/src/pandatoolbase/pathReplace.h +++ b/pandatool/src/pandatoolbase/pathReplace.h @@ -45,6 +45,9 @@ public: PathReplace(); ~PathReplace(); + INLINE void clear_error(); + INLINE bool had_error() const; + INLINE void clear(); INLINE void add_pattern(const string &orig_prefix, const string &replacement_prefix); @@ -71,6 +74,16 @@ public: PathStore _path_store; Filename _path_directory; + // If this is this true, then the error flag is set (see had_error() + // and clear_error()) if any Filename passed to match_path() or + // convert_path(), and unmatched by one of the prefixes, happens to + // be an absolute pathname. + bool _noabs; + + // If this is true, then the error flag is set if any Filename + // passed to match_path() or convert_path() cannot be found. + bool _exists; + private: class Component { public: @@ -100,6 +113,8 @@ private: typedef pvector Entries; Entries _entries; + + bool _error_flag; }; #include "pathReplace.I" diff --git a/pandatool/src/vrmlegg/vrmlToEggConverter.cxx b/pandatool/src/vrmlegg/vrmlToEggConverter.cxx index 35c798823f..b58d639555 100644 --- a/pandatool/src/vrmlegg/vrmlToEggConverter.cxx +++ b/pandatool/src/vrmlegg/vrmlToEggConverter.cxx @@ -98,6 +98,8 @@ get_extension() const { //////////////////////////////////////////////////////////////////// bool VRMLToEggConverter:: convert_file(const Filename &filename) { + clear_error(); + VrmlScene *scene = parse_vrml(filename); if (scene == (VrmlScene *)NULL) { return false; @@ -122,7 +124,7 @@ convert_file(const Filename &filename) { vrml_node((*csi)._node, &get_egg_data(), LMatrix4d::ident_mat()); } - return true; + return !had_error(); } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/xfileegg/xFileToEggConverter.cxx b/pandatool/src/xfileegg/xFileToEggConverter.cxx index e3240ad158..e002f0d968 100644 --- a/pandatool/src/xfileegg/xFileToEggConverter.cxx +++ b/pandatool/src/xfileegg/xFileToEggConverter.cxx @@ -116,6 +116,7 @@ get_extension() const { bool XFileToEggConverter:: convert_file(const Filename &filename) { close(); + clear_error(); if (!_x_file->read(filename)) { nout << "Unable to open X file: " << filename << "\n"; @@ -148,7 +149,7 @@ convert_file(const Filename &filename) { return false; } - return true; + return !had_error(); } ////////////////////////////////////////////////////////////////////