xref: /petsc/src/sys/classes/viewer/impls/string/stringv.c (revision 5becb6a3a7fe6fe66ca978502f4679a4b24b29fc)
1 
2 #include <petsc/private/viewerimpl.h>   /*I  "petscsys.h"  I*/
3 
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 responsable for freeing the string */
9 } PetscViewer_String;
10 
11 static PetscErrorCode PetscViewerDestroy_String(PetscViewer viewer)
12 {
13   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
14 
15   PetscFunctionBegin;
16   if (vstr->ownstring) {
17     PetscCall(PetscFree(vstr->string));
18   }
19   PetscCall(PetscFree(vstr));
20   PetscFunctionReturn(0);
21 }
22 
23 /*@C
24     PetscViewerStringSPrintf - Prints information to a PetscViewer string.
25 
26     Logically Collective on PetscViewer (Hmmm, each processor maintains a separate string)
27 
28     Input Parameters:
29 +   v - a string PetscViewer, formed by PetscViewerStringOpen()
30 -   format - the format of the input
31 
32     Level: developer
33 
34     Fortran Note:
35     This routine is not supported in Fortran.
36 
37 .seealso: PetscViewerStringOpen(), PetscViewerStringGetStringRead(), PetscViewerStringSetString(), PETSCVIEWERSTRING
38 @*/
39 PetscErrorCode  PetscViewerStringSPrintf(PetscViewer viewer,const char format[],...)
40 {
41   va_list            Argp;
42   size_t             fullLength;
43   size_t             shift,cshift;
44   PetscBool          isstring;
45   char               tmp[4096];
46   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
47 
48   PetscFunctionBegin;
49   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
50   PetscValidCharPointer(format,2);
51   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
52   if (!isstring) PetscFunctionReturn(0);
53   PetscCheck(vstr->string,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerStringSetString() before using");
54 
55   va_start(Argp,format);
56   PetscCall(PetscVSNPrintf(tmp,4096,format,&fullLength,Argp));
57   va_end(Argp);
58   PetscCall(PetscStrlen(tmp,&shift));
59   cshift = shift+1;
60   if (cshift >= vstr->maxlen - vstr->curlen - 1) cshift = vstr->maxlen - vstr->curlen - 1;
61   PetscCall(PetscStrncpy(vstr->head,tmp,cshift));
62   vstr->head   += shift;
63   vstr->curlen += shift;
64   PetscFunctionReturn(0);
65 }
66 
67 /*@C
68     PetscViewerStringOpen - Opens a string as a PetscViewer. This is a very
69     simple PetscViewer; information on the object is simply stored into
70     the string in a fairly nice way.
71 
72     Collective
73 
74     Input Parameters:
75 +   comm - the communicator
76 .   string - the string to use
77 -   len    - the string length
78 
79     Output Parameter:
80 .   lab - the PetscViewer
81 
82     Level: advanced
83 
84     Fortran Note:
85     This routine is not supported in Fortran.
86 
87 .seealso: PetscViewerDestroy(), PetscViewerStringSPrintf(), PetscViewerStringGetStringRead(), PetscViewerStringSetString(), PETSCVIEWERSTRING
88 @*/
89 PetscErrorCode  PetscViewerStringOpen(MPI_Comm comm,char string[],size_t len,PetscViewer *lab)
90 {
91   PetscFunctionBegin;
92   PetscCall(PetscViewerCreate(comm,lab));
93   PetscCall(PetscViewerSetType(*lab,PETSCVIEWERSTRING));
94   PetscCall(PetscViewerStringSetString(*lab,string,len));
95   PetscFunctionReturn(0);
96 }
97 
98 PetscErrorCode PetscViewerGetSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
99 {
100   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
101 
102   PetscFunctionBegin;
103   PetscCall(PetscViewerStringOpen(PETSC_COMM_SELF,vstr->head,vstr->maxlen-vstr->curlen,sviewer));
104   PetscFunctionReturn(0);
105 }
106 
107 PetscErrorCode PetscViewerRestoreSubViewer_String(PetscViewer viewer,MPI_Comm comm,PetscViewer *sviewer)
108 {
109   PetscViewer_String *iviewer = (PetscViewer_String*)(*sviewer)->data;
110   PetscViewer_String *vstr    = (PetscViewer_String*)viewer->data;
111 
112   PetscFunctionBegin;
113   vstr->head    = iviewer->head;
114   vstr->curlen += iviewer->curlen;
115   PetscCall(PetscViewerDestroy(sviewer));
116   PetscFunctionReturn(0);
117 }
118 
119 /*MC
120    PETSCVIEWERSTRING - A viewer that writes to a string
121 
122 .seealso:  PetscViewerStringOpen(), PetscViewerStringSPrintf(), PetscViewerSocketOpen(), PetscViewerDrawOpen(), PETSCVIEWERSOCKET,
123            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, PETSCVIEWERDRAW,
124            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
125            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
126 
127   Level: beginner
128 M*/
129 
130 PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
131 {
132   PetscViewer_String *vstr;
133 
134   PetscFunctionBegin;
135   v->ops->destroy          = PetscViewerDestroy_String;
136   v->ops->view             = NULL;
137   v->ops->flush            = NULL;
138   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
139   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
140   PetscCall(PetscNewLog(v,&vstr));
141   v->data                  = (void*)vstr;
142   vstr->string             = NULL;
143   PetscFunctionReturn(0);
144 }
145 
146 /*@C
147 
148    PetscViewerStringGetStringRead - Returns the string that a string viewer uses
149 
150    Logically Collective on PetscViewer
151 
152   Input Parameter:
153 .   viewer - string viewer
154 
155   Output Parameters:
156 +    string - the string, optional use NULL if you do not need
157 -   len - the length of the string, optional use NULL if you do
158 
159   Notes: Do not write to the string nor free it
160 
161   Level: advanced
162 
163 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringSetString(), PetscViewerStringSPrintf(),
164           PetscViewerStringSetOwnString()
165 @*/
166 PetscErrorCode  PetscViewerStringGetStringRead(PetscViewer viewer,const char *string[],size_t *len)
167 {
168   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
169   PetscBool          isstring;
170 
171   PetscFunctionBegin;
172   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
173   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
174   PetscCheck(isstring,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Only for PETSCVIEWERSTRING");
175   if (string) *string = vstr->string;
176   if (len)    *len    = vstr->maxlen;
177   PetscFunctionReturn(0);
178 }
179 
180 /*@C
181 
182    PetscViewerStringSetString - sets the string that a string viewer will print to
183 
184    Logically Collective on PetscViewer
185 
186   Input Parameters:
187 +   viewer - string viewer you wish to attach string to
188 .   string - the string to print data into
189 -   len - the length of the string
190 
191   Notes: The function does not copy the string, it uses it directly therefore you cannot free
192    the string until the viewer is destroyed. If you call PetscViewerStringSetOwnString() the ownership
193    passes to the viewer and it will be responsable for freeing it. In this case the string must be
194    obtained with PetscMalloc().
195 
196   Level: advanced
197 
198 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(),
199           PetscViewerStringSetOwnString()
200 @*/
201 PetscErrorCode  PetscViewerStringSetString(PetscViewer viewer,char string[],size_t len)
202 {
203   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
204   PetscBool          isstring;
205 
206   PetscFunctionBegin;
207   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
208   PetscValidCharPointer(string,2);
209   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
210   if (!isstring) PetscFunctionReturn(0);
211   PetscCheck(len > 2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"String must have length at least 2");
212 
213   PetscCall(PetscArrayzero(string,len));
214   vstr->string = string;
215   vstr->head   = string;
216   vstr->curlen = 0;
217   vstr->maxlen = len;
218   PetscFunctionReturn(0);
219 }
220 
221 /*@C
222 
223    PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it
224 
225    Logically Collective on PetscViewer
226 
227   Input Parameters:
228 .   viewer - string viewer
229 
230   Notes: If you call this the string must have been obtained with PetscMalloc() and you cannot free the string
231 
232   Level: advanced
233 
234 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(),
235           PetscViewerStringSetString()
236 @*/
237 PetscErrorCode  PetscViewerStringSetOwnString(PetscViewer viewer)
238 {
239   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
240   PetscBool          isstring;
241 
242   PetscFunctionBegin;
243   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
244   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
245   if (!isstring) PetscFunctionReturn(0);
246 
247   vstr->ownstring = PETSC_TRUE;
248   PetscFunctionReturn(0);
249 }
250