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