/* This file contain code to manipulate records in memory Y 25/10/92 */ #include "pdb.h" int first_water_type ; int second_water_type ; /* free an atom record. Part of the pointer in it maybe private to it, and the flags will tell us which. */ void free_atom_record(atom_record * atom) { if (atom != NULL) { int flags = atom->flags ; if (flags & MODIFIED_ATOM) free (atom->definition) ; free(atom) ; } } /* free the file_records structure and all the memory associated with it */ void free_file_records (file_records *file) { int ii = 0 ; for (ii = 0 ; ii < file->atomnum; ii++) free_atom_record (file->atoms[ii]) ; free (file->atoms); free_file_residues(file) ; maybe_free(file->name) ; maybe_free(file->header) ; free (file); } /* take two file_records structures and return one which contain them both */ file_records * merge_file_records(file_records * filea, file_records *fileb) { int sizea = filea->atomnum * sizeof(atom_record *) ; int sizeb = fileb->atomnum * sizeof(atom_record *) ; atom_record ** new = (atom_record **)malloc (sizeb + sizea) ; file_records *new_file = (file_records *)malloc(sizeof(file_records)) ; new_file->atomnum = filea->atomnum + fileb->atomnum ; new_file->atoms = new ; bcopy ( filea->atoms, new , sizea) ; bcopy (fileb->atoms ,(char *)new + sizea, sizeb ) ; return new_file ; } /* merge two files and free the old two */ file_records * merge_files_and_purge (file_records * filea, file_records *fileb) { file_records * new =merge_file_records(filea , fileb) ; free (filea->atoms); free (fileb->atoms); free_file_residues(filea); free_file_residues(fileb); free (filea) ; free(fileb) ; return new ; } /* traverse all the records in a file_records. the second argument is a function apply to the record and the third argument. This one go through all records, including non-atom. */ void traverse_all_file_records(file_records *file, void (*function)(), void * arg) { int ii ; for (ii = 0 ; ii < file->atomnum ; ii++) (*function)(file->atoms[ii], arg) ; } /* traverse PARTof the atom records in a file_records., starting from start. the second argument is a function apply to the record and the third argument. This one go only through the real atom records. */ void traverse_part_file_atoms(file_records *file, void (*function)(), void * arg,int start) { int ii ; for (ii = start ; ii < file->atomnum ; ii++) { atom_record * atom = file->atoms[ii]; int type = atom->atomtype ; if (RECORD_ATOM <= type) (*function)(atom , arg, ii) ; } } /* traverse all the atom records in a file_records. the second argument is a function apply to the record and the third argument. This one go only through the real atom records. */ void traverse_file_atom_records(file_records *file, void (*function)(), void * arg) { traverse_part_file_atoms(file,function,arg,0); } /* internal function, used by traverse_atom_pairs */ /* this one give two warnings : warning: argument passing between incompatible pointer types */ void traverse_rest_of_atoms(atom_record *atom, int (*kk[3])(),int index) { if (kk[2] == NULL || (*(kk[2]))(atom)) traverse_part_file_atoms((file_records *)kk[1],(void *)kk[0] , atom, index +1) ; } void traverse_atom_pairs (void *file, void *function, void *test) { void *kk[3]; kk[0] = (void *) function; kk[1] = (void *) file ; kk[2] = (void *)test ; traverse_file_atom_records(file,traverse_rest_of_atoms, kk); } void traverse_all_atom_pairs (file_records *file, void *function) { traverse_atom_pairs (file, function, NULL) ; } static void *protein_arg ; void do_only_protein(atom_record * atom, void(*function)(),int index) { if(PROTEIN_ATOM_P(atom)) (*function)(atom,protein_arg,index) ; } void traverse_file_protein_atoms(file_records *file, void (*function)(), void * arg) { protein_arg = arg; traverse_file_atom_records(file,do_only_protein,function) ; } static void *water_arg ; void do_only_water(atom_record * atom, void(*function)(),int index) { if (WATER_ATOM_P(atom)) (*function)(atom,water_arg,index) ; } void traverse_file_water_atoms(file_records *file, void (*function)(), void * arg) { water_arg = arg; traverse_file_atom_records(file,do_only_water,function) ; }