1 #define PETSC_DLL 2 /* 3 Provides a general mechanism to maintain a linked list of PETSc objects. 4 This is used to allow PETSc objects to carry a list of "composed" objects 5 */ 6 #include "petsc.h" 7 #include "petscsys.h" 8 9 struct _n_PetscOList { 10 char name[256]; 11 PetscObject obj; 12 PetscOList next; 13 }; 14 15 #undef __FUNCT__ 16 #define __FUNCT__ "PetscOListAdd" 17 /* 18 19 Notes: Replaces item if it is already in list. Removes item if you pass in a 20 PETSC_NULL object. 21 22 .seealso: PetscOListDestroy() 23 */ 24 PetscErrorCode PETSC_DLLEXPORT PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj) 25 { 26 PetscOList olist,nlist,prev; 27 PetscErrorCode ierr; 28 PetscTruth match; 29 30 PetscFunctionBegin; 31 32 if (!obj) { /* this means remove from list if it is there */ 33 nlist = *fl; prev = 0; 34 while (nlist) { 35 ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 36 if (match) { /* found it already in the list */ 37 ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 38 if (prev) prev->next = nlist->next; 39 else if (nlist->next) { 40 *fl = nlist->next; 41 } else { 42 *fl = 0; 43 } 44 ierr = PetscFree(nlist);CHKERRQ(ierr); 45 PetscFunctionReturn(0); 46 } 47 prev = nlist; 48 nlist = nlist->next; 49 } 50 PetscFunctionReturn(0); /* did not find it to remove */ 51 } 52 /* look for it already in list */ 53 nlist = *fl; 54 while (nlist) { 55 ierr = PetscStrcmp(name,nlist->name,&match);CHKERRQ(ierr); 56 if (match) { /* found it in the list */ 57 ierr = PetscObjectReference(obj);CHKERRQ(ierr); 58 ierr = PetscObjectDereference(nlist->obj);CHKERRQ(ierr); 59 nlist->obj = obj; 60 PetscFunctionReturn(0); 61 } 62 nlist = nlist->next; 63 } 64 65 /* add it to list, because it was not already there */ 66 67 ierr = PetscNew(struct _n_PetscOList,&olist);CHKERRQ(ierr); 68 olist->next = 0; 69 olist->obj = obj; 70 ierr = PetscObjectReference(obj);CHKERRQ(ierr); 71 ierr = PetscStrcpy(olist->name,name);CHKERRQ(ierr); 72 73 if (!*fl) { 74 *fl = olist; 75 } else { /* go to end of list */ 76 nlist = *fl; 77 while (nlist->next) { 78 nlist = nlist->next; 79 } 80 nlist->next = olist; 81 } 82 PetscFunctionReturn(0); 83 } 84 85 #undef __FUNCT__ 86 #define __FUNCT__ "PetscOListDestroy" 87 /* 88 PetscOListDestroy - Destroy a list of objects 89 90 Input Parameter: 91 . fl - pointer to list 92 */ 93 PetscErrorCode PETSC_DLLEXPORT PetscOListDestroy(PetscOList fl) 94 { 95 PetscOList tmp; 96 PetscErrorCode ierr; 97 98 PetscFunctionBegin; 99 while (fl) { 100 tmp = fl->next; 101 ierr = PetscObjectDereference(fl->obj);CHKERRQ(ierr); 102 ierr = PetscFree(fl);CHKERRQ(ierr); 103 fl = tmp; 104 } 105 PetscFunctionReturn(0); 106 } 107 108 109 #undef __FUNCT__ 110 #define __FUNCT__ "PetscOListFind" 111 /* 112 PetscOListFind - givn a name, find the matching object 113 114 Input Parameters: 115 + fl - pointer to list 116 - name - name string 117 118 Output Parameters: 119 . ob - the PETSc object 120 121 Notes: 122 The name must have been registered with the PetscOListAdd() before calling this 123 routine. 124 125 .seealso: PetscOListReverseFind() 126 127 */ 128 PetscErrorCode PETSC_DLLEXPORT PetscOListFind(PetscOList fl,const char name[],PetscObject *obj) 129 { 130 PetscErrorCode ierr; 131 PetscTruth match; 132 133 PetscFunctionBegin; 134 135 *obj = 0; 136 while (fl) { 137 ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr); 138 if (match) { 139 *obj = fl->obj; 140 break; 141 } 142 fl = fl->next; 143 } 144 PetscFunctionReturn(0); 145 } 146 147 #undef __FUNCT__ 148 #define __FUNCT__ "PetscOListReverseFind" 149 /* 150 PetscOListReverseFind - given a object, find the matching name if it exists 151 152 Input Parameters: 153 + fl - pointer to list 154 - ob - the PETSc object 155 156 Output Parameters: 157 . name - name string 158 159 Notes: 160 The name must have been registered with the PetscOListAdd() before calling this 161 routine. 162 163 .seealso: PetscOListFind() 164 165 */ 166 PetscErrorCode PETSC_DLLEXPORT PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name) 167 { 168 PetscFunctionBegin; 169 170 *name = 0; 171 while (fl) { 172 if (fl->obj == obj) { 173 *name = fl->name; 174 break; 175 } 176 fl = fl->next; 177 } 178 PetscFunctionReturn(0); 179 } 180 181 182 #undef __FUNCT__ 183 #define __FUNCT__ "PetscOListDuplicate" 184 /* 185 PetscOListDuplicate - Creates a new list from a give object list. 186 187 Input Parameters: 188 . fl - pointer to list 189 190 Output Parameters: 191 . nl - the new list (should point to 0 to start, otherwise appends) 192 193 194 */ 195 PetscErrorCode PETSC_DLLEXPORT PetscOListDuplicate(PetscOList fl,PetscOList *nl) 196 { 197 PetscErrorCode ierr; 198 199 PetscFunctionBegin; 200 while (fl) { 201 ierr = PetscOListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr); 202 fl = fl->next; 203 } 204 PetscFunctionReturn(0); 205 } 206 207 208 209 210 211