xref: /petsc/src/sys/classes/viewer/impls/string/stringv.c (revision aec76313382a76d73a95f2051cbe4b1eab55c1c7)
15c6c1daeSBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/viewerimpl.h> /*I  "petscsys.h"  I*/
35c6c1daeSBarry Smith 
45c6c1daeSBarry Smith typedef struct {
55c6c1daeSBarry Smith   char     *string; /* string where info is stored */
6a5b23f4aSJose E. Roman   char     *head;   /* pointer to beginning of unused portion */
75c6c1daeSBarry Smith   size_t    curlen, maxlen;
8da81f932SPierre Jolivet   PetscBool ownstring; /* string viewer is responsible for freeing the string */
95c6c1daeSBarry Smith } PetscViewer_String;
105c6c1daeSBarry Smith 
11d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer)
12d71ae5a4SJacob Faibussowitsch {
135c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
145c6c1daeSBarry Smith 
155c6c1daeSBarry Smith   PetscFunctionBegin;
161baa6e33SBarry Smith   if (vstr->ownstring) PetscCall(PetscFree(vstr->string));
179566063dSJacob Faibussowitsch   PetscCall(PetscFree(vstr));
183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
195c6c1daeSBarry Smith }
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith /*@C
22811af0c4SBarry Smith   PetscViewerStringSPrintf - Prints information to a `PETSCVIEWERSTRING` `PetscViewer` object
235c6c1daeSBarry Smith 
24cf53795eSBarry Smith   Logically Collective; No Fortran Support
255c6c1daeSBarry Smith 
265c6c1daeSBarry Smith   Input Parameters:
27*aec76313SJacob Faibussowitsch + viewer - a string `PetscViewer`, formed by `PetscViewerStringOpen()`
285c6c1daeSBarry Smith - format - the format of the input
295c6c1daeSBarry Smith 
305c6c1daeSBarry Smith   Level: developer
315c6c1daeSBarry Smith 
32811af0c4SBarry Smith   Note:
333f423023SBarry Smith   Though this is collective each MPI process maintains a separate string
34811af0c4SBarry Smith 
35d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERSTRING`, `PetscViewerStringOpen()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
365c6c1daeSBarry Smith @*/
37d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSPrintf(PetscViewer viewer, const char format[], ...)
38d71ae5a4SJacob Faibussowitsch {
395c6c1daeSBarry Smith   va_list             Argp;
405c6c1daeSBarry Smith   size_t              fullLength;
4189d949e2SBarry Smith   size_t              shift, cshift;
425c6c1daeSBarry Smith   PetscBool           isstring;
435c6c1daeSBarry Smith   char                tmp[4096];
445c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
455c6c1daeSBarry Smith 
465c6c1daeSBarry Smith   PetscFunctionBegin;
475c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
485c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
499566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
503ba16761SJacob Faibussowitsch   if (!isstring) PetscFunctionReturn(PETSC_SUCCESS);
5128b400f6SJacob Faibussowitsch   PetscCheck(vstr->string, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Must call PetscViewerStringSetString() before using");
525c6c1daeSBarry Smith 
535c6c1daeSBarry Smith   va_start(Argp, format);
549b15cf9aSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(tmp, sizeof(tmp), format, &fullLength, Argp));
555c6c1daeSBarry Smith   va_end(Argp);
569566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(tmp, &shift));
5789d949e2SBarry Smith   cshift = shift + 1;
5889d949e2SBarry Smith   if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1;
599b15cf9aSJacob Faibussowitsch   PetscCall(PetscMemcpy(vstr->head, tmp, cshift));
609b15cf9aSJacob Faibussowitsch   vstr->head[cshift - 1] = '\0';
615c6c1daeSBarry Smith   vstr->head += shift;
625c6c1daeSBarry Smith   vstr->curlen += shift;
633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
645c6c1daeSBarry Smith }
655c6c1daeSBarry Smith 
665c6c1daeSBarry Smith /*@C
67811af0c4SBarry Smith   PetscViewerStringOpen - Opens a string as a `PETSCVIEWERSTRING` `PetscViewer`. This is a very
68811af0c4SBarry Smith   simple `PetscViewer`; information on the object is simply stored into
695c6c1daeSBarry Smith   the string in a fairly nice way.
705c6c1daeSBarry Smith 
71cf53795eSBarry Smith   Collective; No Fortran Support
725c6c1daeSBarry Smith 
735c6c1daeSBarry Smith   Input Parameters:
745c6c1daeSBarry Smith + comm   - the communicator
755c6c1daeSBarry Smith . string - the string to use
765c6c1daeSBarry Smith - len    - the string length
775c6c1daeSBarry Smith 
785c6c1daeSBarry Smith   Output Parameter:
79811af0c4SBarry Smith . lab - the `PetscViewer`
805c6c1daeSBarry Smith 
815c6c1daeSBarry Smith   Level: advanced
825c6c1daeSBarry Smith 
83d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERSTRING`, `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
845c6c1daeSBarry Smith @*/
85d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringOpen(MPI_Comm comm, char string[], size_t len, PetscViewer *lab)
86d71ae5a4SJacob Faibussowitsch {
875c6c1daeSBarry Smith   PetscFunctionBegin;
889566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, lab));
899566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*lab, PETSCVIEWERSTRING));
909566063dSJacob Faibussowitsch   PetscCall(PetscViewerStringSetString(*lab, string, len));
913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
925c6c1daeSBarry Smith }
935c6c1daeSBarry Smith 
94d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
95d71ae5a4SJacob Faibussowitsch {
965c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
975c6c1daeSBarry Smith 
985c6c1daeSBarry Smith   PetscFunctionBegin;
999566063dSJacob Faibussowitsch   PetscCall(PetscViewerStringOpen(PETSC_COMM_SELF, vstr->head, vstr->maxlen - vstr->curlen, sviewer));
1003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1015c6c1daeSBarry Smith }
1025c6c1daeSBarry Smith 
103d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
104d71ae5a4SJacob Faibussowitsch {
1055c6c1daeSBarry Smith   PetscViewer_String *iviewer = (PetscViewer_String *)(*sviewer)->data;
1065c6c1daeSBarry Smith   PetscViewer_String *vstr    = (PetscViewer_String *)viewer->data;
1075c6c1daeSBarry Smith 
1085c6c1daeSBarry Smith   PetscFunctionBegin;
1095c6c1daeSBarry Smith   vstr->head = iviewer->head;
1105c6c1daeSBarry Smith   vstr->curlen += iviewer->curlen;
1119566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(sviewer));
1123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1135c6c1daeSBarry Smith }
1145c6c1daeSBarry Smith 
1158556b5ebSBarry Smith /*MC
1168556b5ebSBarry Smith    PETSCVIEWERSTRING - A viewer that writes to a string
1178556b5ebSBarry Smith 
118811af0c4SBarry Smith   Level: beginner
119811af0c4SBarry Smith 
120d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PetscViewerStringSPrintf()`, `PetscViewerSocketOpen()`, `PetscViewerDrawOpen()`, `PETSCVIEWERSOCKET`,
121db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, `PETSCVIEWERDRAW`,
122db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
123db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
1248556b5ebSBarry Smith M*/
1258556b5ebSBarry Smith 
126d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
127d71ae5a4SJacob Faibussowitsch {
1285c6c1daeSBarry Smith   PetscViewer_String *vstr;
1295c6c1daeSBarry Smith 
1305c6c1daeSBarry Smith   PetscFunctionBegin;
1315c6c1daeSBarry Smith   v->ops->destroy          = PetscViewerDestroy_String;
13202c9f0b5SLisandro Dalcin   v->ops->view             = NULL;
13302c9f0b5SLisandro Dalcin   v->ops->flush            = NULL;
134559f443fSBarry Smith   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
135559f443fSBarry Smith   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
1364dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vstr));
1375c6c1daeSBarry Smith   v->data      = (void *)vstr;
13802c9f0b5SLisandro Dalcin   vstr->string = NULL;
1393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1405c6c1daeSBarry Smith }
1415c6c1daeSBarry Smith 
1425c6c1daeSBarry Smith /*@C
1435c6c1daeSBarry Smith 
144811af0c4SBarry Smith   PetscViewerStringGetStringRead - Returns the string that a `PETSCVIEWERSTRING` uses
14536a9e3b9SBarry Smith 
146c3339decSBarry Smith   Logically Collective
14736a9e3b9SBarry Smith 
14836a9e3b9SBarry Smith   Input Parameter:
149811af0c4SBarry Smith . viewer - `PETSCVIEWERSTRING` viewer
15036a9e3b9SBarry Smith 
151fd292e60Sprj-   Output Parameters:
15236a9e3b9SBarry Smith + string - the string, optional use NULL if you do not need
15336a9e3b9SBarry Smith - len    - the length of the string, optional use NULL if you do
15436a9e3b9SBarry Smith 
155d1f92df0SBarry Smith   Level: advanced
156d1f92df0SBarry Smith 
157811af0c4SBarry Smith   Note:
158811af0c4SBarry Smith   Do not write to the string nor free it
15936a9e3b9SBarry Smith 
160d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
161db781477SPatrick Sanan           `PetscViewerStringSetOwnString()`
16236a9e3b9SBarry Smith @*/
163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer, const char *string[], size_t *len)
164d71ae5a4SJacob Faibussowitsch {
16536a9e3b9SBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
16636a9e3b9SBarry Smith   PetscBool           isstring;
16736a9e3b9SBarry Smith 
16836a9e3b9SBarry Smith   PetscFunctionBegin;
16936a9e3b9SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
1709566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
17128b400f6SJacob Faibussowitsch   PetscCheck(isstring, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Only for PETSCVIEWERSTRING");
17236a9e3b9SBarry Smith   if (string) *string = vstr->string;
17336a9e3b9SBarry Smith   if (len) *len = vstr->maxlen;
1743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
17536a9e3b9SBarry Smith }
17636a9e3b9SBarry Smith 
17736a9e3b9SBarry Smith /*@C
17836a9e3b9SBarry Smith 
1795c6c1daeSBarry Smith   PetscViewerStringSetString - sets the string that a string viewer will print to
1805c6c1daeSBarry Smith 
181c3339decSBarry Smith   Logically Collective
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith   Input Parameters:
1845c6c1daeSBarry Smith + viewer - string viewer you wish to attach string to
1855c6c1daeSBarry Smith . string - the string to print data into
1865c6c1daeSBarry Smith - len    - the length of the string
1875c6c1daeSBarry Smith 
188d1f92df0SBarry Smith   Level: advanced
189d1f92df0SBarry Smith 
190d1f92df0SBarry Smith   Note:
191d1f92df0SBarry Smith   The function does not copy the string, it uses it directly therefore you cannot free
192811af0c4SBarry Smith   the string until the viewer is destroyed. If you call `PetscViewerStringSetOwnString()` the ownership
193da81f932SPierre Jolivet   passes to the viewer and it will be responsible for freeing it. In this case the string must be
194811af0c4SBarry Smith   obtained with `PetscMalloc()`.
19536a9e3b9SBarry Smith 
196d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
197db781477SPatrick Sanan           `PetscViewerStringSetOwnString()`
1985c6c1daeSBarry Smith @*/
199d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSetString(PetscViewer viewer, char string[], size_t len)
200d71ae5a4SJacob Faibussowitsch {
2015c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
2025c6c1daeSBarry Smith   PetscBool           isstring;
2035c6c1daeSBarry Smith 
2045c6c1daeSBarry Smith   PetscFunctionBegin;
2055c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2065c6c1daeSBarry Smith   PetscValidCharPointer(string, 2);
2079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
2083ba16761SJacob Faibussowitsch   if (!isstring) PetscFunctionReturn(PETSC_SUCCESS);
20908401ef6SPierre Jolivet   PetscCheck(len > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "String must have length at least 2");
2105c6c1daeSBarry Smith 
2119566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(string, len));
2125c6c1daeSBarry Smith   vstr->string = string;
2135c6c1daeSBarry Smith   vstr->head   = string;
2145c6c1daeSBarry Smith   vstr->curlen = 0;
2155c6c1daeSBarry Smith   vstr->maxlen = len;
2163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2175c6c1daeSBarry Smith }
2185c6c1daeSBarry Smith 
21936a9e3b9SBarry Smith /*@C
22036a9e3b9SBarry Smith 
22136a9e3b9SBarry Smith   PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it
22236a9e3b9SBarry Smith 
223c3339decSBarry Smith   Logically Collective
22436a9e3b9SBarry Smith 
2252fe279fdSBarry Smith   Input Parameter:
22636a9e3b9SBarry Smith . viewer - string viewer
22736a9e3b9SBarry Smith 
228d1f92df0SBarry Smith   Level: advanced
229d1f92df0SBarry Smith 
230811af0c4SBarry Smith   Note:
231811af0c4SBarry Smith   If you call this the string must have been obtained with `PetscMalloc()` and you cannot free the string
23236a9e3b9SBarry Smith 
233d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
234db781477SPatrick Sanan           `PetscViewerStringSetString()`
23536a9e3b9SBarry Smith @*/
236d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer)
237d71ae5a4SJacob Faibussowitsch {
23836a9e3b9SBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
23936a9e3b9SBarry Smith   PetscBool           isstring;
24036a9e3b9SBarry Smith 
24136a9e3b9SBarry Smith   PetscFunctionBegin;
24236a9e3b9SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2439566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
2443ba16761SJacob Faibussowitsch   if (!isstring) PetscFunctionReturn(PETSC_SUCCESS);
24536a9e3b9SBarry Smith 
24636a9e3b9SBarry Smith   vstr->ownstring = PETSC_TRUE;
2473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24836a9e3b9SBarry Smith }
249