xref: /petsc/src/sys/classes/viewer/impls/string/stringv.c (revision 4e278199b78715991f5c71ebbd945c1489263e6c)
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 .seealso:  PetscViewerStringOpen(), PetscViewerStringSPrintf(), PetscViewerSocketOpen(), PetscViewerDrawOpen(), PETSCVIEWERSOCKET,
129            PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, PETSCVIEWERDRAW,
130            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB,
131            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
132 
133   Level: beginner
134 M*/
135 
136 PETSC_EXTERN PetscErrorCode PetscViewerCreate_String(PetscViewer v)
137 {
138   PetscViewer_String *vstr;
139   PetscErrorCode     ierr;
140 
141   PetscFunctionBegin;
142   v->ops->destroy          = PetscViewerDestroy_String;
143   v->ops->view             = NULL;
144   v->ops->flush            = NULL;
145   v->ops->getsubviewer     = PetscViewerGetSubViewer_String;
146   v->ops->restoresubviewer = PetscViewerRestoreSubViewer_String;
147   ierr                     = PetscNewLog(v,&vstr);CHKERRQ(ierr);
148   v->data                  = (void*)vstr;
149   vstr->string             = NULL;
150   PetscFunctionReturn(0);
151 }
152 
153 /*@C
154 
155    PetscViewerStringGetStringRead - Returns the string that a string viewer uses
156 
157    Logically Collective on PetscViewer
158 
159   Input Parameter:
160 .   viewer - string viewer
161 
162   Output Parameters:
163 +    string - the string, optional use NULL if you do not need
164 -   len - the length of the string, optional use NULL if you do
165 
166   Notes: Do not write to the string nor free it
167 
168   Level: advanced
169 
170 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringSetString(), PetscViewerStringSPrintf(),
171           PetscViewerStringSetOwnString()
172 @*/
173 PetscErrorCode  PetscViewerStringGetStringRead(PetscViewer viewer,const char *string[],size_t *len)
174 {
175   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
176   PetscErrorCode     ierr;
177   PetscBool          isstring;
178 
179   PetscFunctionBegin;
180   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
181   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
182   if (!isstring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Only for PETSCVIEWERSTRING");
183   if (string) *string = vstr->string;
184   if (len)    *len    = vstr->maxlen;
185   PetscFunctionReturn(0);
186 }
187 
188 /*@C
189 
190    PetscViewerStringSetString - sets the string that a string viewer will print to
191 
192    Logically Collective on PetscViewer
193 
194   Input Parameters:
195 +   viewer - string viewer you wish to attach string to
196 .   string - the string to print data into
197 -   len - the length of the string
198 
199   Notes: The function does not copy the string, it uses it directly therefore you cannot free
200    the string until the viewer is destroyed. If you call PetscViewerStringSetOwnString() the ownership
201    passes to the viewer and it will be responsable for freeing it. In this case the string must be
202    obtained with PetscMalloc().
203 
204   Level: advanced
205 
206 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(),
207           PetscViewerStringSetOwnString()
208 @*/
209 PetscErrorCode  PetscViewerStringSetString(PetscViewer viewer,char string[],size_t len)
210 {
211   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
212   PetscErrorCode     ierr;
213   PetscBool          isstring;
214 
215   PetscFunctionBegin;
216   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
217   PetscValidCharPointer(string,2);
218   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
219   if (!isstring) PetscFunctionReturn(0);
220   if (len <= 2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"String must have length at least 2");
221 
222   ierr         = PetscArrayzero(string,len);CHKERRQ(ierr);
223   vstr->string = string;
224   vstr->head   = string;
225   vstr->curlen = 0;
226   vstr->maxlen = len;
227   PetscFunctionReturn(0);
228 }
229 
230 /*@C
231 
232    PetscViewerStringSetOwnString - tells the viewer that it now owns the string and is responsible for freeing it
233 
234    Logically Collective on PetscViewer
235 
236   Input Parameters:
237 .   viewer - string viewer
238 
239   Notes: If you call this the string must have been obtained with PetscMalloc() and you cannot free the string
240 
241   Level: advanced
242 
243 .seealso: PetscViewerStringOpen(), PETSCVIEWERSTRING, PetscViewerStringGetStringRead(), PetscViewerStringSPrintf(),
244           PetscViewerStringSetString()
245 @*/
246 PetscErrorCode  PetscViewerStringSetOwnString(PetscViewer viewer)
247 {
248   PetscViewer_String *vstr = (PetscViewer_String*)viewer->data;
249   PetscErrorCode     ierr;
250   PetscBool          isstring;
251 
252   PetscFunctionBegin;
253   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
254   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
255   if (!isstring) PetscFunctionReturn(0);
256 
257   vstr->ownstring = PETSC_TRUE;
258   PetscFunctionReturn(0);
259 }
260 
261