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