/* swi

   RISC OS swi functions

 1.00               Chris Stretch


 1.01  12 May 1999  Laurence Tratt

   * Changed swi.error to be a class based exception rather than string based
   * Added swi.ArgError which is generated for errors when the user passes invalid arguments to
       functions etc
   * Added "errnum" attribute to swi.error, so one can now check to see what the error number was

 1.02  03 March 2002 Dietmar Schwertberger
   * Added string, integer, integers, tuple and tuples
*/

#include "oslib/os.h"
#include <kernel.h>
#include "Python.h"


#define PyBlock_Check(op) ((op)->ob_type == &PyBlockType)


static PyObject *SwiError; /* Exception swi.error */
static PyObject *ArgError; /* Exception swi.ArgError */
static os_error *e;

static PyObject *swi_oserror(void)
{ PyErr_SetString(SwiError,e->errmess);
  PyObject_SetAttrString(PyErr_Occurred(), "errnum", PyInt_FromLong(e->errnum));
  return 0;
}

static PyObject *swi_error(char *s)
{ PyErr_SetString(ArgError,s);
  return 0;
}

typedef struct
{ PyObject_HEAD
  void *block;
  int length; /*length in bytes*/
  int heap;
} PyBlockObject;

static PyTypeObject PyBlockType;

/* block commands */

static PyObject *PyBlock_New(PyObject *self,PyObject *args)
{ int size;
  PyBlockObject *b;
  PyObject *init=0;
  if(!PyArg_ParseTuple(args,"i|O",&size,&init)) return NULL;
  if(size<1) size=1;
  b=PyObject_NEW(PyBlockObject,&PyBlockType);
  if(!b) return NULL;
  b->block=malloc(4*size);
  if(!b->block)
  { Py_DECREF(b);
    return PyErr_NoMemory();
  }
  b->length=4*size;
  b->heap=1;
  if(init)
  { if(PyString_Check(init))
    { int n=PyString_Size(init);
      if (n>4*size) n=4*size;
      memcpy(b->block,PyString_AsString(init),n);
      memset((char*)b->block+n,0,4*size-n);
    }
    else
    { int n,k;
      long *p=(long*)b->block;
      if(!PyList_Check(init)) goto fail;
      n=PyList_Size(init);
      if (n>size) n=size;
      for(k=0;k<n;k++)
      { PyObject *q=PyList_GetItem(init,k);
        if(!PyInt_Check(q)) goto fail;
        p[k]=PyInt_AsLong(q);
      }
      for(;k<size;k++) p[k]=0;
    }
  }
  return (PyObject *)b;
  fail:PyErr_SetString(PyExc_TypeError,
     "block initialiser must be string or list of integers");
  Py_DECREF(b);
  return NULL;
}

static PyObject *PyRegister(PyObject *self,PyObject *args)
{ int size,ptr;
  PyBlockObject *b;
  if(!PyArg_ParseTuple(args,"ii",&size,&ptr)) return NULL;
  if(size<1) size=1;
  b=PyObject_NEW(PyBlockObject,&PyBlockType);
  if(!b) return NULL;
  b->block=(void*)ptr;
  b->length=4*size;
  b->heap=0;
  return (PyObject *)b;
}

static PyObject *PyBlock_ToString(PyBlockObject *self,PyObject *arg)
{ int s=0,e=self->length;
  if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
  if(s<0||e>self->length||s>e)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return NULL;
  }
  return PyString_FromStringAndSize((char*)self->block+s,e-s);
}

static PyObject *PyBlock_NullString(PyBlockObject *self,PyObject *arg)
{ int s=0,e=self->length,i;
  char *p=(char*)self->block;
  if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
  if(s<0||e>self->length||s>e)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return NULL;
  }
  for(i=s;i<e;i++) if(p[i]==0) break;
  return PyString_FromStringAndSize((char*)self->block+s,i-s);
}

static PyObject *PyBlock_CtrlString(PyBlockObject *self,PyObject *arg)
{ int s=0,e=self->length,i;
  char *p=(char*)self->block;
  if(!PyArg_ParseTuple(arg,"|ii",&s,&e)) return NULL;
  if(s<0||e>self->length||s>e)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return NULL;
  }
  for(i=s;i<e;i++) if(p[i]<32) break;
  return PyString_FromStringAndSize((char*)self->block+s,i-s);
}

static PyObject *PyBlock_PadString(PyBlockObject *self,PyObject *arg)
{ int s=0,e=self->length,n,m;
  char *str;
  char c;
  char *p=(char*)self->block;
  if(!PyArg_ParseTuple(arg,"s#c|ii",&str,&n,&c,&s,&e)) return NULL;
  if(s<0||e>self->length||s>e)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return NULL;
  }
  m=e-s;
  if(n>m) n=m;
  memcpy(p+s,str,n);memset(p+s+n,c,m-n);
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *PyBlock_BitSet(PyBlockObject *self,PyObject *arg)
{ int i,x,y;
  int *p=(int*)self->block;
  if(!PyArg_ParseTuple(arg,"iii",&i,&x,&y)) return NULL;
  if(i<0||i>=self->length/4)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return NULL;
  }
  p[i]=(p[i]&y)^x;
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *PyBlock_Resize(PyBlockObject *self,PyObject *arg)
{ int n;
  if(!PyArg_ParseTuple(arg,"i",&n)) return NULL;
  if(n<1) n=1;
  if(self->heap)
  { void *v=realloc(self->block,4*n);
    if (!v) return PyErr_NoMemory();
    self->block=v;
  }
  self->length=4*n;
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *PyBlock_ToFile(PyBlockObject *self,PyObject *arg)
{ int s=0,e=self->length/4;
  PyObject *f;
  FILE *fp;
  if(!PyArg_ParseTuple(arg,"O|ii",&f,&s,&e)) return NULL;
  fp=PyFile_AsFile(f);
  if (!fp)
  { PyErr_SetString(PyExc_TypeError, "arg must be open file");
    return NULL;
  }
  fwrite((int*)(self->block)+s,4,e-s,fp);
  Py_INCREF(Py_None);return Py_None;
}

static struct PyMethodDef PyBlock_Methods[]=
{ { "tostring",(PyCFunction)PyBlock_ToString,1},
  { "padstring",(PyCFunction)PyBlock_PadString,1},
  { "nullstring",(PyCFunction)PyBlock_NullString,1},
  { "ctrlstring",(PyCFunction)PyBlock_CtrlString,1},
  { "bitset",(PyCFunction)PyBlock_BitSet,1},
  { "resize",(PyCFunction)PyBlock_Resize,1},
  { "tofile",(PyCFunction)PyBlock_ToFile,1},
  { NULL,NULL}		/* sentinel */
};

static int block_len(PyBlockObject *b)
{ return b->length/4;
}

static PyObject *block_concat(PyBlockObject *b,PyBlockObject *c)
{ PyErr_SetString(PyExc_IndexError,"block concatenation not implemented");
  return NULL;
}

static PyObject *block_repeat(PyBlockObject *b,int i)
{ PyErr_SetString(PyExc_IndexError,"block repetition not implemented");
  return NULL;
}

static PyObject *block_item(PyBlockObject *b,int i)
{ if(i<0||4*i>=b->length)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return NULL;
  }
  return PyInt_FromLong(((long*)(b->block))[i]);
}

static PyObject *block_slice(PyBlockObject *b,int i,int j)
{ int n,k;
  long *p=b->block;
  PyObject *result;
  if(j>b->length/4) j=b->length/4;
  if(i<0||i>j)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return NULL;
  }
  n=j-i;
  result=PyList_New(n);
  for(k=0;k<n;k++) PyList_SetItem(result,k,PyInt_FromLong(p[i+k]));
  return result;
}

static int block_ass_item(PyBlockObject *b,int i,PyObject *v)
{ if(i<0||i>=b->length/4)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return -1;
  }
  if(!PyInt_Check(v))
  { PyErr_SetString(PyExc_TypeError,"block item must be integer");
    return -1;
  }
  ((long*)(b->block))[i]=PyInt_AsLong(v);
  return 0;
}

static int block_ass_slice(PyBlockObject *b,int i,int j,PyObject *v)
{ int n,k;
  long *p=b->block;
  if(j>b->length/4) j=b->length/4;
  if(i<0||i>j)
  { PyErr_SetString(PyExc_IndexError,"block index out of range");
    return -1;
  }
  if(!PyList_Check(v)) goto fail;
  n=PyList_Size(v);
  if(n>j-i) n=j-i;
  for(k=0;k<n;k++)
  { PyObject *q=PyList_GetItem(v,k);
    if(!PyInt_Check(q)) goto fail;
    p[i+k]=PyInt_AsLong(q);
  }
  for(;k<j-i;k++) p[i+k]=0;
  return 0;
  fail:PyErr_SetString(PyExc_TypeError,"block slice must be integer list");
  return -1;
}

static PySequenceMethods block_as_sequence=
{ (inquiry)block_len,		/*sq_length*/
  (binaryfunc)block_concat,		/*sq_concat*/
  (intargfunc)block_repeat,		/*sq_repeat*/
  (intargfunc)block_item,		/*sq_item*/
  (intintargfunc)block_slice,		/*sq_slice*/
  (intobjargproc)block_ass_item,	/*sq_ass_item*/
  (intintobjargproc)block_ass_slice,	/*sq_ass_slice*/
};

static PyObject *PyBlock_GetAttr(PyBlockObject *s,char *name)
{
  if (!strcmp(name, "length")) return PyInt_FromLong((long)s->length);
  if (!strcmp(name, "start")) return PyInt_FromLong((long)s->block);
  if (!strcmp(name,"end")) return PyInt_FromLong(((long)(s->block)+s->length));
  if (!strcmp(name, "__members__"))
  { PyObject *list = PyList_New(3);
    if (list)
    { PyList_SetItem(list, 0, PyString_FromString("length"));
      PyList_SetItem(list, 1, PyString_FromString("start"));
      PyList_SetItem(list, 2, PyString_FromString("end"));
      if (PyErr_Occurred()) { Py_DECREF(list);list = NULL;}
    }
    return list;
  }
  return Py_FindMethod(PyBlock_Methods, (PyObject*) s,name);
}

static void PyBlock_Dealloc(PyBlockObject *b)
{
    if(b->heap) {
        if (b->heap)
            ;
        else
            PyMem_DEL(b->block);
    }
  PyMem_DEL(b);
}

static PyTypeObject PyBlockType=
{ PyObject_HEAD_INIT(&PyType_Type)
  0,				/*ob_size*/
  "block",			/*tp_name*/
  sizeof(PyBlockObject),	/*tp_size*/
  0,				/*tp_itemsize*/
	/* methods */
  (destructor)PyBlock_Dealloc,	/*tp_dealloc*/
  0,				/*tp_print*/
  (getattrfunc)PyBlock_GetAttr,	/*tp_getattr*/
  0,				/*tp_setattr*/
  0,				/*tp_compare*/
  0,				/*tp_repr*/
  0,				/*tp_as_number*/
  &block_as_sequence,		/*tp_as_sequence*/
  0,				/*tp_as_mapping*/
  0,                            /*tp_hash*/
};

/* swi commands */

static PyObject *swi_swi(PyObject *self,PyObject *args)
{ PyObject *name,*format,*result,*v;
  int swino,carry,rno=0,j,n;
  char *swiname,*fmt,*outfmt;
  _kernel_swi_regs r;
  PyBlockObject *ao;
  if(args==NULL||!PyTuple_Check(args)||(n=PyTuple_Size(args))<2)
  { PyErr_BadArgument(); return NULL;}
  name=PyTuple_GetItem(args,0);
  if(!PyArg_Parse(name,"i",&swino))
  { PyErr_Clear();
    if(!PyArg_Parse(name,"s",&swiname)) return NULL;
    e=xos_swi_number_from_string(swiname,&swino);
    if(e) return swi_oserror();
  }
  format=PyTuple_GetItem(args,1);
  if(!PyArg_Parse(format,"s",&fmt)) return NULL;
  j=2;
  for(;;fmt++)
  { switch(*fmt)
    { case '.': rno++;continue;
      case ';':case 0: goto swicall;
      case '0':case '1':case '2':case '3':case '4':
      case '5':case '6':case '7':case '8':case '9':
        r.r[rno++]=*fmt-'0';continue;
      case '-':r.r[rno++]=-1;continue;
    }
    if(j>=n) return swi_error("Too few arguments");
    v=PyTuple_GetItem(args,j++);
    switch(*fmt)
    { case 'i':if(!PyArg_Parse(v,"i",&r.r[rno])) return NULL;
               break;
      case 's':if(!PyArg_Parse(v,"s",(char**)(&r.r[rno]))) return NULL;
               break;
      case 'b':if(!PyArg_Parse(v,"O",(PyObject**)&ao)) return NULL;
               if(!PyBlock_Check(v)) return swi_error("Not a block");
               r.r[rno]=(int)(ao->block);
               break;
      case 'e':if(!PyArg_Parse(v,"O",(PyObject**)&ao)) return NULL;
               if(!PyBlock_Check(v)) return swi_error("Not a block");
               r.r[rno]=(int)(ao->block)+ao->length;
               break;
      default:return swi_error("Odd format character");
    }
    rno++;
  }
  swicall:e=(os_error*)_kernel_swi_c(swino,&r,&r,&carry);
  if(e) return swi_oserror();
  if(*fmt==0) { Py_INCREF(Py_None);return Py_None;}
  n=0;
  for(outfmt=++fmt;*outfmt;outfmt++)  switch(*outfmt)
  { case 'i':case 's':case '*':n++;break;
    case '.':break;
    default:return swi_error("Odd format character");
  }
  if(n==0) { Py_INCREF(Py_None);return Py_None;}
  if(n!=1)
  { result=PyTuple_New(n);
    if(!result) return NULL;
  }
  rno=0;j=0;
  for(;*fmt;fmt++)
  {  switch(*fmt)
    { case 'i':v=PyInt_FromLong((long)r.r[rno++]); break;
      case 's':v=PyString_FromString((char*)(r.r[rno++])); break;
      case '.':rno++; continue;
      case '*':v=PyInt_FromLong((long)carry); break;
    }
    if(!v) goto fail;
    if(n==1) return v;
    PyTuple_SetItem(result,j,v);
    j++;
  }
  return result;
  fail:Py_DECREF(result);return 0;
}

static PyObject *swi_string(PyObject *self, PyObject *arg)
{ char *s;
  int l=-1;
  if(!PyArg_ParseTuple(arg,"i|i",(unsigned int *)&s, &l)) return NULL;
  if (l==-1)
    l = strlen(s);
  return PyString_FromStringAndSize((char*)s, l);
}

static char swi_string__doc__[] =
"string(address[, length]) -> string\n\
Read a null terminated string from the given address.";


static PyObject *swi_integer(PyObject *self, PyObject *arg)
{ int *i;

  if(!PyArg_ParseTuple(arg,"i",(unsigned int *)&i))
    return NULL;
  return PyInt_FromLong(*i);
}

static char swi_integer__doc__[] =
"integer(address) -> string\n\
Read an integer from the given address.";


static PyObject *swi_integers(PyObject *self, PyObject *arg)
{ int *i;
  int c=-1;
  PyObject *result, *result1;
  
  if(!PyArg_ParseTuple(arg,"i|i",(unsigned int *)&i, &c)) return NULL;
  result=PyList_New(0);
  if (result) {
    while ( c>0 || (c==-1 && *i) ) {
      result1 = PyInt_FromLong((long)*i);
      if (!result1) {
        Py_DECREF(result);
        return NULL;
      }
      if (PyList_Append(result, result1)!=0) {
        Py_DECREF(result);
        Py_DECREF(result1);
        return NULL;
      };
      i++;
      if (c!=-1)
        c--;
    }
  }
  return result;
}

static char swi_integers__doc__[] =
"integers(address[, count]) -> string\n\
Either read a null terminated list of integers or\n\
a list of given length from the given address.";


static PyObject *swi_tuples(PyObject *self, PyObject *arg)
{
  unsigned char *i;         /* points to current */
  int c=-1, l=4, j, zero;         /* count, length, index */
  PyObject *result, *result1, *result11;
  
  if(!PyArg_ParseTuple(arg,"i|ii",(unsigned int *)&i, &l, &c)) return NULL;
  result=PyList_New(0);
  if (result) {
    while (c) {
      result1 = PyTuple_New(l);
      if (!result1) {
        Py_DECREF(result);
        return NULL;
      }
      zero = (c==-1); /* check for zeros? */
      for(j=0;j<l;j++) {
        if (zero && *i)
          zero = 0;   /* non-zero found */
        result11 = PyInt_FromLong((long)(*i));
        if (!result11) {
          Py_DECREF(result);
          return NULL;
        }
        PyTuple_SetItem(result1, j, result11);
        i++;
      }
      if (c==-1 && zero) {
        Py_DECREF(result1);
        c = 0;
        break;
      }
      if (PyList_Append(result, result1)!=0) {
        Py_DECREF(result1);
        Py_DECREF(result);
        return NULL;
      }
      if (c!=-1)
        c--;
    }
  }
  return result;
}

static char swi_tuples__doc__[] =
"tuples(address[, length=4[, count]]) -> string\n\
Either read a null terminated list of byte tuples or\n\
a list of given length from the given address.";


static PyObject *swi_tuple(PyObject *self, PyObject *arg)
{
  unsigned char *i;         /* points to current */
  int c=1, j;
  PyObject *result, *result1;
  
  if(!PyArg_ParseTuple(arg,"i|i",(unsigned int *)&i, &c)) return NULL;
  result = PyTuple_New(c);
  if (!result)
    return NULL;
  for(j=0;j<c;j++) {
    result1 = PyInt_FromLong((long)(i[j]));
    if (!result1) {
      Py_DECREF(result);
      return NULL;
    }
    PyTuple_SetItem(result, j, result1);
  }
  return result;
}

static char swi_tuple__doc__[] =
"tuple(address[, count=1]]) -> tuple\n\
Read count bytes from given address.";


static PyMethodDef SwiMethods[]=
{ { "swi", swi_swi,1},
  { "block", PyBlock_New,1},
  { "register", PyRegister,1},
  { "string", swi_string,METH_VARARGS, swi_string__doc__},
  { "integer", swi_integer,METH_VARARGS, swi_integer__doc__},
  { "integers", swi_integers,METH_VARARGS, swi_integers__doc__},
  { "tuples", swi_tuples,METH_VARARGS, swi_tuples__doc__},
  { "tuple", swi_tuple,METH_VARARGS, swi_tuple__doc__},
  { NULL,NULL,0,NULL}		 /* Sentinel */
};


void initswi()
{ PyObject *m, *d;
  m = Py_InitModule("swi", SwiMethods);
  d = PyModule_GetDict(m);
  SwiError=PyErr_NewException("swi.error", NULL, NULL);
  PyDict_SetItemString(d,"error",SwiError);
  ArgError=PyErr_NewException("swi.ArgError", NULL, NULL);
  PyDict_SetItemString(d,"ArgError",ArgError);
}
