Panda3D
Loading...
Searching...
No Matches
withOutputFile.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file withOutputFile.cxx
10 * @author drose
11 * @date 2001-04-11
12 */
13
14#include "withOutputFile.h"
16#include "zStream.h"
17
18#include "pnotify.h"
19
20/**
21 *
22 */
23WithOutputFile::
24WithOutputFile(bool allow_last_param, bool allow_stdout,
25 bool binary_output) {
26 _allow_last_param = allow_last_param;
27 _allow_stdout = allow_stdout;
28 _binary_output = binary_output;
29 _got_output_filename = false;
30 _output_ptr = nullptr;
31 _owns_output_ptr = false;
32}
33
34/**
35 *
36 */
37WithOutputFile::
38~WithOutputFile() {
39 if (_owns_output_ptr) {
40 delete _output_ptr;
41 _owns_output_ptr = false;
42 }
43}
44
45/**
46 * Returns an output stream that corresponds to the user's intended egg file
47 * output--either stdout, or the named output file.
48 */
49std::ostream &WithOutputFile::
50get_output() {
51 if (_output_ptr == nullptr) {
52 if (!_got_output_filename) {
53 // No filename given; use standard output.
54 if (!_allow_stdout) {
55 nout << "No output filename specified.\n";
56 exit(1);
57 }
58 _output_ptr = &std::cout;
59 _owns_output_ptr = false;
60
61 } else {
62 // Attempt to open the named file.
63 unlink(_output_filename.c_str());
64 _output_filename.make_dir();
65
66 bool pz_file = false;
67#ifdef HAVE_ZLIB
68 if (_output_filename.get_extension() == "pz") {
69 // The filename ends in .pz, which means to automatically compress the
70 // file that we write.
71 pz_file = true;
72 }
73#endif // HAVE_ZLIB
74
75 if (_binary_output || pz_file) {
76 _output_filename.set_binary();
77 } else {
78 _output_filename.set_text();
79 }
80
81 _output_stream.clear();
82 if (!_output_filename.open_write(_output_stream)) {
83 nout << "Unable to write to " << _output_filename << "\n";
84 exit(1);
85 }
86 nout << "Writing " << _output_filename << "\n";
87 _output_ptr = &_output_stream;
88 _owns_output_ptr = false;
89
90#ifdef HAVE_ZLIB
91 if (pz_file) {
92 _output_ptr = new OCompressStream(_output_ptr, _owns_output_ptr);
93 _owns_output_ptr = true;
94 }
95#endif // HAVE_ZLIB
96 }
97 }
98 return *_output_ptr;
99}
100
101/**
102 * Closes the output stream previously opened by get_output(). A subsequent
103 * call to get_output() will open a new stream.
104 */
106close_output() {
107 if (_owns_output_ptr) {
108 delete _output_ptr;
109 _owns_output_ptr = false;
110 }
111 _output_ptr = nullptr;
112 _output_stream.close();
113}
114
115
116
117/**
118 * Returns true if the user specified an output filename, false otherwise
119 * (e.g. the output file is implicitly stdout).
120 */
122has_output_filename() const {
123 return _got_output_filename;
124}
125
126/**
127 * If has_output_filename() returns true, this is the filename that the user
128 * specified. Otherwise, it returns the empty string.
129 */
131get_output_filename() const {
132 if (_got_output_filename) {
133 return _output_filename;
134 }
135 return Filename();
136}
137
138/**
139 * Checks if the last filename on the argument list is a file with the
140 * expected extension (if _allow_last_param was set true), and removes it from
141 * the argument list if it is. Returns true if the arguments are good, false
142 * if something is invalid.
143 *
144 * minimum_args is the number of arguments we know must be input parameters
145 * and therefore cannot be interpreted as output filenames.
146 */
147bool WithOutputFile::
148check_last_arg(ProgramBase::Args &args, int minimum_args) {
149 if (_allow_last_param && !_got_output_filename &&
150 (int)args.size() > minimum_args) {
151 Filename filename = Filename::from_os_specific(args.back());
152
153 if (!_preferred_extension.empty() &&
154 ("." + filename.get_extension()) != _preferred_extension) {
155 // This argument must not be an output filename.
156 if (!_allow_stdout) {
157 nout << "Output filename " << filename
158 << " does not end in " << _preferred_extension
159 << ". If this is really what you intended, "
160 "use the -o output_file syntax.\n";
161 return false;
162 }
163
164 } else {
165 // This argument appears to be an output filename.
166 _got_output_filename = true;
167 _output_filename = filename;
168 args.pop_back();
169
170 if (!verify_output_file_safe()) {
171 return false;
172 }
173 }
174 }
175
176 return true;
177}
178
179/**
180 * This is called when the output file is given as the last parameter on the
181 * command line. Since this is a fairly dangerous way to specify the output
182 * file (it's easy to accidentally overwrite an input file this way), the
183 * convention is to disallow this syntax if the output file already exists.
184 *
185 * This function will test if the output file exists, and issue a warning
186 * message if it does, returning false. If all is well, it will return true.
187 */
188bool WithOutputFile::
189verify_output_file_safe() const {
190 nassertr(_got_output_filename, false);
191
192 if (_output_filename.exists()) {
193 nout << "The output filename " << _output_filename << " already exists. "
194 "If you wish to overwrite it, you must use the -o option to specify "
195 "the output filename, instead of simply specifying it as the last "
196 "parameter.\n";
197 return false;
198 }
199 return true;
200}
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
void set_binary()
Indicates that the filename represents a binary file.
Definition filename.I:414
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...
void set_text()
Indicates that the filename represents a text file.
Definition filename.I:424
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
std::string get_extension() const
Returns the file extension.
Definition filename.I:400
bool exists() const
Returns true if the filename exists on the physical disk, false otherwise.
Filename get_output_filename() const
If has_output_filename() returns true, this is the filename that the user specified.
void close_output()
Closes the output stream previously opened by get_output().
bool has_output_filename() const
Returns true if the user specified an output filename, false otherwise (e.g.
std::ostream & get_output()
Returns an output stream that corresponds to the user's intended egg file output–either stdout,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.