/* Copyright (c) 1996, 1997, The Regents of the University of California. * All rights reserved. See Legal.htm for full text and disclaimer. */ /* Version 2 Paul F. Dubois 9/16/97 */ #define PYPDBDEBUG 0 #include "Python.h" #include "arrayobject.h" #include #define PCK_COMPLEX #include "pdb.h" #include "score.h" /* Maximum dimensions */ #define MAXDIM 7 #define MAXDIM3 (MAXDIM*3) /* Catalogue of errors possible in this module */ /* These get initialized in pypdbinit */ static PyObject *PDBOpenError; static PyObject *PDBNameError; static PyObject *PypdbError; static PyObject *PDBWriteError; static PyObject *PDBIndexError; static PyObject *PDBInternalError; static PyObject * ErrorReturn (PyObject *errorobject, char *message) { PyErr_SetString(errorobject, message); return (PyObject *) NULL; } #define TRY(E) if(! (E)) return NULL /* Declarations for objects of type pseudostruct */ typedef struct { PyObject_HEAD PyObject *dict; } pseudostructobject; staticforward PyTypeObject Pseudostructtype; /* used internally to create the members */ static int pseudostruct_add_member( pseudostructobject *self, char *name, PyObject *value ) { return PyMapping_SetItemString(self->dict, name, value); } static char pseudostruct_members__doc__[] = "List of attributes in the structure"; static PyObject * pseudostruct_members(pseudostructobject *self, PyObject *args) { TRY(PyArg_ParseTuple(args, "")); return PyMapping_Keys(self->dict); } /* ---------------------------------------------------------------- */ static struct PyMethodDef pseudostruct_methods[] = { {"members", (PyCFunction) pseudostruct_members, 1, pseudostruct_members__doc__ }, {NULL, NULL} /* sentinel */ }; /* ---------- */ static pseudostructobject * newpseudostructobject(void) { pseudostructobject *self; TRY(self = PyObject_NEW(pseudostructobject, &Pseudostructtype)); TRY(self->dict = PyDict_New()); return self; } static void pseudostruct_dealloc(pseudostructobject *self) { Py_DECREF(self->dict); PyMem_DEL(self); } static PyObject * pseudostruct_getattr(pseudostructobject *self, char *name) { PyObject * result; if(PyMapping_HasKeyString(self->dict, name)) { result = PyMapping_GetItemString(self->dict, name); return result; } return Py_FindMethod(pseudostruct_methods, (PyObject *)self, name); } /* This allows new members by user. Is this right policy? */ static int pseudostruct_setattr(pseudostructobject *self, char *name, PyObject *v) { return PyMapping_SetItemString(self->dict, name, v); } static char Pseudostructtype__doc__[] = "Objects which appear to be C structs (but aren't)" ; static PyTypeObject Pseudostructtype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "pseudostruct", /*tp_name*/ sizeof(pseudostructobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)pseudostruct_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)pseudostruct_getattr, /*tp_getattr*/ (setattrfunc)pseudostruct_setattr, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ /* Space for future expansion */ 0L,0L,0L,0L, Pseudostructtype__doc__ /* Documentation string */ }; /* End of code for pseudostruct objects */ /* Declarations for objects of type PDBfile */ typedef struct { PyObject_HEAD PDBfile *f; } PDBfileobject; staticforward PyTypeObject PDBfiletype; /* ---------------------------------------------------------------- */ static char PDBfile_cd__doc__[] = "cd(dirname), Change directory in a PDB file, returns status." ; static PyObject * PDBfile_cd (PDBfileobject *self, PyObject *args) { int status; char *dirname; TRY(PyArg_ParseTuple(args, "s",&dirname)); status = PD_cd(self->f, dirname); return Py_BuildValue("i", status); } static char PDBfile_close__doc__[] = "close() -- close the file" ; void static _PDBfile_close (PDBfileobject *self) { if(self->f != NULL) { PD_close(self->f); self->f = NULL; } } static PyObject * PDBfile_close (PDBfileobject *self, PyObject *args) { TRY(PyArg_ParseTuple(args, "")); _PDBfile_close (self); Py_INCREF(Py_None); return Py_None; } static void PDBfile_dealloc(PDBfileobject *self) { if(self->f != NULL) { PD_close(self->f); self->f = NULL; } PyMem_DEL(self); } static char PDBfile_filename__doc__[] = "filename() -- name of file which is open." ; static PyObject * PDBfile_filename(PDBfileobject *self, PyObject *args) { TRY(PyArg_ParseTuple(args, "")); return Py_BuildValue("s", self->f->name); } static char PDBfile_mode__doc__[] = "mode() = mode (a, r, w) of file." ; static char _PDBfile_mode (PDBfileobject *self) { int mode; mode = PD_get_mode(self->f); switch (mode) { case 2: return 'a'; case 3: return 'r'; case 4: return 'w'; default: return '?'; } } static PyObject * PDBfile_mode (PDBfileobject *self, PyObject *args) { int mode; TRY(PyArg_ParseTuple(args, "")); return Py_BuildValue("c", _PDBfile_mode(self)); } static char PDBfile_offset__doc__[] = "offset(): returns the default offset for the file." ; static PyObject * PDBfile_offset (PDBfileobject *self, PyObject *args) { TRY(PyArg_ParseTuple(args, "")); return Py_BuildValue("i",PD_get_offset(self->f)); } static char PDBfile_ls__doc__[] = "ls([path],[type]) - tuple containing list of names in path of given type."; static PyObject * PDBfile_ls (PDBfileobject *self, PyObject *args) { char **list; char *path, *type; int i,n; PyTupleObject *result; PyObject *s; TRY(PyArg_ParseTuple(args, "ss", &path, &type)); if(type[0] == '\0') type=NULL; if(path[0] == '\0') path=NULL; list = PD_ls(self->f, path, type, &n); if(list == NULL) { return ErrorReturn(PypdbError, PD_err); } TRY(result = (PyTupleObject *) PyTuple_New(n)); for(i=0; i < n; i++) { TRY(s = Py_BuildValue("s", list[i])); if(PyTuple_SetItem( (PyObject*) result, i, s)) { return NULL; } } SFREE(list); /* SCORE macro required to free this list */ return (PyObject *) result; } static char PDBfile_open__doc__[] = "open('filename') open filename for reading"; static PyObject * PDBfile_open (PDBfileobject *self, PyObject *args) { char *name; int i,n; _PDBfile_close (self); TRY(PyArg_ParseTuple(args, "s",&name)); self->f = PD_open(name, "r"); if(self->f == (PDBfile *) NULL) { return ErrorReturn(PDBOpenError, PD_err); } (void) PD_cd (self->f, "/"); Py_INCREF(Py_None); return Py_None; } static char PDBfile_create__doc__[] = "create('filename') create filename for writing"; static PyObject * PDBfile_create (PDBfileobject *self, PyObject *args) { char *name; int i,n; _PDBfile_close (self); TRY(PyArg_ParseTuple(args, "s",&name)); self->f = PD_open(name, "w"); if(self->f == (PDBfile *) NULL) { return ErrorReturn(PDBOpenError, PD_err); } Py_INCREF(Py_None); return Py_None; } static char PDBfile_append__doc__[] = "append('filename') open filename for appending to it"; static PyObject * PDBfile_append (PDBfileobject *self, PyObject *args) { char *name; int i,n; _PDBfile_close (self); TRY(PyArg_ParseTuple(args, "s",&name)); self->f = PD_open(name, "a"); if(self->f == (PDBfile *) NULL) { return ErrorReturn(PDBOpenError, PD_err); } Py_INCREF(Py_None); return Py_None; } static char PDBfile_pwd__doc__[] = "pwd(): Return the current directory" ; static PyObject * PDBfile_pwd (PDBfileobject *self, PyObject *args) { TRY(PyArg_ParseTuple(args, "")); return Py_BuildValue("s", PD_pwd(self->f)); } static char PDBfile_type__doc__[] = "type(name) = string containing PDB type of object"; static PyObject * PDBfile_type (PDBfileobject *self, PyObject *args) { char *name, *type; syment *ep; dimdes *dims; TRY(PyArg_ParseTuple(args, "s", &name)); ep = _PD_effective_ep(self->f,name,1,NULL); if(ep==NULL) { return ErrorReturn(PDBNameError, name); } type = PD_entry_type(ep); return Py_BuildValue("s", type); } static char PDBfile_read__doc__[] = "read(name): Return an entire entry."; /* This set of routines turns a name and a file object into a Python object */ /* Handles Fortran objects correctly. */ static PyObject * _PDBarrayreturn (PDBfileobject *pfile, PyArrayObject *result) { int i, j, n, m; if(PD_get_major_order(pfile->f) == COLUMN_MAJOR_ORDER) { /* Modify the strides accordingly */ n = result->nd; if(n > 1) { m = result->strides[n - 1]; /* stride for one element */ for(i=0; i < n ; i++) { result->strides[i] = m; m *= result->dimensions[i]; } result->flags &= ~CONTIGUOUS; } } return PyArray_Return(result); } /* Fait attention! Recursive little puppy follows */ static PyObject * _PDBfile_2_Python(pfile, name, type, dims) PDBfileobject *pfile; char *name; char *type; dimdes *dims; { char full_name[500]; /* buffer */ char *basetype = full_name; char type_letter; memdes *member; int number_of_members, kname; long number_of_elements, string_size; syment *ep; dimdes *temp; defstr *def; int dimensions, i, j; int sizes[MAXDIM]; int *sizes_p; PyObject *oresult; PyArrayObject *result; PyStringObject *sresult; char *sblock; pseudostructobject *tresult; void *vresult; strcpy(basetype, type); j = 0; for(i=0; basetype[i] != '\0'; i++) { if((basetype[i] == ' ') || (basetype[i] == '*')) { j = 1; break; } } /* Is this an indirect ? */ if(j) { basetype[i] = '\0'; if(strcmp(basetype,"float") == 0) { type_letter = 'f'; } else if(strcmp(basetype,"double") == 0) { type_letter = 'd'; } else if(strcmp(basetype,"long") == 0) { type_letter = 'l'; } else if(strcmp(basetype,"integer") == 0) { type_letter = 'l'; } else if(strcmp(basetype,"int") == 0) { type_letter = 'i'; } else { /* Unknown indirect type, packing it up as a string */ if(!PD_read(pfile->f, name, &vresult )) { return ErrorReturn(PypdbError, name); } TRY( oresult = PyString_FromStringAndSize ( vresult, SC_arrlen(vresult) ) ); SFREE (vresult); return oresult; } if(!PD_read(pfile->f, name, &vresult )) { return ErrorReturn (PypdbError, PD_err); } if(vresult == NULL) { Py_INCREF(Py_None); return(Py_None); } dimensions = 1; number_of_elements = SC_arrlen(vresult); sizes[0] = number_of_elements; #if PYPDBDEBUG printf ("%s %s| %d %d\n", name, type, dimensions, number_of_elements); #endif TRY( result = (PyArrayObject *) PyArray_FromDims ( dimensions, sizes, type_letter ) ); memcpy (result->data, vresult, SC_arrlen (vresult)); SFREE(vresult); return _PDBarrayreturn(pfile, result); } /* Now for the regular stuff */ dimensions = 0; temp = dims; number_of_elements = 1; while(temp != NULL) { if(dimensions >= MAXDIM) { return ErrorReturn(PDBInternalError, "Too many dimensions"); } sizes[dimensions++] = temp->number; number_of_elements *= temp->number; temp = temp->next; } #if PYPDBDEBUG printf ("%s %s| %d %d\n", name, type, dimensions, number_of_elements); #endif if(strcmp(type,"float") == 0) { TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'f')); if(!PD_read(pfile->f, name, (float *) result->data)) { return ErrorReturn (PypdbError, PD_err); } return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"double") == 0) { TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'd')); if(!PD_read(pfile->f, name, (double *) result->data)) { return ErrorReturn (PypdbError, PD_err); } return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"long") == 0) { TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'l')); if(!PD_read(pfile->f, name, (long *) result->data)) { return ErrorReturn (PypdbError, PD_err); } return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"integer") == 0) { TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'l')); if(!PD_read_as(pfile->f, name, "long", (long *) result->data)) { return ErrorReturn (PypdbError, PD_err); } return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"logical") == 0) { strcpy(full_name, name); strcat(full_name, "."); strcat(full_name, "value"); return _PDBfile_2_Python(pfile, full_name, "integer", dims); } else if(strcmp(type,"int") == 0) { TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'i')); if(!PD_read(pfile->f, name, (int *) result->data)) { return ErrorReturn (PypdbError, PD_err); } return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"char") == 0) { /* It isn't really useful to turn this into a character array, so we're going to turn it into either one string or an array of strings. */ if(dimensions == 0) { string_size = 1; sizes[0] = 1; sizes_p = sizes; dimensions = 1; } else if(PD_get_major_order(pfile->f) == COLUMN_MAJOR_ORDER) { sizes_p = sizes + 1; string_size = sizes[0]; } else { string_size = sizes[dimensions-1]; sizes_p = sizes; } /* Read the whole mess into one big string then chop it up */ if(! (sblock = (char *) malloc (number_of_elements))) { return ErrorReturn (PypdbError, name); } TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions-1, sizes_p, 'O')); if(!PD_read(pfile->f, name, sblock)) { return ErrorReturn (PypdbError, PD_err); } for(i=0; i < number_of_elements / string_size; i++) { ((PyObject **) result->data)[i] = PyString_FromStringAndSize (sblock+i*string_size, string_size); } free(sblock); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"fcomplex") == 0) { TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'F')); if(!PD_read(pfile->f, name, result->data)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"complex") == 0) { TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'D')); if(!PD_read(pfile->f, name, (complex *) result->data)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else { if (dimensions > 1) { ErrorReturn(PDBInternalError, "Sorry, multidimensional struct not implemented."); } def = PD_inquire_type(pfile->f, type); member = def->members; if(member == NULL) { number_of_members = 0; return ErrorReturn(PDBInternalError, "Sorry, don't understand this type."); } else { number_of_members = 1; while(member->next != (memdes *) NULL) { number_of_members++; member = member->next; } } TRY(result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'O')); /* Each entry is a pseudostruct */ for(j=0; j < number_of_elements; j++) { tresult = newpseudostructobject(); if(tresult == NULL) { /* right here should DECREF contents of result and result */ /* check macro with Hugunin later; same applies later */ return(NULL); } member = def->members; strcpy(full_name, name); if(dimensions > 0) { strcat(full_name, "["); sprintf(full_name + strlen(full_name), "%d", j); strcat(full_name, "]"); } strcat(full_name, "."); kname = strlen(full_name); for(i=0; i < number_of_members; i++) { strcpy(full_name + kname, member->name); /* Recursion */ oresult = _PDBfile_2_Python(pfile, full_name, member->type, member->dimensions); if(oresult == (PyObject *) NULL) { return ErrorReturn(PDBInternalError, "Failed to get member"); } if(pseudostruct_add_member(tresult, member->name, oresult)) { return ErrorReturn(PDBInternalError, "Failed to insert member"); } Py_DECREF(oresult); member = member->next; } if(PySequence_SetItem((PyObject*) result, j, (PyObject*) tresult)) { return NULL; } Py_DECREF(tresult); /* end of loop on number of elements */ } return _PDBarrayreturn(pfile, result); } } static PyObject * _PDBfile_read(pfile, name) PDBfileobject *pfile; char *name; { char *type; syment *ep; dimdes *dims; ep = _PD_effective_ep(pfile->f,name,1,NULL); if(ep==NULL) { return ErrorReturn(PDBNameError, name); } type = PD_entry_type(ep); dims = PD_entry_dimensions(ep); return _PDBfile_2_Python(pfile, name, type, dims); } static PyObject * PDBfile_read(self, args) PDBfileobject *self; PyObject *args; { char *name; TRY(PyArg_ParseTuple(args, "s", &name)); return (PyObject *) _PDBfile_read(self, name); } /* This routine turns a name and index selection into a Python object */ /* Does not check appropriateness of indices */ static PyObject * _PDBfile_read_part(pfile, name, nind, ind) PDBfileobject *pfile; char *name; int nind; long ind[]; { char *type; syment *ep; int i, dimensions, matdim; int sizes[MAXDIM]; PyArrayObject *result; ep = _PD_effective_ep(pfile->f,name,1,NULL); if(ep==NULL) return ErrorReturn(PDBNameError, name); type = PD_entry_type(ep); dimensions = nind / 3; if (dimensions > MAXDIM) { return ErrorReturn(PDBIndexError, name); } for(i=0; i < dimensions; i++) { sizes[i] = (int) ((ind[3*i+1] - ind[3*i])/ind[3*i+2] + 1); } if(strcmp(type,"float") == 0) { result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'f'); if (result == NULL) return NULL; if(!PD_read_alt(pfile->f, name, (float *) result->data, ind)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"double") == 0) { result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'd'); if (result == NULL) return NULL; if(!PD_read_alt(pfile->f, name, (double *) result->data, ind)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"long") == 0) { result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'l'); if (result == NULL) return NULL; if(!PD_read_alt(pfile->f, name, (int *) result->data, ind)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"int") == 0) { result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'i'); if (result == NULL) return NULL; if(!PD_read_alt(pfile->f, name, (int *) result->data, ind)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"char") == 0) { result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'c'); if (result == NULL) return NULL; if(!PD_read_alt(pfile->f, name, (char *) result->data, ind)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"fcomplex") == 0) { result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'F'); if (result == NULL) return NULL; if(!PD_read_alt(pfile->f, name, result->data, ind)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else if(strcmp(type,"complex") == 0) { result = (PyArrayObject *) PyArray_FromDims (dimensions, sizes, 'D'); if (result == NULL) return NULL; if(!PD_read_alt(pfile->f, name, (complex *) result->data, ind)) return ErrorReturn (PypdbError, PD_err); return _PDBarrayreturn(pfile,result); } else { return ErrorReturn(PDBInternalError, "Can't handle type"); } } static char PDBfile_read_part__doc__[] = "read_part(name, (index-triples)) reads part of an entry." ; static PyObject * PDBfile_read_part(self, args) PDBfileobject *self; PyObject *args; { char *name; PyObject *indices; PyObject *value, *value2; int i, nind; long ind[MAXDIM]; TRY(PyArg_ParseTuple(args, "sO", &name, &indices)); if(!PySequence_Check(indices)) { return ErrorReturn(PDBIndexError, name); } nind = PyObject_Length(indices); if(nind < 0) return NULL; if(nind == 0) { return _PDBfile_read(self, name); } if((nind % 3) != 0) { return ErrorReturn(PDBIndexError, name); } for(i=0; i < nind; i++) { value = PySequence_GetItem(indices, i); if(value == (PyObject *) NULL) return NULL; if(!PyNumber_Check(value)) { Py_DECREF(value); return ErrorReturn(PDBIndexError, name); } value2 = PyNumber_Int(value); if(value2 == (PyObject *) NULL) { Py_DECREF(value); if(value != value2) Py_DECREF(value); return ErrorReturn(PDBIndexError, name); } if(value != value2) Py_DECREF(value); ind[i] = PyInt_AsLong(value2); Py_DECREF(value2); } return (PyObject *) _PDBfile_read_part(self, name, nind, ind); } static char PDBfile_shape__doc__[] = "shape(name): Return a tuple giving the dimensions of an entry."; static PyObject * PDBfile_shape(self, args) PDBfileobject *self; PyObject *args; { int i; char *name; syment *ep; dimdes *dims, *temp; int dimensions; PyTupleObject *result; PyObject *t; TRY(PyArg_ParseTuple(args, "s", &name)); ep = _PD_effective_ep(self->f,name,1,NULL); if(ep==NULL) { return ErrorReturn(PDBNameError, name); } dims = PD_entry_dimensions(ep); dimensions = 0; temp = dims; while(temp != NULL) { dimensions++; temp = temp->next; } TRY(result = (PyTupleObject *) PyTuple_New(dimensions)); temp = dims; for(i=0; i < dimensions; i++) { TRY(t=Py_BuildValue("i", temp->number)); if(PyTuple_SetItem((PyObject*) result, i, t)) { return NULL; } temp = temp->next; } return (PyObject *) result; } static char PDBfile_low__doc__[] = "low(name): Return a tuple giving the low of an entry."; static PyObject * PDBfile_low(self, args) PDBfileobject *self; PyObject *args; { int i; char *name; syment *ep; dimdes *dims, *temp; int dimensions; PyTupleObject *result; PyObject *t; TRY(PyArg_ParseTuple(args, "s", &name)); ep = _PD_effective_ep(self->f,name,1,NULL); if(ep==NULL) return ErrorReturn(PDBNameError, name); dims = PD_entry_dimensions(ep); dimensions = 0; temp = dims; while(temp != NULL) { dimensions++; temp = temp->next; } TRY(result = (PyTupleObject *) PyTuple_New(dimensions)); temp = dims; for(i=0; i < dimensions; i++) { TRY(t = Py_BuildValue("i",temp->index_min)); if(PyTuple_SetItem((PyObject*) result, i, t)) { return NULL; } temp = temp->next; } return (PyObject *) result; } static char PDBfile_high__doc__[] = "high(name): Return a Tuple giving the high of an entry."; static PyObject * PDBfile_high(self, args) PDBfileobject *self; PyObject *args; { int i; char *name; syment *ep; dimdes *dims, *temp; int dimensions; PyTupleObject *result; PyObject *t; TRY(PyArg_ParseTuple(args, "s", &name)); ep = _PD_effective_ep(self->f,name,1,NULL); if(ep==NULL) return ErrorReturn(PDBNameError, name); dims = PD_entry_dimensions(ep); dimensions = 0; temp = dims; while(temp != NULL) { dimensions++; temp = temp->next; } TRY(result = (PyTupleObject *) PyTuple_New(dimensions)); temp = dims; for(i=0; i < dimensions; i++) { TRY(t = Py_BuildValue("i",temp->index_max)); if(PyTuple_SetItem((PyObject*) result, i, t)) { return NULL; } temp = temp->next; } return (PyObject *) result; } static char PDBfile_is_column_major__doc__[]= "is_column_major() returns true if file written by Fortran" ; static PyObject * PDBfile_is_column_major(self, args) PDBfileobject *self; PyObject *args; { int result; TRY(PyArg_ParseTuple(args, "")); result = (PD_get_major_order(self->f)==COLUMN_MAJOR_ORDER); return Py_BuildValue("i", result); } static char PDBfile_ln__doc__[] = "ln(var, link): create a link to a variable, return status" ; static PyObject * PDBfile_ln (PDBfileobject *self, PyObject *args) { char *var, *link; TRY(PyArg_ParseTuple(args, "ss", &var, &link)); return Py_BuildValue ("i", PD_ln (self->f, var, link)); } static char PDBfile_mkdir__doc__[] = "mkdir(dirname): create a directory, return status" ; static PyObject * PDBfile_mkdir (PDBfileobject *self, PyObject *args) { char *dirname; TRY(PyArg_ParseTuple(args, "s", &dirname)); return Py_BuildValue ("i", PD_mkdir (self->f, dirname)); } /* returns Py_None for success, NULL for failure, with error already set */ static PyObject* _PDBfile_write (PDBfile *file, char *name, PyObject *obj, int record) { char pdbtype[500]; char *pdbatype; double x; long lx; int i, nd, t, tfile, result; char *sx, *tx; PyArrayObject *ax; PyArrayObject *ox; long ind[3*MAXDIM]; if (PyFloat_Check(obj)) { x = PyFloat_AS_DOUBLE ((PyFloatObject *) obj); nd = (record == 0 ? 0 : 1); ind [0] = record - 1; ind [1] = record - 1; ind [2] = 1; pdbatype = "double"; if (record <= 1) { result = PD_write_alt (file, name, pdbatype, &x, nd, ind); } else { result = PD_append_alt (file, name, &x, nd, ind); } } else if (PyInt_Check(obj)) { lx = PyInt_AS_LONG ((PyIntObject *) obj); nd = (record == 0 ? 0 : 1); ind [0] = record - 1; ind [1] = record - 1; ind [2] = 1; pdbatype = "long"; if (record <= 1) { result = PD_write_alt (file, name, pdbatype, &lx, nd, ind); } else { result = PD_append_alt (file, name, &lx, nd, ind); } } else if (PyString_Check(obj)) { sx = PyString_AS_STRING ((PyStringObject *) obj); tx = MAKE_N (char, (strlen(sx))); memcpy (tx, sx, strlen(sx)); nd = (record == 0) ? 0 : 1; ind [0] = record - 1; ind [1] = record - 1; ind [2] = 1; pdbatype = "char*"; if (record <= 1) { result = PD_write_alt (file, name, pdbatype, &tx, nd, ind); } else { result = PD_append_alt (file, name, &tx, nd, ind); } SFREE(tx); } else if (PyArray_Check(obj)) { ox = (PyArrayObject *) obj; nd = ox->nd; if ((nd > MAXDIM) || ((nd == MAXDIM) && (record > 0))) { return ErrorReturn (PDBWriteError,"Too many dimensions in array."); } t = ox->descr->type_num; tfile = t; switch (t) { case PyArray_CHAR: pdbatype = "char"; break; case PyArray_INT: case PyArray_LONG: tfile = PyArray_INT; pdbatype = "long"; break; case PyArray_FLOAT: case PyArray_DOUBLE: tfile = PyArray_DOUBLE; pdbatype = "double"; break; default: return ErrorReturn (PDBWriteError,"Cannot handle an array of this type."); } ax = (PyArrayObject *) PyArray_ContiguousFromObject((PyObject*) ox, tfile, nd, nd); for (i=0; i < nd; i++) { ind[3*i] = 0; ind[3*i+1] = ox->dimensions[i] - 1; ind[3*i+2] = 1; } if (record > 0) { ind [3*nd] = record - 1; ind [3*nd + 1] = record - 1; ind [3*nd + 2] = 1; nd = nd + 1; } if (record <= 1) { result = PD_write_alt (file, name, pdbatype, ax->data, nd, ind); } else { result = PD_append_alt (file, name, ax->data, nd, ind); } } else { return ErrorReturn (PDBWriteError, "Cannot write this type."); } if (PyArray_Check(obj)) Py_DECREF (ax); if (!result) { return ErrorReturn (PDBWriteError, name); } Py_INCREF (Py_None); return Py_None; } static char PDBfile_write__doc__[]= "write (name, object) writes object to file under given name." ; static PyObject * PDBfile_write (PDBfileobject *self, PyObject *args) { char mode; char *name; PyObject *obj; int record; mode = _PDBfile_mode (self); if (mode != 'w' && mode == 'r') { return ErrorReturn (PDBWriteError, "File not open for writing."); } TRY(PyArg_ParseTuple (args, "sOi", &name, &obj, &record)); return _PDBfile_write (self->f, name, obj, record); } static struct PyMethodDef PDBfile_methods[] = { {"cd", (PyCFunction) PDBfile_cd, 1, PDBfile_cd__doc__}, {"close", (PyCFunction) PDBfile_close, 1, PDBfile_close__doc__}, {"filename", (PyCFunction) PDBfile_filename, 1, PDBfile_filename__doc__}, {"mode", (PyCFunction) PDBfile_mode, 1, PDBfile_mode__doc__}, {"offset", (PyCFunction) PDBfile_offset, 1, PDBfile_offset__doc__}, {"ln", (PyCFunction) PDBfile_ln, 1, PDBfile_ln__doc__}, {"ls", (PyCFunction) PDBfile_ls, 1, PDBfile_ls__doc__}, {"mkdir", (PyCFunction) PDBfile_mkdir, 1, PDBfile_mkdir__doc__}, {"open", (PyCFunction) PDBfile_open, 1, PDBfile_open__doc__}, {"create", (PyCFunction) PDBfile_create, 1, PDBfile_create__doc__}, {"open", (PyCFunction) PDBfile_append, 1, PDBfile_append__doc__}, {"pwd", (PyCFunction) PDBfile_pwd, 1, PDBfile_pwd__doc__}, {"read", (PyCFunction) PDBfile_read, 1, PDBfile_read__doc__}, {"type", (PyCFunction) PDBfile_type, 1, PDBfile_type__doc__}, {"shape", (PyCFunction) PDBfile_shape, 1, PDBfile_shape__doc__}, {"low", (PyCFunction) PDBfile_low, 1, PDBfile_low__doc__}, {"high", (PyCFunction) PDBfile_high, 1, PDBfile_high__doc__}, {"read_part", (PyCFunction) PDBfile_read_part,1, PDBfile_read_part__doc__}, {"is_column_major", (PyCFunction) PDBfile_is_column_major,1,PDBfile_is_column_major__doc__}, {"write", (PyCFunction) PDBfile_write, 1, PDBfile_write__doc__}, {NULL, NULL} /* sentinel */ }; /* ---------- */ static PDBfileobject * newPDBfileobject() { char *name, *access; PDBfileobject *self; self = PyObject_NEW(PDBfileobject, &PDBfiletype); if (self == NULL) return NULL; self->f = (PDBfile *) NULL; return self; } static PyObject * PDBfile_getattr(self, name) PDBfileobject *self; char *name; { return Py_FindMethod(PDBfile_methods, (PyObject *)self, name); } static char PDBfiletype__doc__[] = "PDB file reader." ; static PyTypeObject PDBfiletype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "PDBfile", /*tp_name*/ sizeof(PDBfileobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)PDBfile_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)PDBfile_getattr, /*tp_getattr*/ (setattrfunc)0, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ /* Space for future expansion */ 0L,0L,0L,0L, PDBfiletype__doc__ /* Documentation string */ }; /* End of code for PDBfile objects */ /* -------------------------------------------------------- */ static char pypdb_open__doc__[] = "Create a PDB file object open for read" ; static PyObject * pypdb_open (PyObject *self, PyObject *args) { PDBfileobject *pf; PyObject *result; char *name; pf = newPDBfileobject (); result = PDBfile_open (pf, args); if(result == (PyObject *) NULL) { Py_DECREF (pf); return result; } return (PyObject *) pf; } static char pypdb_create__doc__[] = "Create a PDB file object open for write" ; static PyObject * pypdb_create (PyObject *self, PyObject *args) { PDBfileobject *pf; PyObject *result; char *name; pf = newPDBfileobject (); result = PDBfile_create (pf, args); if(result == (PyObject *) NULL) { Py_DECREF (pf); return result; } return (PyObject *) pf; } static char pypdb_append__doc__[] = "Create a PDB file object open for append" ; static PyObject * pypdb_append (PyObject *self, PyObject *args) { PDBfileobject *pf; PyObject *result; char *name; pf = newPDBfileobject (); result = PDBfile_append (pf, args); if(result == (PyObject *) NULL) { Py_DECREF (pf); return result; } return (PyObject *) pf; } /* List of methods defined in the module */ static struct PyMethodDef pypdb_methods[] = { {"open", pypdb_open, 1, pypdb_open__doc__}, {"create", pypdb_create, 1, pypdb_create__doc__}, {"append", pypdb_append, 1, pypdb_append__doc__}, {NULL, NULL} /* sentinel */ }; /* Initialization function for the module (*must* be called initpypdb) */ static char pypdb_module_documentation[] = "Library of pdb file access methods." ; void initpypdb() { PyObject *m, *d; import_array(); /* Create the module and add the functions */ m = Py_InitModule4("pypdb", pypdb_methods, pypdb_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); PDBOpenError = PyString_FromString("pypdb.Error opening file"); PDBNameError = PyString_FromString("pypdb.Name not in file"); PypdbError = PyString_FromString("pypdb.Error reading file"); PDBWriteError = PyString_FromString("pypdb.Error writing file"); PDBIndexError = PyString_FromString("pypdb.Part-read index error"); PDBInternalError = PyString_FromString("pypdb.Internal error"); PyDict_SetItemString(d, "PDBOpenError", PDBOpenError); PyDict_SetItemString(d, "PDBNameError", PDBNameError); PyDict_SetItemString(d, "PypdbError", PypdbError); PyDict_SetItemString(d, "PDBWriteError", PDBWriteError); PyDict_SetItemString(d, "PDBIndexError", PDBIndexError); PyDict_SetItemString(d, "PDBInternalError", PDBInternalError); /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("Can't initialize module pypdb"); }