summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2005-02-15 10:23:29 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 02:41:01 -0400
commit7dea4f2c80d910c29683b4699d2e02ea7d0629b9 (patch)
treea7acbbb18ff7f5d5fdb8bc689ac02ebc73ac20e4
parent11dc5b17d8b0bdfa6321adb771b8329290ddc139 (diff)
downloadfork-ledger-7dea4f2c80d910c29683b4699d2e02ea7d0629b9.tar.gz
fork-ledger-7dea4f2c80d910c29683b4699d2e02ea7d0629b9.tar.bz2
fork-ledger-7dea4f2c80d910c29683b4699d2e02ea7d0629b9.zip
*** empty log message ***
-rw-r--r--emacs.py53
-rw-r--r--pyfstream.h142
2 files changed, 142 insertions, 53 deletions
diff --git a/emacs.py b/emacs.py
deleted file mode 100644
index 3398ec9c..00000000
--- a/emacs.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import sys
-
-from ledger import *
-
-def emacs_date (seconds):
- return "(%d %d %d)" % (seconds / 65536, seconds % 65536, 0)
-
-class EmacsFormatTransactions (TransactionHandler):
- last_entry = None
- output = None
-
- def __init__ (self):
- self.last_entry = None
-
- if config.output_file:
- self.output = open (config.output_file, "w")
- else:
- self.output = sys.stdout
-
- TransactionHandler.__init__ (self)
-
- def __del__ (self):
- if config.output_file:
- self.output.close ()
-
- def flush (self):
- self.output.write ("))\n")
- self.output.flush ()
-
- def write_entry (self, entry):
- self.output.write("%s %s %s %s\n" %
- (emacs_date (entry.date),
- (entry.state and "t") or "nil",
- (entry.code and "\"%s\"" % entry.code) or "nil",
- (entry.payee and "\"%s\"" % entry.payee) or "nil"))
-
- def __call__ (self, xact):
- if not transaction_has_xdata (xact) or \
- not transaction_xdata (xact).dflags & TRANSACTION_DISPLAYED:
- if self.last_entry is None:
- self.output.write("((")
- self.write_entry (xact.entry)
- elif xact.entry != self.last_entry:
- self.output.write(")\n (")
- self.write_entry (xact.entry)
- else:
- self.output.write("\n")
- self.output.write(" (\"%s\" \"%s\"%s%s)" %
- (xact.account.fullname (), xact.amount,
- (xact.cost and " \"%s\"" % xact.cost) or "",
- (xact.note and " \"%s\"" % xact.note) or ""))
- self.last_entry = xact.entry
- transaction_xdata (xact).dflags |= TRANSACTION_DISPLAYED
diff --git a/pyfstream.h b/pyfstream.h
new file mode 100644
index 00000000..e10b5bd5
--- /dev/null
+++ b/pyfstream.h
@@ -0,0 +1,142 @@
+#ifndef _PYFSTREAM_H
+#define _PYFSTREAM_H
+
+#include <istream>
+#include <ostream>
+#include <streambuf>
+#include <cstdio>
+#include <cstring>
+
+#include "Python.h"
+
+// pyofstream
+// - a stream that writes on a Python file object
+
+class pyoutbuf : public std::streambuf {
+ protected:
+ PyFileObject * fo; // Python file object
+ public:
+ // constructor
+ pyoutbuf (PyFileObject * _fo) : fo(_fo) {}
+
+ protected:
+ // write one character
+ virtual int_type overflow (int_type c) {
+ if (c != EOF) {
+ char z[2];
+ z[0] = c;
+ z[1] = '\0';
+ if (PyFile_WriteString(z, (PyObject *)fo) < 0) {
+ return EOF;
+ }
+ }
+ return c;
+ }
+
+ // write multiple characters
+ virtual std::streamsize xsputn (const char* s, std::streamsize num) {
+ if (PyFile_WriteString(s, (PyObject *)fo) < 0)
+ return 0;
+ return num;
+ }
+};
+
+class pyofstream : public std::ostream {
+ protected:
+ pyoutbuf buf;
+ public:
+ pyofstream (PyFileObject * fo) : std::ostream(0), buf(fo) {
+ rdbuf(&buf);
+ }
+};
+
+// pyifstream
+// - a stream that reads on a file descriptor
+
+class pyinbuf : public std::streambuf {
+ protected:
+ PyFileObject * fo; // Python file object
+ protected:
+ /* data buffer:
+ * - at most, pbSize characters in putback area plus
+ * - at most, bufSize characters in ordinary read buffer
+ */
+ static const int pbSize = 4; // size of putback area
+ static const int bufSize = 1024; // size of the data buffer
+ char buffer[bufSize + pbSize]; // data buffer
+
+ public:
+ /* constructor
+ * - initialize file descriptor
+ * - initialize empty data buffer
+ * - no putback area
+ * => force underflow()
+ */
+ pyinbuf (PyFileObject * _fo) : fo(_fo) {
+ setg (buffer+pbSize, // beginning of putback area
+ buffer+pbSize, // read position
+ buffer+pbSize); // end position
+ }
+
+ protected:
+ // insert new characters into the buffer
+ virtual int_type underflow () {
+#ifndef _MSC_VER
+ using std::memmove;
+#endif
+
+ // is read position before end of buffer?
+ if (gptr() < egptr()) {
+ return traits_type::to_int_type(*gptr());
+ }
+
+ /* process size of putback area
+ * - use number of characters read
+ * - but at most size of putback area
+ */
+ int numPutback;
+ numPutback = gptr() - eback();
+ if (numPutback > pbSize) {
+ numPutback = pbSize;
+ }
+
+ /* copy up to pbSize characters previously read into
+ * the putback area
+ */
+ memmove (buffer+(pbSize-numPutback), gptr()-numPutback,
+ numPutback);
+
+ // read at most bufSize new characters
+ int num;
+ PyObject *line = PyFile_GetLine((PyObject *)fo, bufSize);
+ if (! line || ! PyString_Check(line)) {
+ // ERROR or EOF
+ return EOF;
+ }
+
+ num = PyString_Size(line);
+ if (num == 0)
+ return EOF;
+
+ memmove (buffer+pbSize, PyString_AsString(line), num);
+
+ // reset buffer pointers
+ setg (buffer+(pbSize-numPutback), // beginning of putback area
+ buffer+pbSize, // read position
+ buffer+pbSize+num); // end of buffer
+
+ // return next character
+ return traits_type::to_int_type(*gptr());
+ }
+};
+
+class pyifstream : public std::istream {
+ protected:
+ pyinbuf buf;
+ public:
+ pyifstream (PyFileObject * fo) : std::istream(0), buf(fo) {
+ rdbuf(&buf);
+ }
+};
+
+#endif // _PYFSTREAM_H