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