xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 2bf68e3e0f2a61f71e7c65bee250bfa1c8ce0cdb)
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 = PetscUseMethod(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 /*MC
865    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
866 
867 
868 .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
869            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
870            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
871 
872   Level: beginner
873 
874 M*/
875 #undef __FUNCT__
876 #define __FUNCT__ "PetscViewerCreate_ASCII"
877 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
878 {
879   PetscViewer_ASCII *vascii;
880   PetscErrorCode    ierr;
881 
882   PetscFunctionBegin;
883   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
884   viewer->data = (void*)vascii;
885 
886   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
887   viewer->ops->flush            = PetscViewerFlush_ASCII;
888   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
889   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
890   viewer->ops->view             = PetscViewerView_ASCII;
891   viewer->ops->read             = PetscViewerASCIIRead;
892 
893   /* defaults to stdout unless set with PetscViewerFileSetName() */
894   vascii->fd        = PETSC_STDOUT;
895   vascii->mode      = FILE_MODE_WRITE;
896   vascii->bviewer   = 0;
897   vascii->subviewer = 0;
898   vascii->sviewer   = 0;
899   vascii->tab       = 0;
900   vascii->tab_store = 0;
901   vascii->filename  = 0;
902   vascii->closefile = PETSC_TRUE;
903 
904   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
905   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
906   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
907   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
908   PetscFunctionReturn(0);
909 }
910 
911 #undef __FUNCT__
912 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf"
913 /*@C
914     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
915     several processors.  Output of the first processor is followed by that of the
916     second, etc.
917 
918     Not Collective, must call collective PetscViewerFlush() to get the results out
919 
920     Input Parameters:
921 +   viewer - the ASCII PetscViewer
922 -   format - the usual printf() format string
923 
924     Level: intermediate
925 
926     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
927 
928     Fortran Note:
929       Can only print a single character* string
930 
931 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
932           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
933           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()
934 
935 @*/
936 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
937 {
938   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
939   PetscErrorCode    ierr;
940   PetscMPIInt       rank;
941   PetscInt          tab = vascii->tab;
942   MPI_Comm          comm;
943   FILE              *fp;
944   PetscBool         iascii,hasbviewer = PETSC_FALSE;
945   int               err;
946 
947   PetscFunctionBegin;
948   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
949   PetscValidCharPointer(format,2);
950   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
951   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
952   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
953 
954   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
955   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
956 
957   if (vascii->bviewer) {
958     hasbviewer = PETSC_TRUE;
959     if (!rank) {
960       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
961       ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
962       ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
963     }
964   }
965 
966   fp   = vascii->fd;
967 
968   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
969     va_list Argp;
970     /* flush my own messages that I may have queued up */
971     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
972     PetscInt    i;
973     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
974       ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
975       previous = next;
976       next     = next->next;
977       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
978       ierr     = PetscFree(previous);CHKERRQ(ierr);
979     }
980     vascii->petsc_printfqueue       = 0;
981     vascii->petsc_printfqueuelength = 0;
982 
983     while (tab--) {
984       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
985     }
986 
987     va_start(Argp,format);
988     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
989     err  = fflush(fp);
990     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
991     if (petsc_history) {
992       va_start(Argp,format);
993       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
994       err  = fflush(petsc_history);
995       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
996     }
997     va_end(Argp);
998   } else { /* other processors add to queue */
999     char        *string;
1000     va_list     Argp;
1001     size_t      fullLength;
1002     PrintfQueue next;
1003 
1004     ierr = PetscNew(&next);CHKERRQ(ierr);
1005     if (vascii->petsc_printfqueue) {
1006       vascii->petsc_printfqueue->next = next;
1007       vascii->petsc_printfqueue       = next;
1008     } else {
1009       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
1010     }
1011     vascii->petsc_printfqueuelength++;
1012     next->size = QUEUESTRINGSIZE;
1013     ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
1014     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
1015     string     = next->string;
1016     tab       *= 2;
1017     while (tab--) {
1018       *string++ = ' ';
1019     }
1020     va_start(Argp,format);
1021     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
1022     va_end(Argp);
1023   }
1024   PetscFunctionReturn(0);
1025 }
1026 
1027 #undef __FUNCT__
1028 #define __FUNCT__ "PetscViewerASCIIRead"
1029 /*@C
1030    PetscViewerASCIIRead - Reads from am ASCII file
1031 
1032    Collective on MPI_Comm
1033 
1034    Input Parameters:
1035 +  viewer - the ascii viewer
1036 .  data - location to write the data
1037 .  num - number of items of data to read
1038 -  datatype - type of data to read
1039 
1040    Output Parameters:
1041 .  count - number of items of data actually read, or NULL
1042 
1043    Level: beginner
1044 
1045    Concepts: ascii files
1046 
1047 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1048           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1049           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1050 @*/
1051 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1052 {
1053   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1054   FILE              *fd = vascii->fd;
1055   PetscInt           i;
1056   int                ret = 0;
1057 
1058   PetscFunctionBegin;
1059   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1060   for (i=0; i<num; i++) {
1061     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1062     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1063     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1064     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1065     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1066     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1067     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1068     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1069     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1070   }
1071   if (count) *count = i;
1072   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1073   PetscFunctionReturn(0);
1074 }
1075 
1076