8 1.01 12 May 1999 Laurence Tratt
10 * Changed swi.error to be a class based exception rather than string based
11 * Added swi.ArgError which is generated for errors when the user passes invalid arguments to
13 * Added "errnum" attribute to swi.error, so one can now check to see what the error number was
15 1.02 03 March 2002 Dietmar Schwertberger
16 * Added string, integer, integers, tuple and tuples
24 #define PyBlock_Check(op) ((op)->ob_type == &PyBlockType)
27 static PyObject
*SwiError
; /* Exception swi.error */
28 static PyObject
*ArgError
; /* Exception swi.ArgError */
31 static PyObject
*swi_oserror(void)
32 { PyErr_SetString(SwiError
,e
->errmess
);
33 PyObject_SetAttrString(PyErr_Occurred(), "errnum", PyInt_FromLong(e
->errnum
));
37 static PyObject
*swi_error(char *s
)
38 { PyErr_SetString(ArgError
,s
);
45 int length
; /*length in bytes*/
49 static PyTypeObject PyBlockType
;
53 static PyObject
*PyBlock_New(PyObject
*self
,PyObject
*args
)
57 if(!PyArg_ParseTuple(args
,"i|O",&size
,&init
)) return NULL
;
59 b
=PyObject_NEW(PyBlockObject
,&PyBlockType
);
61 b
->block
=malloc(4*size
);
64 return PyErr_NoMemory();
69 { if(PyString_Check(init
))
70 { int n
=PyString_Size(init
);
71 if (n
>4*size
) n
=4*size
;
72 memcpy(b
->block
,PyString_AsString(init
),n
);
73 memset((char*)b
->block
+n
,0,4*size
-n
);
77 long *p
=(long*)b
->block
;
78 if(!PyList_Check(init
)) goto fail
;
82 { PyObject
*q
=PyList_GetItem(init
,k
);
83 if(!PyInt_Check(q
)) goto fail
;
86 for(;k
<size
;k
++) p
[k
]=0;
90 fail
:PyErr_SetString(PyExc_TypeError
,
91 "block initialiser must be string or list of integers");
96 static PyObject
*PyRegister(PyObject
*self
,PyObject
*args
)
99 if(!PyArg_ParseTuple(args
,"ii",&size
,&ptr
)) return NULL
;
101 b
=PyObject_NEW(PyBlockObject
,&PyBlockType
);
106 return (PyObject
*)b
;
109 static PyObject
*PyBlock_ToString(PyBlockObject
*self
,PyObject
*arg
)
110 { int s
=0,e
=self
->length
;
111 if(!PyArg_ParseTuple(arg
,"|ii",&s
,&e
)) return NULL
;
112 if(s
<0||e
>self
->length
||s
>e
)
113 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
116 return PyString_FromStringAndSize((char*)self
->block
+s
,e
-s
);
119 static PyObject
*PyBlock_NullString(PyBlockObject
*self
,PyObject
*arg
)
120 { int s
=0,e
=self
->length
,i
;
121 char *p
=(char*)self
->block
;
122 if(!PyArg_ParseTuple(arg
,"|ii",&s
,&e
)) return NULL
;
123 if(s
<0||e
>self
->length
||s
>e
)
124 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
127 for(i
=s
;i
<e
;i
++) if(p
[i
]==0) break;
128 return PyString_FromStringAndSize((char*)self
->block
+s
,i
-s
);
131 static PyObject
*PyBlock_CtrlString(PyBlockObject
*self
,PyObject
*arg
)
132 { int s
=0,e
=self
->length
,i
;
133 char *p
=(char*)self
->block
;
134 if(!PyArg_ParseTuple(arg
,"|ii",&s
,&e
)) return NULL
;
135 if(s
<0||e
>self
->length
||s
>e
)
136 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
139 for(i
=s
;i
<e
;i
++) if(p
[i
]<32) break;
140 return PyString_FromStringAndSize((char*)self
->block
+s
,i
-s
);
143 static PyObject
*PyBlock_PadString(PyBlockObject
*self
,PyObject
*arg
)
144 { int s
=0,e
=self
->length
,n
,m
;
147 char *p
=(char*)self
->block
;
148 if(!PyArg_ParseTuple(arg
,"s#c|ii",&str
,&n
,&c
,&s
,&e
)) return NULL
;
149 if(s
<0||e
>self
->length
||s
>e
)
150 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
155 memcpy(p
+s
,str
,n
);memset(p
+s
+n
,c
,m
-n
);
156 Py_INCREF(Py_None
);return Py_None
;
159 static PyObject
*PyBlock_BitSet(PyBlockObject
*self
,PyObject
*arg
)
161 int *p
=(int*)self
->block
;
162 if(!PyArg_ParseTuple(arg
,"iii",&i
,&x
,&y
)) return NULL
;
163 if(i
<0||i
>=self
->length
/4)
164 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
168 Py_INCREF(Py_None
);return Py_None
;
171 static PyObject
*PyBlock_Resize(PyBlockObject
*self
,PyObject
*arg
)
173 if(!PyArg_ParseTuple(arg
,"i",&n
)) return NULL
;
176 { void *v
=realloc(self
->block
,4*n
);
177 if (!v
) return PyErr_NoMemory();
181 Py_INCREF(Py_None
);return Py_None
;
184 static PyObject
*PyBlock_ToFile(PyBlockObject
*self
,PyObject
*arg
)
185 { int s
=0,e
=self
->length
/4;
188 if(!PyArg_ParseTuple(arg
,"O|ii",&f
,&s
,&e
)) return NULL
;
191 { PyErr_SetString(PyExc_TypeError
, "arg must be open file");
194 fwrite((int*)(self
->block
)+s
,4,e
-s
,fp
);
195 Py_INCREF(Py_None
);return Py_None
;
198 static struct PyMethodDef PyBlock_Methods
[]=
199 { { "tostring",(PyCFunction
)PyBlock_ToString
,1},
200 { "padstring",(PyCFunction
)PyBlock_PadString
,1},
201 { "nullstring",(PyCFunction
)PyBlock_NullString
,1},
202 { "ctrlstring",(PyCFunction
)PyBlock_CtrlString
,1},
203 { "bitset",(PyCFunction
)PyBlock_BitSet
,1},
204 { "resize",(PyCFunction
)PyBlock_Resize
,1},
205 { "tofile",(PyCFunction
)PyBlock_ToFile
,1},
206 { NULL
,NULL
} /* sentinel */
209 static int block_len(PyBlockObject
*b
)
210 { return b
->length
/4;
213 static PyObject
*block_concat(PyBlockObject
*b
,PyBlockObject
*c
)
214 { PyErr_SetString(PyExc_IndexError
,"block concatenation not implemented");
218 static PyObject
*block_repeat(PyBlockObject
*b
,Py_ssize_t i
)
219 { PyErr_SetString(PyExc_IndexError
,"block repetition not implemented");
223 static PyObject
*block_item(PyBlockObject
*b
,Py_ssize_t i
)
224 { if(i
<0||4*i
>=b
->length
)
225 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
228 return PyInt_FromLong(((long*)(b
->block
))[i
]);
231 static PyObject
*block_slice(PyBlockObject
*b
,Py_ssize_t i
,Py_ssize_t j
)
235 if(j
>b
->length
/4) j
=b
->length
/4;
237 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
241 result
=PyList_New(n
);
242 for(k
=0;k
<n
;k
++) PyList_SetItem(result
,k
,PyInt_FromSsize_t(p
[i
+k
]));
246 static int block_ass_item(PyBlockObject
*b
,Py_ssize_t i
,PyObject
*v
)
247 { if(i
<0||i
>=b
->length
/4)
248 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
252 { PyErr_SetString(PyExc_TypeError
,"block item must be integer");
255 ((long*)(b
->block
))[i
]=PyInt_AsLong(v
);
259 static int block_ass_slice(PyBlockObject
*b
,Py_ssize_t i
,Py_ssize_t j
,PyObject
*v
)
262 if(j
>b
->length
/4) j
=b
->length
/4;
264 { PyErr_SetString(PyExc_IndexError
,"block index out of range");
267 if(!PyList_Check(v
)) goto fail
;
271 { PyObject
*q
=PyList_GetItem(v
,k
);
272 if(!PyInt_Check(q
)) goto fail
;
273 p
[i
+k
]=PyInt_AsLong(q
);
275 for(;k
<j
-i
;k
++) p
[i
+k
]=0;
277 fail
:PyErr_SetString(PyExc_TypeError
,"block slice must be integer list");
281 static PySequenceMethods block_as_sequence
=
282 { (inquiry
)block_len
, /*sq_length*/
283 (binaryfunc
)block_concat
, /*sq_concat*/
284 (ssizeargfunc
)block_repeat
, /*sq_repeat*/
285 (ssizeargfunc
)block_item
, /*sq_item*/
286 (ssizessizeargfunc
)block_slice
, /*sq_slice*/
287 (ssizeobjargproc
)block_ass_item
, /*sq_ass_item*/
288 (ssizessizeobjargproc
)block_ass_slice
, /*sq_ass_slice*/
291 static PyObject
*PyBlock_GetAttr(PyBlockObject
*s
,char *name
)
293 if (!strcmp(name
, "length")) return PyInt_FromLong((long)s
->length
);
294 if (!strcmp(name
, "start")) return PyInt_FromLong((long)s
->block
);
295 if (!strcmp(name
,"end")) return PyInt_FromLong(((long)(s
->block
)+s
->length
));
296 if (!strcmp(name
, "__members__"))
297 { PyObject
*list
= PyList_New(3);
299 { PyList_SetItem(list
, 0, PyString_FromString("length"));
300 PyList_SetItem(list
, 1, PyString_FromString("start"));
301 PyList_SetItem(list
, 2, PyString_FromString("end"));
302 if (PyErr_Occurred()) { Py_DECREF(list
);list
= NULL
;}
306 return Py_FindMethod(PyBlock_Methods
, (PyObject
*) s
,name
);
309 static void PyBlock_Dealloc(PyBlockObject
*b
)
320 static PyTypeObject PyBlockType
=
321 { PyObject_HEAD_INIT(&PyType_Type
)
324 sizeof(PyBlockObject
), /*tp_size*/
327 (destructor
)PyBlock_Dealloc
, /*tp_dealloc*/
329 (getattrfunc
)PyBlock_GetAttr
, /*tp_getattr*/
334 &block_as_sequence
, /*tp_as_sequence*/
341 static PyObject
*swi_swi(PyObject
*self
,PyObject
*args
)
342 { PyObject
*name
,*format
,*result
,*v
;
343 int swino
,carry
,rno
=0,j
,n
;
344 char *swiname
,*fmt
,*outfmt
;
347 if(args
==NULL
||!PyTuple_Check(args
)||(n
=PyTuple_Size(args
))<2)
348 { PyErr_BadArgument(); return NULL
;}
349 name
=PyTuple_GetItem(args
,0);
350 if(!PyArg_Parse(name
,"i",&swino
))
352 if(!PyArg_Parse(name
,"s",&swiname
)) return NULL
;
353 e
=xos_swi_number_from_string(swiname
,&swino
);
354 if(e
) return swi_oserror();
356 format
=PyTuple_GetItem(args
,1);
357 if(!PyArg_Parse(format
,"s",&fmt
)) return NULL
;
361 { case '.': rno
++;continue;
362 case ';':case 0: goto swicall
;
363 case '0':case '1':case '2':case '3':case '4':
364 case '5':case '6':case '7':case '8':case '9':
365 r
.r
[rno
++]=*fmt
-'0';continue;
366 case '-':r
.r
[rno
++]=-1;continue;
368 if(j
>=n
) return swi_error("Too few arguments");
369 v
=PyTuple_GetItem(args
,j
++);
371 { case 'i':if(!PyArg_Parse(v
,"i",&r
.r
[rno
])) return NULL
;
373 case 's':if(!PyArg_Parse(v
,"s",(char**)(&r
.r
[rno
]))) return NULL
;
375 case 'b':if(!PyArg_Parse(v
,"O",(PyObject
**)&ao
)) return NULL
;
376 if(!PyBlock_Check(v
)) return swi_error("Not a block");
377 r
.r
[rno
]=(int)(ao
->block
);
379 case 'e':if(!PyArg_Parse(v
,"O",(PyObject
**)&ao
)) return NULL
;
380 if(!PyBlock_Check(v
)) return swi_error("Not a block");
381 r
.r
[rno
]=(int)(ao
->block
)+ao
->length
;
383 default:return swi_error("Odd format character");
387 swicall
:e
=(os_error
*)_kernel_swi_c(swino
,&r
,&r
,&carry
);
388 if(e
) return swi_oserror();
389 if(*fmt
==0) { Py_INCREF(Py_None
);return Py_None
;}
391 for(outfmt
=++fmt
;*outfmt
;outfmt
++) switch(*outfmt
)
392 { case 'i':case 's':case '*':n
++;break;
394 default:return swi_error("Odd format character");
396 if(n
==0) { Py_INCREF(Py_None
);return Py_None
;}
398 { result
=PyTuple_New(n
);
399 if(!result
) return NULL
;
404 { case 'i':v
=PyInt_FromLong((long)r
.r
[rno
++]); break;
405 case 's':v
=PyString_FromString((char*)(r
.r
[rno
++])); break;
406 case '.':rno
++; continue;
407 case '*':v
=PyInt_FromLong((long)carry
); break;
411 PyTuple_SetItem(result
,j
,v
);
415 fail
:Py_DECREF(result
);return 0;
418 static PyObject
*swi_string(PyObject
*self
, PyObject
*arg
)
421 if(!PyArg_ParseTuple(arg
,"i|i",(unsigned int *)&s
, &l
)) return NULL
;
424 return PyString_FromStringAndSize((char*)s
, l
);
427 static char swi_string__doc__
[] =
428 "string(address[, length]) -> string\n\
429 Read a null terminated string from the given address.";
432 static PyObject
*swi_integer(PyObject
*self
, PyObject
*arg
)
435 if(!PyArg_ParseTuple(arg
,"i",(unsigned int *)&i
))
437 return PyInt_FromLong(*i
);
440 static char swi_integer__doc__
[] =
441 "integer(address) -> string\n\
442 Read an integer from the given address.";
445 static PyObject
*swi_integers(PyObject
*self
, PyObject
*arg
)
448 PyObject
*result
, *result1
;
450 if(!PyArg_ParseTuple(arg
,"i|i",(unsigned int *)&i
, &c
)) return NULL
;
451 result
=PyList_New(0);
453 while ( c
>0 || (c
==-1 && *i
) ) {
454 result1
= PyInt_FromLong((long)*i
);
459 if (PyList_Append(result
, result1
)!=0) {
472 static char swi_integers__doc__
[] =
473 "integers(address[, count]) -> string\n\
474 Either read a null terminated list of integers or\n\
475 a list of given length from the given address.";
478 static PyObject
*swi_tuples(PyObject
*self
, PyObject
*arg
)
480 unsigned char *i
; /* points to current */
481 int c
=-1, l
=4, j
, zero
; /* count, length, index */
482 PyObject
*result
, *result1
, *result11
;
484 if(!PyArg_ParseTuple(arg
,"i|ii",(unsigned int *)&i
, &l
, &c
)) return NULL
;
485 result
=PyList_New(0);
488 result1
= PyTuple_New(l
);
493 zero
= (c
==-1); /* check for zeros? */
496 zero
= 0; /* non-zero found */
497 result11
= PyInt_FromLong((long)(*i
));
502 PyTuple_SetItem(result1
, j
, result11
);
510 if (PyList_Append(result
, result1
)!=0) {
522 static char swi_tuples__doc__
[] =
523 "tuples(address[, length=4[, count]]) -> string\n\
524 Either read a null terminated list of byte tuples or\n\
525 a list of given length from the given address.";
528 static PyObject
*swi_tuple(PyObject
*self
, PyObject
*arg
)
530 unsigned char *i
; /* points to current */
532 PyObject
*result
, *result1
;
534 if(!PyArg_ParseTuple(arg
,"i|i",(unsigned int *)&i
, &c
)) return NULL
;
535 result
= PyTuple_New(c
);
539 result1
= PyInt_FromLong((long)(i
[j
]));
544 PyTuple_SetItem(result
, j
, result1
);
549 static char swi_tuple__doc__
[] =
550 "tuple(address[, count=1]]) -> tuple\n\
551 Read count bytes from given address.";
554 static PyMethodDef SwiMethods
[]=
555 { { "swi", swi_swi
, METH_VARARGS
},
556 { "block", PyBlock_New
, METH_VARARGS
},
557 { "register", PyRegister
, METH_VARARGS
},
558 { "string", swi_string
, METH_VARARGS
, swi_string__doc__
},
559 { "integer", swi_integer
, METH_VARARGS
, swi_integer__doc__
},
560 { "integers", swi_integers
, METH_VARARGS
, swi_integers__doc__
},
561 { "tuples", swi_tuples
, METH_VARARGS
, swi_tuples__doc__
},
562 { "tuple", swi_tuple
, METH_VARARGS
, swi_tuple__doc__
},
563 { NULL
,NULL
,0,NULL
} /* Sentinel */
569 m
= Py_InitModule("swi", SwiMethods
);
570 d
= PyModule_GetDict(m
);
571 SwiError
=PyErr_NewException("swi.error", NULL
, NULL
);
572 PyDict_SetItemString(d
,"error",SwiError
);
573 ArgError
=PyErr_NewException("swi.ArgError", NULL
, NULL
);
574 PyDict_SetItemString(d
,"ArgError",ArgError
);