Actual source code: olist.c

  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

  8: struct _n_PetscOList {
  9:     char        name[256];
 10:     PetscObject obj;
 11:     PetscOList  next;
 12: };

 16: /*@C
 17:      PetscOListAdd - Adds a new object to an PetscOList

 19:     Input Parameters:
 20: +     fl - the object list
 21: .     name - the name to use for the object
 22: -     obj - the object to attach

 24:     Level: developer

 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

 30: .seealso: PetscOListDestroy(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()

 32: @*/
 33: PetscErrorCode  PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj)
 34: {
 35:   PetscOList     olist,nlist,prev;
 37:   PetscTruth     match;


 41:   if (!obj) { /* this means remove from list if it is there */
 42:     nlist = *fl; prev = 0;
 43:     while (nlist) {
 44:       PetscStrcmp(name,nlist->name,&match);
 45:       if (match) {  /* found it already in the list */
 46:         PetscObjectDereference(nlist->obj);
 47:         if (prev) prev->next = nlist->next;
 48:         else if (nlist->next) {
 49:           *fl = nlist->next;
 50:         } else {
 51:           *fl = 0;
 52:         }
 53:         PetscFree(nlist);
 54:         return(0);
 55:       }
 56:       prev  = nlist;
 57:       nlist = nlist->next;
 58:     }
 59:     return(0); /* did not find it to remove */
 60:   }
 61:   /* look for it already in list */
 62:   nlist = *fl;
 63:   while (nlist) {
 64:     PetscStrcmp(name,nlist->name,&match);
 65:     if (match) {  /* found it in the list */
 66:       PetscObjectReference(obj);
 67:       PetscObjectDereference(nlist->obj);
 68:       nlist->obj = obj;
 69:       return(0);
 70:     }
 71:     nlist = nlist->next;
 72:   }

 74:   /* add it to list, because it was not already there */

 76:   PetscNew(struct _n_PetscOList,&olist);
 77:   olist->next = 0;
 78:   olist->obj  = obj;
 79:   PetscObjectReference(obj);
 80:   PetscStrcpy(olist->name,name);

 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:   return(0);
 92: }

 96: /*@C
 97:     PetscOListDestroy - Destroy a list of objects

 99:     Input Parameter:
100: .   fl   - pointer to list

102:     Level: developer

104: .seealso: PetscOListAdd(), PetscOListFind(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()

106: @*/
107: PetscErrorCode  PetscOListDestroy(PetscOList fl)
108: {
109:   PetscOList     tmp;

113:   while (fl) {
114:     tmp   = fl->next;
115:     PetscObjectDereference(fl->obj);
116:     PetscFree(fl);
117:     fl    = tmp;
118:   }
119:   return(0);
120: }


125: /*@C
126:     PetscOListFind - givn a name, find the matching object

128:     Input Parameters:
129: +   fl   - pointer to list
130: -   name - name string

132:     Output Parameters:
133: .   ob - the PETSc object

135:     Level: developer

137:     Notes:
138:     The name must have been registered with the PetscOListAdd() before calling this 
139:     routine.

141: .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListReverseFind(), PetscOListDuplicate()

143: @*/
144: PetscErrorCode  PetscOListFind(PetscOList fl,const char name[],PetscObject *obj)
145: {
147:   PetscTruth     match;


151:   *obj = 0;
152:   while (fl) {
153:     PetscStrcmp(name,fl->name,&match);
154:     if (match) {
155:       *obj = fl->obj;
156:       break;
157:     }
158:     fl = fl->next;
159:   }
160:   return(0);
161: }

165: /*@C
166:     PetscOListReverseFind - given a object, find the matching name if it exists

168:     Input Parameters:
169: +   fl   - pointer to list
170: -   ob - the PETSc object

172:     Output Parameters:
173: .   name - name string

175:     Level: developer

177:     Notes:
178:     The name must have been registered with the PetscOListAdd() before calling this 
179:     routine.

181: .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListDuplicate(), PetscOListFind(), PetscOListDuplicate()

183: @*/
184: PetscErrorCode  PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name)
185: {

188:   *name = 0;
189:   while (fl) {
190:     if (fl->obj == obj) {
191:       *name = fl->name;
192:       break;
193:     }
194:     fl = fl->next;
195:   }
196:   return(0);
197: }

201: /*@C
202:     PetscOListDuplicate - Creates a new list from a give object list.

204:     Input Parameters:
205: .   fl   - pointer to list

207:     Output Parameters:
208: .   nl - the new list (should point to 0 to start, otherwise appends)

210:     Level: developer

212: .seealso: PetscOListDestroy(), PetscOListAdd(), PetscOListReverseFind(), PetscOListFind(), PetscOListDuplicate()

214: @*/
215: PetscErrorCode  PetscOListDuplicate(PetscOList fl,PetscOList *nl)
216: {

220:   while (fl) {
221:     PetscOListAdd(nl,fl->name,fl->obj);
222:     fl = fl->next;
223:   }
224:   return(0);
225: }