[Python-checkins] CVS: python/dist/src/RISCOS/Modules config.c,NONE,1.1 drawfmodule.c,NONE,1.1 getpath_riscos.c,NONE,1.1 riscosmodule.c,NONE,1.1 swimodule.c,NONE,1.1

Guido van Rossum gvanrossum@users.sourceforge.net
Thu, 01 Mar 2001 21:57:56 -0800


Update of /cvsroot/python/python/dist/src/RISCOS/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv8816/Modules

Added Files:
	config.c drawfmodule.c getpath_riscos.c riscosmodule.c 
	swimodule.c 
Log Message:
RISCOS files by dschwertberger

--- NEW FILE: config.c ---
/* -*- C -*- ***********************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* Module configuration */

/* !!! !!! !!! This file is edited by the makesetup script !!! !!! !!! */

/* This file contains the table of built-in modules.
   See init_builtin() in import.c. */

#include "Python.h"


/* -- ADDMODULE MARKER 1 -- */

extern void PyMarshal_Init();
extern void initimp();
extern void initriscos();
extern void initswi();

struct _inittab _PyImport_Inittab[] = {

	{"riscos", initriscos},

/* -- ADDMODULE MARKER 2 -- */

	/* This module "lives in" with marshal.c */
	{"marshal", PyMarshal_Init},

	/* This lives it with import.c */
	{"imp", initimp},

	/* These entries are here for sys.builtin_module_names */
	{"__main__", NULL},
	{"__builtin__", NULL},
	{"sys", NULL},

	/* Sentinel */
	{0, 0}
};

--- NEW FILE: drawfmodule.c ---
/* drawf  DrawFile functions */

#include "h.os"
#include "h.osfile"
#include "h.drawfile"
#include "Python.h"

#include <limits.h>

#define PyDrawF_Check(op) ((op)->ob_type == &PyDrawFType)
#define HDRSIZE 40
#define GRPHDRSIZE 36
#define DRAWTYPE 0xaff
#define NEXT(d) ((drawfile_object*)((char*)(d)+(d)->size))

typedef struct
{ PyObject_HEAD
  drawfile_diagram *drawf;
  int size; /*length in bytes*/
  int nobjs;  /* no of objects */
} PyDrawFObject;

typedef struct dheader
{  char tag [4];
   int major_version;
   int minor_version;
   char source [12];
   os_box bbox;
} dheader;

static PyObject *DrawFError; /* Exception drawf.error */
static os_error *e;
static PyTypeObject PyDrawFType;

static dheader header=
{ {'D','r','a','w'},
  201,0,
  {'P','y','t','h','o','n',' ',' ',' ',' ',' ',' '},
  {INT_MAX,INT_MAX,INT_MIN,INT_MIN}
};

static PyObject *drawf_oserror(void)
{ PyErr_SetString(DrawFError,e->errmess);
  return 0;
}

static PyObject *drawf_error(char *s)
{ PyErr_SetString(DrawFError,s);
  return 0;
}

/* DrawFile commands */

static void countobjs(PyDrawFObject *pd)
{ int k=0,q;
  drawfile_diagram *dd=pd->drawf;
  drawfile_object *d=dd->objects;
  char *end=(char*)dd+pd->size;
  pd->nobjs=-1;
  while((char*)d<end)
  { k++;
    q=d->size;
    if(q<=0||q&3) return ;
    d=NEXT(d);
  }
  if ((char*)d==end) pd->nobjs=k;
}

static drawfile_object *findobj(PyDrawFObject *pd,int n)
{ drawfile_diagram *dd=pd->drawf;
  drawfile_object *d=dd->objects;
  for(;n>0;n--) d=NEXT(d);
  return d;
}

static PyDrawFObject* new(int size)
{ PyDrawFObject *b=PyObject_NEW(PyDrawFObject,&PyDrawFType);
  if(!b) return NULL;
  size+=HDRSIZE;
  b->drawf=malloc(size);
  if(!b->drawf)
  { Py_DECREF(b);
    return (PyDrawFObject*)PyErr_NoMemory();
  }
  b->size=size;
  return b;
}

static void extend(os_box *b,os_box *c)
{ if(b->x0>c->x0) b->x0=c->x0;
  if(b->y0>c->y0) b->y0=c->y0;
  if(b->x1<c->x1) b->x1=c->x1;
  if(b->y1<c->y1) b->y1=c->y1;
}

static PyObject *DrawF_New(PyObject *self,PyObject *args)
{ PyDrawFObject *b;
  if(!PyArg_ParseTuple(args,"")) return NULL;
  b=new(0);
  if(!b) return NULL;
  *((dheader*)b->drawf)=header;
  b->nobjs=0;
  return (PyObject *)b;
}

static PyObject *DrawF_Load(PyObject *self,PyObject *args)
{ int size;
  char *fname;
  PyDrawFObject *b;
  fileswitch_object_type ot;
  if(!PyArg_ParseTuple(args,"s",&fname)) return NULL;
  e=xosfile_read_no_path(fname,&ot,0,0,&size,0);
  if(e) return drawf_oserror();
  size-=HDRSIZE;
  if(ot!=osfile_IS_FILE||size<0||size&3) return drawf_error("Bad draw file");
  b=new(size);
  if(!b) return NULL;
  e=xosfile_load_stamped_no_path(fname,(byte*)(b->drawf),0,0,0,0,0);
  if(e)
  { Py_DECREF(b);
    return drawf_oserror();
  }
  countobjs(b);
  if(b->nobjs>=0) return (PyObject *)b;
  Py_DECREF(b);
  return drawf_error("Corrupt draw file");
}


static PyObject *DrawF_Save(PyDrawFObject *self,PyObject *arg)
{ char *fname;
  if(!PyArg_ParseTuple(arg,"s",&fname)) return NULL;
  e=xosfile_save_stamped(fname,DRAWTYPE,
  (byte*)(self->drawf),(byte*)(self->drawf)+self->size);
  if (e) return drawf_oserror();
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_Render(PyDrawFObject *self,PyObject *arg)
{ int flags,trans,clip,flat;
  if(!PyArg_ParseTuple(arg,"iiii",&flags,&trans,&clip,&flat)) return NULL;
  e=xdrawfile_render((drawfile_render_flags)flags,self->drawf,self->size,
  (os_trfm*)trans,(os_box*)clip,flat);
  if(e) return drawf_oserror();
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_Path(PyDrawFObject *self,PyObject *arg)
{ PyObject *pl;
  PyObject *dp=0;
  os_colour fill;
  os_colour outline;
  int width,start=0;
  drawfile_path_style style;
  int size=40;
  int n,i,element_count;
  drawfile_diagram *diag;
  drawfile_object *dobj;
  drawfile_path *dpath;
  draw_path *thepath;
  draw_line_style line_style;
  draw_dash_pattern *dash_pattern=0;
  os_box *box;
  long *pe;
  if(!PyArg_ParseTuple(arg,"O!(iiii)|O!i",&PyList_Type,&pl,(int*)&fill,
     (int*)&outline,&width,(int*)&style,&PyTuple_Type,&dp,&start)) return NULL;
  if(dp)
  { element_count=PyTuple_Size(dp);
    size+=4*element_count+8;
    style.flags|=drawfile_PATH_DASHED;
  }
  else style.flags&=~drawfile_PATH_DASHED;
  n=PyList_Size(pl);
  size+=4*n+8;
  for(i=0;i<n;i++) if(!PyInt_Check(PyList_GetItem(pl,i))) size+=4;
  diag=realloc(self->drawf,self->size+size);
  if(!diag) return PyErr_NoMemory();
  self->drawf=diag;
  dobj=(drawfile_object*)((char*)diag+self->size);
  dobj->type=drawfile_TYPE_PATH;
  dobj->size=size;
  dpath=&dobj->data.path;
  self->size+=size;
  self->nobjs++;
  box=&dpath->bbox;
  dpath->fill=fill;dpath->outline=outline;
  dpath->width=width;dpath->style=style;
  pe=(long*)&(dpath->path);
  if(dp)
  { dash_pattern=&(((drawfile_path_with_pattern*)dpath)->pattern);
    dash_pattern->start=start;
    dash_pattern->element_count=element_count;
    for(i=0;i<element_count;i++)
    { dash_pattern->elements[i]=(int)PyInt_AsLong(PyTuple_GetItem(dp,i));
    }
    pe+=element_count+2;
  }
  thepath=(draw_path*)pe;
  *pe++=draw_MOVE_TO;
  for(i=0;i<n;i++)
  { PyObject *p=PyList_GetItem(pl,i);
    if(PyInt_Check(p))
      *pe++=PyInt_AsLong(p);
    else
    {
      *pe++=PyInt_AsLong(PyTuple_GetItem(p,0));
      *pe++=PyInt_AsLong(PyTuple_GetItem(p,1));
    }
  }
  *pe=draw_END_PATH;
  line_style.join_style=style.flags&3;
  line_style.end_cap_style=(style.flags&3)>>2;
  line_style.start_cap_style=(style.flags&3)>>4;
  line_style.reserved=0;
  line_style.mitre_limit=10;
  line_style.start_cap_width=style.cap_width;
  line_style.end_cap_width=style.cap_width;
  line_style.start_cap_length=style.cap_length;
  line_style.end_cap_length=style.cap_length;
  e=xdraw_process_path(thepath,0x70000000,0,0,width,&line_style,dash_pattern,
  (draw_output_path)((char*)box+0x80000000),0);
  if(e) return drawf_oserror();

  /* draw_process_path seems to have a bug:
     If the bounding box size is zero, it returns 0x7FFFFFFF, ..., 0x80000000 instead of the
     correct size. */
  if (box->x0==0x7FFFFFFF)
  {
      /* path has zero extension, so forget it; it would be invisible anyway */
      self->size-=size;
      self->nobjs--;
      diag=realloc(self->drawf,self->size);
      if(!diag) return PyErr_NoMemory();
      self->drawf=diag;
  }
  else
      extend(&(diag->bbox),box);
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_Text(PyDrawFObject *self,PyObject *arg)
{ os_colour fill,bg_hint;
  drawfile_text_style style;
  int xsize,ysize,x,y;
  int size,len;
  char *text;
  drawfile_diagram *diag;
  drawfile_object *dobj;
  drawfile_text *dtext;
  os_box *box;
  if(!PyArg_ParseTuple(arg,"(ii)s(iiiii)",&x,&y,&text,
     (int*)&fill,(int*)&bg_hint,(int*)&style,&xsize,&ysize)) return NULL;
  len=strlen(text);
  size=((len+4)&(~3))+52;
  diag=realloc(self->drawf,self->size+size);
  if(!diag) return PyErr_NoMemory();
  self->drawf=diag;
  dobj=(drawfile_object*)((char*)diag+self->size);
  dobj->type=drawfile_TYPE_TEXT;
  dobj->size=size;
  dtext=&dobj->data.text;
  self->size+=size;
  self->nobjs++;
  dtext->fill=fill;
  dtext->bg_hint=bg_hint;
  dtext->style=style;
  dtext->xsize=xsize;
  dtext->ysize=ysize;
  dtext->base.x=x;
  dtext->base.y=y;
  memset(dtext->text,0,(len+4)&(~3));
  sprintf(dtext->text,"%s",text);
  box=&(dtext->bbox);
  box->x0=x;box->y0=y;box->x1=x+len*xsize;box->y1=y+ysize;
  extend(&(diag->bbox),box);
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_TText(PyDrawFObject *self,PyObject *arg)
{ os_colour fill,bg_hint;
  drawfile_text_style style;
  int xsize,ysize,x,y;
  int t1,t2,t3,t4,t5,t6;
  int size,len;
  char *text;
  drawfile_diagram *diag;
  drawfile_object *dobj;
  drawfile_trfm_text *dtext;
  os_box *box;
  t1=1<<16;t2=0;
  t3=0;t4=1<<16;
  t5=t6=0;
  if(!PyArg_ParseTuple(arg,"(ii)s(iiiii)|(iiiiii)",&x,&y,&text,
     (int*)&fill,(int*)&bg_hint,(int*)&style,&xsize,&ysize,&t1,&t2,&t3,&t4,&t5,&t6)) return NULL;
  len=strlen(text);
  size=((len+4)&(~3))+52+28;
  diag=realloc(self->drawf,self->size+size);
  if(!diag) return PyErr_NoMemory();
  self->drawf=diag;
  dobj=(drawfile_object*)((char*)diag+self->size);
  dobj->type=drawfile_TYPE_TRFM_TEXT;
  dobj->size=size;
  dtext=&dobj->data.trfm_text;
  self->size+=size;
  self->nobjs++;
  dtext->trfm.entries[0][0]=t1;
  dtext->trfm.entries[0][1]=t2;
  dtext->trfm.entries[1][0]=t3;
  dtext->trfm.entries[1][1]=t4;
  dtext->trfm.entries[2][0]=t5;
  dtext->trfm.entries[2][1]=t6;
  dtext->flags=0;
  dtext->fill=fill;
  dtext->bg_hint=bg_hint;
  dtext->style=style;
  dtext->xsize=xsize;
  dtext->ysize=ysize;
  dtext->base.x=x;
  dtext->base.y=y;
  memset(dtext->text,0,(len+4)&(~3));
  sprintf(dtext->text,"%s",text);
  box=&(dtext->bbox);
  box->x0=x;box->y0=y;box->x1=x+len*xsize;box->y1=y+ysize;
  extend(&(diag->bbox),box);
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_FontTable(PyDrawFObject *self,PyObject *arg)
{ int size=8,n=0;
  PyObject *d,*key,*value;
  drawfile_diagram *diag;
  drawfile_object *dobj;
  char *dtable;
  if(!PyArg_ParseTuple(arg,"O!",&PyDict_Type,&d)) return NULL;
  while(PyDict_Next(d,&n,&key,&value))
  { int m=PyString_Size(value);
    if(m<0||!PyInt_Check(key)) return NULL;
    size+=m+2;
  }
  size=(size+3)&(~3);
  diag=realloc(self->drawf,self->size+size);
  if(!diag) return PyErr_NoMemory();
  self->drawf=diag;
  dobj=(drawfile_object*)((char*)diag+self->size);
  dobj->type=drawfile_TYPE_FONT_TABLE;
  dobj->size=size;
  dtable=(char*)(&dobj->data.font_table);
  self->size+=size;
  self->nobjs++;
  memset(dtable,0,size-8);
  n=0;
  while(PyDict_Next(d,&n,&key,&value))
  { int m=PyString_Size(value);
    *dtable=(char)PyInt_AsLong(key);
    strcpy(dtable+1,PyString_AsString(value));
    dtable+=m+2;
  }
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_Group(PyDrawFObject *self,PyObject *arg)
{ int size,n;
  PyDrawFObject *g;
  char *name="";
  drawfile_diagram *diag;
  drawfile_object *dobj;
  drawfile_group *dgroup;
  if(!PyArg_ParseTuple(arg,"O!|s",&PyDrawFType,(PyObject*)&g,&name))
       return NULL;
  size=g->size-4;
  diag=realloc(self->drawf,self->size+size);
  if(!diag) return PyErr_NoMemory();
  self->drawf=diag;
  self->nobjs++;
  dobj=(drawfile_object*)((char*)diag+self->size);
  self->size+=size;
  dobj->type=drawfile_TYPE_GROUP;
  dobj->size=g->size-4;
  dgroup=&dobj->data.group;
  dgroup->bbox=g->drawf->bbox;
  memset(dgroup->name,' ',12);
  n=strlen(name);
  if(n>12) n=12;
  memcpy(dgroup->name,name,n);
  memcpy((char*)dgroup->objects,(char*)g->drawf+40,g->size-40);
  extend(&(diag->bbox),&(dgroup->bbox));
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_Find(PyDrawFObject *self,PyObject *arg)
{ int x,y,n=0;
  int r=-1;
  drawfile_object *d;
  if(!PyArg_ParseTuple(arg,"ii|i",&x,&y,&n)) return NULL;
  if(n<self->nobjs&&n>=0)
  { d=findobj(self,n);
    while(n<self->nobjs)
    { if(x>=d->data.text.bbox.x0&&x<=d->data.text.bbox.x1&&
         y>=d->data.text.bbox.y0&&y<=d->data.text.bbox.y1) { r=n;break;}
      n++;
      d=NEXT(d);
    }
  }
  return PyInt_FromLong(r);
}


static PyObject *DrawF_Box(PyDrawFObject *self,PyObject *arg)
{ int n=-1;
  os_box *box;
  if(!PyArg_ParseTuple(arg,"|i",&n)) return NULL;
  if(n>=self->nobjs|n<0) box=&(self->drawf->bbox);
  else box=&(findobj(self,n)->data.text.bbox);
  return Py_BuildValue("iiii",box->x0,box->y0,box->x1,box->y1);
}

static void SetBlock(drawfile_object *d,int size,int type,int offset,int value)
{ char *end=(char*)d+size;
  printf("s%d t%d o%d v%d\n",size,type,offset,value);
  for(;(char*)d<end;d=NEXT(d))
    if(d->type==type) ((int*)(d))[offset]=value;
    else if(d->type==drawfile_TYPE_GROUP)
           SetBlock((drawfile_object*)&d->data.group.objects,
                    d->size,type,offset,value);
  printf("SetBlock Done\n");
}

static PyObject *SetWord(PyDrawFObject *self,PyObject *arg,int type,int offset)
{ int n=PyTuple_Size(arg);
  int m,value,q;
  PyObject *par;
  drawfile_object *e,*d=self->drawf->objects;
  if(n==0) return  drawf_error("Value Required");
  par=PyTuple_GetItem(arg,0);
  if(!PyInt_Check(par))
  { PyErr_SetString(PyExc_TypeError,"Int Required");
    return 0;
  }
  value=(int)PyInt_AsLong(par);
  if(n==1) SetBlock(d,self->size-HDRSIZE,type,offset,value);
  else
  { for(m=1;m<n;m++)
    { par=PyTuple_GetItem(arg,m);
      if(!PyInt_Check(par))
      { PyErr_SetString(PyExc_TypeError,"Int Required");
        return 0;
      }
      q=(int)PyInt_AsLong(par);
      if(q<0||q>=self->nobjs)
      { PyErr_SetString(PyExc_ValueError,"Object out of range");
        return 0;
      }
      e=d;
      for(;q>0;q--) e=NEXT(e);
      if(e->type==type)
      { ((int*)(e))[offset]=value;
      }
      else if(e->type==drawfile_TYPE_GROUP)
             SetBlock((drawfile_object*)&e->data.group.objects,
                      e->size-GRPHDRSIZE,type,offset,value);
    }
  }
  Py_INCREF(Py_None);return Py_None;
}

static PyObject *DrawF_PathFill(PyDrawFObject *self,PyObject *arg)
{ return SetWord(self,arg,drawfile_TYPE_PATH,6);
}

static PyObject *DrawF_PathColour(PyDrawFObject *self,PyObject *arg)
{ return SetWord(self,arg,drawfile_TYPE_PATH,7);
}

static PyObject *DrawF_TextColour(PyDrawFObject *self,PyObject *arg)
{ return SetWord(self,arg,drawfile_TYPE_TEXT,6);
}

static PyObject *DrawF_TextBackground(PyDrawFObject *self,PyObject *arg)
{ return SetWord(self,arg,drawfile_TYPE_TEXT,7);
}

static struct PyMethodDef PyDrawF_Methods[]=
{
  { "render",(PyCFunction)DrawF_Render,1},
  { "save",(PyCFunction)DrawF_Save,1},
  { "path",(PyCFunction)DrawF_Path,1},
  { "text",(PyCFunction)DrawF_Text,1},
  { "ttext",(PyCFunction)DrawF_TText,1},
  { "fonttable",(PyCFunction)DrawF_FontTable,1},
  { "group",(PyCFunction)DrawF_Group,1},
  { "find",(PyCFunction)DrawF_Find,1},
  { "box",(PyCFunction)DrawF_Box,1},
  { "pathfill",(PyCFunction)DrawF_PathFill,1},
  { "pathcolour",(PyCFunction)DrawF_PathColour,1},
  { "textcolour",(PyCFunction)DrawF_TextColour,1},
  { "textbackground",(PyCFunction)DrawF_TextBackground,1},
  { NULL,NULL}		/* sentinel */
};

static int drawf_len(PyDrawFObject *b)
{ return b->nobjs;
}

static PyObject *drawf_concat(PyDrawFObject *b,PyDrawFObject *c)
{ int size=b->size+c->size-2*HDRSIZE;
  PyDrawFObject *p=new(size);
  drawfile_diagram *dd;
  drawfile_object *d;
  int n;
  if(!p) return NULL;
  dd=p->drawf;
  d=(drawfile_object*)((char*)dd+b->size);
  memcpy((char*)dd,(char*)(b->drawf),b->size);
  memcpy(d,(char*)(c->drawf)+HDRSIZE,c->size-HDRSIZE);
  p->nobjs=b->nobjs+c->nobjs;
  for(n=c->nobjs;n>0;n--)
  { extend(&(dd->bbox),&(d->data.path.bbox));
    d=NEXT(d);
  }
  return (PyObject*)p;
}

static PyObject *drawf_repeat(PyDrawFObject *b,int i)
{ PyErr_SetString(PyExc_IndexError,"drawf repetition not implemented");
  return NULL;
}

static PyObject *drawf_item(PyDrawFObject *b,int i)
{ PyDrawFObject *c;
  int size;
  drawfile_diagram *dd;
  drawfile_object *d;
  if(i<0||i>=b->nobjs)
  { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
    return NULL;
  }
  d=findobj(b,i);
  size=(char*)findobj(b,i+1)-(char*)d;
  c=new(size);
  if(!c) return NULL;
  dd=c->drawf;
  *((dheader*)dd)=header;
  memcpy(dd->objects,d,size);
  c->nobjs=1;
  extend(&(dd->bbox),&(d->data.path.bbox));
  return (PyObject*)c;
}

static PyObject *drawf_slice(PyDrawFObject *b,int i,int j)
{ PyDrawFObject *c;
  int size,n;
  drawfile_diagram *dd;
  drawfile_object *d;
  if(i<0||j>b->nobjs)
  { PyErr_SetString(PyExc_IndexError,"drawf index out of range");
    return NULL;
  }
  d=findobj(b,i);
  size=(char*)findobj(b,j)-(char*)d;
  c=new(size);
  if(!c) return NULL;
  dd=c->drawf;
  *((dheader*)dd)=header;
  memcpy(dd->objects,d,size);
  c->nobjs=j-i;
  for(n=j-i;n>0;n--)
  { extend(&(dd->bbox),&(d->data.path.bbox));
    d=NEXT(d);
  }
  return (PyObject*)c;
}

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

static int drawf_ass_slice(PyDrawFObject *b,int i,int j,PyObject *v)
{ PyErr_SetString(PyExc_IndexError,"drawf ass_slice not implemented");
  return NULL;
}

static PySequenceMethods drawf_as_sequence=
{ (inquiry)drawf_len,
  (binaryfunc)drawf_concat,
  (intargfunc)drawf_repeat,
  (intargfunc)drawf_item,
  (intintargfunc)drawf_slice,
  (intobjargproc)drawf_ass_item,
  (intintobjargproc)drawf_ass_slice,
};

static PyObject *PyDrawF_GetAttr(PyDrawFObject *s,char *name)
{
  if (!strcmp(name, "size")) return PyInt_FromLong((long)s->size);
  if (!strcmp(name, "start")) return PyInt_FromLong((long)s->drawf);
  if (!strcmp(name, "__members__"))
  { PyObject *list = PyList_New(2);
    if (list)
    { PyList_SetItem(list, 0, PyString_FromString("size"));
      PyList_SetItem(list, 1, PyString_FromString("start"));
      if (PyErr_Occurred()) { Py_DECREF(list);list = NULL;}
    }
    return list;
  }
  return Py_FindMethod(PyDrawF_Methods, (PyObject*) s,name);
}

static void PyDrawF_Dealloc(PyDrawFObject *b)
{
    if (b->drawf)
        ;
    else
        PyMem_DEL(b->drawf);
  PyMem_DEL(b);
}

static PyTypeObject PyDrawFType=
{ PyObject_HEAD_INIT(&PyType_Type)
  0,				/*ob_size*/
  "drawf",			/*tp_name*/
  sizeof(PyDrawFObject),	/*tp_size*/
  0,				/*tp_itemsize*/
	/* methods */
  (destructor)PyDrawF_Dealloc,	/*tp_dealloc*/
  0,				/*tp_print*/
  (getattrfunc)PyDrawF_GetAttr,	/*tp_getattr*/
  0,				/*tp_setattr*/
  0,				/*tp_compare*/
  0,				/*tp_repr*/
  0,				/*tp_as_number*/
  &drawf_as_sequence,		/*tp_as_sequence*/
  0,				/*tp_as_mapping*/
  0,                            /*tp_hash*/
};



static PyMethodDef DrawFMethods[]=
{
  { "load",DrawF_Load,1},
  { "new",DrawF_New,1},
  { NULL,NULL}		 /* Sentinel */
};

void initdrawf()
{ PyObject *m, *d;
  m = Py_InitModule("drawf", DrawFMethods);
  d = PyModule_GetDict(m);
  DrawFError=PyString_FromString("drawf.error");
  PyDict_SetItemString(d,"error",DrawFError);
}

--- NEW FILE: getpath_riscos.c ---
#include "Python.h"
#include "osdefs.h"

static char *prefix,*exec_prefix,*progpath,*module_search_path=0;

static void
calculate_path()
{ char *pypath=getenv("Python$Path");
  if(pypath)
  { module_search_path=malloc(strlen(pypath)+1);
    if (module_search_path) sprintf(module_search_path,"%s",pypath);
    else
    {  /* We can't exit, so print a warning and limp along */
       fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
       fprintf(stderr, "Using default static PYTHONPATH.\n");
    }
  }
  if(!module_search_path) module_search_path = "<Python$Dir>.Lib";
  prefix="";
  exec_prefix=prefix;
  progpath="<Python$Dir>";
}

/* External interface */

char *
Py_GetPath()
{
	if (!module_search_path)
		calculate_path();
	return module_search_path;
}

char *
Py_GetPrefix()
{
	if (!module_search_path)
		calculate_path();
	return prefix;
}

char *
Py_GetExecPrefix()
{
	if (!module_search_path)
		calculate_path();
	return exec_prefix;
}

char *
Py_GetProgramFullPath()
{
	if (!module_search_path)
		calculate_path();
	return progpath;
}

--- NEW FILE: riscosmodule.c ---
/* RISCOS module implementation */

#include "h.osfscontrol"
#include "h.osgbpb"
#include "h.os"
#include "h.osfile"

#include "Python.h"

#include <errno.h>

static os_error *e;

static PyObject *RiscosError; /* Exception riscos.error */

static PyObject *riscos_oserror(void)
{ PyErr_SetString(RiscosError,e->errmess);
  return 0;
}

static PyObject *riscos_error(char *s) { PyErr_SetString(RiscosError,s);return 0;}

/* RISCOS file commands */

static PyObject *riscos_remove(PyObject *self,PyObject *args)
{       char *path1;
	if (!PyArg_Parse(args, "s", &path1)) return NULL;
	if (remove(path1)) return PyErr_SetFromErrno(RiscosError);
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *riscos_rename(PyObject *self,PyObject *args)
{	char *path1, *path2;
	if (!PyArg_Parse(args, "(ss)", &path1, &path2)) return NULL;
	if (rename(path1,path2)) return PyErr_SetFromErrno(RiscosError);;
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *riscos_system(PyObject *self,PyObject *args)
{	char *command;
	if (!PyArg_Parse(args, "s", &command)) return NULL;
	return PyInt_FromLong(system(command));
}

static PyObject *riscos_chdir(PyObject *self,PyObject *args)
{	char *path;
	if (!PyArg_Parse(args, "s", &path)) return NULL;
	e=xosfscontrol_dir(path);
	if(e) return riscos_oserror();
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *canon(char *path)
{ int len;
  PyObject *obj;
  char *buf;
  e=xosfscontrol_canonicalise_path(path,0,0,0,0,&len);
  if(e) return riscos_oserror();
  obj=PyString_FromStringAndSize(NULL,-len);
  if(obj==NULL) return NULL;
  buf=PyString_AsString(obj);
  e=xosfscontrol_canonicalise_path(path,buf,0,0,1-len,&len);
  if(len!=1) return riscos_error("Error expanding path");
  if(!e) return obj;
  Py_DECREF(obj);
  return riscos_oserror();
}

static PyObject *riscos_getcwd(PyObject *self,PyObject *args)
{ if(!PyArg_NoArgs(args)) return NULL;
  return canon("@");
}

static PyObject *riscos_expand(PyObject *self,PyObject *args)
{	char *path;
	if (!PyArg_Parse(args, "s", &path)) return NULL;
        return canon(path);
}

static PyObject *riscos_mkdir(PyObject *self,PyObject *args)
{	char *path;
        int mode;
        if (!PyArg_ParseTuple(args, "s|i", &path, &mode)) return NULL;
        e=xosfile_create_dir(path,0);
        if(e) return riscos_oserror();
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *riscos_listdir(PyObject *self,PyObject *args)
{	char *path,buf[256];
        PyObject *d, *v;
        int c=0,count;
	if (!PyArg_Parse(args, "s", &path)) return NULL;
	d=PyList_New(0);
	if(!d) return NULL;
	for(;;)
	{ e=xosgbpb_dir_entries(path,(osgbpb_string_list*)buf,
	                             1,c,256,0,&count,&c);
	  if(e)
	  { Py_DECREF(d);return riscos_oserror();
	  }
	  if(count)
	  { v=PyString_FromString(buf);
	    if(!v) { Py_DECREF(d);return 0;}
	    if(PyList_Append(d,v)) {Py_DECREF(d);Py_DECREF(v);return 0;}
	  }
	  if(c==-1) break;
	}
	return d;
}

static PyObject *riscos_stat(PyObject *self,PyObject *args)
{	char *path;
        int ob,len;
        bits t=0;
        bits ld,ex,at,ft,mode;
	if (!PyArg_Parse(args, "s", &path)) return NULL;
	e=xosfile_read_stamped_no_path(path,&ob,&ld,&ex,&len,&at,&ft);
	if(e) return riscos_oserror();
	switch (ob)
	{ case osfile_IS_FILE:mode=0100000;break;  /* OCTAL */
	  case osfile_IS_DIR:mode=040000;break;
	  case osfile_IS_IMAGE:mode=0140000;break;
	  default:return riscos_error("Not found");
	}
	if(ft!=-1) t=unixtime(ld,ex);
	mode|=(at&7)<<6;
	mode|=((at&112)*9)>>4;
        return Py_BuildValue("(lllllllllllll)",
		    (long)mode,/*st_mode*/
		    0,/*st_ino*/
		    0,/*st_dev*/
		    0,/*st_nlink*/
		    0,/*st_uid*/
		    0,/*st_gid*/
		    (long)len,/*st_size*/
		    (long)t,/*st_atime*/
		    (long)t,/*st_mtime*/
		    (long)t,/*st_ctime*/
		    (long)ft,/*file type*/
		    (long)at,/*attributes*/
		    (long)ob/*object type*/
		    );
}

static PyObject *riscos_chmod(PyObject *self,PyObject *args)
{	char *path;
        bits mode;
        bits attr;
        attr=(mode&0x700)>>8;
        attr|=(mode&7)<<4;
	if (!PyArg_Parse(args, "(si)", &path,(int*)&mode)) return NULL;
        e=xosfile_write_attr(path,attr);
        if(e) return riscos_oserror();
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *riscos_utime(PyObject *self,PyObject *args)
{	char *path;
        int x,y;
	if (!PyArg_Parse(args, "(s(ii))", &path,&x,&y)) return NULL;
        e=xosfile_stamp(path);
        if(e) return riscos_oserror();
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *riscos_settype(PyObject *self,PyObject *args)
{	char *path,*name;
        int type;
	if (!PyArg_Parse(args, "(si)", &path,&type))
	{ PyErr_Clear();
	  if (!PyArg_Parse(args, "(ss)", &path,&name)) return NULL;
	  e=xosfscontrol_file_type_from_string(name,(bits*)&type);
	  if(e) return riscos_oserror();
	}
        e=xosfile_set_type(path,type);
        if(e) return riscos_oserror();
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *riscos_getenv(PyObject *self,PyObject *args)
{ char *name,*value;
  if(!PyArg_Parse(args,"s",&name)) return NULL;
  value=getenv(name);
  if(value) return PyString_FromString(value);
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *riscos_putenv(PyObject *self,PyObject *args)
{ char *name,*value;
  int len;
  os_var_type type=os_VARTYPE_LITERAL_STRING;
  if(!PyArg_ParseTuple(args,"ss|i",&name,&value,&type)) return NULL;
  if(type!=os_VARTYPE_STRING&&type!=os_VARTYPE_MACRO&&type!=os_VARTYPE_EXPANDED
                            &&type!=os_VARTYPE_LITERAL_STRING)
    return riscos_error("Bad putenv type");
  len=strlen(value);
  if(type!=os_VARTYPE_LITERAL_STRING) len++;
                          /* Other types need null terminator! */
  e=xos_set_var_val(name,(byte*)value,len,0,type,0,0);
  if(e) return riscos_oserror();
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *riscos_delenv(PyObject *self,PyObject *args)
{ char *name;
  if(!PyArg_Parse(args,"s",&name)) return NULL;
  e=xos_set_var_val(name,NULL,-1,0,0,0,0);
  if(e) return riscos_oserror();
  Py_INCREF(Py_None);
  return Py_None;
}

static PyObject *riscos_getenvdict(PyObject *self,PyObject *args)
{ PyObject *dict;
  char value[257];
  char *which="*";
  int size;
  char *context=NULL;
  if(!PyArg_ParseTuple(args,"|s",&which)) return NULL;
  dict = PyDict_New();
  if (!dict) return NULL;
  /* XXX This part ignores errors */
  while(!xos_read_var_val(which,value,sizeof(value)-1,(int)context,
         os_VARTYPE_EXPANDED,&size,(int *)&context,0))
  { PyObject *v;
    value[size]='\0';
    v = PyString_FromString(value);
    if (v == NULL) continue;
    PyDict_SetItemString(dict, context, v);
    Py_DECREF(v);
  }
  return dict;
}

static PyMethodDef riscos_methods[] = {

	{"unlink",	riscos_remove},
        {"remove",      riscos_remove},
	{"rename",	riscos_rename},
	{"system",	riscos_system},
	{"rmdir",	riscos_remove},
	{"chdir",	riscos_chdir},
	{"getcwd",	riscos_getcwd},
	{"expand",      riscos_expand},
	{"mkdir",	riscos_mkdir,1},
	{"listdir",	riscos_listdir},
	{"stat",	riscos_stat},
	{"lstat",	riscos_stat},
        {"chmod",	riscos_chmod},
	{"utime",	riscos_utime},
	{"settype",	riscos_settype},
	{"getenv",      riscos_getenv},
	{"putenv",      riscos_putenv},
	{"delenv",      riscos_delenv},
	{"getenvdict",  riscos_getenvdict,1},
	{NULL,		NULL}		 /* Sentinel */
};



void
initriscos()
{
	PyObject *m, *d;

	m = Py_InitModule("riscos", riscos_methods);
	d = PyModule_GetDict(m);

	/* Initialize riscos.error exception */
	RiscosError = PyString_FromString("riscos.error");
	if (RiscosError == NULL || PyDict_SetItemString(d, "error", RiscosError) != 0)
		Py_FatalError("can't define riscos.error");
}

--- NEW FILE: swimodule.c ---
/* 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
*/

#include "h.os"
#include "h.kernel"
#include "Python.h"

#include <errno.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 PyMethodDef SwiMethods[]=
{ { "swi",swi_swi,1},
  { "block",PyBlock_New,1},
  { "register",PyRegister,1},
  { NULL,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);
}