home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / Amiga_Misc / unused / amigalibsmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-01  |  8.9 KB  |  386 lines

  1.  
  2. /********************************************************************
  3.  
  4.     Lowlevel amiga shared library support.
  5.  
  6.     Provides `amigalib' object, which is an opened library.
  7.     The following methods are defined on the object:
  8.  
  9.         call         - perform lib call
  10.         base        - return library base
  11.         version        - return library version & revision
  12.         repr        - print object
  13.  
  14.     The `amigalibs' module provides the following functions:
  15.  
  16.         openlib        - open library (return amigalib object)
  17.         obj2reg        - convert Python object to 680x0 ULONG register value
  18.                       (needed for library calls, to pass python int or string
  19.                       objects)
  20.                       Handy feature: returns 0 for None objects.
  21.         addr        - get address of value of passed python object.
  22.                       For strings: the same as obj2reg.
  23.                       Handy feature: returns 0 for None objects.
  24.         fixstr        - Fix a string that contains a \0 character (truncate it).
  25.                       Returns new string.
  26.  
  27.     Note: libraries closes themself only (but always) when the object
  28.           is discarded.
  29.  
  30. -----------------------------------------------
  31.     (c) 1996 Irmen de Jong.
  32.  
  33.     History:
  34.  
  35.     15-feb-96    Created.
  36.     17-feb-96    Added version memberfunc + lvo tuple calling convention.
  37.     18-feb-96    Implemented register argument passing.
  38.                 Added addr.
  39.     20-feb-96    Added fixstr.
  40.     24-feb-96    Added check for exec.library -> 4.w instead of OpenLibrary()
  41.  
  42.     TODO:
  43.     - some sort of structure support, including pointers.
  44.  
  45. **************************************************************************/
  46.  
  47.  
  48.  
  49. #include <exec/libraries.h>
  50. #include <proto/exec.h>
  51.  
  52.  
  53. #include "allobjects.h"
  54. #include "modsupport.h"
  55.  
  56.  
  57. #ifndef min
  58. #define min(a,b) ((a)<=(b) ? (a):(b))
  59. #endif
  60.  
  61. static object *AmigalibsError;    /* Exception */    
  62.  
  63. typedef struct {
  64.     OB_HEAD
  65.     struct Library *libbase;    /* the library base */
  66.     char* libname;                /* library name */
  67. } amigalibobject;
  68.  
  69.  
  70.  
  71. /* Prototypes for functions defined in amigalibsmodule.c */
  72.  
  73. /* Assembly functions to be found in amigalibsmodule_asm.asm */
  74.  
  75. extern __asm __regargs ULONG
  76. amigalibs_calllib(register __a0 struct Library *libbase, 
  77.                   register __d0 LONG LVOvalue,
  78.                   register __d1 UWORD regspec,
  79.                   register __a1 ULONG *regs);
  80.  
  81. static void lib_dealloc(amigalibobject * );
  82. static PyObject * lib_call(amigalibobject * , PyObject * );
  83. static PyObject * lib_getattr(amigalibobject * , unsigned char * );
  84. static PyObject * lib_repr(amigalibobject * );
  85. static PyObject * newamigalibobject(unsigned char * , int );
  86. static PyObject * amigalibs_openlib(PyObject * , PyObject * );
  87. static BOOL obj2reg(PyObject * , ULONG *val);
  88. static PyObject * amigalibs_obj2reg(PyObject * , PyObject * );
  89. static PyObject * amigalibs_addr(PyObject * , PyObject * );
  90. static PyObject * amigalibs_fixstr(PyObject * , PyObject * );
  91.  
  92.  
  93.  
  94. /******************************** amigalib object methods ****************/
  95.  
  96. /*** AMIGALIB OBJECT MEMBER FUNCTIONS ***/
  97.  
  98. static struct methodlist lib_methods[] = {
  99.     {"call",    (method)lib_call  , 1},
  100.     {NULL,        NULL}        /* sentinel */
  101. };
  102.  
  103.  
  104. static void
  105. lib_dealloc(amigalibobject *self)            // `destructor'
  106. {
  107.     if(self->libbase)
  108.     {
  109.         if(strcmp(self->libname,"exec.library")!=0)
  110.             CloseLibrary(self->libbase);
  111.  
  112.         self->libbase=NULL;
  113.     }
  114.     DEL(self);
  115. }
  116.  
  117.  
  118. /*
  119. **    CALL - perform library call
  120. */
  121. static object *
  122. lib_call(amigalibobject *self, object *args)                // call
  123. {
  124.     object *dic;
  125.     int LVO_value;
  126.     ULONG regspec, orig_regspec;
  127.     int pos=0;
  128.     object *key, *value;
  129.  
  130.     /* the registers: */
  131.     ULONG reg[16];
  132.  
  133.     if (!newgetargs(args, "(ii)O", &LVO_value, ®spec, &dic)) return NULL;
  134.  
  135.     if(!PyDict_Check(dic))
  136.     {
  137.         err_setstr(TypeError, "2nd arg must be dictionary");
  138.         return NULL;
  139.     }
  140.  
  141.     if(LVO_value>-30 || LVO_value%2)
  142.     {
  143.         err_setstr(ValueError, "illegal LVO value");
  144.         return NULL;
  145.     }
  146.  
  147.     if(regspec<0 || regspec >0xFFFF)
  148.     {
  149.         err_setstr(ValueError, "illegal regspec");
  150.         return NULL;
  151.     }
  152.     
  153.     orig_regspec=regspec;
  154.  
  155.     while(PyDict_Next(dic,&pos,&key,&value))
  156.     {
  157.         int regnr =  PyInt_AsLong(key);
  158.         if(!PyInt_Check(key) || regnr<0 || regnr>15)
  159.         {
  160.             err_setstr(ValueError, "illegal key/regnr.");
  161.             return NULL;
  162.         }
  163.         else
  164.         {
  165.             ULONG regval;
  166.             if(!obj2reg(value,®val))
  167.             {
  168.                 err_setstr(ValueError, "illegal register value");
  169.                 return NULL;
  170.             }
  171.  
  172.             /* OK: the register `regnr' must get the value `regval' */
  173.             /* Check if register regnr indeed must get a value */
  174.             if(regspec & (1<<regnr))
  175.             {
  176.                 /* Yes, put value in register & clear register bit */
  177.                 reg[regnr]=regval;
  178.                 regspec &= ~(1<<regnr);
  179.             }
  180.             else
  181.             {
  182.                 err_setstr(ValueError, "registers not consistent with LVO spec");
  183.                 return NULL;
  184.             }
  185.         }
  186.     }
  187.  
  188.     /* Are there still registers to assign a value to? */
  189.     if(regspec)
  190.     {
  191.         err_setstr(ValueError, "too few arguments provided");
  192.         return NULL;
  193.     }
  194.  
  195.     /* XXXX TODO: SHOULD PASS ARGUMENTS ALSO */
  196.     return newintobject(
  197.             amigalibs_calllib(self->libbase,
  198.                 LVO_value,orig_regspec,reg));
  199. }
  200.  
  201.  
  202. static object *
  203. lib_getattr(amigalibobject *ao, char *name)
  204. {
  205.     if (strcmp(name, "base") == 0)
  206.         return newintobject((long)ao->libbase);
  207.     if (strcmp(name, "version") == 0)
  208.         return mkvalue("(ii)", ao->libbase->lib_Version, ao->libbase->lib_Revision);
  209.  
  210.     return findmethod(lib_methods, (object *)ao, name);
  211. }
  212.  
  213. static object *
  214. lib_repr(amigalibobject *ao)
  215. {
  216.     char buf[300];
  217.     sprintf(buf, "<amiga library '%.256s', V %ld.%ld, base %lx, at %lx>",
  218.         ao->libbase->lib_Node.ln_Name,
  219.         ao->libbase->lib_Version,
  220.         ao->libbase->lib_Revision,
  221.         ao->libbase,(long)ao);
  222.     return newstringobject(buf);
  223. }
  224.  
  225. static typeobject Amigalibtype = {
  226.     OB_HEAD_INIT(&Typetype)
  227.     0,            /*ob_size*/
  228.     "amigalib",        /*tp_name*/
  229.     sizeof(amigalibobject),    /*tp_size*/
  230.     0,            /*tp_itemsize*/
  231.     /* methods */
  232.     (destructor)lib_dealloc, /*tp_dealloc*/
  233.     0,            /*tp_print*/
  234.     (getattrfunc)lib_getattr, /*tp_getattr*/
  235.     0,            /*tp_setattr*/
  236.     0,            /*tp_compare*/
  237.     (reprfunc)lib_repr,        /*tp_repr*/
  238. };
  239.  
  240.  
  241.  
  242. /******************************** MODULE FUNCTIONS ************************/
  243.  
  244. static object *
  245. newamigalibobject(char *libname, int libver)
  246. {
  247.     amigalibobject *ao;
  248.  
  249.     if(ao = NEWOBJ(amigalibobject, &Amigalibtype))
  250.     {
  251.         if(strcmp(libname,"exec.library")==0)
  252.             ao->libbase = *(struct Library**)4L;
  253.         else
  254.             ao->libbase = OpenLibrary(libname,libver);
  255.  
  256.         if(!ao->libbase)
  257.         {
  258.             err_setstr(AmigalibsError, "can't open library");
  259.             DECREF(ao);
  260.             ao = NULL;
  261.         }
  262.     }
  263.     return (object *)ao;
  264. }
  265.  
  266.  
  267. static object *
  268. amigalibs_openlib(object *self, object *args)
  269. {
  270.     char *libname;
  271.     int libver;
  272.     
  273.     if (!getargs(args, "(si)", &libname, &libver))
  274.         return NULL;
  275.  
  276.     return newamigalibobject(libname,libver);
  277. }
  278.  
  279.  
  280. static BOOL
  281. obj2reg(object *arg, ULONG *val)
  282. {
  283.          if(PyInt_Check(arg)) *val=(ULONG)PyInt_AsLong(arg);
  284.     else if(PyString_Check(arg)) *val=(ULONG)PyString_AsString(arg);
  285.     else if(PyFloat_Check(arg)) *val=(ULONG)PyFloat_AsDouble(arg);
  286.     else if(arg==Py_None) *val=0;
  287.  
  288. //    else if(PyLong_Check(arg)) *val=
  289. //    else if(PyAccess_Check(arg)) *val=
  290. //    else if(PyAnyNumber_Check(arg)) *val=
  291. //    else if(PyAnySequence_Check(arg)) *val=
  292. //    else if(PyAnyMapping_Check(arg)) *val=
  293. //    else if(PyNothing_Check(arg)) *val=
  294. //    else if(PyType_Check(arg)) *val=
  295. //    else if(PyList_Check(arg)) *val=
  296. //    else if(PyDict_Check(arg)) *val=
  297. //    else if(PyTuple_Check(arg)) *val=
  298. //    else if(PyFile_Check(arg)) *val=
  299. //    else if(PyClass_Check(arg)) *val=
  300. //    else if(PyFunction_Check(arg)) *val=
  301. //    else if(PyMethod_Check(arg)) *val=
  302. //    else if(PyInstance_Check(arg)) *val=
  303. //    else if(PyCFunction_Check(arg)) *val=
  304. //    else if(PyModule_Check(arg)) *val=
  305. //    else if(PyCode_Check(arg)) *val=
  306. //    else if(PyFrame_Check(arg)) *val=
  307. //    else if(PyRange_Check(arg)) *val=
  308.  
  309.     else return FALSE;
  310.  
  311.     return TRUE;
  312. }
  313.  
  314. static object *
  315. amigalibs_obj2reg(object *self, object *arg)
  316. {
  317.     ULONG res;
  318.     if(!arg)
  319.         return (object*) PyErr_BadArgument();
  320.  
  321.     if(obj2reg(arg, &res))
  322.         return newintobject(res);
  323.     else
  324.     {
  325.         err_setstr(TypeError, "can't convert type to register ULONG");
  326.         return NULL;
  327.     }
  328. }
  329.  
  330. static object *
  331. amigalibs_addr(object *self, object *arg)
  332. {
  333.     if(arg)
  334.     {
  335.         if(PyInt_Check(arg))
  336.             return newintobject((long) &((PyIntObject*)arg)->ob_ival);
  337.         else if(PyFloat_Check(arg))
  338.             return newintobject((long) &((PyFloatObject*)arg)->ob_fval);
  339.         else if(PyString_Check(arg))
  340.             return newintobject((long) &((PyStringObject*)arg)->ob_sval);
  341.         else if(arg==Py_None)
  342.             return newintobject(0);
  343.     }
  344.     return (object*)PyErr_BadArgument();
  345. }
  346.  
  347. static object *
  348. amigalibs_fixstr(object *self, object *arg)
  349. {
  350.     if(arg && PyString_Check(arg))
  351.     {
  352.         char * str = PyString_AS_STRING((PyStringObject*)arg);
  353.         int len = PyString_Size(arg);
  354.         int len2 = strlen(str);
  355.         return PyString_FromStringAndSize(str,min(len,len2));
  356.     }
  357.     return (object*)PyErr_BadArgument();
  358. }
  359.  
  360.  
  361. /*** FUNCTIONS FROM THE MODULE ***/
  362.  
  363. static struct methodlist amigalibs_global_methods[] = {
  364.     {"openlib",    amigalibs_openlib, 0},
  365.     {"obj2reg", amigalibs_obj2reg, 0},
  366.     {"addr",  amigalibs_addr, 0},
  367.     {"fixstr",  amigalibs_fixstr, 0},
  368.     {NULL,        NULL}        /* sentinel */
  369. };
  370.  
  371.  
  372. void
  373. initamigalibs Py_PROTO((void))
  374. {
  375.     object *m, *d;
  376.     
  377.     m = initmodule("amigalibs", amigalibs_global_methods);
  378.     d = getmoduledict(m);
  379.     
  380.     /* Initialize amigalibs.error exception */
  381.     AmigalibsError = PyErr_NewException("amigalibs.error", NULL, NULL);
  382.  
  383.     if (AmigalibsError != NULL)
  384.         dictinsert(d, "error", AmigalibsError);
  385. }
  386.