xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 487a658c8b32ba712a1dc8280daad2fd70c1dcd9)
1 
2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>  /*I "petscviewer.h" I*/
3 
4 #define QUEUESTRINGSIZE 8192
5 
6 static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
7 {
8   PetscErrorCode    ierr;
9   PetscMPIInt       rank;
10   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
11   int               err;
12 
13   PetscFunctionBegin;
14   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
15   if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
16     if (vascii->fd && vascii->closefile) {
17       err = fclose(vascii->fd);
18       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
19     }
20     if (vascii->storecompressed) {
21       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
22       FILE *fp;
23       ierr = PetscStrncpy(par,"gzip ",sizeof(par));CHKERRQ(ierr);
24       ierr = PetscStrlcat(par,vascii->filename,sizeof(par));CHKERRQ(ierr);
25 #if defined(PETSC_HAVE_POPEN)
26       ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr);
27       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
28       ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr);
29 #else
30       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
31 #endif
32     }
33   }
34   ierr = PetscFree(vascii->filename);CHKERRQ(ierr);
35   PetscFunctionReturn(0);
36 }
37 
38 /* ----------------------------------------------------------------------*/
39 PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
40 {
41   PetscErrorCode    ierr;
42   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
43   PetscViewerLink   *vlink;
44   PetscBool         flg;
45 
46   PetscFunctionBegin;
47   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
48   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
49   ierr = PetscFree(vascii);CHKERRQ(ierr);
50 
51   /* remove the viewer from the list in the MPI Communicator */
52   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
53     ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr);
54   }
55 
56   ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
57   if (flg) {
58     if (vlink && vlink->viewer == viewer) {
59       if (vlink->next) {
60         ierr = MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);CHKERRQ(ierr);
61       } else {
62         ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);CHKERRQ(ierr);
63       }
64       ierr = PetscFree(vlink);CHKERRQ(ierr);
65     } else {
66       while (vlink && vlink->next) {
67         if (vlink->next->viewer == viewer) {
68           PetscViewerLink *nv = vlink->next;
69           vlink->next = vlink->next->next;
70           ierr = PetscFree(nv);CHKERRQ(ierr);
71         }
72         vlink = vlink->next;
73       }
74     }
75   }
76 
77   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
78     PetscViewer aviewer;
79     ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
80     if (flg && aviewer == viewer) {
81       ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);CHKERRQ(ierr);
82     }
83   }
84   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
85     PetscViewer aviewer;
86     ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
87     if (flg && aviewer == viewer) {
88       ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);CHKERRQ(ierr);
89     }
90   }
91   PetscFunctionReturn(0);
92 }
93 
94 PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
95 {
96   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
97   PetscErrorCode    ierr;
98 
99   PetscFunctionBegin;
100   ierr = PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);CHKERRQ(ierr);
101   PetscFunctionReturn(0);
102 }
103 
104 PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
105 {
106   PetscErrorCode    ierr;
107   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
108   int               err;
109   MPI_Comm          comm;
110   PetscMPIInt       rank,size;
111   FILE              *fd = vascii->fd;
112 
113   PetscFunctionBegin;
114   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
115   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
116   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
117 
118   if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
119     err = fflush(vascii->fd);
120     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
121   }
122 
123   if (vascii->allowsynchronized) {
124     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
125     char          *message;
126     MPI_Status    status;
127 
128     ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
129 
130     /* First processor waits for messages from all other processors */
131     if (!rank) {
132       /* flush my own messages that I may have queued up */
133       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
134       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
135         if (!vascii->bviewer) {
136           ierr = PetscFPrintf(comm,fd,"%s",next->string);CHKERRQ(ierr);
137         } else {
138           ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);CHKERRQ(ierr);
139         }
140         previous = next;
141         next     = next->next;
142         ierr     = PetscFree(previous->string);CHKERRQ(ierr);
143         ierr     = PetscFree(previous);CHKERRQ(ierr);
144       }
145       vascii->petsc_printfqueue       = 0;
146       vascii->petsc_printfqueuelength = 0;
147       for (i=1; i<size; i++) {
148         /* to prevent a flood of messages to process zero, request each message separately */
149         ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
150         ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
151         for (j=0; j<n; j++) {
152           PetscMPIInt size = 0;
153 
154           ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
155           ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
156           ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
157           if (!vascii->bviewer) {
158             ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
159           } else {
160             ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);CHKERRQ(ierr);
161           }
162           ierr = PetscFree(message);CHKERRQ(ierr);
163         }
164       }
165     } else { /* other processors send queue to processor 0 */
166       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
167 
168       ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
169       ierr = MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
170       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
171         ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
172         ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
173         previous = next;
174         next     = next->next;
175         ierr     = PetscFree(previous->string);CHKERRQ(ierr);
176         ierr     = PetscFree(previous);CHKERRQ(ierr);
177       }
178       vascii->petsc_printfqueue       = 0;
179       vascii->petsc_printfqueuelength = 0;
180     }
181     ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
182   }
183   PetscFunctionReturn(0);
184 }
185 
186 /*@C
187     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
188 
189     Not Collective
190 
191 +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
192 -   fd - file pointer
193 
194     Level: intermediate
195 
196     Fortran Note:
197     This routine is not supported in Fortran.
198 
199   Concepts: PetscViewer^file pointer
200   Concepts: file pointer^getting from PetscViewer
201 
202 .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
203           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
204 @*/
205 PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
206 {
207   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
208 
209   PetscFunctionBegin;
210   *fd = vascii->fd;
211   PetscFunctionReturn(0);
212 }
213 
214 PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
215 {
216   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
217 
218   PetscFunctionBegin;
219   *mode = vascii->mode;
220   PetscFunctionReturn(0);
221 }
222 
223 PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
224 {
225   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
226 
227   PetscFunctionBegin;
228   vascii->mode = mode;
229   PetscFunctionReturn(0);
230 }
231 
232 /*
233    If petsc_history is on, then all Petsc*Printf() results are saved
234    if the appropriate (usually .petschistory) file.
235 */
236 PETSC_INTERN FILE *petsc_history;
237 
238 /*@
239     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
240 
241     Not Collective, but only first processor in set has any effect
242 
243     Input Parameters:
244 +    viewer - obtained with PetscViewerASCIIOpen()
245 -    tabs - number of tabs
246 
247     Level: developer
248 
249     Fortran Note:
250     This routine is not supported in Fortran.
251 
252   Concepts: PetscViewerASCII^formating
253   Concepts: tab^setting
254 
255 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
256           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
257           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
258 @*/
259 PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
260 {
261   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
262   PetscBool         iascii;
263   PetscErrorCode    ierr;
264 
265   PetscFunctionBegin;
266   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
267   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
268   if (iascii) ascii->tab = tabs;
269   PetscFunctionReturn(0);
270 }
271 
272 /*@
273     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
274 
275     Not Collective, meaningful on first processor only.
276 
277     Input Parameters:
278 .    viewer - obtained with PetscViewerASCIIOpen()
279     Output Parameters:
280 .    tabs - number of tabs
281 
282     Level: developer
283 
284     Fortran Note:
285     This routine is not supported in Fortran.
286 
287   Concepts: PetscViewerASCII^formating
288   Concepts: tab^retrieval
289 
290 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
291           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
292           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
293 @*/
294 PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
295 {
296   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
297   PetscBool         iascii;
298   PetscErrorCode    ierr;
299 
300   PetscFunctionBegin;
301   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
302   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
303   if (iascii && tabs) *tabs = ascii->tab;
304   PetscFunctionReturn(0);
305 }
306 
307 /*@
308     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
309 
310     Not Collective, but only first processor in set has any effect
311 
312     Input Parameters:
313 +    viewer - obtained with PetscViewerASCIIOpen()
314 -    tabs - number of tabs
315 
316     Level: developer
317 
318     Fortran Note:
319     This routine is not supported in Fortran.
320 
321   Concepts: PetscViewerASCII^formating
322   Concepts: tab^setting
323 
324 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
325           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
326           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
327 @*/
328 PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
329 {
330   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
331   PetscBool         iascii;
332   PetscErrorCode    ierr;
333 
334   PetscFunctionBegin;
335   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
336   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
337   if (iascii) ascii->tab += tabs;
338   PetscFunctionReturn(0);
339 }
340 
341 /*@
342     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
343 
344     Not Collective, but only first processor in set has any effect
345 
346     Input Parameters:
347 +    viewer - obtained with PetscViewerASCIIOpen()
348 -    tabs - number of tabs
349 
350     Level: developer
351 
352     Fortran Note:
353     This routine is not supported in Fortran.
354 
355   Concepts: PetscViewerASCII^formating
356   Concepts: tab^setting
357 
358 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
359           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
360           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
361 @*/
362 PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
363 {
364   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
365   PetscBool         iascii;
366   PetscErrorCode    ierr;
367 
368   PetscFunctionBegin;
369   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
370   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
371   if (iascii) ascii->tab -= tabs;
372   PetscFunctionReturn(0);
373 }
374 
375 /*@C
376     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
377 
378     Collective on PetscViewer
379 
380     Input Parameters:
381 .    viewer - obtained with PetscViewerASCIIOpen()
382 
383     Level: intermediate
384 
385   Concepts: PetscViewerASCII^formating
386   Concepts: tab^setting
387 
388 .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
389           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
390           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
391 @*/
392 PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
393 {
394   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
395   PetscBool         iascii;
396   PetscErrorCode    ierr;
397 
398   PetscFunctionBegin;
399   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
400   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
401   if (iascii) ascii->allowsynchronized++;
402   PetscFunctionReturn(0);
403 }
404 
405 /*@C
406     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
407 
408     Collective on PetscViewer
409 
410     Input Parameters:
411 .    viewer - obtained with PetscViewerASCIIOpen()
412 
413     Level: intermediate
414 
415   Concepts: PetscViewerASCII^formating
416   Concepts: tab^setting
417 
418 .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
419           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
420           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
421 @*/
422 PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
423 {
424   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
425   PetscBool         iascii;
426   PetscErrorCode    ierr;
427 
428   PetscFunctionBegin;
429   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
430   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
431   if (iascii) {
432     ascii->allowsynchronized--;
433     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
434   }
435   PetscFunctionReturn(0);
436 }
437 
438 /*@C
439     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
440      lines are tabbed.
441 
442     Not Collective, but only first processor in set has any effect
443 
444     Input Parameters:
445 .    viewer - obtained with PetscViewerASCIIOpen()
446 
447     Level: developer
448 
449     Fortran Note:
450     This routine is not supported in Fortran.
451 
452   Concepts: PetscViewerASCII^formating
453   Concepts: tab^setting
454 
455 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
456           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
457           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
458 @*/
459 PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
460 {
461   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
462   PetscBool         iascii;
463   PetscErrorCode    ierr;
464 
465   PetscFunctionBegin;
466   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
467   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
468   if (iascii) ascii->tab++;
469   PetscFunctionReturn(0);
470 }
471 
472 /*@C
473     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
474      lines are tabbed.
475 
476     Not Collective, but only first processor in set has any effect
477 
478     Input Parameters:
479 .    viewer - obtained with PetscViewerASCIIOpen()
480 
481     Level: developer
482 
483     Fortran Note:
484     This routine is not supported in Fortran.
485 
486   Concepts: PetscViewerASCII^formating
487   Concepts: tab^setting
488 
489 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
490           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
491           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
492 @*/
493 PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
494 {
495   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
496   PetscErrorCode    ierr;
497   PetscBool         iascii;
498 
499   PetscFunctionBegin;
500   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
501   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
502   if (iascii) {
503     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
504     ascii->tab--;
505   }
506   PetscFunctionReturn(0);
507 }
508 
509 /*@
510     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
511 
512     Not Collective, but only first processor in set has any effect
513 
514     Input Parameters:
515 +    viewer - obtained with PetscViewerASCIIOpen()
516 -    flg - PETSC_TRUE or PETSC_FALSE
517 
518     Level: developer
519 
520     Fortran Note:
521     This routine is not supported in Fortran.
522 
523   Concepts: PetscViewerASCII^formating
524   Concepts: tab^setting
525 
526 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
527           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
528           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
529 @*/
530 PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
531 {
532   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
533   PetscBool         iascii;
534   PetscErrorCode    ierr;
535 
536   PetscFunctionBegin;
537   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
538   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
539   if (iascii) {
540     if (flg) ascii->tab = ascii->tab_store;
541     else {
542       ascii->tab_store = ascii->tab;
543       ascii->tab       = 0;
544     }
545   }
546   PetscFunctionReturn(0);
547 }
548 
549 /* ----------------------------------------------------------------------- */
550 
551 
552 /*@C
553     PetscViewerASCIIPrintf - Prints to a file, only from the first
554     processor in the PetscViewer
555 
556     Not Collective, but only first processor in set has any effect
557 
558     Input Parameters:
559 +    viewer - obtained with PetscViewerASCIIOpen()
560 -    format - the usual printf() format string
561 
562     Level: developer
563 
564     Fortran Note:
565     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
566     That is, you can only pass a single character string from Fortran.
567 
568   Concepts: PetscViewerASCII^printing
569   Concepts: printing^to file
570   Concepts: printf
571 
572 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
573           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
574           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
575 @*/
576 PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
577 {
578   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
579   PetscMPIInt       rank;
580   PetscInt          tab,intab = ascii->tab;
581   PetscErrorCode    ierr;
582   FILE              *fd = ascii->fd;
583   PetscBool         iascii;
584   int               err;
585 
586   PetscFunctionBegin;
587   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
588   PetscValidCharPointer(format,2);
589   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
590   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
591   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
592   if (rank) PetscFunctionReturn(0);
593 
594   if (ascii->bviewer) { /* pass string up to parent viewer */
595     char        *string;
596     va_list     Argp;
597     size_t      fullLength;
598 
599     ierr = PetscCalloc1(QUEUESTRINGSIZE, &string);CHKERRQ(ierr);
600     va_start(Argp,format);
601     ierr = PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);CHKERRQ(ierr);
602     va_end(Argp);
603     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);CHKERRQ(ierr);
604     ierr = PetscFree(string);CHKERRQ(ierr);
605   } else { /* write directly to file */
606     va_list Argp;
607     /* flush my own messages that I may have queued up */
608     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
609     PetscInt    i;
610     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
611       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);CHKERRQ(ierr);
612       previous = next;
613       next     = next->next;
614       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
615       ierr     = PetscFree(previous);CHKERRQ(ierr);
616     }
617     ascii->petsc_printfqueue       = 0;
618     ascii->petsc_printfqueuelength = 0;
619     tab = intab;
620     while (tab--) {
621       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"  ");CHKERRQ(ierr);
622     }
623 
624     va_start(Argp,format);
625     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
626     err  = fflush(fd);
627     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
628     if (petsc_history) {
629       va_start(Argp,format);
630       tab = intab;
631       while (tab--) {
632         ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");CHKERRQ(ierr);
633       }
634       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
635       err  = fflush(petsc_history);
636       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
637     }
638     va_end(Argp);
639   }
640   PetscFunctionReturn(0);
641 }
642 
643 /*@C
644      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
645 
646     Collective on PetscViewer
647 
648   Input Parameters:
649 +  viewer - the PetscViewer; either ASCII or binary
650 -  name - the name of the file it should use
651 
652     Level: advanced
653 
654 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
655           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
656 
657 @*/
658 PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
659 {
660   PetscErrorCode ierr;
661   char           b[PETSC_MAX_PATH_LEN];
662 
663   PetscFunctionBegin;
664   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
665   PetscValidCharPointer(name,2);
666   ierr = PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));CHKERRQ(ierr);
667   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));CHKERRQ(ierr);
668   PetscFunctionReturn(0);
669 }
670 
671 /*@C
672      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
673 
674     Not Collective
675 
676   Input Parameter:
677 .  viewer - the PetscViewer; either ASCII or binary
678 
679   Output Parameter:
680 .  name - the name of the file it is using
681 
682     Level: advanced
683 
684 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
685 
686 @*/
687 PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
688 {
689   PetscErrorCode ierr;
690 
691   PetscFunctionBegin;
692   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
693   PetscValidPointer(name,2);
694   ierr = PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
695   PetscFunctionReturn(0);
696 }
697 
698 PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
699 {
700   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
701 
702   PetscFunctionBegin;
703   *name = vascii->filename;
704   PetscFunctionReturn(0);
705 }
706 
707 PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
708 {
709   PetscErrorCode    ierr;
710   size_t            len;
711   char              fname[PETSC_MAX_PATH_LEN],*gz;
712   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
713   PetscBool         isstderr,isstdout;
714   PetscMPIInt       rank;
715 
716   PetscFunctionBegin;
717   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
718   if (!name) PetscFunctionReturn(0);
719   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
720 
721   /* Is this file to be compressed */
722   vascii->storecompressed = PETSC_FALSE;
723 
724   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
725   if (gz) {
726     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
727     if (len == 3) {
728       if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
729       *gz = 0;
730       vascii->storecompressed = PETSC_TRUE;
731     }
732   }
733   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
734   if (!rank) {
735     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
736     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
737     /* empty filename means stdout */
738     if (name[0] == 0)  isstdout = PETSC_TRUE;
739     if (isstderr)      vascii->fd = PETSC_STDERR;
740     else if (isstdout) vascii->fd = PETSC_STDOUT;
741     else {
742 
743 
744       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
745       switch (vascii->mode) {
746       case FILE_MODE_READ:
747         vascii->fd = fopen(fname,"r");
748         break;
749       case FILE_MODE_WRITE:
750         vascii->fd = fopen(fname,"w");
751         break;
752       case FILE_MODE_APPEND:
753         vascii->fd = fopen(fname,"a");
754         break;
755       case FILE_MODE_UPDATE:
756         vascii->fd = fopen(fname,"r+");
757         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
758         break;
759       case FILE_MODE_APPEND_UPDATE:
760         /* I really want a file which is opened at the end for updating,
761            not a+, which opens at the beginning, but makes writes at the end.
762         */
763         vascii->fd = fopen(fname,"r+");
764         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
765         else {
766           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
767         }
768         break;
769       default:
770         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
771       }
772       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
773     }
774   }
775 #if defined(PETSC_USE_LOG)
776   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
777 #endif
778   PetscFunctionReturn(0);
779 }
780 
781 PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
782 {
783   PetscMPIInt       rank;
784   PetscErrorCode    ierr;
785   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
786 
787   PetscFunctionBegin;
788   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
789   ierr         = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
790   ierr         = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr);
791   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
792   ierr         = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr);
793   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
794   ovascii->fd  = vascii->fd;
795   ovascii->tab = vascii->tab;
796   ovascii->closefile = PETSC_FALSE;
797 
798   vascii->sviewer = *outviewer;
799 
800   (*outviewer)->format  = viewer->format;
801 
802   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
803   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
804   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
805   PetscFunctionReturn(0);
806 }
807 
808 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
809 {
810   PetscErrorCode    ierr;
811   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
812 
813   PetscFunctionBegin;
814   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
815   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
816 
817   ascii->sviewer             = 0;
818   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
819   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
820   PetscFunctionReturn(0);
821 }
822 
823 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
824 {
825   PetscErrorCode    ierr;
826   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
827 
828   PetscFunctionBegin;
829   if (ascii->filename) {
830     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
831   }
832   PetscFunctionReturn(0);
833 }
834 
835 /*MC
836    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
837 
838 
839 .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
840            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
841            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
842 
843   Level: beginner
844 
845 M*/
846 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
847 {
848   PetscViewer_ASCII *vascii;
849   PetscErrorCode    ierr;
850 
851   PetscFunctionBegin;
852   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
853   viewer->data = (void*)vascii;
854 
855   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
856   viewer->ops->flush            = PetscViewerFlush_ASCII;
857   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
858   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
859   viewer->ops->view             = PetscViewerView_ASCII;
860   viewer->ops->read             = PetscViewerASCIIRead;
861 
862   /* defaults to stdout unless set with PetscViewerFileSetName() */
863   vascii->fd        = PETSC_STDOUT;
864   vascii->mode      = FILE_MODE_WRITE;
865   vascii->bviewer   = 0;
866   vascii->subviewer = 0;
867   vascii->sviewer   = 0;
868   vascii->tab       = 0;
869   vascii->tab_store = 0;
870   vascii->filename  = 0;
871   vascii->closefile = PETSC_TRUE;
872 
873   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
874   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
875   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
876   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
877   PetscFunctionReturn(0);
878 }
879 
880 /*@C
881     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
882     several processors.  Output of the first processor is followed by that of the
883     second, etc.
884 
885     Not Collective, must call collective PetscViewerFlush() to get the results out
886 
887     Input Parameters:
888 +   viewer - the ASCII PetscViewer
889 -   format - the usual printf() format string
890 
891     Level: intermediate
892 
893     Notes:
894     You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
895 
896     Fortran Note:
897       Can only print a single character* string
898 
899 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
900           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
901           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()
902 
903 @*/
904 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
905 {
906   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
907   PetscErrorCode    ierr;
908   PetscMPIInt       rank;
909   PetscInt          tab = vascii->tab;
910   MPI_Comm          comm;
911   FILE              *fp;
912   PetscBool         iascii,hasbviewer = PETSC_FALSE;
913   int               err;
914 
915   PetscFunctionBegin;
916   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
917   PetscValidCharPointer(format,2);
918   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
919   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
920   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
921 
922   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
923   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
924 
925   if (vascii->bviewer) {
926     hasbviewer = PETSC_TRUE;
927     if (!rank) {
928       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
929       ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
930       ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
931     }
932   }
933 
934   fp   = vascii->fd;
935 
936   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
937     va_list Argp;
938     /* flush my own messages that I may have queued up */
939     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
940     PetscInt    i;
941     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
942       ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
943       previous = next;
944       next     = next->next;
945       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
946       ierr     = PetscFree(previous);CHKERRQ(ierr);
947     }
948     vascii->petsc_printfqueue       = 0;
949     vascii->petsc_printfqueuelength = 0;
950 
951     while (tab--) {
952       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
953     }
954 
955     va_start(Argp,format);
956     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
957     err  = fflush(fp);
958     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
959     if (petsc_history) {
960       va_start(Argp,format);
961       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
962       err  = fflush(petsc_history);
963       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
964     }
965     va_end(Argp);
966   } else { /* other processors add to queue */
967     char        *string;
968     va_list     Argp;
969     size_t      fullLength;
970     PrintfQueue next;
971 
972     ierr = PetscNew(&next);CHKERRQ(ierr);
973     if (vascii->petsc_printfqueue) {
974       vascii->petsc_printfqueue->next = next;
975       vascii->petsc_printfqueue       = next;
976     } else {
977       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
978     }
979     vascii->petsc_printfqueuelength++;
980     next->size = QUEUESTRINGSIZE;
981     ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
982     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
983     string     = next->string;
984     tab       *= 2;
985     while (tab--) {
986       *string++ = ' ';
987     }
988     va_start(Argp,format);
989     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
990     va_end(Argp);
991     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
992       ierr       = PetscFree(next->string);CHKERRQ(ierr);
993       next->size = fullLength + 2*vascii->tab;
994       ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
995       ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
996       string     = next->string;
997       tab        = 2*vascii->tab;
998       while (tab--) {
999         *string++ = ' ';
1000       }
1001       va_start(Argp,format);
1002       ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);CHKERRQ(ierr);
1003       va_end(Argp);
1004     }
1005   }
1006   PetscFunctionReturn(0);
1007 }
1008 
1009 /*@C
1010    PetscViewerASCIIRead - Reads from am ASCII file
1011 
1012    Collective on MPI_Comm
1013 
1014    Input Parameters:
1015 +  viewer - the ascii viewer
1016 .  data - location to write the data
1017 .  num - number of items of data to read
1018 -  datatype - type of data to read
1019 
1020    Output Parameters:
1021 .  count - number of items of data actually read, or NULL
1022 
1023    Level: beginner
1024 
1025    Concepts: ascii files
1026 
1027 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1028           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1029           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1030 @*/
1031 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1032 {
1033   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1034   FILE              *fd = vascii->fd;
1035   PetscInt           i;
1036   int                ret = 0;
1037 
1038   PetscFunctionBegin;
1039   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1040   for (i=0; i<num; i++) {
1041     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1042     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1043     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1044     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1045     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1046     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1047 #if defined(PETSC_USE_REAL___FLOAT128)
1048     else if (dtype == PETSC___FLOAT128) {
1049       double tmp;
1050       ret = fscanf(fd, "%lg", &tmp);
1051       ((__float128*)data)[i] = tmp;
1052     }
1053 #endif
1054     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1055     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1056     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1057   }
1058   if (count) *count = i;
1059   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1060   PetscFunctionReturn(0);
1061 }
1062 
1063