xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 65fb505c3bb3585bd41d1326df8aece6b778cc8e)
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 - optained 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 - optained 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 - optained 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 - optained 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__ "PetscViewerASCIISynchronizedAllow"
384 /*@C
385     PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
386 
387     Collective on PetscViewer
388 
389     Input Parameters:
390 +    viewer - optained with PetscViewerASCIIOpen()
391 -    allow - PETSC_TRUE to allow the synchronized printing
392 
393     Level: intermediate
394 
395   Concepts: PetscViewerASCII^formating
396   Concepts: tab^setting
397 
398 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
399           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
400           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
401 @*/
402 PetscErrorCode  PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
403 {
404   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
405   PetscBool         iascii;
406   PetscErrorCode    ierr;
407 
408   PetscFunctionBegin;
409   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
410   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
411   if (iascii) ascii->allowsynchronized = allow;
412   PetscFunctionReturn(0);
413 }
414 
415 #undef __FUNCT__
416 #define __FUNCT__ "PetscViewerASCIIPushTab"
417 /*@
418     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
419      lines are tabbed.
420 
421     Not Collective, but only first processor in set has any effect
422 
423     Input Parameters:
424 .    viewer - optained with PetscViewerASCIIOpen()
425 
426     Level: developer
427 
428     Fortran Note:
429     This routine is not supported in Fortran.
430 
431   Concepts: PetscViewerASCII^formating
432   Concepts: tab^setting
433 
434 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
435           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
436           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
437 @*/
438 PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
439 {
440   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
441   PetscBool         iascii;
442   PetscErrorCode    ierr;
443 
444   PetscFunctionBegin;
445   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
446   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
447   if (iascii) ascii->tab++;
448   PetscFunctionReturn(0);
449 }
450 
451 #undef __FUNCT__
452 #define __FUNCT__ "PetscViewerASCIIPopTab"
453 /*@
454     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
455      lines are tabbed.
456 
457     Not Collective, but only first processor in set has any effect
458 
459     Input Parameters:
460 .    viewer - optained with PetscViewerASCIIOpen()
461 
462     Level: developer
463 
464     Fortran Note:
465     This routine is not supported in Fortran.
466 
467   Concepts: PetscViewerASCII^formating
468   Concepts: tab^setting
469 
470 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
471           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
472           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
473 @*/
474 PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
475 {
476   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
477   PetscErrorCode    ierr;
478   PetscBool         iascii;
479 
480   PetscFunctionBegin;
481   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
482   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
483   if (iascii) {
484     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
485     ascii->tab--;
486   }
487   PetscFunctionReturn(0);
488 }
489 
490 #undef __FUNCT__
491 #define __FUNCT__ "PetscViewerASCIIUseTabs"
492 /*@
493     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
494 
495     Not Collective, but only first processor in set has any effect
496 
497     Input Parameters:
498 +    viewer - optained with PetscViewerASCIIOpen()
499 -    flg - PETSC_TRUE or PETSC_FALSE
500 
501     Level: developer
502 
503     Fortran Note:
504     This routine is not supported in Fortran.
505 
506   Concepts: PetscViewerASCII^formating
507   Concepts: tab^setting
508 
509 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
510           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
511           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
512 @*/
513 PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
514 {
515   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
516   PetscBool         iascii;
517   PetscErrorCode    ierr;
518 
519   PetscFunctionBegin;
520   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
521   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
522   if (iascii) {
523     if (flg) ascii->tab = ascii->tab_store;
524     else {
525       ascii->tab_store = ascii->tab;
526       ascii->tab       = 0;
527     }
528   }
529   PetscFunctionReturn(0);
530 }
531 
532 /* ----------------------------------------------------------------------- */
533 
534 
535 #undef __FUNCT__
536 #define __FUNCT__ "PetscViewerASCIIPrintf"
537 /*@C
538     PetscViewerASCIIPrintf - Prints to a file, only from the first
539     processor in the PetscViewer
540 
541     Not Collective, but only first processor in set has any effect
542 
543     Input Parameters:
544 +    viewer - optained with PetscViewerASCIIOpen()
545 -    format - the usual printf() format string
546 
547     Level: developer
548 
549     Fortran Note:
550     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
551     That is, you can only pass a single character string from Fortran.
552 
553   Concepts: PetscViewerASCII^printing
554   Concepts: printing^to file
555   Concepts: printf
556 
557 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
558           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
559           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
560 @*/
561 PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
562 {
563   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
564   PetscMPIInt       rank;
565   PetscInt          tab,intab = ascii->tab;
566   PetscErrorCode    ierr;
567   FILE              *fd = ascii->fd;
568   PetscBool         iascii;
569   int               err;
570 
571   PetscFunctionBegin;
572   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
573   PetscValidCharPointer(format,2);
574   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
575   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
576   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
577   if (rank) PetscFunctionReturn(0);
578 
579   if (ascii->bviewer) { /* pass string up to parent viewer */
580     char        *string;
581     va_list     Argp;
582     size_t      fullLength;
583 
584     ierr       = PetscCalloc1(QUEUESTRINGSIZE, &string);CHKERRQ(ierr);
585     tab        = intab;
586     tab       *= 2;
587     while (tab--) {
588       *string++ = ' ';
589     }
590     va_start(Argp,format);
591     ierr = PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
592     va_end(Argp);
593 
594     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);CHKERRQ(ierr);
595     ierr = PetscFree(string);CHKERRQ(ierr);
596   } else { /* write directly to file */
597     va_list Argp;
598     /* flush my own messages that I may have queued up */
599     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
600     PetscInt    i;
601     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
602       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);CHKERRQ(ierr);
603       previous = next;
604       next     = next->next;
605       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
606       ierr     = PetscFree(previous);CHKERRQ(ierr);
607     }
608     ascii->petsc_printfqueue       = 0;
609     ascii->petsc_printfqueuelength = 0;
610     tab = intab;
611     while (tab--) {
612       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"  ");CHKERRQ(ierr);
613     }
614 
615     va_start(Argp,format);
616     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
617     err  = fflush(fd);
618     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
619     if (petsc_history) {
620       va_start(Argp,format);
621       tab = intab;
622       while (tab--) {
623         ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");CHKERRQ(ierr);
624       }
625       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
626       err  = fflush(petsc_history);
627       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
628     }
629     va_end(Argp);
630   }
631   PetscFunctionReturn(0);
632 }
633 
634 #undef __FUNCT__
635 #define __FUNCT__ "PetscViewerFileSetName"
636 /*@C
637      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
638 
639     Collective on PetscViewer
640 
641   Input Parameters:
642 +  viewer - the PetscViewer; either ASCII or binary
643 -  name - the name of the file it should use
644 
645     Level: advanced
646 
647 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
648           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
649 
650 @*/
651 PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
652 {
653   PetscErrorCode ierr;
654 
655   PetscFunctionBegin;
656   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
657   PetscValidCharPointer(name,2);
658   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));CHKERRQ(ierr);
659   PetscFunctionReturn(0);
660 }
661 
662 #undef __FUNCT__
663 #define __FUNCT__ "PetscViewerFileGetName"
664 /*@C
665      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
666 
667     Not Collective
668 
669   Input Parameter:
670 .  viewer - the PetscViewer; either ASCII or binary
671 
672   Output Parameter:
673 .  name - the name of the file it is using
674 
675     Level: advanced
676 
677 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
678 
679 @*/
680 PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
681 {
682   PetscErrorCode ierr;
683 
684   PetscFunctionBegin;
685   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
686   ierr = PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
687   PetscFunctionReturn(0);
688 }
689 
690 #undef __FUNCT__
691 #define __FUNCT__ "PetscViewerFileGetName_ASCII"
692 PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
693 {
694   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
695 
696   PetscFunctionBegin;
697   *name = vascii->filename;
698   PetscFunctionReturn(0);
699 }
700 
701 #undef __FUNCT__
702 #define __FUNCT__ "PetscViewerFileSetName_ASCII"
703 PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
704 {
705   PetscErrorCode    ierr;
706   size_t            len;
707   char              fname[PETSC_MAX_PATH_LEN],*gz;
708   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
709   PetscBool         isstderr,isstdout;
710   PetscMPIInt       rank;
711 
712   PetscFunctionBegin;
713   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
714   if (!name) PetscFunctionReturn(0);
715   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
716 
717   /* Is this file to be compressed */
718   vascii->storecompressed = PETSC_FALSE;
719 
720   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
721   if (gz) {
722     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
723     if (len == 3) {
724       *gz = 0;
725       vascii->storecompressed = PETSC_TRUE;
726     }
727   }
728   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
729   if (!rank) {
730     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
731     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
732     /* empty filename means stdout */
733     if (name[0] == 0)  isstdout = PETSC_TRUE;
734     if (isstderr)      vascii->fd = PETSC_STDERR;
735     else if (isstdout) vascii->fd = PETSC_STDOUT;
736     else {
737 
738 
739       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
740       switch (vascii->mode) {
741       case FILE_MODE_READ:
742         vascii->fd = fopen(fname,"r");
743         break;
744       case FILE_MODE_WRITE:
745         vascii->fd = fopen(fname,"w");
746         break;
747       case FILE_MODE_APPEND:
748         vascii->fd = fopen(fname,"a");
749         break;
750       case FILE_MODE_UPDATE:
751         vascii->fd = fopen(fname,"r+");
752         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
753         break;
754       case FILE_MODE_APPEND_UPDATE:
755         /* I really want a file which is opened at the end for updating,
756            not a+, which opens at the beginning, but makes writes at the end.
757         */
758         vascii->fd = fopen(fname,"r+");
759         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
760         else {
761           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
762         }
763         break;
764       default:
765         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
766       }
767       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
768     }
769   }
770 #if defined(PETSC_USE_LOG)
771   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
772 #endif
773   PetscFunctionReturn(0);
774 }
775 
776 #undef __FUNCT__
777 #define __FUNCT__ "PetscViewerGetSubViewer_ASCII"
778 PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
779 {
780   PetscMPIInt       rank;
781   PetscErrorCode    ierr;
782   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
783 
784   PetscFunctionBegin;
785   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
786   ierr = PetscViewerASCIISynchronizedAllow(viewer,PETSC_TRUE);CHKERRQ(ierr);
787   ierr         = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr);
788   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
789   ierr         = PetscViewerASCIISynchronizedAllow(*outviewer,PETSC_TRUE);CHKERRQ(ierr);
790   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
791   ovascii->fd  = vascii->fd;
792   ovascii->tab = vascii->tab;
793 
794   vascii->sviewer = *outviewer;
795 
796   (*outviewer)->format  = viewer->format;
797 
798   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
799   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
800   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
801   PetscFunctionReturn(0);
802 }
803 
804 #undef __FUNCT__
805 #define __FUNCT__ "PetscViewerRestoreSubViewer_ASCII"
806 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
807 {
808   PetscErrorCode    ierr;
809   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
810 
811   PetscFunctionBegin;
812   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer PetscViewer never obtained from PetscViewer");
813   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate a SubViewer PetscViewer");
814 
815   ascii->sviewer             = 0;
816   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
817   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
818   ierr                       = PetscViewerFlush(viewer);CHKERRQ(ierr);
819   PetscFunctionReturn(0);
820 }
821 
822 #undef __FUNCT__
823 #define __FUNCT__ "PetscViewerView_ASCII"
824 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
825 {
826   PetscErrorCode    ierr;
827   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
828 
829   PetscFunctionBegin;
830   if (ascii->filename) {
831     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
832   }
833   PetscFunctionReturn(0);
834 }
835 
836 #undef __FUNCT__
837 #define __FUNCT__ "PetscViewerCreate_ASCII"
838 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
839 {
840   PetscViewer_ASCII *vascii;
841   PetscErrorCode    ierr;
842 
843   PetscFunctionBegin;
844   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
845   viewer->data = (void*)vascii;
846 
847   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
848   viewer->ops->flush            = PetscViewerFlush_ASCII;
849   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
850   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
851   viewer->ops->view             = PetscViewerView_ASCII;
852   viewer->ops->read             = PetscViewerASCIIRead;
853 
854   /* defaults to stdout unless set with PetscViewerFileSetName() */
855   vascii->fd        = PETSC_STDOUT;
856   vascii->mode      = FILE_MODE_WRITE;
857   vascii->bviewer   = 0;
858   vascii->subviewer = 0;
859   vascii->sviewer   = 0;
860   vascii->tab       = 0;
861   vascii->tab_store = 0;
862   vascii->filename  = 0;
863   vascii->closefile = PETSC_TRUE;
864 
865   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
866   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
867   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
868   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
869   PetscFunctionReturn(0);
870 }
871 
872 #undef __FUNCT__
873 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf"
874 /*@C
875     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
876     several processors.  Output of the first processor is followed by that of the
877     second, etc.
878 
879     Not Collective, must call collective PetscViewerFlush() to get the results out
880 
881     Input Parameters:
882 +   viewer - the ASCII PetscViewer
883 -   format - the usual printf() format string
884 
885     Level: intermediate
886 
887     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
888 
889     Fortran Note:
890       Can only print a single character* string
891 
892 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
893           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
894           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
895 
896 @*/
897 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
898 {
899   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
900   PetscErrorCode    ierr;
901   PetscMPIInt       rank;
902   PetscInt          tab = vascii->tab;
903   MPI_Comm          comm;
904   FILE              *fp;
905   PetscBool         iascii,hasbviewer = PETSC_FALSE;
906   int               err;
907 
908   PetscFunctionBegin;
909   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
910   PetscValidCharPointer(format,2);
911   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
912   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
913   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
914 
915   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
916   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
917 
918   if (vascii->bviewer) {
919     hasbviewer = PETSC_TRUE;
920     if (!rank) {
921       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
922       ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
923       ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
924     }
925   }
926 
927   fp   = vascii->fd;
928 
929   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
930     va_list Argp;
931     /* flush my own messages that I may have queued up */
932     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
933     PetscInt    i;
934     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
935       ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
936       previous = next;
937       next     = next->next;
938       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
939       ierr     = PetscFree(previous);CHKERRQ(ierr);
940     }
941     vascii->petsc_printfqueue       = 0;
942     vascii->petsc_printfqueuelength = 0;
943 
944     while (tab--) {
945       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
946     }
947 
948     va_start(Argp,format);
949     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
950     err  = fflush(fp);
951     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
952     if (petsc_history) {
953       va_start(Argp,format);
954       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
955       err  = fflush(petsc_history);
956       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
957     }
958     va_end(Argp);
959   } else { /* other processors add to queue */
960     char        *string;
961     va_list     Argp;
962     size_t      fullLength;
963     PrintfQueue next;
964 
965     ierr = PetscNew(&next);CHKERRQ(ierr);
966     if (vascii->petsc_printfqueue) {
967       vascii->petsc_printfqueue->next = next;
968       vascii->petsc_printfqueue       = next;
969     } else {
970       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
971     }
972     vascii->petsc_printfqueuelength++;
973     next->size = QUEUESTRINGSIZE;
974     ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
975     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
976     string     = next->string;
977     tab       *= 2;
978     while (tab--) {
979       *string++ = ' ';
980     }
981     va_start(Argp,format);
982     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
983     va_end(Argp);
984   }
985   PetscFunctionReturn(0);
986 }
987 
988 #undef __FUNCT__
989 #define __FUNCT__ "PetscViewerASCIIRead"
990 /*@C
991    PetscViewerASCIIRead - Reads from am ASCII file
992 
993    Collective on MPI_Comm
994 
995    Input Parameters:
996 +  viewer - the ascii viewer
997 .  data - location to write the data
998 .  num - number of items of data to read
999 -  datatype - type of data to read
1000 
1001    Output Parameters:
1002 .  count - number of items of data actually read, or NULL
1003 
1004    Level: beginner
1005 
1006    Concepts: ascii files
1007 
1008 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
1009           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1010           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1011 @*/
1012 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1013 {
1014   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1015   FILE              *fd = vascii->fd;
1016   PetscInt           i;
1017   int                ret = 0;
1018 
1019   PetscFunctionBegin;
1020   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1021   for (i=0; i<num; i++) {
1022     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1023     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1024 #if PETSC_USE_64BIT_INDICES
1025 #if (PETSC_SIZEOF_LONG_LONG == 8)
1026     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%ld",  &(((PetscInt*)data)[i]));
1027 #else
1028     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%lld",  &(((PetscInt*)data)[i]));
1029 #endif
1030 #else
1031     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%d",  &(((PetscInt*)data)[i]));
1032 #endif
1033     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1034     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1035     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1036     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1037     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1038     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1039   }
1040   if (count) *count = i;
1041   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1042   PetscFunctionReturn(0);
1043 }
1044 
1045