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 beginning 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;

 15:   if (vstr->ownstring) PetscFree(vstr->string);
 16:   PetscFree(vstr);
 17:   return 0;
 18: }

 20: /*@C
 21:     PetscViewerStringSPrintf - Prints information to a `PETSCVIEWERSTRING` `PetscViewer` object

 23:     Logically Collective on viewer

 25:     Input Parameters:
 26: +   v - a string `PetscViewer`, formed by `PetscViewerStringOpen()`
 27: -   format - the format of the input

 29:     Level: developer

 31:     Note:
 32:     Though this is collective each MPI rank maintains a separate string

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

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

 50:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
 51:   if (!isstring) return 0;

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

 66: /*@C
 67:     PetscViewerStringOpen - Opens a string as a `PETSCVIEWERSTRING` `PetscViewer`. This is a very
 68:     simple `PetscViewer`; information on the object is simply stored into
 69:     the string in a fairly nice way.

 71:     Collective

 73:     Input Parameters:
 74: +   comm - the communicator
 75: .   string - the string to use
 76: -   len    - the string length

 78:     Output Parameter:
 79: .   lab - the `PetscViewer`

 81:     Level: advanced

 83:     Fortran Note:
 84:     This routine is not supported in Fortran.

 86: .seealso: `PETSCVIEWERSTRING`, `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
 87: @*/
 88: PetscErrorCode PetscViewerStringOpen(MPI_Comm comm, char string[], size_t len, PetscViewer *lab)
 89: {
 90:   PetscViewerCreate(comm, lab);
 91:   PetscViewerSetType(*lab, PETSCVIEWERSTRING);
 92:   PetscViewerStringSetString(*lab, string, len);
 93:   return 0;
 94: }

 96: PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
 97: {
 98:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;

100:   PetscViewerStringOpen(PETSC_COMM_SELF, vstr->head, vstr->maxlen - vstr->curlen, sviewer);
101:   return 0;
102: }

104: PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
105: {
106:   PetscViewer_String *iviewer = (PetscViewer_String *)(*sviewer)->data;
107:   PetscViewer_String *vstr    = (PetscViewer_String *)viewer->data;

109:   vstr->head = iviewer->head;
110:   vstr->curlen += iviewer->curlen;
111:   PetscViewerDestroy(sviewer);
112:   return 0;
113: }

115: /*MC
116:    PETSCVIEWERSTRING - A viewer that writes to a string

118:   Level: beginner

120: .seealso: `PetscViewerStringOpen()`, `PetscViewerStringSPrintf()`, `PetscViewerSocketOpen()`, `PetscViewerDrawOpen()`, `PETSCVIEWERSOCKET`,
121:           `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, `PETSCVIEWERDRAW`,
122:           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
123:           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
124: M*/

126: PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
127: {
128:   PetscViewer_String *vstr;

130:   v->ops->destroy          = PetscViewerDestroy_String;
131:   v->ops->view             = NULL;
132:   v->ops->flush            = NULL;
133:   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
134:   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
135:   PetscNew(&vstr);
136:   v->data      = (void *)vstr;
137:   vstr->string = NULL;
138:   return 0;
139: }

141: /*@C

143:    PetscViewerStringGetStringRead - Returns the string that a `PETSCVIEWERSTRING` uses

145:    Logically Collective on viewer

147:   Input Parameter:
148: .   viewer -  `PETSCVIEWERSTRING` viewer

150:   Output Parameters:
151: +    string - the string, optional use NULL if you do not need
152: -   len - the length of the string, optional use NULL if you do

154:   Note:
155:   Do not write to the string nor free it

157:   Level: advanced

159: .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
160:           `PetscViewerStringSetOwnString()`
161: @*/
162: PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer, const char *string[], size_t *len)
163: {
164:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
165:   PetscBool           isstring;

168:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
170:   if (string) *string = vstr->string;
171:   if (len) *len = vstr->maxlen;
172:   return 0;
173: }

175: /*@C

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

179:    Logically Collective on viewer

181:   Input Parameters:
182: +   viewer - string viewer you wish to attach string to
183: .   string - the string to print data into
184: -   len - the length of the string

186:   Note: The function does not copy the string, it uses it directly therefore you cannot free
187:    the string until the viewer is destroyed. If you call `PetscViewerStringSetOwnString()` the ownership
188:    passes to the viewer and it will be responsable for freeing it. In this case the string must be
189:    obtained with `PetscMalloc()`.

191:   Level: advanced

193: .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
194:           `PetscViewerStringSetOwnString()`
195: @*/
196: PetscErrorCode PetscViewerStringSetString(PetscViewer viewer, char string[], size_t len)
197: {
198:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
199:   PetscBool           isstring;

203:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
204:   if (!isstring) return 0;

207:   PetscArrayzero(string, len);
208:   vstr->string = string;
209:   vstr->head   = string;
210:   vstr->curlen = 0;
211:   vstr->maxlen = len;
212:   return 0;
213: }

215: /*@C

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

219:    Logically Collective on viewer

221:   Input Parameters:
222: .   viewer - string viewer

224:   Note:
225:   If you call this the string must have been obtained with `PetscMalloc()` and you cannot free the string

227:   Level: advanced

229: .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
230:           `PetscViewerStringSetString()`
231: @*/
232: PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer)
233: {
234:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
235:   PetscBool           isstring;

238:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
239:   if (!isstring) return 0;

241:   vstr->ownstring = PETSC_TRUE;
242:   return 0;
243: }