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