xref: /petsc/src/sys/objects/olist.c (revision 9a2402e950ff689ca19bdb3cbaeb3a7b77642051)
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