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