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 responsible 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; No Fortran Support

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

 47:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
 48:   if (!isstring) return 0;

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

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

 68:     Collective; No Fortran Support

 70:     Input Parameters:
 71: +   comm - the communicator
 72: .   string - the string to use
 73: -   len    - the string length

 75:     Output Parameter:
 76: .   lab - the `PetscViewer`

 78:     Level: advanced

 80: .seealso: [](sec_viewers), `PETSCVIEWERSTRING`, `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
 81: @*/
 82: PetscErrorCode PetscViewerStringOpen(MPI_Comm comm, char string[], size_t len, PetscViewer *lab)
 83: {
 84:   PetscViewerCreate(comm, lab);
 85:   PetscViewerSetType(*lab, PETSCVIEWERSTRING);
 86:   PetscViewerStringSetString(*lab, string, len);
 87:   return 0;
 88: }

 90: PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
 91: {
 92:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;

 94:   PetscViewerStringOpen(PETSC_COMM_SELF, vstr->head, vstr->maxlen - vstr->curlen, sviewer);
 95:   return 0;
 96: }

 98: PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
 99: {
100:   PetscViewer_String *iviewer = (PetscViewer_String *)(*sviewer)->data;
101:   PetscViewer_String *vstr    = (PetscViewer_String *)viewer->data;

103:   vstr->head = iviewer->head;
104:   vstr->curlen += iviewer->curlen;
105:   PetscViewerDestroy(sviewer);
106:   return 0;
107: }

109: /*MC
110:    PETSCVIEWERSTRING - A viewer that writes to a string

112:   Level: beginner

114: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PetscViewerStringSPrintf()`, `PetscViewerSocketOpen()`, `PetscViewerDrawOpen()`, `PETSCVIEWERSOCKET`,
115:           `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, `PETSCVIEWERDRAW`,
116:           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
117:           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
118: M*/

120: PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
121: {
122:   PetscViewer_String *vstr;

124:   v->ops->destroy          = PetscViewerDestroy_String;
125:   v->ops->view             = NULL;
126:   v->ops->flush            = NULL;
127:   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
128:   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
129:   PetscNew(&vstr);
130:   v->data      = (void *)vstr;
131:   vstr->string = NULL;
132:   return 0;
133: }

135: /*@C

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

139:    Logically Collective

141:   Input Parameter:
142: .   viewer -  `PETSCVIEWERSTRING` viewer

144:   Output Parameters:
145: +    string - the string, optional use NULL if you do not need
146: -   len - the length of the string, optional use NULL if you do

148:   Level: advanced

150:   Note:
151:   Do not write to the string nor free it

153: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
154:           `PetscViewerStringSetOwnString()`
155: @*/
156: PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer, const char *string[], size_t *len)
157: {
158:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
159:   PetscBool           isstring;

162:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
164:   if (string) *string = vstr->string;
165:   if (len) *len = vstr->maxlen;
166:   return 0;
167: }

169: /*@C

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

173:    Logically Collective

175:   Input Parameters:
176: +   viewer - string viewer you wish to attach string to
177: .   string - the string to print data into
178: -   len - the length of the string

180:   Level: advanced

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

188: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
189:           `PetscViewerStringSetOwnString()`
190: @*/
191: PetscErrorCode PetscViewerStringSetString(PetscViewer viewer, char string[], size_t len)
192: {
193:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
194:   PetscBool           isstring;

198:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
199:   if (!isstring) return 0;

202:   PetscArrayzero(string, len);
203:   vstr->string = string;
204:   vstr->head   = string;
205:   vstr->curlen = 0;
206:   vstr->maxlen = len;
207:   return 0;
208: }

210: /*@C

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

214:    Logically Collective

216:   Input Parameters:
217: .   viewer - string viewer

219:   Level: advanced

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

224: .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
225:           `PetscViewerStringSetString()`
226: @*/
227: PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer)
228: {
229:   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
230:   PetscBool           isstring;

233:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring);
234:   if (!isstring) return 0;

236:   vstr->ownstring = PETSC_TRUE;
237:   return 0;
238: }