Actual source code: olist.c
1: /*$Id: olist.c,v 1.22 2001/03/23 23:20:38 balay Exp $*/
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 _PetscOList {
10: char name[128];
11: PetscObject obj;
12: PetscOList next;
13: };
15: /*
17: Notes: Replaces item if it is already in list. Removes item if you pass in a
18: PETSC_NULL object.
20: .seealso: PetscOListDestroy()
21: */
22: int PetscOListAdd(PetscOList *fl,const char name[],PetscObject obj)
23: {
24: PetscOList olist,nlist,prev;
25: int ierr;
26: PetscTruth match;
30: if (!obj) { /* this means remove from list if it is there */
31: nlist = *fl; prev = 0;
32: while (nlist) {
33: PetscStrcmp(name,nlist->name,&match);
34: if (match) { /* found it already in the list */
35: PetscObjectDereference(nlist->obj);
36: if (prev) prev->next = nlist->next;
37: else if (nlist->next) {
38: *fl = nlist->next;
39: } else {
40: *fl = 0;
41: }
42: PetscFree(nlist);
43: return(0);
44: }
45: prev = nlist;
46: nlist = nlist->next;
47: }
48: return(0); /* did not find it to remove */
49: }
50: /* look for it already in list */
51: nlist = *fl;
52: while (nlist) {
53: PetscStrcmp(name,nlist->name,&match);
54: if (match) { /* found it in the list */
55: PetscObjectDereference(nlist->obj);
56: PetscObjectReference(obj);
57: nlist->obj = obj;
58: return(0);
59: }
60: nlist = nlist->next;
61: }
63: /* add it to list, because it was not already there */
65: ierr = PetscNew(struct _PetscOList,&olist);
66: olist->next = 0;
67: olist->obj = obj;
68: PetscObjectReference(obj);
69: PetscStrcpy(olist->name,name);
71: if (!*fl) {
72: *fl = olist;
73: } else { /* go to end of list */
74: nlist = *fl;
75: while (nlist->next) {
76: nlist = nlist->next;
77: }
78: nlist->next = olist;
79: }
80: return(0);
81: }
83: /*
84: PetscOListDestroy - Destroy a list of objects
86: Input Parameter:
87: . fl - pointer to list
88: */
89: int PetscOListDestroy(PetscOList *fl)
90: {
91: PetscOList tmp, entry = *fl;
92: int ierr;
95: while (entry) {
96: tmp = entry->next;
97: ierr = PetscObjectDereference(entry->obj);
98: ierr = PetscFree(entry);
99: entry = tmp;
100: }
101: *fl = 0;
102: return(0);
103: }
106: /*
107: PetscOListFind - givn a name, find the matching object
109: Input Parameters:
110: + fl - pointer to list
111: - name - name string
113: Output Parameters:
114: . ob - the PETSc object
116: Notes:
117: The name must have been registered with the PetscOListAdd() before calling this
118: routine.
120: .seealso: PetscOListReverseFind()
122: */
123: int PetscOListFind(PetscOList fl,const char name[],PetscObject *obj)
124: {
125: int ierr;
126: PetscTruth match;
130: *obj = 0;
131: while (fl) {
132: PetscStrcmp(name,fl->name,&match);
133: if (match) {
134: *obj = fl->obj;
135: break;
136: }
137: fl = fl->next;
138: }
139: return(0);
140: }
142: /*
143: PetscOListReverseFind - given a object, find the matching name if it exists
145: Input Parameters:
146: + fl - pointer to list
147: - ob - the PETSc object
149: Output Parameters:
150: . name - name string
152: Notes:
153: The name must have been registered with the PetscOListAdd() before calling this
154: routine.
156: .seealso: PetscOListFind()
158: */
159: int PetscOListReverseFind(PetscOList fl,PetscObject obj,char **name)
160: {
163: *name = 0;
164: while (fl) {
165: if (fl->obj == obj) {
166: *name = fl->name;
167: break;
168: }
169: fl = fl->next;
170: }
171: return(0);
172: }
175: /*
176: PetscOListDuplicate - Creates a new list from a give object list.
178: Input Parameters:
179: . fl - pointer to list
181: Output Parameters:
182: . nl - the new list (should point to 0 to start, otherwise appends)
185: */
186: int PetscOListDuplicate(PetscOList fl,PetscOList *nl)
187: {
191: while (fl) {
192: PetscOListAdd(nl,fl->name,fl->obj);
193: fl = fl->next;
194: }
195: return(0);
196: }