Actual source code: olist.c
1: /*
2: Provides a general mechanism to maintain a linked list of PETSc objects.
3: This is used to allow PETSc objects to carry a list of "composed" objects
4: */
5: #include petsc.h
6: #include petscsys.h
8: struct _PetscOList {
9: char name[256];
10: PetscObject obj;
11: PetscOList next;
12: };
16: /*
18: Notes: Replaces item if it is already in list. Removes item if you pass in a
19: PETSC_NULL object.
21: .seealso: PetscOListDestroy()
22: */
23: PetscErrorCode PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj)
24: {
25: PetscOList olist,nlist,prev;
27: PetscTruth match;
31: if (!obj) { /* this means remove from list if it is there */
32: nlist = *fl; prev = 0;
33: while (nlist) {
34: PetscStrcmp(name,nlist->name,&match);
35: if (match) { /* found it already in the list */
36: PetscObjectDereference(nlist->obj);
37: if (prev) prev->next = nlist->next;
38: else if (nlist->next) {
39: *fl = nlist->next;
40: } else {
41: *fl = 0;
42: }
43: PetscFree(nlist);
44: return(0);
45: }
46: prev = nlist;
47: nlist = nlist->next;
48: }
49: return(0); /* did not find it to remove */
50: }
51: /* look for it already in list */
52: nlist = *fl;
53: while (nlist) {
54: PetscStrcmp(name,nlist->name,&match);
55: if (match) { /* found it in the list */
56: PetscObjectDereference(nlist->obj);
57: PetscObjectReference(obj);
58: nlist->obj = obj;
59: return(0);
60: }
61: nlist = nlist->next;
62: }
64: /* add it to list, because it was not already there */
66: PetscNew(struct _PetscOList,&olist);
67: olist->next = 0;
68: olist->obj = obj;
69: PetscObjectReference(obj);
70: PetscStrcpy(olist->name,name);
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: return(0);
82: }
86: /*
87: PetscOListDestroy - Destroy a list of objects
89: Input Parameter:
90: . fl - pointer to list
91: */
92: PetscErrorCode PetscOListDestroy(PetscOList *fl)
93: {
94: PetscOList tmp, entry = *fl;
98: while (entry) {
99: tmp = entry->next;
100: PetscObjectDereference(entry->obj);
101: PetscFree(entry);
102: entry = tmp;
103: }
104: *fl = 0;
105: return(0);
106: }
111: /*
112: PetscOListFind - givn a name, find the matching object
114: Input Parameters:
115: + fl - pointer to list
116: - name - name string
118: Output Parameters:
119: . ob - the PETSc object
121: Notes:
122: The name must have been registered with the PetscOListAdd() before calling this
123: routine.
125: .seealso: PetscOListReverseFind()
127: */
128: PetscErrorCode PetscOListFind(PetscOList fl,const char name[],PetscObject *obj)
129: {
131: PetscTruth match;
135: *obj = 0;
136: while (fl) {
137: PetscStrcmp(name,fl->name,&match);
138: if (match) {
139: *obj = fl->obj;
140: break;
141: }
142: fl = fl->next;
143: }
144: return(0);
145: }
149: /*
150: PetscOListReverseFind - given a object, find the matching name if it exists
152: Input Parameters:
153: + fl - pointer to list
154: - ob - the PETSc object
156: Output Parameters:
157: . name - name string
159: Notes:
160: The name must have been registered with the PetscOListAdd() before calling this
161: routine.
163: .seealso: PetscOListFind()
165: */
166: PetscErrorCode PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name)
167: {
170: *name = 0;
171: while (fl) {
172: if (fl->obj == obj) {
173: *name = fl->name;
174: break;
175: }
176: fl = fl->next;
177: }
178: return(0);
179: }
184: /*
185: PetscOListDuplicate - Creates a new list from a give object list.
187: Input Parameters:
188: . fl - pointer to list
190: Output Parameters:
191: . nl - the new list (should point to 0 to start, otherwise appends)
194: */
195: PetscErrorCode PetscOListDuplicate(PetscOList fl,PetscOList *nl)
196: {
200: while (fl) {
201: PetscOListAdd(nl,fl->name,fl->obj);
202: fl = fl->next;
203: }
204: return(0);
205: }