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