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