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