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