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);