Actual source code: olist.c
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
9: struct _n_PetscOList {
10: char name[256];
11: PetscObject obj;
12: PetscOList next;
13: };
17: /*
19: Notes: Replaces item if it is already in list. Removes item if you pass in a
20: PETSC_NULL object.
22: .seealso: PetscOListDestroy()
23: */
24: PetscErrorCode PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj)
25: {
26: PetscOList olist,nlist,prev;
28: PetscTruth match;
32: if (!obj) { /* this means remove from list if it is there */
33: nlist = *fl; prev = 0;
34: while (nlist) {
35: PetscStrcmp(name,nlist->name,&match);
36: if (match) { /* found it already in the list */
37: PetscObjectDereference(nlist->obj);
38: if (prev) prev->next = nlist->next;
39: else if (nlist->next) {
40: *fl = nlist->next;
41: } else {
42: *fl = 0;
43: }
44: PetscFree(nlist);
45: return(0);
46: }
47: prev = nlist;
48: nlist = nlist->next;
49: }
50: return(0); /* did not find it to remove */
51: }
52: /* look for it already in list */
53: nlist = *fl;
54: while (nlist) {
55: PetscStrcmp(name,nlist->name,&match);
56: if (match) { /* found it in the list */
57: PetscObjectDereference(nlist->obj);
58: PetscObjectReference(obj);
59: nlist->obj = obj;
60: return(0);
61: }
62: nlist = nlist->next;
63: }
65: /* add it to list, because it was not already there */
67: PetscNew(struct _n_PetscOList,&olist);
68: olist->next = 0;
69: olist->obj = obj;
70: PetscObjectReference(obj);
71: PetscStrcpy(olist->name,name);
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: return(0);
83: }
87: /*
88: PetscOListDestroy - Destroy a list of objects
90: Input Parameter:
91: . fl - pointer to list
92: */
93: PetscErrorCode PetscOListDestroy(PetscOList *fl)
94: {
95: PetscOList tmp, entry = *fl;
99: while (entry) {
100: tmp = entry->next;
101: PetscObjectDereference(entry->obj);
102: PetscFree(entry);
103: entry = tmp;
104: }
105: *fl = 0;
106: return(0);
107: }
112: /*
113: PetscOListFind - givn a name, find the matching object
115: Input Parameters:
116: + fl - pointer to list
117: - name - name string
119: Output Parameters:
120: . ob - the PETSc object
122: Notes:
123: The name must have been registered with the PetscOListAdd() before calling this
124: routine.
126: .seealso: PetscOListReverseFind()
128: */
129: PetscErrorCode PetscOListFind(PetscOList fl,const char name[],PetscObject *obj)
130: {
132: PetscTruth match;
136: *obj = 0;
137: while (fl) {
138: PetscStrcmp(name,fl->name,&match);
139: if (match) {
140: *obj = fl->obj;
141: break;
142: }
143: fl = fl->next;
144: }
145: return(0);
146: }
150: /*
151: PetscOListReverseFind - given a object, find the matching name if it exists
153: Input Parameters:
154: + fl - pointer to list
155: - ob - the PETSc object
157: Output Parameters:
158: . name - name string
160: Notes:
161: The name must have been registered with the PetscOListAdd() before calling this
162: routine.
164: .seealso: PetscOListFind()
166: */
167: PetscErrorCode PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name)
168: {
171: *name = 0;
172: while (fl) {
173: if (fl->obj == obj) {
174: *name = fl->name;
175: break;
176: }
177: fl = fl->next;
178: }
179: return(0);
180: }
185: /*
186: PetscOListDuplicate - Creates a new list from a give object list.
188: Input Parameters:
189: . fl - pointer to list
191: Output Parameters:
192: . nl - the new list (should point to 0 to start, otherwise appends)
195: */
196: PetscErrorCode PetscOListDuplicate(PetscOList fl,PetscOList *nl)
197: {
201: while (fl) {
202: PetscOListAdd(nl,fl->name,fl->obj);
203: fl = fl->next;
204: }
205: return(0);
206: }