00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: mystdio.c,v 1.2 2007-01-13 12:23:40 sven Exp $";
00022 #endif
00023
00024 #include <Python.h>
00025 #include <structmember.h>
00026 #include <eggdrop/eggdrop.h>
00027
00028 #include "pythonscript.h"
00029
00030 #define Stdio_Check(op) PyObject_TypeCheck(op, &Stdio_Type)
00031
00032 typedef struct {
00033 PyObject_HEAD
00034 int softspace;
00035 unsigned Type;
00036 } StdioObject;
00037
00038 typedef struct {
00039 char *buf;
00040 unsigned bufsize;
00041 unsigned strlen;
00042 } tLineBuf;
00043
00044 static tLineBuf LineBuf[2];
00045
00046 partymember_t *LogTarget;
00047
00048 static PyObject *Stdio_New(PyTypeObject *Type, PyObject *args, PyObject *kwds) {
00049 unsigned IOtype;
00050 PyObject *Para;
00051 StdioObject *Stdio;
00052
00053 if (!PyArg_ParseTuple(args, "O", &Para)) return 0;
00054 if (Stdio_Check(Para)) {
00055 Stdio = (StdioObject *) Para;
00056 IOtype = Stdio->Type;
00057 } else if (PyInt_Check(Para)) {
00058 IOtype = PyInt_AsLong(Para) - 1;
00059 } else {
00060 PyErr_Format(PyExc_TypeError, "Expected eggdrop.stdio got %s", Para->ob_type->tp_name);
00061 return 0;
00062 }
00063 if (!(Stdio = (StdioObject *) Type->tp_alloc(Type, 0))) return 0;
00064 Stdio->softspace = 0;
00065 Stdio->Type = IOtype;
00066 return (PyObject *) Stdio;
00067 }
00068
00069 static void Log(int Target, const char *Text) {
00070 char *Prefix;
00071
00072 if (!Target) Prefix = "Python: %s";
00073 else Prefix = "Python Error: %s";
00074
00075 if (LogTarget) {
00076 partymember_printf(LogTarget, Prefix, Text);
00077 return;
00078 }
00079 putlog(LOG_MISC, "*", Prefix, Text);
00080 }
00081
00082 static size_t WriteLine(unsigned Target, char *Text, size_t len) {
00083 size_t written;
00084 char *newline;
00085
00086 newline = memchr(Text, '\n', len);
00087 if (!newline) return 0;
00088 written = newline - Text + 1;
00089 *newline = 0;
00090 if (written > 1 && newline[-1] == '\r') newline[-1] = 0;
00091 Log(Target, Text);
00092 return written;
00093 }
00094
00095 static void Write(int Target, const char *Text, int len) {
00096 int written;
00097 char *TextPtr;
00098 tLineBuf *Line = &LineBuf[Target];
00099
00100 if (Line->strlen + len > Line->bufsize) {
00101 Line->bufsize = ((Line->strlen + len) & ~0x3FF) + 1024;
00102 Line->buf = realloc(Line->buf, Line->bufsize);
00103 }
00104 memcpy(Line->buf + Line->strlen, Text, len);
00105 Line->strlen += len;
00106 TextPtr = Line->buf;
00107 while ((written = WriteLine(Target, TextPtr, Line->strlen))) {
00108 TextPtr += written;
00109 Line->strlen -= written;
00110 }
00111 if (Line->strlen) memmove(Line->buf, TextPtr, Line->strlen);
00112 if (Line->bufsize > 0x100000 && Line->strlen < 1024) {
00113 Line->bufsize = 1024;
00114 Line->buf = realloc(Line->buf, 1024);
00115 }
00116 }
00117
00118 void Flush(unsigned Target) {
00119 if (LineBuf[Target].strlen) Write(Target, "\n", 1);
00120 }
00121
00122 static PyObject *Stdio_Write(PyObject *self, PyObject *args) {
00123 int len;
00124 const char *Text;
00125 StdioObject *this = (StdioObject *) self;
00126
00127 if (!PyArg_ParseTuple(args, "s#", &Text, &len)) return 0;
00128 if (this->Type < 2) Write(this->Type, Text, len);
00129 Py_INCREF(Py_None);
00130 return Py_None;
00131 }
00132
00133 static PyObject *Stdio_Flush(PyObject *self, PyObject *args) {
00134 StdioObject *this = (StdioObject *) self;
00135
00136 if (this->Type < 2) Flush(this->Type);
00137 Py_INCREF(Py_None);
00138 return Py_None;
00139 }
00140
00141 static PyMemberDef Stdio_Members[] = {
00142 {"softspace", T_INT, offsetof(StdioObject, softspace), 0, "Has a documented use for print and an undocumented use for the interactive interpreter."},
00143 {0}
00144 };
00145
00146 static PyMethodDef Stdio_Methods[] = {
00147 {"write", Stdio_Write, METH_VARARGS, "Write some text"},
00148 {"flush", Stdio_Flush, METH_NOARGS, "Display the buffered content *now*"},
00149 {0}
00150 };
00151
00152 PyTypeObject Stdio_Type = {
00153 PyObject_HEAD_INIT(0)
00154 0,
00155 "eggdrop.stdio",
00156 sizeof(StdioObject),
00157 0,
00158 0,
00159 0,
00160 0,
00161 0,
00162 0,
00163 0,
00164 0,
00165 0,
00166 0,
00167 0,
00168 0,
00169 0,
00170 0,
00171 0,
00172 0,
00173 Py_TPFLAGS_DEFAULT |
00174 Py_TPFLAGS_BASETYPE,
00175 "handels logging and partyline output using sys.stdout and sys.stderr",
00176 0,
00177 0,
00178 0,
00179 0,
00180 0,
00181 0,
00182 Stdio_Methods,
00183 Stdio_Members,
00184 0,
00185 0,
00186 0,
00187 0,
00188 0,
00189 0,
00190 0,
00191 0,
00192 Stdio_New
00193 };