xref: /petsc/src/sys/classes/viewer/impls/string/stringv.c (revision 1baa6e3354bfe224b33a0c158f482508792a8a6e)
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 
115c6c1daeSBarry Smith static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer)
125c6c1daeSBarry Smith {
135c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
145c6c1daeSBarry Smith 
155c6c1daeSBarry Smith   PetscFunctionBegin;
16*1baa6e33SBarry Smith   if (vstr->ownstring) PetscCall(PetscFree(vstr->string));
179566063dSJacob Faibussowitsch   PetscCall(PetscFree(vstr));
185c6c1daeSBarry Smith   PetscFunctionReturn(0);
195c6c1daeSBarry Smith }
205c6c1daeSBarry Smith 
215c6c1daeSBarry Smith /*@C
225c6c1daeSBarry Smith     PetscViewerStringSPrintf - Prints information to a PetscViewer string.
235c6c1daeSBarry Smith 
245c6c1daeSBarry Smith     Logically Collective on PetscViewer (Hmmm, each processor maintains a separate string)
255c6c1daeSBarry Smith 
265c6c1daeSBarry Smith     Input Parameters:
275c6c1daeSBarry Smith +   v - a string PetscViewer, formed by PetscViewerStringOpen()
285c6c1daeSBarry Smith -   format - the format of the input
295c6c1daeSBarry Smith 
305c6c1daeSBarry Smith     Level: developer
315c6c1daeSBarry Smith 
325c6c1daeSBarry Smith     Fortran Note:
335c6c1daeSBarry Smith     This routine is not supported in Fortran.
345c6c1daeSBarry Smith 
35db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`, `PETSCVIEWERSTRING`
365c6c1daeSBarry Smith @*/
375c6c1daeSBarry Smith PetscErrorCode  PetscViewerStringSPrintf(PetscViewer viewer,const char format[],...)
385c6c1daeSBarry Smith {
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));
505c6c1daeSBarry Smith   if (!isstring) PetscFunctionReturn(0);
5128b400f6SJacob Faibussowitsch   PetscCheck(vstr->string,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerStringSetString() before using");
525c6c1daeSBarry Smith 
535c6c1daeSBarry Smith   va_start(Argp,format);
549566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(tmp,4096,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;
599566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(vstr->head,tmp,cshift));
605c6c1daeSBarry Smith   vstr->head   += shift;
615c6c1daeSBarry Smith   vstr->curlen += shift;
625c6c1daeSBarry Smith   PetscFunctionReturn(0);
635c6c1daeSBarry Smith }
645c6c1daeSBarry Smith 
655c6c1daeSBarry Smith /*@C
665c6c1daeSBarry Smith     PetscViewerStringOpen - Opens a string as a PetscViewer. This is a very
675c6c1daeSBarry Smith     simple PetscViewer; information on the object is simply stored into
685c6c1daeSBarry Smith     the string in a fairly nice way.
695c6c1daeSBarry Smith 
70d083f849SBarry Smith     Collective
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:
785c6c1daeSBarry Smith .   lab - the PetscViewer
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith     Level: advanced
815c6c1daeSBarry Smith 
825c6c1daeSBarry Smith     Fortran Note:
835c6c1daeSBarry Smith     This routine is not supported in Fortran.
845c6c1daeSBarry Smith 
85db781477SPatrick Sanan .seealso: `PetscViewerDestroy()`, `PetscViewerStringSPrintf()`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSetString()`, `PETSCVIEWERSTRING`
865c6c1daeSBarry Smith @*/
8789d949e2SBarry Smith PetscErrorCode  PetscViewerStringOpen(MPI_Comm comm,char string[],size_t len,PetscViewer *lab)
885c6c1daeSBarry Smith {
895c6c1daeSBarry Smith   PetscFunctionBegin;
909566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(comm,lab));
919566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*lab,PETSCVIEWERSTRING));
929566063dSJacob Faibussowitsch   PetscCall(PetscViewerStringSetString(*lab,string,len));
935c6c1daeSBarry Smith   PetscFunctionReturn(0);
945c6c1daeSBarry Smith }
955c6c1daeSBarry Smith 
963f08860eSBarry Smith PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
975c6c1daeSBarry Smith {
985c6c1daeSBarry Smith   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith   PetscFunctionBegin;
1019566063dSJacob Faibussowitsch   PetscCall(PetscViewerStringOpen(PETSC_COMM_SELF,vstr->head,vstr->maxlen-vstr->curlen,sviewer));
1025c6c1daeSBarry Smith   PetscFunctionReturn(0);
1035c6c1daeSBarry Smith }
1045c6c1daeSBarry Smith 
1053f08860eSBarry Smith PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
1065c6c1daeSBarry Smith {
1075c6c1daeSBarry Smith   PetscViewer_String *iviewer = (PetscViewer_String*)(*sviewer)->data;
1085c6c1daeSBarry Smith   PetscViewer_String *vstr    = (PetscViewer_String*)viewer->data;
1095c6c1daeSBarry Smith 
1105c6c1daeSBarry Smith   PetscFunctionBegin;
1115c6c1daeSBarry Smith   vstr->head    = iviewer->head;
1125c6c1daeSBarry Smith   vstr->curlen += iviewer->curlen;
1139566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(sviewer));
1145c6c1daeSBarry Smith   PetscFunctionReturn(0);
1155c6c1daeSBarry Smith }
1165c6c1daeSBarry Smith 
1178556b5ebSBarry Smith /*MC
1188556b5ebSBarry Smith    PETSCVIEWERSTRING - A viewer that writes to a string
1198556b5ebSBarry Smith 
120db781477SPatrick Sanan .seealso: `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 
1251b266c99SBarry Smith   Level: beginner
1268556b5ebSBarry Smith M*/
1278556b5ebSBarry Smith 
1288cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
1295c6c1daeSBarry Smith {
1305c6c1daeSBarry Smith   PetscViewer_String *vstr;
1315c6c1daeSBarry Smith 
1325c6c1daeSBarry Smith   PetscFunctionBegin;
1335c6c1daeSBarry Smith   v->ops->destroy          = PetscViewerDestroy_String;
13402c9f0b5SLisandro Dalcin   v->ops->view             = NULL;
13502c9f0b5SLisandro Dalcin   v->ops->flush            = NULL;
136559f443fSBarry Smith   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
137559f443fSBarry Smith   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
1389566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(v,&vstr));
1395c6c1daeSBarry Smith   v->data                  = (void*)vstr;
14002c9f0b5SLisandro Dalcin   vstr->string             = NULL;
1415c6c1daeSBarry Smith   PetscFunctionReturn(0);
1425c6c1daeSBarry Smith }
1435c6c1daeSBarry Smith 
1445c6c1daeSBarry Smith /*@C
1455c6c1daeSBarry Smith 
14636a9e3b9SBarry Smith    PetscViewerStringGetStringRead - Returns the string that a string viewer uses
14736a9e3b9SBarry Smith 
14836a9e3b9SBarry Smith    Logically Collective on PetscViewer
14936a9e3b9SBarry Smith 
15036a9e3b9SBarry Smith   Input Parameter:
15136a9e3b9SBarry Smith .   viewer - string viewer
15236a9e3b9SBarry Smith 
153fd292e60Sprj-   Output Parameters:
15436a9e3b9SBarry Smith +    string - the string, optional use NULL if you do not need
15536a9e3b9SBarry Smith -   len - the length of the string, optional use NULL if you do
15636a9e3b9SBarry Smith 
15736a9e3b9SBarry Smith   Notes: Do not write to the string nor free it
15836a9e3b9SBarry Smith 
15936a9e3b9SBarry Smith   Level: advanced
16036a9e3b9SBarry Smith 
161db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringSetString()`, `PetscViewerStringSPrintf()`,
162db781477SPatrick Sanan           `PetscViewerStringSetOwnString()`
16336a9e3b9SBarry Smith @*/
16436a9e3b9SBarry Smith PetscErrorCode  PetscViewerStringGetStringRead(PetscViewer viewer,const char *string[],size_t *len)
16536a9e3b9SBarry Smith {
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;
17536a9e3b9SBarry Smith   PetscFunctionReturn(0);
17636a9e3b9SBarry Smith }
17736a9e3b9SBarry Smith 
17836a9e3b9SBarry Smith /*@C
17936a9e3b9SBarry Smith 
1805c6c1daeSBarry Smith    PetscViewerStringSetString - sets the string that a string viewer will print to
1815c6c1daeSBarry Smith 
1825c6c1daeSBarry Smith    Logically Collective on PetscViewer
1835c6c1daeSBarry Smith 
1845c6c1daeSBarry Smith   Input Parameters:
1855c6c1daeSBarry Smith +   viewer - string viewer you wish to attach string to
1865c6c1daeSBarry Smith .   string - the string to print data into
1875c6c1daeSBarry Smith -   len - the length of the string
1885c6c1daeSBarry Smith 
189effebcafSBarry Smith   Notes: The function does not copy the string, it uses it directly therefore you cannot free
19036a9e3b9SBarry Smith    the string until the viewer is destroyed. If you call PetscViewerStringSetOwnString() the ownership
19136a9e3b9SBarry Smith    passes to the viewer and it will be responsable for freeing it. In this case the string must be
19236a9e3b9SBarry Smith    obtained with PetscMalloc().
19336a9e3b9SBarry Smith 
1945c6c1daeSBarry Smith   Level: advanced
1955c6c1daeSBarry Smith 
196db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
197db781477SPatrick Sanan           `PetscViewerStringSetOwnString()`
1985c6c1daeSBarry Smith @*/
19936a9e3b9SBarry Smith PetscErrorCode  PetscViewerStringSetString(PetscViewer viewer,char string[],size_t len)
2005c6c1daeSBarry Smith {
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));
2085c6c1daeSBarry Smith   if (!isstring) PetscFunctionReturn(0);
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;
2165c6c1daeSBarry Smith   PetscFunctionReturn(0);
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 
22336a9e3b9SBarry Smith    Logically Collective on PetscViewer
22436a9e3b9SBarry Smith 
22536a9e3b9SBarry Smith   Input Parameters:
22636a9e3b9SBarry Smith .   viewer - string viewer
22736a9e3b9SBarry Smith 
22836a9e3b9SBarry Smith   Notes: If you call this the string must have been obtained with PetscMalloc() and you cannot free the string
22936a9e3b9SBarry Smith 
23036a9e3b9SBarry Smith   Level: advanced
23136a9e3b9SBarry Smith 
232db781477SPatrick Sanan .seealso: `PetscViewerStringOpen()`, `PETSCVIEWERSTRING`, `PetscViewerStringGetStringRead()`, `PetscViewerStringSPrintf()`,
233db781477SPatrick Sanan           `PetscViewerStringSetString()`
23436a9e3b9SBarry Smith @*/
23536a9e3b9SBarry Smith PetscErrorCode  PetscViewerStringSetOwnString(PetscViewer viewer)
23636a9e3b9SBarry Smith {
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));
24336a9e3b9SBarry Smith   if (!isstring) PetscFunctionReturn(0);
24436a9e3b9SBarry Smith 
24536a9e3b9SBarry Smith   vstr->ownstring = PETSC_TRUE;
24636a9e3b9SBarry Smith   PetscFunctionReturn(0);
24736a9e3b9SBarry Smith }
248