mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
add vfs->close_read_file() to work around compiler bug
This commit is contained in:
parent
62d58d924e
commit
86b7edace2
@ -808,28 +808,14 @@ load(const Filename& filename, size_t &size) const {
|
||||
istream *audioFile = NULL;
|
||||
|
||||
Filename binary_filename = Filename::binary_filename(filename);
|
||||
if (use_vfs) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
if (!vfs->exists(filename)) {
|
||||
audio_error("File " << filename << " does not exist.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audioFile = vfs->open_read_file(binary_filename);
|
||||
|
||||
} else {
|
||||
if (!filename.exists()) {
|
||||
audio_error("File " << filename << " does not exist.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audioFile = new ifstream;
|
||||
if (!binary_filename.open_read(*(ifstream *)audioFile)) {
|
||||
delete audioFile;
|
||||
audioFile = NULL;
|
||||
}
|
||||
if (!vfs->exists(filename)) {
|
||||
audio_error("File " << filename << " does not exist.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
audioFile = vfs->open_read_file(binary_filename);
|
||||
|
||||
if (audioFile == (istream *)NULL) {
|
||||
// Unable to open.
|
||||
@ -846,18 +832,18 @@ load(const Filename& filename, size_t &size) const {
|
||||
char *buffer = new char[size];
|
||||
if (buffer == NULL) {
|
||||
audio_error("out-of-memory error while loading "<<filename);
|
||||
delete audioFile;
|
||||
vfs->close_read_file(audioFile);
|
||||
return NULL;
|
||||
}
|
||||
audioFile->read(buffer, size);
|
||||
if (!(*audioFile)) {
|
||||
audio_error("Read error while loading "<<filename);
|
||||
delete audioFile;
|
||||
vfs->close_read_file(audioFile);
|
||||
delete [] buffer;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
delete audioFile;
|
||||
vfs->close_read_file(audioFile);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -787,7 +787,7 @@ vfs_close_callback(U32 file_handle) {
|
||||
return;
|
||||
}
|
||||
istream *istr = (istream *)file_handle;
|
||||
delete istr;
|
||||
vfs->close_read_file(istr);
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,7 +165,7 @@ will_close_connection() const {
|
||||
// Access: Public, Virtual
|
||||
// Description: Opens the document for reading. Returns a newly
|
||||
// allocated istream on success (which you should
|
||||
// eventually delete when you are done reading).
|
||||
// pass to close_read_file() when you are done reading).
|
||||
// Returns NULL on failure. This may only be called
|
||||
// once for a particular HTTPChannel.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -174,6 +174,31 @@ open_read_file() const {
|
||||
return ((HTTPChannel *)this)->read_body();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPChannel::close_read_file
|
||||
// Access: Public
|
||||
// Description: Closes a file opened by a previous call to
|
||||
// open_read_file(). This really just deletes the
|
||||
// istream pointer, but it is recommended to use this
|
||||
// interface instead of deleting it explicitly, to help
|
||||
// work around compiler issues.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void HTTPChannel::
|
||||
close_read_file(istream *stream) const {
|
||||
if (stream != (istream *)NULL) {
|
||||
// For some reason--compiler bug in gcc 3.2?--explicitly deleting
|
||||
// the stream pointer does not call the appropriate global delete
|
||||
// function; instead apparently calling the system delete
|
||||
// function. So we call the delete function by hand instead.
|
||||
#ifndef NDEBUG
|
||||
stream->~istream();
|
||||
(*global_operator_delete)(stream);
|
||||
#else
|
||||
delete stream;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: HTTPChannel::get_status_string
|
||||
// Access: Published
|
||||
|
@ -72,6 +72,7 @@ public:
|
||||
|
||||
virtual bool is_regular_file() const;
|
||||
virtual istream *open_read_file() const;
|
||||
void close_read_file(istream *stream) const;
|
||||
|
||||
bool will_close_connection() const;
|
||||
|
||||
|
@ -107,7 +107,7 @@ read(Filename filename, string display_name) {
|
||||
<< "Reading " << display_name << "\n";
|
||||
|
||||
bool read_ok = read(*file);
|
||||
delete file;
|
||||
vfs->close_read_file(file);
|
||||
return read_ok;
|
||||
|
||||
} else {
|
||||
|
@ -98,7 +98,7 @@ load_egg_file(const string &filename, CoordinateSystem cs) {
|
||||
return NULL;
|
||||
}
|
||||
okflag = loader._data.read(*istr);
|
||||
delete istr;
|
||||
vfs->close_read_file(istr);
|
||||
|
||||
if (!okflag) {
|
||||
egg2pg_cat.error()
|
||||
|
@ -200,7 +200,7 @@ hash_file(const Filename &filename) {
|
||||
count = istr->gcount();
|
||||
}
|
||||
|
||||
delete istr;
|
||||
vfs->close_read_file(istr);
|
||||
MD5_Final(md, &ctx);
|
||||
|
||||
// Store the individual bytes as big-endian ints, from historical
|
||||
|
@ -142,6 +142,11 @@ update_type_handle(TypeHandle &destination, TypeHandle refined) {
|
||||
|
||||
} else if (refined.is_derived_from(destination)) {
|
||||
// Updating with a more-specific type, no problem.
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
<< "Updating pointer " << (void *)_ref_ptr << " from type "
|
||||
<< destination << " to type " << refined << "\n";
|
||||
}
|
||||
destination = refined;
|
||||
|
||||
} else {
|
||||
|
@ -259,13 +259,18 @@ operator_new_handler(size_t size) {
|
||||
|
||||
if (_recursion_protect) {
|
||||
ptr = default_operator_new(size);
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
<< "Allocating pointer " << (void *)ptr
|
||||
<< " during recursion protect.\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
MemoryUsage *mu = get_global_ptr();
|
||||
if (mu->_track_memory_usage) {
|
||||
ptr = default_operator_new(size);
|
||||
get_global_ptr()->ns_record_void_pointer(ptr, size);
|
||||
|
||||
|
||||
} else {
|
||||
_is_cpp_operator = true;
|
||||
ptr = default_operator_new(size);
|
||||
@ -288,6 +293,11 @@ operator_new_handler(size_t size) {
|
||||
void MemoryUsage::
|
||||
operator_delete_handler(void *ptr) {
|
||||
if (_recursion_protect) {
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
<< "Deleting pointer " << (void *)ptr
|
||||
<< " during recursion protect.\n";
|
||||
}
|
||||
default_operator_delete(ptr);
|
||||
|
||||
} else {
|
||||
@ -605,6 +615,11 @@ ns_remove_pointer(ReferenceCount *ptr) {
|
||||
void MemoryUsage::
|
||||
ns_record_void_pointer(void *ptr, size_t size) {
|
||||
if (_track_memory_usage) {
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
<< "Recording void pointer " << (void *)ptr << "\n";
|
||||
}
|
||||
|
||||
// We have to protect modifications to the table from recursive
|
||||
// calls by toggling _recursion_protect while we adjust it.
|
||||
_recursion_protect = true;
|
||||
@ -654,6 +669,11 @@ ns_record_void_pointer(void *ptr, size_t size) {
|
||||
void MemoryUsage::
|
||||
ns_remove_void_pointer(void *ptr) {
|
||||
if (_track_memory_usage) {
|
||||
if (express_cat.is_spam()) {
|
||||
express_cat.spam()
|
||||
<< "Removing void pointer " << (void *)ptr << "\n";
|
||||
}
|
||||
|
||||
Table::iterator ti;
|
||||
ti = _table.find(ptr);
|
||||
if (ti == _table.end()) {
|
||||
@ -677,7 +697,8 @@ ns_remove_void_pointer(void *ptr) {
|
||||
|
||||
if ((info._flags & MemoryInfo::F_got_ref) != 0) {
|
||||
express_cat.error()
|
||||
<< "Pointer " << (void *)ptr << " did not destruct before being deleted!\n";
|
||||
<< "Pointer " << (void *)ptr
|
||||
<< " did not destruct before being deleted!\n";
|
||||
}
|
||||
|
||||
info._flags &= ~MemoryInfo::F_got_void;
|
||||
|
@ -163,6 +163,31 @@ open_read_file() const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFile::close_read_file
|
||||
// Access: Public
|
||||
// Description: Closes a file opened by a previous call to
|
||||
// open_read_file(). This really just deletes the
|
||||
// istream pointer, but it is recommended to use this
|
||||
// interface instead of deleting it explicitly, to help
|
||||
// work around compiler issues.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void VirtualFile::
|
||||
close_read_file(istream *stream) const {
|
||||
if (stream != (istream *)NULL) {
|
||||
// For some reason--compiler bug in gcc 3.2?--explicitly deleting
|
||||
// the stream pointer does not call the appropriate global delete
|
||||
// function; instead apparently calling the system delete
|
||||
// function. So we call the delete function by hand instead.
|
||||
#ifndef NDEBUG
|
||||
stream->~istream();
|
||||
(*global_operator_delete)(stream);
|
||||
#else
|
||||
delete stream;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFile::read_file
|
||||
// Access: Public
|
||||
@ -201,7 +226,7 @@ read_file(string &result) const {
|
||||
result.assign(&result_vec[0], result_vec.size());
|
||||
|
||||
bool failed = in->fail() && !in->eof();
|
||||
delete in;
|
||||
close_read_file(in);
|
||||
|
||||
if (failed) {
|
||||
express_cat.info()
|
||||
|
@ -54,6 +54,7 @@ PUBLISHED:
|
||||
|
||||
INLINE string read_file() const;
|
||||
virtual istream *open_read_file() const;
|
||||
void close_read_file(istream *stream) const;
|
||||
|
||||
public:
|
||||
bool read_file(string &result) const;
|
||||
|
@ -30,6 +30,31 @@ VirtualFileMount::
|
||||
~VirtualFileMount() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileMount::close_read_file
|
||||
// Access: Public
|
||||
// Description: Closes a file opened by a previous call to
|
||||
// open_read_file(). This really just deletes the
|
||||
// istream pointer, but it is recommended to use this
|
||||
// interface instead of deleting it explicitly, to help
|
||||
// work around compiler issues.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void VirtualFileMount::
|
||||
close_read_file(istream *stream) const {
|
||||
if (stream != (istream *)NULL) {
|
||||
// For some reason--compiler bug in gcc 3.2?--explicitly deleting
|
||||
// the stream pointer does not call the appropriate global delete
|
||||
// function; instead apparently calling the system delete
|
||||
// function. So we call the delete function by hand instead.
|
||||
#ifndef NDEBUG
|
||||
stream->~istream();
|
||||
(*global_operator_delete)(stream);
|
||||
#else
|
||||
delete stream;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileMount::output
|
||||
// Access: Public, Virtual
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
virtual bool is_regular_file(const Filename &file) const=0;
|
||||
|
||||
virtual istream *open_read_file(const Filename &file) const=0;
|
||||
void close_read_file(istream *stream) const;
|
||||
virtual bool scan_directory(vector_string &contents,
|
||||
const Filename &dir) const=0;
|
||||
|
||||
|
@ -72,7 +72,7 @@ open_read_file(const Filename &file) const {
|
||||
ifstream *stream = new ifstream;
|
||||
if (!pathname.open_read(*stream)) {
|
||||
// Couldn't open the file for some reason.
|
||||
delete stream;
|
||||
close_read_file(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -575,6 +575,31 @@ get_global_ptr() {
|
||||
return _global_ptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileSystem::close_read_file
|
||||
// Access: Published
|
||||
// Description: Closes a file opened by a previous call to
|
||||
// open_read_file(). This really just deletes the
|
||||
// istream pointer, but it is recommended to use this
|
||||
// interface instead of deleting it explicitly, to help
|
||||
// work around compiler issues.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void VirtualFileSystem::
|
||||
close_read_file(istream *stream) const {
|
||||
if (stream != (istream *)NULL) {
|
||||
// For some reason--compiler bug in gcc 3.2?--explicitly deleting
|
||||
// the stream pointer does not call the appropriate global delete
|
||||
// function; instead apparently calling the system delete
|
||||
// function. So we call the delete function by hand instead.
|
||||
#ifndef NDEBUG
|
||||
stream->~istream();
|
||||
(*global_operator_delete)(stream);
|
||||
#else
|
||||
delete stream;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VirtualFileSystem::scan_mount_points
|
||||
// Access: Public
|
||||
|
@ -84,6 +84,7 @@ PUBLISHED:
|
||||
|
||||
INLINE string read_file(const Filename &filename) const;
|
||||
INLINE istream *open_read_file(const Filename &filename) const;
|
||||
void close_read_file(istream *stream) const;
|
||||
|
||||
public:
|
||||
INLINE bool read_file(const Filename &filename, string &result) const;
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "pnmFileType.h"
|
||||
#include "pnmReader.h"
|
||||
#include "config_pnmimage.h"
|
||||
#include "config_express.h"
|
||||
#include "virtualFileSystem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -77,22 +76,9 @@ make_reader(const Filename &filename, PNMFileType *type) const {
|
||||
}
|
||||
|
||||
} else {
|
||||
if (use_vfs) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
owns_file = true;
|
||||
file = vfs->open_read_file(filename);
|
||||
|
||||
} else {
|
||||
ifstream *new_istream = new ifstream;
|
||||
Filename actual_name = Filename::binary_filename(filename);
|
||||
if (!actual_name.open_read(*new_istream)) {
|
||||
delete new_istream;
|
||||
|
||||
} else {
|
||||
owns_file = true;
|
||||
file = new_istream;
|
||||
}
|
||||
}
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
owns_file = true;
|
||||
file = vfs->open_read_file(filename);
|
||||
}
|
||||
|
||||
if (file == (istream *)NULL) {
|
||||
@ -147,7 +133,14 @@ make_reader(istream *file, bool owns_file, const Filename &filename,
|
||||
<< "Image file appears to be empty.\n";
|
||||
}
|
||||
if (owns_file) {
|
||||
delete file;
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
// We're assuming here that the file was opened via VFS. That
|
||||
// may not necessarily be the case, but we don't make that
|
||||
// distinction. However, at the moment at least, that
|
||||
// distinction doesn't matter, since vfs->close_read_file()
|
||||
// just deletes the file pointer anyway.
|
||||
vfs->close_read_file(file);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -204,14 +197,22 @@ make_reader(istream *file, bool owns_file, const Filename &filename,
|
||||
write_types(pnmimage_cat.error(false), 2);
|
||||
}
|
||||
if (owns_file) {
|
||||
delete file;
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
// We're assuming here that the file was opened via VFS. That
|
||||
// may not necessarily be the case, but we don't make that
|
||||
// distinction. However, at the moment at least, that
|
||||
// distinction doesn't matter, since vfs->close_read_file()
|
||||
// just deletes the file pointer anyway.
|
||||
vfs->close_read_file(file);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PNMReader *reader = type->make_reader(file, owns_file, magic_number);
|
||||
if (reader == NULL && owns_file) {
|
||||
delete file;
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->close_read_file(file);
|
||||
}
|
||||
|
||||
if (!reader->is_valid()) {
|
||||
|
@ -17,6 +17,7 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pnmReader.h"
|
||||
#include "virtualFileSystem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMReader::Destructor
|
||||
@ -26,7 +27,14 @@
|
||||
PNMReader::
|
||||
~PNMReader() {
|
||||
if (_owns_file) {
|
||||
delete _file;
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
|
||||
// We're assuming here that the file was opened via VFS. That
|
||||
// may not necessarily be the case, but we don't make that
|
||||
// distinction. However, at the moment at least, that
|
||||
// distinction doesn't matter, since vfs->close_read_file()
|
||||
// just deletes the file pointer anyway.
|
||||
vfs->close_read_file(_file);
|
||||
}
|
||||
_file = (istream *)NULL;
|
||||
}
|
||||
|
@ -86,7 +86,8 @@ void DatagramInputFile::
|
||||
close() {
|
||||
_in_file.close();
|
||||
if (_owns_in) {
|
||||
delete _in;
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->close_read_file(_in);
|
||||
}
|
||||
_in = (istream *)NULL;
|
||||
_owns_in = false;
|
||||
|
@ -47,61 +47,32 @@ load_prc_file(const string &filename) {
|
||||
|
||||
ConfigPageManager *cp_mgr = ConfigPageManager::get_global_ptr();
|
||||
|
||||
if (use_vfs) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->resolve_filename(path, cp_mgr->get_search_path()) ||
|
||||
vfs->resolve_filename(path, get_model_path());
|
||||
|
||||
istream *file = vfs->open_read_file(path);
|
||||
if (file == (istream *)NULL) {
|
||||
util_cat.error()
|
||||
<< "Unable to open " << path << "\n";
|
||||
return NULL;
|
||||
}
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
vfs->resolve_filename(path, cp_mgr->get_search_path()) ||
|
||||
vfs->resolve_filename(path, get_model_path());
|
||||
|
||||
istream *file = vfs->open_read_file(path);
|
||||
if (file == (istream *)NULL) {
|
||||
util_cat.error()
|
||||
<< "Unable to open " << path << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
util_cat.info()
|
||||
<< "Reading " << path << "\n";
|
||||
|
||||
ConfigPage *page = cp_mgr->make_explicit_page(path);
|
||||
bool read_ok = page->read_prc(*file);
|
||||
vfs->close_read_file(file);
|
||||
|
||||
if (read_ok) {
|
||||
return page;
|
||||
|
||||
util_cat.info()
|
||||
<< "Reading " << path << "\n";
|
||||
|
||||
ConfigPage *page = cp_mgr->make_explicit_page(path);
|
||||
bool read_ok = page->read_prc(*file);
|
||||
delete file;
|
||||
|
||||
if (read_ok) {
|
||||
return page;
|
||||
|
||||
} else {
|
||||
util_cat.info()
|
||||
<< "Unable to read " << path << "\n";
|
||||
cp_mgr->delete_explicit_page(page);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else {
|
||||
path.resolve_filename(cp_mgr->get_search_path()) ||
|
||||
path.resolve_filename(get_model_path());
|
||||
|
||||
ifstream file;
|
||||
if (!path.open_read(file)) {
|
||||
util_cat.error()
|
||||
<< "Unable to open " << path << "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
util_cat.info()
|
||||
<< "Reading " << path << "\n";
|
||||
|
||||
ConfigPage *page = cp_mgr->make_explicit_page(path);
|
||||
bool read_ok = page->read_prc(file);
|
||||
|
||||
if (read_ok) {
|
||||
return page;
|
||||
|
||||
} else {
|
||||
util_cat.info()
|
||||
<< "Unable to read " << path << "\n";
|
||||
cp_mgr->delete_explicit_page(page);
|
||||
return NULL;
|
||||
}
|
||||
<< "Unable to read " << path << "\n";
|
||||
cp_mgr->delete_explicit_page(page);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "config_xfile.h"
|
||||
#include "standard_templates.h"
|
||||
#include "zStream.h"
|
||||
#include "config_express.h"
|
||||
#include "virtualFileSystem.h"
|
||||
#include "dcast.h"
|
||||
|
||||
@ -81,32 +80,17 @@ clear() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool XFile::
|
||||
read(Filename filename) {
|
||||
ifstream in;
|
||||
|
||||
filename.set_text();
|
||||
if (use_vfs) {
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
istream *in = vfs->open_read_file(filename);
|
||||
if (in == (istream *)NULL) {
|
||||
xfile_cat.error()
|
||||
<< "Cannot open " << filename << " for reading.\n";
|
||||
return false;
|
||||
}
|
||||
bool okflag = read(*in, filename);
|
||||
delete in;
|
||||
return okflag;
|
||||
|
||||
} else {
|
||||
filename.open_read(in);
|
||||
|
||||
if (!in) {
|
||||
xfile_cat.error()
|
||||
<< "Cannot open " << filename << " for reading.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
return read(in, filename);
|
||||
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
|
||||
istream *in = vfs->open_read_file(filename);
|
||||
if (in == (istream *)NULL) {
|
||||
xfile_cat.error()
|
||||
<< "Cannot open " << filename << " for reading.\n";
|
||||
return false;
|
||||
}
|
||||
bool okflag = read(*in, filename);
|
||||
vfs->close_read_file(in);
|
||||
return okflag;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
x
Reference in New Issue
Block a user