mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
here we go
This commit is contained in:
parent
e2bfd4c7ed
commit
e7660fd47c
@ -7,12 +7,13 @@
|
||||
executionEnvironment.I executionEnvironment.cxx \
|
||||
executionEnvironment.h filename.I filename.cxx filename.h \
|
||||
load_dso.cxx load_dso.h dSearchPath.I dSearchPath.cxx \
|
||||
dSearchPath.h pfstream.h vector_string.cxx vector_string.h \
|
||||
gnu_getopt.c gnu_getopt.h gnu_getopt1.c
|
||||
dSearchPath.h pfstream.h vector_string.cxx vector_string.h \
|
||||
gnu_getopt.c gnu_getopt.h gnu_getopt1.c pfstreamBuf.h pfstreamBuf.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
executionEnvironment.I executionEnvironment.h filename.I \
|
||||
filename.h load_dso.h dSearchPath.I dSearchPath.h \
|
||||
pfstream.h vector_string.h gnu_getopt.h
|
||||
pfstream.h pfstream.I vector_string.h gnu_getopt.h \
|
||||
pfstreamBuf.h
|
||||
|
||||
#end lib_target
|
||||
|
@ -6,87 +6,28 @@
|
||||
#ifndef __PFSTREAM_H__
|
||||
#define __PFSTREAM_H__
|
||||
|
||||
#include <dtoolbase.h>
|
||||
#include "pfstreambuf.h"
|
||||
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
class EXPCL_DTOOL ipfstream : public istream {
|
||||
PUBLISHED:
|
||||
INLINE ipfstream(const string);
|
||||
|
||||
#ifdef WIN32_VC
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#endif
|
||||
INLINE void flush(void);
|
||||
private:
|
||||
PipeStreamBuf _psb;
|
||||
|
||||
class EXPCL_DTOOL ipfstream {
|
||||
private:
|
||||
ifstream *ifs;
|
||||
FILE *fd;
|
||||
bool ok;
|
||||
|
||||
ipfstream() {}
|
||||
ipfstream(const ipfstream&) {}
|
||||
public:
|
||||
ipfstream(std::string cmd, int mode = ios::in, int = 0664) : ok(false) {
|
||||
#ifndef PENV_PS2
|
||||
fd = popen(cmd.c_str(), (mode & ios::in)?"r":"w");
|
||||
if (fd != (FILE *)0l) {
|
||||
// this can't work under windows until this is re-written
|
||||
#ifdef WIN32_VC
|
||||
cerr << "ipfstream: this class needs to be rewritten for windows!"
|
||||
<< endl;
|
||||
#else
|
||||
ifs = new ifstream(fileno(fd));
|
||||
#endif // WIN32_VC
|
||||
ok = true;
|
||||
}
|
||||
#endif // PENV_PS2
|
||||
}
|
||||
|
||||
~ipfstream() {
|
||||
#ifndef PENV_PS2
|
||||
if (ok) {
|
||||
pclose(fd);
|
||||
delete ifs;
|
||||
}
|
||||
#endif // PENV_PS2
|
||||
}
|
||||
|
||||
INLINE operator istream&() {
|
||||
return *ifs;
|
||||
}
|
||||
INLINE ipfstream(void);
|
||||
};
|
||||
|
||||
class EXPCL_DTOOL opfstream {
|
||||
private:
|
||||
ofstream *ofs;
|
||||
FILE *fd;
|
||||
bool ok;
|
||||
class EXPCL_DTOOL opfstream : public ostream {
|
||||
PUBLISHED:
|
||||
INLINE opfstream(const string);
|
||||
|
||||
opfstream() {}
|
||||
opfstream(const opfstream&) {}
|
||||
public:
|
||||
opfstream(std::string cmd, int mode = ios::out, int = 0664) : ok(false) {
|
||||
#ifndef PENV_PS2
|
||||
fd = popen(cmd.c_str(), (mode & ios::out)?"w":"r");
|
||||
if (fd != (FILE *)0L) {
|
||||
#ifndef WIN32_VC
|
||||
ofs = new ofstream(fileno(fd));
|
||||
#endif
|
||||
ok = true;
|
||||
}
|
||||
#endif // PENV_PS2
|
||||
}
|
||||
~opfstream() {
|
||||
#ifndef PENV_PS2
|
||||
if (ok) {
|
||||
pclose(fd);
|
||||
delete ofs;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
INLINE void flush(void);
|
||||
private:
|
||||
PipeStreamBuf _psb;
|
||||
|
||||
INLINE operator ostream&() {
|
||||
return *ofs;
|
||||
}
|
||||
INLINE opfstream(void);
|
||||
};
|
||||
|
||||
#endif /* __PFSTREAM_H__ */
|
||||
|
@ -4,32 +4,55 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pfstreamBuf.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef HAVE_STREAMSIZE
|
||||
// Some compilers (notably SGI) don't define this for us
|
||||
typedef int streamsize;
|
||||
#endif /* HAVE_STREAMSIZE */
|
||||
|
||||
PipeStreamBuf::PipeStreamBuf(void) {
|
||||
PipeStreamBuf::PipeStreamBuf(PipeStreamBuf::Direction dir) : _dir(dir),
|
||||
_pipe((FILE*)0L) {
|
||||
#ifndef WIN32_VC
|
||||
// taken from Dr. Ose.
|
||||
// These lines, which are essential on Irix and Linux, seem to be
|
||||
// unnecessary and not understood on Windows.
|
||||
allocate();
|
||||
setp(base(), ebuf());
|
||||
assert((dir == Input) || (dir == Output));
|
||||
if (dir == Input) {
|
||||
cerr << "allocated reserve is " << blen() << " bytes long" << endl;
|
||||
setg(base(), ebuf(), ebuf());
|
||||
} else {
|
||||
setp(base(), ebuf());
|
||||
}
|
||||
#endif /* WIN32_VC */
|
||||
}
|
||||
|
||||
PipeStreamBuf::~PipeStreamBuf(void) {
|
||||
sync();
|
||||
// any other cleanup needed (pclose, etc)
|
||||
if (_pipe != (FILE*)0L) {
|
||||
sync();
|
||||
flush();
|
||||
// any other cleanup needed (pclose, etc)
|
||||
pclose(_pipe);
|
||||
}
|
||||
}
|
||||
|
||||
void PipeStreamBuf::flush(void) {
|
||||
// if there's anything to do here
|
||||
assert(_pipe != (FILE*)0L);
|
||||
if (_dir == Output) {
|
||||
write_chars("", 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
void PipeStreamBuf::command(const string cmd) {
|
||||
assert(_pipe == (FILE*)0L);
|
||||
const char *typ = (_dir == Output)?"w":"r";
|
||||
_pipe = popen(cmd.c_str(), typ);
|
||||
}
|
||||
|
||||
int PipeStreamBuf::overflow(int c) {
|
||||
assert(_pipe != (FILE*)0L);
|
||||
assert(_dir == Output);
|
||||
streamsize n = pptr() - pbase();
|
||||
if (n != 0) {
|
||||
write_chars(pbase(), n, false);
|
||||
@ -44,11 +67,65 @@ int PipeStreamBuf::overflow(int c) {
|
||||
}
|
||||
|
||||
int PipeStreamBuf::sync(void) {
|
||||
streamsize n = pptr() - pbase();
|
||||
write_chars(pbase(), n, false);
|
||||
pbump(-n);
|
||||
assert(_pipe != (FILE*)0L);
|
||||
if (_dir == Output) {
|
||||
streamsize n = pptr() - pbase();
|
||||
write_chars(pbase(), n, false);
|
||||
pbump(-n);
|
||||
} else {
|
||||
streamsize n = egptr() - gptr();
|
||||
gbump(n); // flush all our stored input away
|
||||
cerr << "pfstream tossed out " << n << " bytes" << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PipeStreamBuf::underflow(void) {
|
||||
assert(_pipe != (FILE*)0L);
|
||||
assert(_dir == Input);
|
||||
if (gptr() < egptr()) {
|
||||
char c = *(gptr());
|
||||
return c;
|
||||
}
|
||||
if (feof(_pipe) != 0)
|
||||
return EOF;
|
||||
char* buf = new char[blen()];
|
||||
size_t n = fread(buf, 1, blen(), _pipe);
|
||||
int ret = buf[0];
|
||||
if (n == 0)
|
||||
ret = EOF;
|
||||
else {
|
||||
memcpy(base()+(blen() - n), buf, n);
|
||||
gbump(-n);
|
||||
}
|
||||
delete buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PipeStreamBuf::write_chars(const char* start, int length, bool flush) {
|
||||
assert(_dir == Output);
|
||||
size_t orig = _line_buffer.length();
|
||||
string latest(start, length);
|
||||
string line;
|
||||
|
||||
if (flush) {
|
||||
// if we're going to flush the stream now, we dump the whole thing
|
||||
// reguardless of whether we have reached end-of-line.
|
||||
line = _line_buffer + latest;
|
||||
_line_buffer = "";
|
||||
} else {
|
||||
// Otherwise, we check for the end-of-line character.
|
||||
_line_buffer += latest;
|
||||
size_t eol = _line_buffer.rfind('\n', orig);
|
||||
if (eol != string::npos) {
|
||||
line = _line_buffer.substr(0, eol+1);
|
||||
_line_buffer = _line_buffer.substr(eol+1);
|
||||
}
|
||||
}
|
||||
// now output 'line'
|
||||
size_t wrote = fwrite(line.c_str(), 1, line.length(), _pipe);
|
||||
if (wrote != line.length())
|
||||
cerr << "wrote only " << wrote << " of " << line.length()
|
||||
<< " bytes to pipe" << endl;
|
||||
fflush(_pipe);
|
||||
}
|
||||
|
@ -8,18 +8,33 @@
|
||||
|
||||
#include <dtoolbase.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
class EXPCL_PANDA PipeStreamBuf : public streambuf {
|
||||
#ifdef WIN32_VC
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#endif
|
||||
|
||||
class EXPCL_DTOOL PipeStreamBuf : public streambuf {
|
||||
public:
|
||||
PipeStreamBuf(void);
|
||||
enum Direction { Input, Output };
|
||||
|
||||
PipeStreamBuf(Direction);
|
||||
virtual ~PipeStreamBuf(void);
|
||||
|
||||
void flush();
|
||||
void command(const string);
|
||||
protected:
|
||||
virtual int overflow(int c);
|
||||
virtual int sync();
|
||||
virtual int underflow();
|
||||
virtual int sync(void);
|
||||
virtual int underflow(void);
|
||||
private:
|
||||
Direction _dir;
|
||||
string _line_buffer;
|
||||
FILE* _pipe;
|
||||
|
||||
void write_chars(const char*, int, bool);
|
||||
};
|
||||
|
||||
#endif /* __PFSTREAMBUF_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user