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, entry = *fl; 96 PetscErrorCode ierr; 97 98 PetscFunctionBegin; 99 while (entry) { 100 tmp = entry->next; 101 ierr = PetscObjectDereference(entry->obj);CHKERRQ(ierr); 102 ierr = PetscFree(entry);CHKERRQ(ierr); 103 entry = tmp; 104 } 105 *fl = 0; 106 PetscFunctionReturn(0); 107 } 108 109 110 #undef __FUNCT__ 111 #define __FUNCT__ "PetscOListFind" 112 /* 113 PetscOListFind - givn a name, find the matching object 114 115 Input Parameters: 116 + fl - pointer to list 117 - name - name string 118 119 Output Parameters: 120 . ob - the PETSc object 121 122 Notes: 123 The name must have been registered with the PetscOListAdd() before calling this 124 routine. 125 126 .seealso: PetscOListReverseFind() 127 128 */ 129 PetscErrorCode PETSC_DLLEXPORT PetscOListFind(PetscOList fl,const char name[],PetscObject *obj) 130 { 131 PetscErrorCode ierr; 132 PetscTruth match; 133 134 PetscFunctionBegin; 135 136 *obj = 0; 137 while (fl) { 138 ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr); 139 if (match) { 140 *obj = fl->obj; 141 break; 142 } 143 fl = fl->next; 144 } 145 PetscFunctionReturn(0); 146 } 147 148 #undef __FUNCT__ 149 #define __FUNCT__ "PetscOListReverseFind" 150 /* 151 PetscOListReverseFind - given a object, find the matching name if it exists 152 153 Input Parameters: 154 + fl - pointer to list 155 - ob - the PETSc object 156 157 Output Parameters: 158 . name - name string 159 160 Notes: 161 The name must have been registered with the PetscOListAdd() before calling this 162 routine. 163 164 .seealso: PetscOListFind() 165 166 */ 167 PetscErrorCode PETSC_DLLEXPORT PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name) 168 { 169 PetscFunctionBegin; 170 171 *name = 0; 172 while (fl) { 173 if (fl->obj == obj) { 174 *name = fl->name; 175 break; 176 } 177 fl = fl->next; 178 } 179 PetscFunctionReturn(0); 180 } 181 182 183 #undef __FUNCT__ 184 #define __FUNCT__ "PetscOListDuplicate" 185 /* 186 PetscOListDuplicate - Creates a new list from a give object list. 187 188 Input Parameters: 189 . fl - pointer to list 190 191 Output Parameters: 192 . nl - the new list (should point to 0 to start, otherwise appends) 193 194 195 */ 196 PetscErrorCode PETSC_DLLEXPORT PetscOListDuplicate(PetscOList fl,PetscOList *nl) 197 { 198 PetscErrorCode ierr; 199 200 PetscFunctionBegin; 201 while (fl) { 202 ierr = PetscOListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr); 203 fl = fl->next; 204 } 205 PetscFunctionReturn(0); 206 } 207 208 209 210 211 212