xref: /petsc/src/sys/classes/viewer/impls/string/stringv.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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;
836a9e3b9SBarry Smith   PetscBool ownstring; /* string viewer is responsable for freeing the string */
95c6c1daeSBarry Smith } PetscViewer_String;
105c6c1daeSBarry Smith 
11*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer)
12*d71ae5a4SJacob 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));
185c6c1daeSBarry Smith   PetscFunctionReturn(0);
195c6c1daeSBarry Smith }
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith /*@C
22811af0c4SBarry Smith     PetscViewerStringSPrintf - Prints information to a `PETSCVIEWERSTRING` `PetscViewer` object
235c6c1daeSBarry Smith 
24811af0c4SBarry Smith     Logically Collective on viewer
255c6c1daeSBarry Smith 
265c6c1daeSBarry Smith     Input Parameters:
27811af0c4SBarry Smith +   v - 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:
33811af0c4SBarry Smith     Though this is collective each MPI rank maintains a separate string
34811af0c4SBarry Smith 
355c6c1daeSBarry Smith     Fortran Note:
365c6c1daeSBarry Smith     This routine is not supported in Fortran.
375c6c1daeSBarry Smith 
38811af0c4SBarry Smith .seealso: `PETSCVIEWERSTRING`, `PetscViewerStringOpen()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
395c6c1daeSBarry Smith @*/
40*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSPrintf(PetscViewer viewer, const char format[], ...)
41*d71ae5a4SJacob Faibussowitsch {
425c6c1daeSBarry Smith   va_list             Argp;
435c6c1daeSBarry Smith   size_t              fullLength;
4489d949e2SBarry Smith   size_t              shift, cshift;
455c6c1daeSBarry Smith   PetscBool           isstring;
465c6c1daeSBarry Smith   char                tmp[4096];
475c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
485c6c1daeSBarry Smith 
495c6c1daeSBarry Smith   PetscFunctionBegin;
505c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
515c6c1daeSBarry Smith   PetscValidCharPointer(format, 2);
529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
535c6c1daeSBarry Smith   if (!isstring) PetscFunctionReturn(0);
5428b400f6SJacob Faibussowitsch   PetscCheck(vstr->string, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Must call PetscViewerStringSetString() before using");
555c6c1daeSBarry Smith 
565c6c1daeSBarry Smith   va_start(Argp, format);
579566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(tmp, 4096, format, &fullLength, Argp));
585c6c1daeSBarry Smith   va_end(Argp);
599566063dSJacob Faibussowitsch   PetscCall(PetscStrlen(tmp, &shift));
6089d949e2SBarry Smith   cshift = shift + 1;
6189d949e2SBarry Smith   if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1;
629566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(vstr->head, tmp, cshift));
635c6c1daeSBarry Smith   vstr->head += shift;
645c6c1daeSBarry Smith   vstr->curlen += shift;
655c6c1daeSBarry Smith   PetscFunctionReturn(0);
665c6c1daeSBarry Smith }
675c6c1daeSBarry Smith 
685c6c1daeSBarry Smith /*@C
69811af0c4SBarry Smith     PetscViewerStringOpen - Opens a string as a `PETSCVIEWERSTRING` `PetscViewer`. This is a very
70811af0c4SBarry Smith     simple `PetscViewer`; information on the object is simply stored into
715c6c1daeSBarry Smith     the string in a fairly nice way.
725c6c1daeSBarry Smith 
73d083f849SBarry Smith     Collective
745c6c1daeSBarry Smith 
755c6c1daeSBarry Smith     Input Parameters:
765c6c1daeSBarry Smith +   comm - the communicator
775c6c1daeSBarry Smith .   string - the string to use
785c6c1daeSBarry Smith -   len    - the string length
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith     Output Parameter:
81811af0c4SBarry Smith .   lab - the `PetscViewer`
825c6c1daeSBarry Smith 
835c6c1daeSBarry Smith     Level: advanced
845c6c1daeSBarry Smith 
855c6c1daeSBarry Smith     Fortran Note:
865c6c1daeSBarry Smith     This routine is not supported in Fortran.
875c6c1daeSBarry Smith 
88811af0c4SBarry Smith .seealso: `PETSCVIEWERSTRING`, `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
895c6c1daeSBarry Smith @*/
90*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringOpen(MPI_Comm comm, char string[], size_t len, PetscViewer *lab)
91*d71ae5a4SJacob Faibussowitsch {
925c6c1daeSBarry Smith   PetscFunctionBegin;
939566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm, lab));
949566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*lab, PETSCVIEWERSTRING));
959566063dSJacob Faibussowitsch   PetscCall(PetscViewerStringSetString(*lab, string, len));
965c6c1daeSBarry Smith   PetscFunctionReturn(0);
975c6c1daeSBarry Smith }
985c6c1daeSBarry Smith 
99*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
100*d71ae5a4SJacob Faibussowitsch {
1015c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
1025c6c1daeSBarry Smith 
1035c6c1daeSBarry Smith   PetscFunctionBegin;
1049566063dSJacob Faibussowitsch   PetscCall(PetscViewerStringOpen(PETSC_COMM_SELF, vstr->head, vstr->maxlen - vstr->curlen, sviewer));
1055c6c1daeSBarry Smith   PetscFunctionReturn(0);
1065c6c1daeSBarry Smith }
1075c6c1daeSBarry Smith 
108*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
109*d71ae5a4SJacob Faibussowitsch {
1105c6c1daeSBarry Smith   PetscViewer_String *iviewer = (PetscViewer_String *)(*sviewer)->data;
1115c6c1daeSBarry Smith   PetscViewer_String *vstr    = (PetscViewer_String *)viewer->data;
1125c6c1daeSBarry Smith 
1135c6c1daeSBarry Smith   PetscFunctionBegin;
1145c6c1daeSBarry Smith   vstr->head = iviewer->head;
1155c6c1daeSBarry Smith   vstr->curlen += iviewer->curlen;
1169566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(sviewer));
1175c6c1daeSBarry Smith   PetscFunctionReturn(0);
1185c6c1daeSBarry Smith }
1195c6c1daeSBarry Smith 
1208556b5ebSBarry Smith /*MC
1218556b5ebSBarry Smith    PETSCVIEWERSTRING - A viewer that writes to a string
1228556b5ebSBarry Smith 
123811af0c4SBarry Smith   Level: beginner
124811af0c4SBarry Smith 
125db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PetscViewerStringSPrintf()`, `PetscViewerSocketOpen()`, `PetscViewerDrawOpen()`, `PETSCVIEWERSOCKET`,
126db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, `PETSCVIEWERDRAW`,
127db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
128db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
1298556b5ebSBarry Smith M*/
1308556b5ebSBarry Smith 
131*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
132*d71ae5a4SJacob Faibussowitsch {
1335c6c1daeSBarry Smith   PetscViewer_String *vstr;
1345c6c1daeSBarry Smith 
1355c6c1daeSBarry Smith   PetscFunctionBegin;
1365c6c1daeSBarry Smith   v->ops->destroy          = PetscViewerDestroy_String;
13702c9f0b5SLisandro Dalcin   v->ops->view             = NULL;
13802c9f0b5SLisandro Dalcin   v->ops->flush            = NULL;
139559f443fSBarry Smith   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
140559f443fSBarry Smith   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
1414dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&vstr));
1425c6c1daeSBarry Smith   v->data      = (void *)vstr;
14302c9f0b5SLisandro Dalcin   vstr->string = NULL;
1445c6c1daeSBarry Smith   PetscFunctionReturn(0);
1455c6c1daeSBarry Smith }
1465c6c1daeSBarry Smith 
1475c6c1daeSBarry Smith /*@C
1485c6c1daeSBarry Smith 
149811af0c4SBarry Smith    PetscViewerStringGetStringRead - Returns the string that a `PETSCVIEWERSTRING` uses
15036a9e3b9SBarry Smith 
151811af0c4SBarry Smith    Logically Collective on viewer
15236a9e3b9SBarry Smith 
15336a9e3b9SBarry Smith   Input Parameter:
154811af0c4SBarry Smith .   viewer -  `PETSCVIEWERSTRING` viewer
15536a9e3b9SBarry Smith 
156fd292e60Sprj-   Output Parameters:
15736a9e3b9SBarry Smith +    string - the string, optional use NULL if you do not need
15836a9e3b9SBarry Smith -   len - the length of the string, optional use NULL if you do
15936a9e3b9SBarry Smith 
160811af0c4SBarry Smith   Note:
161811af0c4SBarry Smith   Do not write to the string nor free it
16236a9e3b9SBarry Smith 
16336a9e3b9SBarry Smith   Level: advanced
16436a9e3b9SBarry Smith 
165db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
166db781477SPatrick Sanan           `PetscViewerStringSetOwnString()`
16736a9e3b9SBarry Smith @*/
168*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer, const char *string[], size_t *len)
169*d71ae5a4SJacob Faibussowitsch {
17036a9e3b9SBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
17136a9e3b9SBarry Smith   PetscBool           isstring;
17236a9e3b9SBarry Smith 
17336a9e3b9SBarry Smith   PetscFunctionBegin;
17436a9e3b9SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
1759566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
17628b400f6SJacob Faibussowitsch   PetscCheck(isstring, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Only for PETSCVIEWERSTRING");
17736a9e3b9SBarry Smith   if (string) *string = vstr->string;
17836a9e3b9SBarry Smith   if (len) *len = vstr->maxlen;
17936a9e3b9SBarry Smith   PetscFunctionReturn(0);
18036a9e3b9SBarry Smith }
18136a9e3b9SBarry Smith 
18236a9e3b9SBarry Smith /*@C
18336a9e3b9SBarry Smith 
1845c6c1daeSBarry Smith    PetscViewerStringSetString - sets the string that a string viewer will print to
1855c6c1daeSBarry Smith 
186811af0c4SBarry Smith    Logically Collective on viewer
1875c6c1daeSBarry Smith 
1885c6c1daeSBarry Smith   Input Parameters:
1895c6c1daeSBarry Smith +   viewer - string viewer you wish to attach string to
1905c6c1daeSBarry Smith .   string - the string to print data into
1915c6c1daeSBarry Smith -   len - the length of the string
1925c6c1daeSBarry Smith 
193811af0c4SBarry Smith   Note: The function does not copy the string, it uses it directly therefore you cannot free
194811af0c4SBarry Smith    the string until the viewer is destroyed. If you call `PetscViewerStringSetOwnString()` the ownership
19536a9e3b9SBarry Smith    passes to the viewer and it will be responsable for freeing it. In this case the string must be
196811af0c4SBarry Smith    obtained with `PetscMalloc()`.
19736a9e3b9SBarry Smith 
1985c6c1daeSBarry Smith   Level: advanced
1995c6c1daeSBarry Smith 
200db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
201db781477SPatrick Sanan           `PetscViewerStringSetOwnString()`
2025c6c1daeSBarry Smith @*/
203*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSetString(PetscViewer viewer, char string[], size_t len)
204*d71ae5a4SJacob Faibussowitsch {
2055c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
2065c6c1daeSBarry Smith   PetscBool           isstring;
2075c6c1daeSBarry Smith 
2085c6c1daeSBarry Smith   PetscFunctionBegin;
2095c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2105c6c1daeSBarry Smith   PetscValidCharPointer(string, 2);
2119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
2125c6c1daeSBarry Smith   if (!isstring) PetscFunctionReturn(0);
21308401ef6SPierre Jolivet   PetscCheck(len > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "String must have length at least 2");
2145c6c1daeSBarry Smith 
2159566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(string, len));
2165c6c1daeSBarry Smith   vstr->string = string;
2175c6c1daeSBarry Smith   vstr->head   = string;
2185c6c1daeSBarry Smith   vstr->curlen = 0;
2195c6c1daeSBarry Smith   vstr->maxlen = len;
2205c6c1daeSBarry Smith   PetscFunctionReturn(0);
2215c6c1daeSBarry Smith }
2225c6c1daeSBarry Smith 
22336a9e3b9SBarry Smith /*@C
22436a9e3b9SBarry Smith 
22536a9e3b9SBarry Smith    PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it
22636a9e3b9SBarry Smith 
227811af0c4SBarry Smith    Logically Collective on viewer
22836a9e3b9SBarry Smith 
22936a9e3b9SBarry Smith   Input Parameters:
23036a9e3b9SBarry Smith .   viewer - string viewer
23136a9e3b9SBarry Smith 
232811af0c4SBarry Smith   Note:
233811af0c4SBarry Smith   If you call this the string must have been obtained with `PetscMalloc()` and you cannot free the string
23436a9e3b9SBarry Smith 
23536a9e3b9SBarry Smith   Level: advanced
23636a9e3b9SBarry Smith 
237db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
238db781477SPatrick Sanan           `PetscViewerStringSetString()`
23936a9e3b9SBarry Smith @*/
240*d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer)
241*d71ae5a4SJacob Faibussowitsch {
24236a9e3b9SBarry Smith   PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
24336a9e3b9SBarry Smith   PetscBool           isstring;
24436a9e3b9SBarry Smith 
24536a9e3b9SBarry Smith   PetscFunctionBegin;
24636a9e3b9SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2479566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
24836a9e3b9SBarry Smith   if (!isstring) PetscFunctionReturn(0);
24936a9e3b9SBarry Smith 
25036a9e3b9SBarry Smith   vstr->ownstring = PETSC_TRUE;
25136a9e3b9SBarry Smith   PetscFunctionReturn(0);
25236a9e3b9SBarry Smith }
253