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 _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 PETSC_DLLEXPORT 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 _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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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: }