modules/pythonscript/pythonscript.c File Reference

#include <Python.h>
#include <structmember.h>
#include <eggdrop/eggdrop.h>
#include "pythonscript.h"

Go to the source code of this file.

Functions

static int my_load_script (void *ignore, char *fname)
static int my_link_var (void *ignore, script_linked_var_t *var)
static int my_unlink_var (void *ignore, script_linked_var_t *var)
static int my_create_command (void *ignore, script_raw_command_t *info)
static int my_delete_command (void *ignore, script_raw_command_t *info)
static int my_get_arg (void *ignore, script_args_t *args, int num, script_var_t *var, int type)
static int my_python_cb_delete (event_owner_t *owner, void *client_data)
static event_owner_tGetContext ()
static int my_python_callbacker (script_callback_t *me,...)
PyObject * c_to_python_var (script_var_t *v)
int python_to_c_var (PyObject *obj, script_var_t *var, int type)
static int mls (partymember_t *p, char *nick, user_t *u, char *cmd, char *text)
static int party_python (partymember_t *p, char *nick, user_t *u, char *cmd, char *text)
static int Cleanup (void *client_data, script_args_t *args, script_var_t *retval)
static PyObject * Help (PyObject *self, PyObject *Args)
static int pythonscript_close (int why)
static void pythonscript_unload (void)
EXPORT_SCOPE int pythonscript_LTX_start (egg_module_t *modinfo)

Variables

static const char rcsid [] = "$Id: pythonscript.c,v 1.6 2008-10-17 15:57:42 sven Exp $"
script_module_t my_script_interface
static egg_module_tpython_modinfo
static int python_owners = 0
static event_owner_tpython_owner = 0
static PyObject * SysPath
static PyObject * SysModules
static PyObject * CommonModule
static PyObject * PartylineModule
static PyObject * PartylineDict
static PyObject * RealHelper
static PyObject * SysMod
static PyObject * MinInt
static PyObject * MaxInt
static PyObject * MinUInt
static PyObject * MaxUInt
static event_owner_tCurrentContext
static char * CurrentContextString
static PyMethodDef HelpMethod
static bind_list_t party_commands []
static PyMethodDef * methods


Function Documentation

PyObject* c_to_python_var ( script_var_t v  ) 

Definition at line 293 of file pythonscript.c.

References byte_array_b::bytes, c_to_python_var(), byte_array_b::do_free, Egguser_Type, byte_array_b::len, script_var_b::len, NULL, SCRIPT_ARRAY, SCRIPT_BYTES, SCRIPT_FREE, SCRIPT_FREE_VAR, SCRIPT_INTEGER, SCRIPT_PARTIER, SCRIPT_POINTER, SCRIPT_STRING, SCRIPT_STRING_LIST, SCRIPT_TYPE_MASK, SCRIPT_UNSIGNED, SCRIPT_USER, SCRIPT_VAR, script_var_b::type, EgguserObject::user, and script_var_b::value.

Referenced by c_to_python_var(), Get(), GetFlags(), GetIrcMasks(), GetVar(), my_command_handler(), and my_python_callbacker().

00293                                            {
00294   PyObject *result;
00295 
00296   result = NULL;
00297   /* If it's an array, we call ourselves recursively. */
00298   if (v->type & SCRIPT_ARRAY) {
00299     PyObject *element;
00300     int i;
00301 
00302     result = PyTuple_New(v->len);
00303     /* If it's an array of script_var_t's, then it's easy. */
00304     if ((v->type & SCRIPT_TYPE_MASK) == SCRIPT_VAR) {
00305       script_var_t **v_list;
00306 
00307       v_list = (script_var_t **)v->value;
00308       for (i = 0; i < v->len; i++) {
00309         element = c_to_python_var(v_list[i]);
00310         if (!element) {
00311           Py_DECREF(result);
00312           return 0;
00313         }
00314         PyTuple_SET_ITEM(result, i, element);
00315       }
00316     }
00317     else {
00318       /* Otherwise, we have to turn them into fake script_var_t's. */
00319       script_var_t v_sub;
00320       void **values;
00321 
00322       values = (void **)v->value;
00323       for (i = 0; i < v->len; i++) {
00324         v_sub.type = v->type & (~SCRIPT_ARRAY);
00325         v_sub.value = values[i];
00326         v_sub.len = -1;
00327         element = c_to_python_var(&v_sub);
00328         if (!element) {
00329           Py_DECREF(result);
00330           return 0;
00331         }
00332         PyTuple_SET_ITEM(result, i, element);
00333       }
00334     }
00335     /* Whew */
00336     if (v->type & SCRIPT_FREE) free(v->value);
00337     if (v->type & SCRIPT_FREE_VAR) free(v);
00338     return result;
00339   }
00340 
00341   /* Here is where we handle the basic types. */
00342   switch (v->type & SCRIPT_TYPE_MASK) {
00343     case SCRIPT_INTEGER:
00344       result = PyInt_FromLong((int) v->value);
00345       break;
00346     case SCRIPT_UNSIGNED:
00347       /* Python has no "unsigned" type. A Python "int" is a C "long".
00348        * So, if sizeof(int) == sizeof(long) like on IA32 a Python "int"
00349        * might be too short to store a C "unsigned".
00350        * Use a Python "long" in that case */
00351       if ((unsigned) v->value <= PyInt_GetMax()) {
00352         result = PyInt_FromLong((unsigned) v->value);
00353       } else {
00354         result = PyLong_FromUnsignedLong((unsigned) v->value);
00355       }
00356       break;
00357     case SCRIPT_STRING: {
00358       char *str = v->value;
00359 
00360       if (!str) str = "";
00361       if (v->len == -1) v->len = strlen(str);
00362       result = PyString_FromStringAndSize(str, v->len);
00363       if (v->value && v->type & SCRIPT_FREE) free(v->value);
00364       break;
00365     }
00366     case SCRIPT_STRING_LIST: {
00367       char **str = v->value;
00368       PyObject *element;
00369 
00370       result = PyList_New(0);
00371       for (str = v->value; str && *str; ++str) {
00372         element = PyString_FromString(*str);
00373         PyList_Append(result, element);
00374       }
00375       break;
00376     }
00377     case SCRIPT_BYTES: {
00378       byte_array_t *bytes = v->value;
00379       result = PyString_FromStringAndSize(bytes->bytes, bytes->len);
00380       if (bytes->do_free) free(bytes->bytes);
00381       if (v->type & SCRIPT_FREE) free(bytes);
00382       break;
00383     }
00384 #if 0
00385     case SCRIPT_POINTER: {
00386       char str[32];
00387 
00388       sprintf(str, "#%u", (unsigned int) v->value);
00389       result = Tcl_NewStringObj(str, -1);
00390       break;
00391     }
00392     case SCRIPT_PARTIER: {
00393       partymember_t *p = v->value;
00394       int pid;
00395 
00396       if (p) pid = p->pid;
00397       else pid = -1;
00398       result = Tcl_NewIntObj(pid);
00399       break;
00400     }
00401 #endif
00402     case SCRIPT_USER: {
00403       /* An eggdrop user record (struct userrec *). */
00404       user_t *u = v->value;
00405 
00406       if (u) {
00407         EgguserObject *O = (EgguserObject *) Egguser_Type.tp_new(&Egguser_Type, 0, 0);
00408         O->user = u;
00409         result = (PyObject *) O;
00410       } else {
00411         Py_INCREF(Py_None);
00412         result = Py_None;
00413       }
00414       break;
00415     }
00416     default:
00417       /* Default: just "None". */
00418       Py_INCREF(Py_None);
00419       result = Py_None;
00420   }
00421   if (v->type & SCRIPT_FREE_VAR) free(v);
00422   return result;
00423 }

static int Cleanup ( void *  client_data,
script_args_t args,
script_var_t retval 
) [static]

Definition at line 586 of file pythonscript.c.

References event_owner_b::client_data, GetContext(), script_args_b::len, SCRIPT_ERROR, SCRIPT_INTEGER, script_remove_events_by_owner(), SCRIPT_STRING, script_var_b::type, and script_var_b::value.

Referenced by pythonscript_LTX_start().

00586                                                                                   {
00587   if (args->len) {
00588     retval->type = SCRIPT_ERROR | SCRIPT_STRING;
00589     retval->value = "This function does not accept any parameters.";
00590     return 0;
00591   }
00592   retval->type = SCRIPT_INTEGER;
00593   retval->value = (void *) script_remove_events_by_owner(python_modinfo, GetContext()->client_data);
00594   return 0;
00595 }

static event_owner_t* GetContext (  )  [static]

Definition at line 62 of file pythonscript.c.

References event_owner_b::client_data, CurrentContextString, event_owner_b::module, my_python_cb_delete(), event_owner_b::name, event_owner_b::on_delete, python_owners, event_owner_b::script, and SysModules.

Referenced by Cleanup(), and python_to_c_var().

00063 {
00064   PyObject *Mod;
00065 
00066   if (CurrentContext) return CurrentContext;
00067   if (!(python_owners & 7)) python_owner = realloc(python_owner, (python_owners + 8) * sizeof(*python_owner));
00068 
00069   Mod = PyDict_GetItemString(SysModules, CurrentContextString); /* Borrowed reference */
00070   Py_INCREF(Mod);
00071 
00072   python_owner[python_owners].name = "pythonscript";
00073   python_owner[python_owners].module = python_modinfo;
00074   python_owner[python_owners].script = strdup(CurrentContextString);
00075   python_owner[python_owners].client_data = Mod;
00076   python_owner[python_owners].on_delete = my_python_cb_delete;
00077   CurrentContext = &python_owner[python_owners++];
00078   return CurrentContext;
00079 }

static PyObject* Help ( PyObject *  self,
PyObject *  Args 
) [static]

Definition at line 597 of file pythonscript.c.

References Callable_Check, FlushAll, RealHelper, SysMod, and Write().

00597                                                       {
00598   PyObject *O = 0, *Stdout, *Write, *DocStr, *HelpStr;
00599 
00600   PyArg_ParseTuple(Args, "|O", &O);
00601   if (!O || !Callable_Check(O)) return PyObject_CallObject(RealHelper, Args);
00602   Stdout = PyObject_GetAttrString(SysMod, "stdout");
00603   if (!Stdout || !(Write = PyObject_GetAttrString(Stdout, "write"))) return 0;
00604   Py_DECREF(Stdout);
00605   DocStr = PyObject_GetAttrString(O, "__doc__");
00606   if (!(HelpStr = Py_BuildValue("(O)", DocStr))) {
00607     Py_DECREF(Write);
00608     return 0;
00609   }
00610   Py_DECREF(DocStr);
00611   PyObject_CallObject(Write, HelpStr);
00612   Py_DECREF(HelpStr);
00613   FlushAll();
00614   Py_INCREF(Py_None);
00615   return Py_None;
00616 }

static int mls ( partymember_t p,
char *  nick,
user_t u,
char *  cmd,
char *  text 
) [static]

Definition at line 555 of file pythonscript.c.

References LogTarget, and my_load_script().

00555                                                                                {
00556   LogTarget = p;
00557   my_load_script(0, text);
00558   LogTarget = 0;
00559   return 0;
00560 }

static int my_create_command ( void *  ignore,
script_raw_command_t info 
) [static]

Definition at line 255 of file pythonscript.c.

References Callable_Type, script_raw_command_t::class, CallableObject::client_data, egg_mprintf(), EggdropModule, FlushAll, script_raw_command_t::name, PYTHON_FUNC, and CallableObject::type.

00255                                                                        {
00256   char *cmdname;
00257   CallableObject *O = PyObject_New(CallableObject, &Callable_Type);
00258 
00259   if (info->class && strlen(info->class)) {
00260     cmdname = egg_mprintf("%s_%s", info->class, info->name);
00261   }
00262   else {
00263     cmdname = strdup(info->name);
00264   }
00265   O->type = PYTHON_FUNC;
00266   O->client_data = info;
00267   if (PyModule_AddObject(EggdropModule, cmdname, (PyObject *)O)) {
00268     free(cmdname);
00269     PyErr_Print();
00270     FlushAll();
00271     return 1;
00272   }
00273   free(cmdname);
00274   return 0;
00275 }

static int my_delete_command ( void *  ignore,
script_raw_command_t info 
) [static]

Definition at line 278 of file pythonscript.c.

References CallableObject::client_data, EggdropModule, and script_raw_command_t::name.

00279 {
00280   PyObject *Dict = *_PyObject_GetDictPtr(EggdropModule);
00281   CallableObject *Callable;
00282 
00283   Callable = (CallableObject *) PyDict_GetItemString(Dict, info->name);
00284                            /* Warning! Borrowed reference */
00285   if (!Callable) return 0;                   /* It never existed, that's the same as deleting it */
00286   Callable->client_data = 0;
00287   PyDict_DelItemString(Dict, info->name);
00288   return 0;
00289 }

static int my_get_arg ( void *  ignore,
script_args_t args,
int  num,
script_var_t var,
int  type 
) [static]

Definition at line 541 of file pythonscript.c.

References script_args_b::client_data, and python_to_c_var().

00541                                                                                                {
00542   PyObject *ParameterTuple, *Parameter;
00543 
00544   ParameterTuple = args->client_data;
00545   Parameter = PyTuple_GetItem(ParameterTuple, num);
00546   if (!Parameter) {
00547     // XXX: write some kind of error log?
00548     PyErr_Clear();
00549     return 1;
00550   }
00551 
00552   return python_to_c_var(Parameter, var, type);
00553 }

static int my_link_var ( void *  ignore,
script_linked_var_t var 
) [static]

Definition at line 153 of file pythonscript.c.

References Callable_Type, script_linked_var_b::class, CallableObject::client_data, egg_mprintf(), EggdropModule, FlushAll, script_linked_var_b::name, PYTHON_VAR, and CallableObject::type.

00153                                                                {
00154   CallableObject *O;
00155   char *cmdname;
00156 
00157   O = PyObject_New(CallableObject, &Callable_Type);       /* new reference */
00158   if (!O) {
00159     PyErr_Print();
00160     FlushAll();
00161     return -1;
00162   }
00163 
00164   if (var->class && strlen(var->class)) {
00165     cmdname = egg_mprintf("%s_%s", var->class, var->name);
00166   }
00167   else {
00168     cmdname = strdup(var->name);
00169   }
00170   O->type = PYTHON_VAR;
00171   O->client_data = var;
00172   PyModule_AddObject(EggdropModule, cmdname, (PyObject *) O); /* EggdropModule steals a reference to O */
00173   free(cmdname);
00174   return 0;
00175 }

static int my_load_script ( void *  ignore,
char *  fname 
) [static]

Definition at line 82 of file pythonscript.c.

References CommonModule, CurrentContextString, FlushAll, python_owners, SCRIPT_ERR_CODE, SCRIPT_ERR_NOT_RESPONSIBLE, SCRIPT_OK, and SysPath.

00083 {
00084   int len, i;
00085   char *fullname, *name, *path;
00086   PyObject *PathString, *CommonDict, *NewMod;
00087 
00088   /* Check the filename and make sure it ends in .py */
00089   len = strlen(fname);
00090   if (len < 4 || fname[len-1] != 'y' || fname[len-2] != 'p' || fname[len-3] != '.') {
00091     /* Nope, let someone else load it. */
00092     return SCRIPT_ERR_NOT_RESPONSIBLE;
00093   }
00094   fullname = strdup(fname);
00095   name = rindex(fullname, '/');
00096   if (!name) {
00097     name = fullname;
00098     path = "";
00099   } else {
00100     *name++ = 0;
00101     path = fullname;
00102   }
00103   name[strlen(name) - 3] = 0;
00104 
00105   for (i = 1; i < python_owners; ++i) {
00106     if (!strcmp(python_owner[i].script, name)) {
00107       CurrentContext = &python_owner[i];
00108       if (!PyImport_ReloadModule(python_owner[i].client_data)) {
00109         PyErr_Print();
00110         FlushAll();
00111         free(fullname);
00112         CurrentContext = 0;
00113         return SCRIPT_ERR_CODE;
00114       }
00115       CurrentContext = 0;
00116       return SCRIPT_OK;
00117     }
00118   }
00119   
00120   CurrentContext = 0;
00121   CurrentContextString = name;
00122   PathString = PyString_FromString(path);
00123   PyList_Insert(SysPath, 0, PathString);
00124   Py_DECREF(PathString);
00125   if (!(NewMod = PyImport_ImportModule(name))) {
00126     PyErr_Print();
00127     FlushAll();
00128     free(fullname);
00129     CurrentContextString = 0;
00130     return SCRIPT_ERR_CODE;
00131   }
00132 
00133   CommonDict = PyObject_GetAttrString(CommonModule, name);
00134   if (!CommonDict) {
00135     PyErr_Clear();
00136     CommonDict = PyDict_New();
00137     PyModule_AddObject(CommonModule, name, CommonDict);   /* CommonModule steals a reference to CommonDict */
00138   } else {
00139     Py_DECREF(CommonDict);
00140   }
00141   PyDict_SetItemString(CommonDict, "module", NewMod);
00142   /* XXX: We just leaked a reference to the new module.
00143    * I guess we should save this to do something with it at
00144    * a later time but i don't have a solid idea, what ... */
00145   PyList_SetSlice(SysPath, 0, 0, 0);
00146   free(fullname);
00147   CurrentContextString = 0;
00148   CurrentContext = 0;
00149   return SCRIPT_OK;
00150 }

static int my_python_callbacker ( script_callback_t me,
  ... 
) [static]

Definition at line 192 of file pythonscript.c.

References c_to_python_var(), script_callback_b::callback_data, cmd, FlushAll, script_var_b::len, script_callback_b::owner, SCRIPT_INTEGER, SCRIPT_UNSIGNED, script_callback_b::syntax, script_var_b::type, and script_var_b::value.

Referenced by python_to_c_var().

00193 {
00194   script_var_t var;
00195   int i, n, retval;
00196   PyObject *cmd, *param, *arg, *RetObj;
00197   va_list va;
00198 
00199   cmd = me->callback_data;
00200 
00201   if (me->syntax) n = strlen(me->syntax);
00202   else n = 0;
00203 
00204   if (n) param = PyTuple_New(n);
00205   else param = 0;
00206 
00207   va_start(va, me);
00208   for (i = 0; i < n; i++) {
00209     var.type = me->syntax[i];
00210     if (var.type == SCRIPT_UNSIGNED || var.type == SCRIPT_INTEGER) var.value = (void *) (va_arg(va, int));
00211     else var.value = va_arg(va, void *);
00212     var.len = -1;
00213     arg = c_to_python_var(&var);       /* New reference */
00214     if (!arg) {
00215       Py_DECREF(param);
00216       PyErr_Print();
00217       FlushAll();
00218       return 0;
00219     }
00220     PyTuple_SET_ITEM(param, i, arg);   /* param steals the reference from arg */
00221   }
00222   va_end(va);
00223 
00224   CurrentContext = me->owner;
00225   RetObj = PyObject_CallObject(cmd, param);
00226   FlushAll();
00227   CurrentContext = 0;
00228 
00229   if (!RetObj) {
00230     PyErr_Print();
00231     FlushAll();
00232     return 0;
00233   }
00234   if (PyInt_Check(RetObj)) retval = PyInt_AS_LONG(RetObj);
00235   else retval = !PyObject_Not(RetObj);
00236   
00237   Py_DECREF(RetObj);
00238 
00239   return retval;
00240 }

static int my_python_cb_delete ( event_owner_t owner,
void *  client_data 
) [static]

Definition at line 243 of file pythonscript.c.

References script_callback_b::callback_data, script_callback_b::name, and script_callback_b::syntax.

Referenced by GetContext(), and pythonscript_LTX_start().

00243                                                                         {
00244   script_callback_t *me = client_data;
00245   PyObject *Callback = me->callback_data;
00246 
00247   Py_DECREF(Callback);
00248   if (me->syntax) free(me->syntax);
00249   if (me->name) free(me->name);
00250   free(me);
00251   return 0;
00252 }

static int my_unlink_var ( void *  ignore,
script_linked_var_t var 
) [static]

Definition at line 178 of file pythonscript.c.

References CallableObject::client_data, EggdropModule, and script_linked_var_b::name.

00178                                                                  {
00179   PyObject *Dict = *_PyObject_GetDictPtr(EggdropModule);
00180   CallableObject *Callable;
00181 
00182   Callable = (CallableObject *) PyDict_GetItemString(Dict, var->name); /* Warning! Borrowed reference */
00183   if (!Callable) return 0;                   /* It never existed, that's the same as deleting it */
00184   Callable->client_data = 0;
00185   PyDict_DelItemString(Dict, var->name);
00186   /* at this point the Callable object might (should!) be gone. Don't try to access it */
00187   return 0;
00188 }

static int party_python ( partymember_t p,
char *  nick,
user_t u,
char *  cmd,
char *  text 
) [static]

Definition at line 562 of file pythonscript.c.

References _, BIND_RET_LOG, egg_isowner(), FlushAll, user::handle, LogTarget, PartylineDict, and partymember_write().

00563 {
00564   PyObject *ret;
00565 
00566   if (!u || !egg_isowner(u->handle)) {
00567     partymember_write(p, _("You must be a permanent owner (defined in the config file) to use this command.\n"), -1);
00568     return BIND_RET_LOG;
00569   }
00570 
00571   if (!text) {
00572     partymember_write(p, _("Syntax: .python <pythonexpression>"), -1);
00573     return 0;
00574   }
00575 
00576   CurrentContext = python_owner;
00577   LogTarget = p;
00578   ret = PyRun_String(text, Py_single_input, PartylineDict, PartylineDict);
00579   CurrentContext = 0;
00580   if (!ret) PyErr_Print();
00581   FlushAll();
00582   LogTarget = 0;
00583   return 0;
00584 }

int python_to_c_var ( PyObject *  obj,
script_var_t var,
int  type 
)

Definition at line 429 of file pythonscript.c.

References byte_array_b::bytes, script_callback_b::callback, script_callback_b::callback_data, script_callback_b::delete_data, Egguser_Check, user::flags, script_callback_b::flags, GetContext(), byte_array_b::len, script_var_b::len, MaxInt, MaxUInt, MinInt, MinUInt, my_python_callbacker(), script_callback_b::name, NULL, script_callback_b::owner, SCRIPT_BYTES, SCRIPT_CALLBACK, SCRIPT_FREE, SCRIPT_INTEGER, SCRIPT_PARTIER, SCRIPT_STRING, SCRIPT_TYPE_MASK, SCRIPT_UNSIGNED, SCRIPT_USER, script_callback_b::syntax, script_var_b::type, EgguserObject::user, USER_DELETED, and script_var_b::value.

Referenced by my_get_arg(), and SetVar().

00429                                                                 {
00430   var->type = type;
00431   var->len = -1;
00432   var->value = 0;
00433 
00434   switch (type & SCRIPT_TYPE_MASK) {
00435     case SCRIPT_STRING: {
00436       char *Str;
00437 
00438       Str = PyString_AsString(obj);
00439       if (!Str) return 1;
00440       var->value = strdup(Str);
00441       var->len = strlen(var->value);
00442       return 0;
00443     }
00444     case SCRIPT_CALLBACK: {
00445       script_callback_t *cback; /* Callback struct */
00446       PyObject *FunctionName, *ModuleName;
00447       char *CFuncName = 0, *CModName = 0;
00448 
00449       if (!PyCallable_Check(obj)) {
00450         PyErr_Format(PyExc_TypeError, "Object of type %s is not callable.", obj->ob_type->tp_name);
00451         return 1;
00452       }
00453       cback = malloc(sizeof(*cback));
00454       cback->callback = (Function) my_python_callbacker;
00455       cback->callback_data = obj;
00456       Py_INCREF(obj);
00457 
00458       ModuleName = PyObject_GetAttrString(obj, "__module__");
00459       FunctionName = PyObject_GetAttrString(obj, "__name__");
00460       if (ModuleName) CModName = PyString_AsString(ModuleName);
00461       if (FunctionName) CFuncName = PyString_AsString(FunctionName);
00462       PyErr_Clear();
00463       if (!CModName) CModName = "python";
00464       if (CFuncName) {
00465         cback->name = malloc(strlen(CModName) + strlen(CFuncName) + 2);
00466         sprintf(cback->name, "%s.%s", CModName, CFuncName);
00467       } else {
00468         cback->name = malloc(strlen(CModName) + 12);
00469         sprintf(cback->name, "%s.0x%08x", CModName, ((int) obj) & 0xFFFFFFFF);
00470       }
00471         
00472       Py_XDECREF(ModuleName);
00473       Py_XDECREF(FunctionName);
00474 
00475       cback->delete_data = 0;
00476       cback->syntax = 0;
00477       cback->flags = 0;
00478       cback->owner = GetContext();
00479 //      putlog(LOG_MISC, "*", "Created Callback %s %p %s %p", cback->owner->name, cback->owner->module, cback->owner->script, cback->owner->client_data);
00480 
00481       var->value = cback;
00482       return 0;
00483     }
00484     case SCRIPT_BYTES: {
00485       byte_array_t *byte_array;
00486 
00487       byte_array = malloc(sizeof(*byte_array));
00488 
00489       var->value = byte_array;
00490       var->type |= SCRIPT_FREE;
00491 
00492       return PyString_AsStringAndSize(obj, (char **) &byte_array->bytes, &byte_array->len);
00493     }
00494     case SCRIPT_UNSIGNED:
00495     case SCRIPT_INTEGER: {
00496       if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
00497         PyErr_SetString(PyExc_TypeError, "an integer is required");
00498         return 1;
00499       }
00500       PyErr_Clear();
00501       if ((((type & SCRIPT_TYPE_MASK) == SCRIPT_UNSIGNED) && (PyObject_Compare(obj, MinUInt) < 0 ||
00502                                                               PyObject_Compare(obj, MaxUInt) > 0)) ||
00503           (((type & SCRIPT_TYPE_MASK) == SCRIPT_INTEGER) && (PyObject_Compare(obj, MinInt) < 0 ||
00504                                                              PyObject_Compare(obj, MaxInt) > 0))) {
00505         PyErr_SetString(PyExc_OverflowError, "Python value does not fit in C type");
00506         return 1;
00507       }
00508 
00509       if (PyInt_Check(obj)) var->value = (void *) PyInt_AsLong(obj);
00510       else var->value = (void *) PyLong_AsUnsignedLong(obj);
00511       return 0;
00512     }
00513 #if 0
00514     case SCRIPT_PARTIER: {
00515       int pid = -1;
00516 
00517       err = Tcl_GetIntFromObj(myinterp, obj, &pid);
00518       if (!err) var->value = partymember_lookup_pid(pid);
00519       else var->value = NULL;
00520       break;
00521     }
00522 #endif
00523     case SCRIPT_USER: {
00524       EgguserObject *O = (EgguserObject *) obj;
00525 
00526       if (!Egguser_Check(obj)) {
00527         PyErr_Format(PyExc_TypeError, "Expected eggdrop.egguser, got %s", obj->ob_type->tp_name);
00528         return 1;
00529       }
00530       if (!O->user || (O->user->flags & USER_DELETED)) {
00531         PyErr_SetString(PyExc_RuntimeError, "This user has been deleted.");
00532         return 1;
00533       }
00534       var->value = O->user;
00535       return 0;
00536     }
00537   }
00538   return 1;
00539 }

static int pythonscript_close ( int  why  )  [static]

Definition at line 628 of file pythonscript.c.

References bind_rem_list(), and script_unregister_module().

Referenced by pythonscript_LTX_start().

00629 {
00630   bind_rem_list("party", party_commands);
00631 
00632   script_unregister_module(&my_script_interface);
00633 
00634   return 0;
00635 }

int pythonscript_LTX_start ( egg_module_t modinfo  ) 

Definition at line 648 of file pythonscript.c.

References egg_module::author, bind_add_list(), Callable_Type, Cleanup(), event_owner_b::client_data, egg_module::close_func, CommonModule, egg_module::description, EggdropModule, Egguser_Type, HelpMethod, LOG_MISC, MaxInt, MaxUInt, MinInt, MinUInt, event_owner_b::module, my_create_command(), my_python_cb_delete(), MyDict_Type, MyModule_Add(), MyModule_Init(), event_owner_b::name, egg_module::name, event_owner_b::on_delete, PartylineDict, PartylineModule, putlog(), python_owners, pythonscript_close(), pythonscript_unload(), RealHelper, event_owner_b::script, script_playback(), script_register_module(), Stdio_Type, SysMod, SysModules, SysPath, egg_module::unload_func, and egg_module::version.

00648                                                   {
00649   PyObject *builtinModule, *Stdout, *Stderr, *Para, *Helper;
00650   static script_raw_command_t script_cleanup = {
00651     "python", "cleanup", Cleanup, 0
00652   };
00653 
00654   python_modinfo = modinfo;
00655 
00656   modinfo->name = "pythonscript";
00657   modinfo->author = "eggdev";
00658   modinfo->version = "0.0.1";
00659   modinfo->description = "provides python scripting support";
00660   modinfo->close_func = pythonscript_close;
00661   modinfo->unload_func = pythonscript_unload;
00662 
00663   /* Create the interpreter and let tcl load its init.tcl */
00664   Py_Initialize();
00665 
00666   MyModule_Init();
00667   PyType_Ready(&MyDict_Type);
00668   PyType_Ready(&Callable_Type);
00669   PyType_Ready(&Stdio_Type);
00670   PyType_Ready(&Egguser_Type);
00671 
00672   MinInt = PyInt_FromLong(INT_MIN);
00673   MaxInt = PyInt_FromLong(INT_MAX);
00674   MinUInt = PyInt_FromLong(0);
00675   MaxUInt = PyInt_FromLong(UINT_MAX);
00676   if (PyObject_Compare(MinUInt, MaxUInt) >= 0) MaxUInt = PyLong_FromUnsignedLong(UINT_MAX);
00677 
00678   SysMod = PyImport_ImportModule("sys");
00679   if (!SysMod || !(SysPath = PyObject_GetAttrString(SysMod, "path")) || !(SysModules = PyObject_GetAttrString(SysMod, "modules"))) {
00680     putlog(LOG_MISC, "*", "Module 'pythonscript' could not be initialized: Couldn't get sys.path");
00681     Py_Finalize();
00682     return -4;
00683   }
00684 
00685   EggdropModule = MyModule_Add("eggdrop", "this module contains the interface to the eggdrop bot");
00686   CommonModule = Py_InitModule3("common", methods, "this module is a kind of semipersistent storage space for scripts");
00687   PartylineModule = Py_InitModule3("partyline", methods, "this is the partyline mamespace");
00688   PartylineDict = PyModule_GetDict(PartylineModule);
00689 
00690   if (!EggdropModule || !CommonModule || !PartylineModule|| !PartylineDict) {
00691     putlog(LOG_MISC, "*", "Module 'pythonscript' could not be initialized: Failed to create modules");
00692     Py_Finalize();
00693     return -4;
00694   }
00695 
00696   Py_INCREF(&Stdio_Type);
00697   Py_INCREF(&Egguser_Type);
00698   PyModule_AddObject(EggdropModule, "stdio", (PyObject *) &Stdio_Type);
00699   PyModule_AddObject(EggdropModule, "egguser", (PyObject *) &Egguser_Type);
00700 
00701   Para = Py_BuildValue("(i)", 1);
00702   Stdout = Stdio_Type.tp_new(&Stdio_Type, Para, 0);
00703   Py_DECREF(Para);
00704   Para = Py_BuildValue("(i)", 2);
00705   Stderr = Stdio_Type.tp_new(&Stdio_Type, Para, 0);
00706   Py_DECREF(Para);
00707   PyModule_AddObject(SysMod, "stdout", Stdout);
00708   PyModule_AddObject(SysMod, "stderr", Stderr);
00709   
00710   builtinModule = PyImport_ImportModule("__builtin__");
00711   if (!builtinModule || PyModule_AddObject(PartylineModule, "__builtins__", builtinModule)) {
00712     putlog(LOG_MISC, "*", "Error inserting '__builtin__' module. builtin commands will not be available from the partyline");
00713   } else {
00714     Helper = PyCFunction_NewEx(&HelpMethod, 0, 0);
00715     RealHelper = PyObject_GetAttrString(builtinModule, "help");
00716     PyModule_AddObject(builtinModule, "help", Helper);
00717   }
00718   Py_XDECREF(builtinModule);
00719   PyErr_Clear();
00720 
00721   my_create_command(0, &script_cleanup);
00722   script_register_module(&my_script_interface);
00723   script_playback(&my_script_interface);
00724 
00725   bind_add_list("party", party_commands);
00726 
00727   python_owners = 1;
00728   python_owner = malloc(8 * sizeof(*python_owner));
00729   python_owner[0].name = "pythonscript";
00730   python_owner[0].module = python_modinfo;
00731   python_owner[0].script = "partyline";
00732   python_owner[0].client_data = PartylineModule;
00733   python_owner[0].on_delete = my_python_cb_delete;
00734 
00735 
00736   return 0;
00737 }

static void pythonscript_unload ( void   )  [static]

Definition at line 637 of file pythonscript.c.

Referenced by pythonscript_LTX_start().

00638 {
00639   Py_Finalize();
00640 }


Variable Documentation

PyObject * CommonModule [static]

Definition at line 56 of file pythonscript.c.

Referenced by my_load_script(), and pythonscript_LTX_start().

Definition at line 59 of file pythonscript.c.

char* CurrentContextString [static]

Definition at line 60 of file pythonscript.c.

Referenced by GetContext(), and my_load_script().

PyMethodDef HelpMethod [static]

Initial value:

 {
  "help", Help, METH_VARARGS, 0
}

Definition at line 618 of file pythonscript.c.

Referenced by pythonscript_LTX_start().

PyObject * MaxInt [static]

Definition at line 57 of file pythonscript.c.

Referenced by python_to_c_var(), and pythonscript_LTX_start().

PyObject * MaxUInt [static]

Definition at line 57 of file pythonscript.c.

Referenced by python_to_c_var(), and pythonscript_LTX_start().

PyMethodDef* methods [static]

Initial value:

 {
  0
}

Definition at line 642 of file pythonscript.c.

PyObject* MinInt [static]

Definition at line 57 of file pythonscript.c.

Referenced by python_to_c_var(), and pythonscript_LTX_start().

PyObject * MinUInt [static]

Definition at line 57 of file pythonscript.c.

Referenced by python_to_c_var(), and pythonscript_LTX_start().

Initial value:

Definition at line 42 of file pythonscript.c.

Initial value:

 {
  {"n", "python", (Function) party_python},
  {"n", "load", (Function) mls},
  {0}
}

Definition at line 622 of file pythonscript.c.

PyObject * PartylineDict [static]

Definition at line 56 of file pythonscript.c.

Referenced by party_python(), and pythonscript_LTX_start().

PyObject * PartylineModule [static]

Definition at line 56 of file pythonscript.c.

Referenced by pythonscript_LTX_start().

Definition at line 50 of file pythonscript.c.

static event_owner_t * python_owner = 0 [static]

Definition at line 53 of file pythonscript.c.

int python_owners = 0 [static]

Definition at line 52 of file pythonscript.c.

Referenced by GetContext(), my_load_script(), and pythonscript_LTX_start().

const char rcsid[] = "$Id: pythonscript.c,v 1.6 2008-10-17 15:57:42 sven Exp $" [static]

Definition at line 21 of file pythonscript.c.

PyObject * RealHelper [static]

Definition at line 56 of file pythonscript.c.

Referenced by Help(), and pythonscript_LTX_start().

PyObject * SysMod [static]

Definition at line 56 of file pythonscript.c.

Referenced by Help(), and pythonscript_LTX_start().

PyObject * SysModules [static]

Definition at line 56 of file pythonscript.c.

Referenced by GetContext(), and pythonscript_LTX_start().

PyObject* SysPath [static]

Definition at line 56 of file pythonscript.c.

Referenced by my_load_script(), and pythonscript_LTX_start().


Generated on Sun Nov 30 18:43:36 2008 for eggdrop1.9 by  doxygen 1.5.6