1af0996ceSBarry Smith #include <petsc/private/viewerimpl.h> /*I "petscsys.h" I*/
25c6c1daeSBarry Smith
35c6c1daeSBarry Smith typedef struct {
45c6c1daeSBarry Smith char *string; /* string where info is stored */
5a5b23f4aSJose E. Roman char *head; /* pointer to beginning of unused portion */
65c6c1daeSBarry Smith size_t curlen, maxlen;
7da81f932SPierre Jolivet PetscBool ownstring; /* string viewer is responsible for freeing the string */
85c6c1daeSBarry Smith } PetscViewer_String;
95c6c1daeSBarry Smith
PetscViewerDestroy_String(PetscViewer viewer)10d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer)
11d71ae5a4SJacob Faibussowitsch {
125c6c1daeSBarry Smith PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
135c6c1daeSBarry Smith
145c6c1daeSBarry Smith PetscFunctionBegin;
151baa6e33SBarry Smith if (vstr->ownstring) PetscCall(PetscFree(vstr->string));
169566063dSJacob Faibussowitsch PetscCall(PetscFree(vstr));
173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
185c6c1daeSBarry Smith }
195c6c1daeSBarry Smith
205c6c1daeSBarry Smith /*@C
21811af0c4SBarry Smith PetscViewerStringSPrintf - Prints information to a `PETSCVIEWERSTRING` `PetscViewer` object
225c6c1daeSBarry Smith
23cf53795eSBarry Smith Logically Collective; No Fortran Support
245c6c1daeSBarry Smith
255c6c1daeSBarry Smith Input Parameters:
26aec76313SJacob Faibussowitsch + viewer - a string `PetscViewer`, formed by `PetscViewerStringOpen()`
275c6c1daeSBarry Smith - format - the format of the input
285c6c1daeSBarry Smith
295c6c1daeSBarry Smith Level: developer
305c6c1daeSBarry Smith
31811af0c4SBarry Smith Note:
323f423023SBarry Smith Though this is collective each MPI process maintains a separate string
33811af0c4SBarry Smith
34d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERSTRING`, `PetscViewerStringOpen()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
355c6c1daeSBarry Smith @*/
PetscViewerStringSPrintf(PetscViewer viewer,const char format[],...)36d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSPrintf(PetscViewer viewer, const char format[], ...)
37d71ae5a4SJacob Faibussowitsch {
385c6c1daeSBarry Smith va_list Argp;
395c6c1daeSBarry Smith size_t fullLength;
4089d949e2SBarry Smith size_t shift, cshift;
415c6c1daeSBarry Smith PetscBool isstring;
425c6c1daeSBarry Smith char tmp[4096];
435c6c1daeSBarry Smith PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
445c6c1daeSBarry Smith
455c6c1daeSBarry Smith PetscFunctionBegin;
465c6c1daeSBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
474f572ea9SToby Isaac PetscAssertPointer(format, 2);
489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
493ba16761SJacob Faibussowitsch if (!isstring) PetscFunctionReturn(PETSC_SUCCESS);
5028b400f6SJacob Faibussowitsch PetscCheck(vstr->string, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Must call PetscViewerStringSetString() before using");
515c6c1daeSBarry Smith
525c6c1daeSBarry Smith va_start(Argp, format);
539b15cf9aSJacob Faibussowitsch PetscCall(PetscVSNPrintf(tmp, sizeof(tmp), format, &fullLength, Argp));
545c6c1daeSBarry Smith va_end(Argp);
559566063dSJacob Faibussowitsch PetscCall(PetscStrlen(tmp, &shift));
5689d949e2SBarry Smith cshift = shift + 1;
5789d949e2SBarry Smith if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1;
589b15cf9aSJacob Faibussowitsch PetscCall(PetscMemcpy(vstr->head, tmp, cshift));
599b15cf9aSJacob Faibussowitsch vstr->head[cshift - 1] = '\0';
605c6c1daeSBarry Smith vstr->head += shift;
615c6c1daeSBarry Smith vstr->curlen += shift;
623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
635c6c1daeSBarry Smith }
645c6c1daeSBarry Smith
655c6c1daeSBarry Smith /*@C
66811af0c4SBarry Smith PetscViewerStringOpen - Opens a string as a `PETSCVIEWERSTRING` `PetscViewer`. This is a very
67811af0c4SBarry Smith simple `PetscViewer`; information on the object is simply stored into
685c6c1daeSBarry Smith the string in a fairly nice way.
695c6c1daeSBarry Smith
70cf53795eSBarry Smith Collective; No Fortran Support
715c6c1daeSBarry Smith
725c6c1daeSBarry Smith Input Parameters:
735c6c1daeSBarry Smith + comm - the communicator
745c6c1daeSBarry Smith . string - the string to use
755c6c1daeSBarry Smith - len - the string length
765c6c1daeSBarry Smith
775c6c1daeSBarry Smith Output Parameter:
78811af0c4SBarry Smith . lab - the `PetscViewer`
795c6c1daeSBarry Smith
805c6c1daeSBarry Smith Level: advanced
815c6c1daeSBarry Smith
82d1f92df0SBarry Smith .seealso: [](sec_viewers), `PETSCVIEWERSTRING`, `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`
835c6c1daeSBarry Smith @*/
PetscViewerStringOpen(MPI_Comm comm,char string[],size_t len,PetscViewer * lab)84*ce78bad3SBarry Smith PetscErrorCode PetscViewerStringOpen(MPI_Comm comm, char string[], size_t len, PetscViewer *lab) PeNS
85d71ae5a4SJacob Faibussowitsch {
865c6c1daeSBarry Smith PetscFunctionBegin;
879566063dSJacob Faibussowitsch PetscCall(PetscViewerCreate(comm, lab));
889566063dSJacob Faibussowitsch PetscCall(PetscViewerSetType(*lab, PETSCVIEWERSTRING));
899566063dSJacob Faibussowitsch PetscCall(PetscViewerStringSetString(*lab, string, len));
903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
915c6c1daeSBarry Smith }
925c6c1daeSBarry Smith
PetscViewerGetSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer * sviewer)9334e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
94d71ae5a4SJacob Faibussowitsch {
955c6c1daeSBarry Smith PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
965c6c1daeSBarry Smith
975c6c1daeSBarry Smith PetscFunctionBegin;
989566063dSJacob Faibussowitsch PetscCall(PetscViewerStringOpen(PETSC_COMM_SELF, vstr->head, vstr->maxlen - vstr->curlen, sviewer));
993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1005c6c1daeSBarry Smith }
1015c6c1daeSBarry Smith
PetscViewerRestoreSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer * sviewer)10234e79e72SJacob Faibussowitsch static PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer, MPI_Comm comm, PetscViewer *sviewer)
103d71ae5a4SJacob Faibussowitsch {
1045c6c1daeSBarry Smith PetscViewer_String *iviewer = (PetscViewer_String *)(*sviewer)->data;
1055c6c1daeSBarry Smith PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
1065c6c1daeSBarry Smith
1075c6c1daeSBarry Smith PetscFunctionBegin;
1085c6c1daeSBarry Smith vstr->head = iviewer->head;
1095c6c1daeSBarry Smith vstr->curlen += iviewer->curlen;
1109566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(sviewer));
1113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1125c6c1daeSBarry Smith }
1135c6c1daeSBarry Smith
1148556b5ebSBarry Smith /*MC
1158556b5ebSBarry Smith PETSCVIEWERSTRING - A viewer that writes to a string
1168556b5ebSBarry Smith
117811af0c4SBarry Smith Level: beginner
118811af0c4SBarry Smith
119d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PetscViewerStringSPrintf()`, `PetscViewerSocketOpen()`, `PetscViewerDrawOpen()`, `PETSCVIEWERSOCKET`,
120db781477SPatrick Sanan `PetscViewerCreate()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PETSCVIEWERBINARY`, `PETSCVIEWERDRAW`,
121db781477SPatrick Sanan `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERASCII`, `PETSCVIEWERMATLAB`,
122db781477SPatrick Sanan `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
1238556b5ebSBarry Smith M*/
1248556b5ebSBarry Smith
PetscViewerCreate_String(PetscViewer v)125d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
126d71ae5a4SJacob Faibussowitsch {
1275c6c1daeSBarry Smith PetscViewer_String *vstr;
1285c6c1daeSBarry Smith
1295c6c1daeSBarry Smith PetscFunctionBegin;
1305c6c1daeSBarry Smith v->ops->destroy = PetscViewerDestroy_String;
13102c9f0b5SLisandro Dalcin v->ops->view = NULL;
13202c9f0b5SLisandro Dalcin v->ops->flush = NULL;
133559f443fSBarry Smith v->ops->getsubviewer = PetscViewerGetSubViewer_String;
134559f443fSBarry Smith v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
1354dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&vstr));
1365c6c1daeSBarry Smith v->data = (void *)vstr;
13702c9f0b5SLisandro Dalcin vstr->string = NULL;
1383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
1395c6c1daeSBarry Smith }
1405c6c1daeSBarry Smith
1415c6c1daeSBarry Smith /*@C
142811af0c4SBarry Smith PetscViewerStringGetStringRead - Returns the string that a `PETSCVIEWERSTRING` uses
14336a9e3b9SBarry Smith
144c3339decSBarry Smith Logically Collective
14536a9e3b9SBarry Smith
14636a9e3b9SBarry Smith Input Parameter:
147811af0c4SBarry Smith . viewer - `PETSCVIEWERSTRING` viewer
14836a9e3b9SBarry Smith
149fd292e60Sprj- Output Parameters:
15026a11704SBarry Smith + string - the string, optional use `NULL` if you do not need
15126a11704SBarry Smith - len - the length of the string, optional use `NULL` if you do not need it
15236a9e3b9SBarry Smith
153d1f92df0SBarry Smith Level: advanced
154d1f92df0SBarry Smith
155811af0c4SBarry Smith Note:
156811af0c4SBarry Smith Do not write to the string nor free it
15736a9e3b9SBarry Smith
158*ce78bad3SBarry Smith Fortran Note:
159*ce78bad3SBarry Smith Copies the current contents of the `PETSCVIEWERSTRING` viewer string
160*ce78bad3SBarry Smith
161d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
162db781477SPatrick Sanan `PetscViewerStringSetOwnString()`
16336a9e3b9SBarry Smith @*/
PetscViewerStringGetStringRead(PetscViewer viewer,const char * string[],size_t * len)164*ce78bad3SBarry Smith PetscErrorCode PetscViewerStringGetStringRead(PetscViewer viewer, const char *string[], size_t *len) PeNS
165d71ae5a4SJacob Faibussowitsch {
16636a9e3b9SBarry Smith PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
16736a9e3b9SBarry Smith PetscBool isstring;
16836a9e3b9SBarry Smith
16936a9e3b9SBarry Smith PetscFunctionBegin;
17036a9e3b9SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
1719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
17228b400f6SJacob Faibussowitsch PetscCheck(isstring, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Only for PETSCVIEWERSTRING");
17336a9e3b9SBarry Smith if (string) *string = vstr->string;
17436a9e3b9SBarry Smith if (len) *len = vstr->maxlen;
1753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
17636a9e3b9SBarry Smith }
17736a9e3b9SBarry Smith
17836a9e3b9SBarry Smith /*@C
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 @*/
PetscViewerStringSetString(PetscViewer viewer,char string[],size_t len)199*ce78bad3SBarry Smith PetscErrorCode PetscViewerStringSetString(PetscViewer viewer, char string[], size_t len) PeNS
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);
2064f572ea9SToby Isaac PetscAssertPointer(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
2195d83a8b1SBarry Smith /*@
22026a11704SBarry Smith PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it with `PetscFree()`
22136a9e3b9SBarry Smith
222c3339decSBarry Smith Logically Collective
22336a9e3b9SBarry Smith
2242fe279fdSBarry Smith Input Parameter:
22536a9e3b9SBarry Smith . viewer - string viewer
22636a9e3b9SBarry Smith
227d1f92df0SBarry Smith Level: advanced
228d1f92df0SBarry Smith
229811af0c4SBarry Smith Note:
230811af0c4SBarry Smith If you call this the string must have been obtained with `PetscMalloc()` and you cannot free the string
23136a9e3b9SBarry Smith
232d1f92df0SBarry Smith .seealso: [](sec_viewers), `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
233db781477SPatrick Sanan `PetscViewerStringSetString()`
23436a9e3b9SBarry Smith @*/
PetscViewerStringSetOwnString(PetscViewer viewer)235d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscViewerStringSetOwnString(PetscViewer viewer)
236d71ae5a4SJacob Faibussowitsch {
23736a9e3b9SBarry Smith PetscViewer_String *vstr = (PetscViewer_String *)viewer->data;
23836a9e3b9SBarry Smith PetscBool isstring;
23936a9e3b9SBarry Smith
24036a9e3b9SBarry Smith PetscFunctionBegin;
24136a9e3b9SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
2429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
2433ba16761SJacob Faibussowitsch if (!isstring) PetscFunctionReturn(PETSC_SUCCESS);
24436a9e3b9SBarry Smith
24536a9e3b9SBarry Smith vstr->ownstring = PETSC_TRUE;
2463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
24736a9e3b9SBarry Smith }
248