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