xref: /petsc/src/sys/objects/olist.c (revision f963788bda91a1d728e4d3144eba9dd2a8083b3a)
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;
96   PetscErrorCode ierr;
97 
98   PetscFunctionBegin;
99   while (fl) {
100     tmp   = fl->next;
101     ierr  = PetscObjectDereference(fl->obj);CHKERRQ(ierr);
102     ierr  = PetscFree(fl);CHKERRQ(ierr);
103     fl    = tmp;
104   }
105   PetscFunctionReturn(0);
106 }
107 
108 
109 #undef __FUNCT__
110 #define __FUNCT__ "PetscOListFind"
111 /*
112     PetscOListFind - givn a name, find the matching object
113 
114     Input Parameters:
115 +   fl   - pointer to list
116 -   name - name string
117 
118     Output Parameters:
119 .   ob - the PETSc object
120 
121     Notes:
122     The name must have been registered with the PetscOListAdd() before calling this
123     routine.
124 
125 .seealso: PetscOListReverseFind()
126 
127 */
128 PetscErrorCode PETSC_DLLEXPORT PetscOListFind(PetscOList fl,const char name[],PetscObject *obj)
129 {
130   PetscErrorCode ierr;
131   PetscTruth     match;
132 
133   PetscFunctionBegin;
134 
135   *obj = 0;
136   while (fl) {
137     ierr = PetscStrcmp(name,fl->name,&match);CHKERRQ(ierr);
138     if (match) {
139       *obj = fl->obj;
140       break;
141     }
142     fl = fl->next;
143   }
144   PetscFunctionReturn(0);
145 }
146 
147 #undef __FUNCT__
148 #define __FUNCT__ "PetscOListReverseFind"
149 /*
150     PetscOListReverseFind - given a object, find the matching name if it exists
151 
152     Input Parameters:
153 +   fl   - pointer to list
154 -   ob - the PETSc object
155 
156     Output Parameters:
157 .   name - name string
158 
159     Notes:
160     The name must have been registered with the PetscOListAdd() before calling this
161     routine.
162 
163 .seealso: PetscOListFind()
164 
165 */
166 PetscErrorCode PETSC_DLLEXPORT PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name)
167 {
168   PetscFunctionBegin;
169 
170   *name = 0;
171   while (fl) {
172     if (fl->obj == obj) {
173       *name = fl->name;
174       break;
175     }
176     fl = fl->next;
177   }
178   PetscFunctionReturn(0);
179 }
180 
181 
182 #undef __FUNCT__
183 #define __FUNCT__ "PetscOListDuplicate"
184 /*
185     PetscOListDuplicate - Creates a new list from a give object list.
186 
187     Input Parameters:
188 .   fl   - pointer to list
189 
190     Output Parameters:
191 .   nl - the new list (should point to 0 to start, otherwise appends)
192 
193 
194 */
195 PetscErrorCode PETSC_DLLEXPORT PetscOListDuplicate(PetscOList fl,PetscOList *nl)
196 {
197   PetscErrorCode ierr;
198 
199   PetscFunctionBegin;
200   while (fl) {
201     ierr = PetscOListAdd(nl,fl->name,fl->obj);CHKERRQ(ierr);
202     fl = fl->next;
203   }
204   PetscFunctionReturn(0);
205 }
206 
207 
208 
209 
210 
211