00001 // Filename: withOutputFile.cxx 00002 // Created by: drose (11Apr01) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 #include "withOutputFile.h" 00020 #include "executionEnvironment.h" 00021 00022 #include "notify.h" 00023 00024 //////////////////////////////////////////////////////////////////// 00025 // Function: WithOutputFile::Constructor 00026 // Access: Public 00027 // Description: 00028 //////////////////////////////////////////////////////////////////// 00029 WithOutputFile:: 00030 WithOutputFile(bool allow_last_param, bool allow_stdout, 00031 bool binary_output) { 00032 _allow_last_param = allow_last_param; 00033 _allow_stdout = allow_stdout; 00034 _binary_output = binary_output; 00035 _got_output_filename = false; 00036 _output_ptr = (ostream *)NULL; 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: WithOutputFile::Destructor 00041 // Access: Public, Virtual 00042 // Description: 00043 //////////////////////////////////////////////////////////////////// 00044 WithOutputFile:: 00045 ~WithOutputFile() { 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: WithOutputFile::get_output 00050 // Access: Public 00051 // Description: Returns an output stream that corresponds to the 00052 // user's intended egg file output--either stdout, or 00053 // the named output file. 00054 //////////////////////////////////////////////////////////////////// 00055 ostream &WithOutputFile:: 00056 get_output() { 00057 if (_output_ptr == (ostream *)NULL) { 00058 if (!_got_output_filename) { 00059 // No filename given; use standard output. 00060 nassertr(_allow_stdout, _output_stream); 00061 _output_ptr = &cout; 00062 00063 } else { 00064 // Attempt to open the named file. 00065 unlink(_output_filename.c_str()); 00066 _output_filename.make_dir(); 00067 00068 if (_binary_output) { 00069 _output_filename.set_binary(); 00070 } else { 00071 _output_filename.set_text(); 00072 } 00073 00074 if (!_output_filename.open_write(_output_stream)) { 00075 nout << "Unable to write to " << _output_filename << "\n"; 00076 exit(1); 00077 } 00078 nout << "Writing " << _output_filename << "\n"; 00079 _output_ptr = &_output_stream; 00080 } 00081 } 00082 return *_output_ptr; 00083 } 00084 00085 //////////////////////////////////////////////////////////////////// 00086 // Function: WithOutputFile::has_output_filename 00087 // Access: Public 00088 // Description: Returns true if the user specified an output 00089 // filename, false otherwise (e.g. the output file is 00090 // implicitly stdout). 00091 //////////////////////////////////////////////////////////////////// 00092 bool WithOutputFile:: 00093 has_output_filename() const { 00094 return _got_output_filename; 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: WithOutputFile::get_output_filename 00099 // Access: Public 00100 // Description: If has_output_filename() returns true, this is the 00101 // filename that the user specified. Otherwise, it 00102 // returns the empty string. 00103 //////////////////////////////////////////////////////////////////// 00104 Filename WithOutputFile:: 00105 get_output_filename() const { 00106 if (_got_output_filename) { 00107 return _output_filename; 00108 } 00109 return Filename(); 00110 } 00111 00112 //////////////////////////////////////////////////////////////////// 00113 // Function: WithOutputFile::check_last_arg 00114 // Access: Protected 00115 // Description: Checks if the last filename on the argument list is 00116 // a file with the expected extension (if 00117 // _allow_last_param was set true), and removes it from 00118 // the argument list if it is. Returns true if the 00119 // arguments are good, false if something is invalid. 00120 // 00121 // minimum_args is the number of arguments we know must 00122 // be input parameters and therefore cannot be 00123 // interpreted as output filenames. 00124 //////////////////////////////////////////////////////////////////// 00125 bool WithOutputFile:: 00126 check_last_arg(ProgramBase::Args &args, int minimum_args) { 00127 if (_allow_last_param && !_got_output_filename && 00128 (int)args.size() > minimum_args) { 00129 Filename filename = Filename::from_os_specific(args.back()); 00130 00131 if (!_preferred_extension.empty() && 00132 ("." + filename.get_extension()) != _preferred_extension) { 00133 // This argument must not be an output filename. 00134 if (!_allow_stdout) { 00135 nout << "Output filename " << filename 00136 << " does not end in " << _preferred_extension 00137 << ". If this is really what you intended, " 00138 "use the -o output_file syntax.\n"; 00139 return false; 00140 } 00141 00142 } else { 00143 // This argument appears to be an output filename. 00144 _got_output_filename = true; 00145 _output_filename = filename; 00146 args.pop_back(); 00147 00148 if (!verify_output_file_safe()) { 00149 return false; 00150 } 00151 } 00152 } 00153 00154 return true; 00155 } 00156 00157 //////////////////////////////////////////////////////////////////// 00158 // Function: WithOutputFile::verify_output_file_safe 00159 // Access: Protected 00160 // Description: This is called when the output file is given as the 00161 // last parameter on the command line. Since this is a 00162 // fairly dangerous way to specify the output file (it's 00163 // easy to accidentally overwrite an input file this 00164 // way), the convention is to disallow this syntax if 00165 // the output file already exists. 00166 // 00167 // This function will test if the output file exists, 00168 // and issue a warning message if it does, returning 00169 // false. If all is well, it will return true. 00170 //////////////////////////////////////////////////////////////////// 00171 bool WithOutputFile:: 00172 verify_output_file_safe() const { 00173 nassertr(_got_output_filename, false); 00174 00175 if (_output_filename.exists()) { 00176 nout << "The output filename " << _output_filename << " already exists. " 00177 "If you wish to overwrite it, you must use the -o option to specify " 00178 "the output filename, instead of simply specifying it as the last " 00179 "parameter.\n"; 00180 return false; 00181 } 00182 return true; 00183 }