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: PetscObjectReference(obj);
58: PetscObjectDereference(nlist->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;
99: while (fl) {
100: tmp = fl->next;
101: PetscObjectDereference(fl->obj);
102: PetscFree(fl);
103: fl = tmp;
104: }
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: }