Actual source code: stringv.c

      2: #include <petsc/private/viewerimpl.h>

      4: typedef struct  {
      5:   char      *string;         /* string where info is stored */
      6:   char      *head;           /* pointer to begining of unused portion */
      7:   size_t    curlen,maxlen;
      8:   PetscBool ownstring;       /* string viewer is responsable for freeing the string */
      9: } PetscViewer_String;

     11: static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer)
     12: {
     13:   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
     14:   PetscErrorCode     ierr;

     17:   if (vstr->ownstring) {
     18:     PetscFree(vstr->string);
     19:   }
     20:   PetscFree(vstr);
     21:   return(0);
     22: }

     24: /*@C
     25:     PetscViewerStringSPrintf - Prints information to a PetscViewer string.

     27:     Logically Collective on PetscViewer (Hmmm, each processor maintains a separate string)

     29:     Input Parameters:
     30: +   v - a string PetscViewer, formed by PetscViewerStringOpen()
     31: -   format - the format of the input

     33:     Level: developer

     35:     Fortran Note:
     36:     This routine is not supported in Fortran.

     38: .seealso: PetscViewerStringOpen(), PetscViewerStringGetStringRead(), PetscViewerStringSetString(), PETSCVIEWERSTRING
     39: @*/
     40: PetscErrorCode  PetscViewerStringSPrintf(PetscViewer viewer,const char format[],...)
     41: {
     42:   va_list            Argp;
     43:   size_t             fullLength;
     44:   size_t             shift,cshift;
     45:   PetscErrorCode     ierr;
     46:   PetscBool          isstring;
     47:   char               tmp[4096];
     48:   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;

     53:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
     54:   if (!isstring) return(0);
     55:   if (!vstr->string) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerStringSetString() before using");

     57:   va_start(Argp,format);
     58:   PetscVSNPrintf(tmp,4096,format,&fullLength,Argp);
     59:   va_end(Argp);
     60:   PetscStrlen(tmp,&shift);
     61:   cshift = shift+1;
     62:   if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1;
     63:   PetscStrncpy(vstr->head,tmp,cshift);
     64:   vstr->head   += shift;
     65:   vstr->curlen += shift;
     66:   return(0);
     67: }

     69: /*@C
     70:     PetscViewerStringOpen - Opens a string as a PetscViewer. This is a very
     71:     simple PetscViewer; information on the object is simply stored into
     72:     the string in a fairly nice way.

     74:     Collective

     76:     Input Parameters:
     77: +   comm - the communicator
     78: .   string - the string to use
     79: -   len    - the string length

     81:     Output Parameter:
     82: .   lab - the PetscViewer

     84:     Level: advanced

     86:     Fortran Note:
     87:     This routine is not supported in Fortran.

     89: .seealso: PetscViewerDestroy(), PetscViewerStringSPrintf(), PetscViewerStringGetStringRead(), PetscViewerStringSetString(), PETSCVIEWERSTRING
     90: @*/
     91: PetscErrorCode  PetscViewerStringOpen(MPI_Comm comm,char string[],size_t len,PetscViewer *lab)
     92: {

     96:   PetscViewerCreate(comm,lab);
     97:   PetscViewerSetType(*lab,PETSCVIEWERSTRING);
     98:   PetscViewerStringSetString(*lab,string,len);
     99:   return(0);
    100: }

    102: PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
    103: {
    104:   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
    105:   PetscErrorCode     ierr;

    108:   PetscViewerStringOpen(PETSC_COMM_SELF,vstr->head,vstr->maxlen-vstr->curlen,sviewer);
    109:   return(0);
    110: }

    112: PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
    113: {
    114:   PetscErrorCode     ierr;
    115:   PetscViewer_String *iviewer = (PetscViewer_String*)(*sviewer)->data;
    116:   PetscViewer_String *vstr    = (PetscViewer_String*)viewer->data;

    119:   vstr->head    = iviewer->head;
    120:   vstr->curlen += iviewer->curlen;
    121:   PetscViewerDestroy(sviewer);
    122:   return(0);
    123: }

    125: /*MC
    126:    PETSCVIEWERSTRING - A viewer that writes to a string

    129: .seealso:  PetscViewerStringOpen(), PetscViewerStringSPrintf(), PetscViewerSocketOpen(), PetscViewerDrawOpen(), PETSCVIEWERSOCKET,
    130:            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, PETSCVIEWERDRAW,
    131:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
    132:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

    134:   Level: beginner
    135: M*/

    137: PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
    138: {
    139:   PetscViewer_String *vstr;
    140:   PetscErrorCode     ierr;

    143:   v->ops->destroy          = PetscViewerDestroy_String;
    144:   v->ops->view             = NULL;
    145:   v->ops->flush            = NULL;
    146:   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
    147:   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
    148:   PetscNewLog(v,&vstr);
    149:   v->data                  = (void*)vstr;
    150:   vstr->string             = NULL;
    151:   return(0);
    152: }

    154: /*@C

    156:    PetscViewerStringGetStringRead - Returns the string that a string viewer uses

    158:    Logically Collective on PetscViewer

    160:   Input Parameter:
    161: .   viewer - string viewer

    163:   Output Parameters:
    164: +    string - the string, optional use NULL if you do not need
    165: -   len - the length of the string, optional use NULL if you do

    167:   Notes: Do not write to the string nor free it

    169:   Level: advanced

    171: .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringSetString(), PetscViewerStringSPrintf(),
    172:           PetscViewerStringSetOwnString()
    173: @*/
    174: PetscErrorCode  PetscViewerStringGetStringRead(PetscViewer viewer,const char *string[],size_t *len)
    175: {
    176:   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
    177:   PetscErrorCode     ierr;
    178:   PetscBool          isstring;

    182:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    183:   if (!isstring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Only for PETSCVIEWERSTRING");
    184:   if (string) *string = vstr->string;
    185:   if (len)    *len    = vstr->maxlen;
    186:   return(0);
    187: }

    189: /*@C

    191:    PetscViewerStringSetString - sets the string that a string viewer will print to

    193:    Logically Collective on PetscViewer

    195:   Input Parameters:
    196: +   viewer - string viewer you wish to attach string to
    197: .   string - the string to print data into
    198: -   len - the length of the string

    200:   Notes: The function does not copy the string, it uses it directly therefore you cannot free
    201:    the string until the viewer is destroyed. If you call PetscViewerStringSetOwnString() the ownership
    202:    passes to the viewer and it will be responsable for freeing it. In this case the string must be
    203:    obtained with PetscMalloc().

    205:   Level: advanced

    207: .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(),
    208:           PetscViewerStringSetOwnString()
    209: @*/
    210: PetscErrorCode  PetscViewerStringSetString(PetscViewer viewer,char string[],size_t len)
    211: {
    212:   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
    213:   PetscErrorCode     ierr;
    214:   PetscBool          isstring;

    219:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    220:   if (!isstring) return(0);
    221:   if (len <= 2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"String must have length at least 2");

    223:   PetscArrayzero(string,len);
    224:   vstr->string = string;
    225:   vstr->head   = string;
    226:   vstr->curlen = 0;
    227:   vstr->maxlen = len;
    228:   return(0);
    229: }

    231: /*@C

    233:    PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it

    235:    Logically Collective on PetscViewer

    237:   Input Parameters:
    238: .   viewer - string viewer

    240:   Notes: If you call this the string must have been obtained with PetscMalloc() and you cannot free the string

    242:   Level: advanced

    244: .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(),
    245:           PetscViewerStringSetString()
    246: @*/
    247: PetscErrorCode  PetscViewerStringSetOwnString(PetscViewer viewer)
    248: {
    249:   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
    250:   PetscErrorCode     ierr;
    251:   PetscBool          isstring;

    255:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
    256:   if (!isstring) return(0);

    258:   vstr->ownstring = PETSC_TRUE;
    259:   return(0);
    260: }