home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / p / python / pytexdoc / ext / source / !Python / Modules / c / swimodule < prev    next >
Encoding:
Text File  |  1995-09-15  |  11.2 KB  |  409 lines

  1. /* swi swi functions */
  2.  
  3. #include "h.os"
  4. #include "h.kernel"
  5. #include "Python.h"
  6.  
  7. #include <errno.h>
  8.  
  9. #define PyBlock_Check(op) ((op)->ob_type == &PyBlockType)
  10.  
  11.  
  12. static PyObject *SwiError; /* Exception swi.error */
  13. static os_error *e;
  14.  
  15. static PyObject *swi_oserror(void)
  16. { PyErr_SetString(SwiError,e->errmess);
  17.   return 0;
  18. }
  19.  
  20. static PyObject *swi_error(char *s)
  21. { PyErr_SetString(SwiError,s);
  22.   return 0;
  23. }
  24.  
  25. typedef struct
  26. { PyObject_HEAD
  27.   void *block;
  28.   int length; /*length in bytes*/
  29.   int heap;
  30. } PyBlockObject;
  31.  
  32. static PyTypeObject PyBlockType;
  33.  
  34. /* block commands */
  35.  
  36. static PyObject *PyBlock_New(PyObject *self,PyObject *args)
  37. { int size;
  38.   PyBlockObject *b;
  39.   PyObject *init=0;
  40.   if(!PyArg_ParseTuple(args,"i|O",&size,&init)) return NULL;
  41.   if(size<1) size=1;
  42.   b=PyObject_NEW(PyBlockObject,&PyBlockType);
  43.   if(!b) return NULL;
  44.   b->block=malloc(4*size);
  45.   if(!b->block)
  46.   { Py_DECREF(b);
  47.     return PyErr_NoMemory();
  48.   }
  49.   b->length=4*size;
  50.   b->heap=1;
  51.   if(init)
  52.   { if(PyString_Check(init))
  53.     { int n=PyString_Size(init);
  54.       if (n>4*size) n=4*size;
  55.       memcpy(b->block,PyString_AsString(init),n);
  56.       memset((char*)b->block+n,0,4*size-n);
  57.     }
  58.     else
  59.     { int n,k;
  60.       long *p=(long*)b->block;
  61.       if(!PyList_Check(init)) goto fail;
  62.       n=PyList_Size(init);
  63.       if (n>size) n=size;
  64.       for(k=0;k<n;k++)
  65.       { PyObject *q=PyList_GetItem(init,k);
  66.         if(!PyInt_Check(q)) goto fail;
  67.         p[k]=PyInt_AsLong(q);
  68.       }
  69.       for(;k<size;k++) p[k]=0;
  70.     }
  71.   }
  72.   return (PyObject *)b;
  73.   fail:PyErr_SetString(PyExc_TypeError,
  74.      "block initialiser must be string or list of integers");
  75.   Py_DECREF(b);
  76.   return NULL;
  77. }
  78.  
  79. static PyObject *PyRegister(PyObject *self,PyObject *args)
  80. { int size,ptr;
  81.   PyBlockObject *b;
  82.   if(!PyArg_ParseTuple(args,"ii",&size,&ptr)) return NULL;
  83.   if(size<1) size=1;
  84.   b=PyObject_NEW(PyBlockObject,&PyBlockType);
  85.   if(!b) return NULL;
  86.   b->block=(void*)ptr;
  87.   b->length=4*size;
  88.   b->heap=0;
  89.   return (PyObject *)b;
  90. }
  91.  
  92. static PyObject *PyBlock_ToString(PyBlockObject *self,PyObject *arg)
  93. { int s=0,e=self->length;
  94.   if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
  95.   if(s<0||e>self->length||s>e)
  96.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  97.     return NULL;
  98.   }
  99.   return PyString_FromStringAndSize((char*)self->block+s,e-s);
  100. }
  101.  
  102. static PyObject *PyBlock_NullString(PyBlockObject *self,PyObject *arg)
  103. { int s=0,e=self->length,i;
  104.   char *p=(char*)self->block;
  105.   if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
  106.   if(s<0||e>self->length||s>e)
  107.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  108.     return NULL;
  109.   }
  110.   for(i=s;i<e;i++) if(p[i]==0) break;
  111.   return PyString_FromStringAndSize((char*)self->block+s,i-s);
  112. }
  113.  
  114. static PyObject *PyBlock_CtrlString(PyBlockObject *self,PyObject *arg)
  115. { int s=0,e=self->length,i;
  116.   char *p=(char*)self->block;
  117.   if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
  118.   if(s<0||e>self->length||s>e)
  119.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  120.     return NULL;
  121.   }
  122.   for(i=s;i<e;i++) if(p[i]<32) break;
  123.   return PyString_FromStringAndSize((char*)self->block+s,i-s);
  124. }
  125.  
  126. static PyObject *PyBlock_PadString(PyBlockObject *self,PyObject *arg)
  127. { int s=0,e=self->length,n,m;
  128.   char *str;
  129.   char c;
  130.   char *p=(char*)self->block;
  131.   if(!PyArg_ParseTuple(arg,"s#c|ii",&str,&n,&c,&s,&e)) return NULL;
  132.   if(s<0||e>self->length||s>e)
  133.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  134.     return NULL;
  135.   }
  136.   m=e-s;
  137.   if(n>m) n=m;
  138.   memcpy(p+s,str,n);memset(p+s+n,c,m-n);
  139.   Py_INCREF(Py_None);return Py_None;
  140. }
  141.  
  142. static PyObject *PyBlock_BitSet(PyBlockObject *self,PyObject *arg)
  143. { int i,x,y;
  144.   int *p=(int*)self->block;
  145.   if(!PyArg_ParseTuple(arg,"iii",&i,&x,&y)) return NULL;
  146.   if(i<0||i>=self->length/4)
  147.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  148.     return NULL;
  149.   }
  150.   p[i]=(p[i]&y)^x;
  151.   Py_INCREF(Py_None);return Py_None;
  152. }
  153.  
  154. static PyObject *PyBlock_Resize(PyBlockObject *self,PyObject *arg)
  155. { int n;
  156.   if(!PyArg_ParseTuple(arg,"i",&n)) return NULL;
  157.   if(n<1) n=1;
  158.   if(self->heap)
  159.   { void *v=realloc(self->block,4*n);
  160.     if (!v) return PyErr_NoMemory();
  161.     self->block=v;
  162.   }
  163.   self->length=4*n;
  164.   Py_INCREF(Py_None);return Py_None;
  165. }
  166.  
  167. static PyObject *PyBlock_ToFile(PyBlockObject *self,PyObject *arg)
  168. { int s=0,e=self->length/4;
  169.   PyObject *f;
  170.   FILE *fp;
  171.   if(!PyArg_ParseTuple(arg,"O|ii",&f,&s,&e)) return NULL;
  172.   fp=PyFile_AsFile(f);
  173.   if (!fp)
  174.   { PyErr_SetString(PyExc_TypeError, "arg must be open file");
  175.     return NULL;
  176.   }
  177.   fwrite((int*)(self->block)+s,4,e-s,fp);
  178.   Py_INCREF(Py_None);return Py_None;
  179. }
  180.  
  181. static struct PyMethodDef PyBlock_Methods[]=
  182. { { "tostring",(PyCFunction)PyBlock_ToString,1},
  183.   { "padstring",(PyCFunction)PyBlock_PadString,1},
  184.   { "nullstring",(PyCFunction)PyBlock_NullString,1},
  185.   { "ctrlstring",(PyCFunction)PyBlock_CtrlString,1},
  186.   { "bitset",(PyCFunction)PyBlock_BitSet,1},
  187.   { "resize",(PyCFunction)PyBlock_Resize,1},
  188.   { "tofile",(PyCFunction)PyBlock_ToFile,1},
  189.   { NULL,NULL}        /* sentinel */
  190. };
  191.  
  192. static int block_len(PyBlockObject *b)
  193. { return b->length/4;
  194. }
  195.  
  196. static PyObject *block_concat(PyBlockObject *b,PyBlockObject *c)
  197. { PyErr_SetString(PyExc_IndexError,"block concatenation not implemented");
  198.   return NULL;
  199. }
  200.  
  201. static PyObject *block_repeat(PyBlockObject *b,int i)
  202. { PyErr_SetString(PyExc_IndexError,"block repetition not implemented");
  203.   return NULL;
  204. }
  205.  
  206. static PyObject *block_item(PyBlockObject *b,int i)
  207. { if(i<0||4*i>=b->length)
  208.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  209.     return NULL;
  210.   }
  211.   return PyInt_FromLong(((long*)(b->block))[i]);
  212. }
  213.  
  214. static PyObject *block_slice(PyBlockObject *b,int i,int j)
  215. { int n,k;
  216.   long *p=b->block;
  217.   PyObject *result;
  218.   if(i<0||4*j>b->length||i>j)
  219.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  220.     return NULL;
  221.   }
  222.   n=j-i;
  223.   result=PyList_New(n);
  224.   for(k=0;k<n;k++) PyList_SetItem(result,k,PyInt_FromLong(p[i+k]));
  225.   return result;
  226. }
  227.  
  228. static int block_ass_item(PyBlockObject *b,int i,PyObject *v)
  229. { if(i<0||4*i>=b->length)
  230.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  231.     return -1;
  232.   }
  233.   if(!PyInt_Check(v))
  234.   { PyErr_SetString(PyExc_TypeError,"block item must be integer");
  235.     return -1;
  236.   }
  237.   ((long*)(b->block))[i]=PyInt_AsLong(v);
  238.   return 0;
  239. }
  240.  
  241. static int block_ass_slice(PyBlockObject *b,int i,int j,PyObject *v)
  242. { int n,k;
  243.   long *p=b->block;
  244.   if(i<0||4*j>b->length||i>j)
  245.   { PyErr_SetString(PyExc_IndexError,"block index out of range");
  246.     return -1;
  247.   }
  248.   if(!PyList_Check(v)) goto fail;
  249.   n=PyList_Size(v);
  250.   if(n>j-i) n=j-i;
  251.   for(k=0;k<n;k++)
  252.   { PyObject *q=PyList_GetItem(v,k);
  253.     if(!PyInt_Check(q)) goto fail;
  254.     p[i+k]=PyInt_AsLong(q);
  255.   }
  256.   for(;k<j-i;k++) p[i+k]=0;
  257.   return 0;
  258.   fail:PyErr_SetString(PyExc_TypeError,"block slice must be integer list");
  259.   return -1;
  260. }
  261.  
  262. static PySequenceMethods block_as_sequence=
  263. { (inquiry)block_len,        /*sq_length*/
  264.   (binaryfunc)block_concat,        /*sq_concat*/
  265.   (intargfunc)block_repeat,        /*sq_repeat*/
  266.   (intargfunc)block_item,        /*sq_item*/
  267.   (intintargfunc)block_slice,        /*sq_slice*/
  268.   (intobjargproc)block_ass_item,    /*sq_ass_item*/
  269.   (intintobjargproc)block_ass_slice,    /*sq_ass_slice*/
  270. };
  271.  
  272. static PyObject *PyBlock_GetAttr(PyBlockObject *s,char *name)
  273. {
  274.   if (!strcmp(name, "length")) return PyInt_FromLong((long)s->length);
  275.   if (!strcmp(name, "start")) return PyInt_FromLong((long)s->block);
  276.   if (!strcmp(name,"end")) return PyInt_FromLong(((long)(s->block)+s->length));
  277.   if (!strcmp(name, "__members__"))
  278.   { PyObject *list = PyList_New(3);
  279.     if (list)
  280.     { PyList_SetItem(list, 0, PyString_FromString("length"));
  281.       PyList_SetItem(list, 1, PyString_FromString("start"));
  282.       PyList_SetItem(list, 2, PyString_FromString("end"));
  283.       if (PyErr_Occurred()) { Py_DECREF(list);list = NULL;}
  284.     }
  285.     return list;
  286.   }
  287.   return Py_FindMethod(PyBlock_Methods, (PyObject*) s,name);
  288. }
  289.  
  290. static void PyBlock_Dealloc(PyBlockObject *b)
  291. { if(b->heap) { PyMem_XDEL(b->block);}
  292.   PyMem_DEL(b);
  293. }
  294.  
  295. static PyTypeObject PyBlockType=
  296. { PyObject_HEAD_INIT(&PyType_Type)
  297.   0,                /*ob_size*/
  298.   "block",            /*tp_name*/
  299.   sizeof(PyBlockObject),    /*tp_size*/
  300.   0,                /*tp_itemsize*/
  301.     /* methods */
  302.   (destructor)PyBlock_Dealloc,    /*tp_dealloc*/
  303.   0,                /*tp_print*/
  304.   (getattrfunc)PyBlock_GetAttr,    /*tp_getattr*/
  305.   0,                /*tp_setattr*/
  306.   0,                /*tp_compare*/
  307.   0,                /*tp_repr*/
  308.   0,                /*tp_as_number*/
  309.   &block_as_sequence,        /*tp_as_sequence*/
  310.   0,                /*tp_as_mapping*/
  311.   0,                            /*tp_hash*/
  312. };
  313.  
  314. /* swi commands */
  315.  
  316. static PyObject *swi_swi(PyObject *self,PyObject *args)
  317. { PyObject *name,*format,*result,*v;
  318.   int swino,carry,rno=0,j,n;
  319.   char *swiname,*fmt,*outfmt;
  320.   _kernel_swi_regs r;
  321.   PyBlockObject *ao;
  322.   if(args==NULL||!PyTuple_Check(args)||(n=PyTuple_Size(args))<2)
  323.   { PyErr_BadArgument(); return NULL;}
  324.   name=PyTuple_GetItem(args,0);
  325.   if(!PyArg_Parse(name,"i",&swino))
  326.   { PyErr_Clear();
  327.     if(!PyArg_Parse(name,"s",&swiname)) return NULL;
  328.     printf("decoding %s %p\n",swiname,xos_swi_number_from_string);
  329.     e=xos_swi_number_from_string(swiname,&swino);
  330.     printf("result %d\n",swino);
  331.     if(e) return swi_oserror();
  332.   }
  333.   format=PyTuple_GetItem(args,1);
  334.   if(!PyArg_Parse(format,"s",&fmt)) return NULL;
  335.   j=2;
  336.   for(;;fmt++)
  337.   { switch(*fmt)
  338.     { case '.': rno++;continue;
  339.       case ';':case 0: goto swicall;
  340.       case '0':case '1':case '2':case '3':case '4':
  341.       case '5':case '6':case '7':case '8':case '9':
  342.         r.r[rno++]=*fmt-'0';continue;
  343.       case '-':r.r[rno++]=-1;continue;
  344.     }
  345.     if(j>=n) return swi_error("Too few arguments");
  346.     v=PyTuple_GetItem(args,j++);
  347.     switch(*fmt)
  348.     { case 'i':if(!PyArg_Parse(v,"i",&r.r[rno])) return NULL;
  349.                break;
  350.       case 's':if(!PyArg_Parse(v,"s",(char**)(&r.r[rno]))) return NULL;
  351.                break;
  352.       case 'b':if(!PyArg_Parse(v,"O",(PyObject**)&ao)) return NULL;
  353.                if(!PyBlock_Check(v)) return swi_error("Not a block");
  354.                r.r[rno]=(int)(ao->block);
  355.                break;
  356.       case 'e':if(!PyArg_Parse(v,"O",(PyObject**)&ao)) return NULL;
  357.                if(!PyBlock_Check(v)) return swi_error("Not a block");
  358.                r.r[rno]=(int)(ao->block)+ao->length;
  359.                break;
  360.       default:return swi_error("Odd format character");
  361.     }
  362.     rno++;
  363.   }
  364.   swicall:e=(os_error*)_kernel_swi_c(swino,&r,&r,&carry);
  365.   if(e) return swi_oserror();
  366.   if(*fmt==0) { Py_INCREF(Py_None);return Py_None;}
  367.   n=0;
  368.   for(outfmt=++fmt;*outfmt;outfmt++)  switch(*outfmt)
  369.   { case 'i':case 's':case '*':n++;break;
  370.     case '.':break;
  371.     default:return swi_error("Odd format character");
  372.   }
  373.   if(n==0) { Py_INCREF(Py_None);return Py_None;}
  374.   if(n!=1)
  375.   { result=PyTuple_New(n);
  376.     if(!result) return NULL;
  377.   }
  378.   rno=0;j=0;
  379.   for(;*fmt;fmt++)
  380.   {  switch(*fmt)
  381.     { case 'i':v=PyInt_FromLong((long)r.r[rno++]); break;
  382.       case 's':v=PyString_FromString((char*)(r.r[rno++])); break;
  383.       case '.':rno++; continue;
  384.       case '*':v=PyInt_FromLong((long)carry); break;
  385.     }
  386.     if(!v) goto fail;
  387.     if(n==1) return v;
  388.     PyTuple_SetItem(result,j,v);
  389.     j++;
  390.   }
  391.   return result;
  392.   fail:Py_DECREF(result);return 0;
  393. }
  394.  
  395. static PyMethodDef SwiMethods[]=
  396. { { "swi",swi_swi,1},
  397.   { "block",PyBlock_New,1},
  398.   { "register",PyRegister,1},
  399.   { NULL,NULL}         /* Sentinel */
  400. };
  401.  
  402. void initswi()
  403. { PyObject *m, *d;
  404.   m = Py_InitModule("swi", SwiMethods);
  405.   d = PyModule_GetDict(m);
  406.   SwiError=PyString_FromString("swi.error");
  407.   PyDict_SetItemString(d,"error",SwiError);
  408. }
  409.