filenameUnifier.cxx

00001 // Filename: filenameUnifier.cxx
00002 // Created by:  drose (05Dec00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "filenameUnifier.h"
00016 
00017 #include "executionEnvironment.h"
00018 
00019 Filename FilenameUnifier::_txa_filename;
00020 Filename FilenameUnifier::_txa_dir;
00021 Filename FilenameUnifier::_rel_dirname;
00022 
00023 FilenameUnifier::CanonicalFilenames FilenameUnifier::_canonical_filenames;
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: FilenameUnifier::set_txa_filename
00027 //       Access: Public, Static
00028 //  Description: Notes the filename the .txa file was found in.  This
00029 //               may have come from the command line, or it may have
00030 //               been implicitly located.  This has other implications
00031 //               for the FilenameUnifier, particularly in locating the bam
00032 //               file that saves the filenameUnifier state from last
00033 //               session.
00034 ////////////////////////////////////////////////////////////////////
00035 void FilenameUnifier::
00036 set_txa_filename(const Filename &txa_filename) {
00037   _txa_filename = txa_filename;
00038   _txa_dir = txa_filename.get_dirname();
00039   if (_txa_dir.empty()) {
00040     _txa_dir = ".";
00041   }
00042   make_canonical(_txa_dir);
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: FilenameUnifier::set_rel_dirname
00047 //       Access: Public, Static
00048 //  Description: Sets the name of the directory that texture filenames
00049 //               will be written relative to, when generating egg
00050 //               files.  This is not the directory the textures are
00051 //               actually written to (see set_map_dirname()), but
00052 //               rather is the name of some directory above that,
00053 //               which will be the starting point for the pathnames
00054 //               written to the egg files.  If this is empty, the full
00055 //               pathnames will be written to the egg files.
00056 ////////////////////////////////////////////////////////////////////
00057 void FilenameUnifier::
00058 set_rel_dirname(const Filename &rel_dirname) {
00059   _rel_dirname = rel_dirname;
00060   if (!_rel_dirname.empty()) {
00061     make_canonical(_rel_dirname);
00062   }
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: FilenameUnifier::make_bam_filename
00067 //       Access: Public, Static
00068 //  Description: Returns a new filename that's made relative to the
00069 //               bam file itself, suitable for writing to the bam file.
00070 ////////////////////////////////////////////////////////////////////
00071 Filename FilenameUnifier::
00072 make_bam_filename(Filename filename) {
00073   make_canonical(filename);
00074   filename.make_relative_to(_txa_dir);
00075   return filename;
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: FilenameUnifier::get_bam_filename
00080 //       Access: Public, Static
00081 //  Description: Returns an absolute pathname based on the given
00082 //               relative pathname, presumably read from the bam file
00083 //               and relative to the bam file.
00084 ////////////////////////////////////////////////////////////////////
00085 Filename FilenameUnifier::
00086 get_bam_filename(Filename filename) {
00087   if (!filename.empty()) {
00088     filename.make_absolute(_txa_dir);
00089   }
00090   return filename;
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: FilenameUnifier::make_egg_filename
00095 //       Access: Public, Static
00096 //  Description: Returns a new filename that's made relative to the
00097 //               rel_directory, suitable for writing out within egg
00098 //               files.
00099 ////////////////////////////////////////////////////////////////////
00100 Filename FilenameUnifier::
00101 make_egg_filename(Filename filename) {
00102   if (!filename.empty()) {
00103     make_canonical(filename);
00104     filename.make_relative_to(_rel_dirname);
00105   }
00106   return filename;
00107 }
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: FilenameUnifier::make_user_filename
00111 //       Access: Public, Static
00112 //  Description: Returns a new filename that's made relative to the
00113 //               current directory, suitable for reporting to the
00114 //               user.
00115 ////////////////////////////////////////////////////////////////////
00116 Filename FilenameUnifier::
00117 make_user_filename(Filename filename) {
00118   if (!filename.empty()) {
00119     make_canonical(filename);
00120     filename.make_relative_to(ExecutionEnvironment::get_cwd());
00121   }
00122   return filename;
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: FilenameUnifier::make_canonical
00127 //       Access: Public, Static
00128 //  Description: Does the same thing as Filename::make_canonical()--it
00129 //               converts the filename to its canonical form--but
00130 //               caches the operation so that repeated calls to
00131 //               filenames in the same directory will tend to be
00132 //               faster.
00133 ////////////////////////////////////////////////////////////////////
00134 void FilenameUnifier::
00135 make_canonical(Filename &filename) {
00136   if (filename.empty()) {
00137     return;
00138   }
00139 
00140   Filename orig_dirname = filename.get_dirname();
00141 
00142   CanonicalFilenames::iterator fi;
00143   fi = _canonical_filenames.find(orig_dirname);
00144   if (fi != _canonical_filenames.end()) {
00145     filename.set_dirname((*fi).second);
00146     return;
00147   }
00148 
00149   Filename new_dirname = orig_dirname;
00150   if (new_dirname.empty()) {
00151     new_dirname = ".";
00152   }
00153   new_dirname.make_canonical();
00154   filename.set_dirname(new_dirname);
00155 
00156   _canonical_filenames.insert(CanonicalFilenames::value_type(orig_dirname, new_dirname));
00157 }