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