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