xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 0a3e67a1ed129a79ff861d04ef412bfe2fadf78d)
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       = PetscMalloc(next->size*sizeof(char), &next->string);CHKERRQ(ierr);
586     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
587     string     = next->string;
588     tab        = intab;
589     tab       *= 2;
590     while (tab--) {
591       *string++ = ' ';
592     }
593     va_start(Argp,format);
594     ierr = PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
595     va_end(Argp);
596   }
597   PetscFunctionReturn(0);
598 }
599 
600 #undef __FUNCT__
601 #define __FUNCT__ "PetscViewerFileSetName"
602 /*@C
603      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
604 
605     Collective on PetscViewer
606 
607   Input Parameters:
608 +  viewer - the PetscViewer; either ASCII or binary
609 -  name - the name of the file it should use
610 
611     Level: advanced
612 
613 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
614           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
615 
616 @*/
617 PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
618 {
619   PetscErrorCode ierr;
620 
621   PetscFunctionBegin;
622   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
623   PetscValidCharPointer(name,2);
624   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));CHKERRQ(ierr);
625   PetscFunctionReturn(0);
626 }
627 
628 #undef __FUNCT__
629 #define __FUNCT__ "PetscViewerFileGetName"
630 /*@C
631      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
632 
633     Not Collective
634 
635   Input Parameter:
636 .  viewer - the PetscViewer; either ASCII or binary
637 
638   Output Parameter:
639 .  name - the name of the file it is using
640 
641     Level: advanced
642 
643 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
644 
645 @*/
646 PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
647 {
648   PetscErrorCode ierr;
649 
650   PetscFunctionBegin;
651   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
652   ierr = PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
653   PetscFunctionReturn(0);
654 }
655 
656 #undef __FUNCT__
657 #define __FUNCT__ "PetscViewerFileGetName_ASCII"
658 PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
659 {
660   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
661 
662   PetscFunctionBegin;
663   *name = vascii->filename;
664   PetscFunctionReturn(0);
665 }
666 
667 #undef __FUNCT__
668 #define __FUNCT__ "PetscViewerFileSetName_ASCII"
669 PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
670 {
671   PetscErrorCode    ierr;
672   size_t            len;
673   char              fname[PETSC_MAX_PATH_LEN],*gz;
674   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
675   PetscBool         isstderr,isstdout;
676   PetscMPIInt       rank;
677 
678   PetscFunctionBegin;
679   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
680   if (!name) PetscFunctionReturn(0);
681   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
682 
683   /* Is this file to be compressed */
684   vascii->storecompressed = PETSC_FALSE;
685 
686   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
687   if (gz) {
688     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
689     if (len == 3) {
690       *gz = 0;
691       vascii->storecompressed = PETSC_TRUE;
692     }
693   }
694   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
695   if (!rank) {
696     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
697     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
698     /* empty filename means stdout */
699     if (name[0] == 0)  isstdout = PETSC_TRUE;
700     if (isstderr)      vascii->fd = PETSC_STDERR;
701     else if (isstdout) vascii->fd = PETSC_STDOUT;
702     else {
703 
704 
705       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
706       switch (vascii->mode) {
707       case FILE_MODE_READ:
708         vascii->fd = fopen(fname,"r");
709         break;
710       case FILE_MODE_WRITE:
711         vascii->fd = fopen(fname,"w");
712         break;
713       case FILE_MODE_APPEND:
714         vascii->fd = fopen(fname,"a");
715         break;
716       case FILE_MODE_UPDATE:
717         vascii->fd = fopen(fname,"r+");
718         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
719         break;
720       case FILE_MODE_APPEND_UPDATE:
721         /* I really want a file which is opened at the end for updating,
722            not a+, which opens at the beginning, but makes writes at the end.
723         */
724         vascii->fd = fopen(fname,"r+");
725         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
726         else {
727           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
728         }
729         break;
730       default:
731         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
732       }
733       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
734     }
735   }
736 #if defined(PETSC_USE_LOG)
737   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
738 #endif
739   PetscFunctionReturn(0);
740 }
741 
742 #undef __FUNCT__
743 #define __FUNCT__ "PetscViewerGetSingleton_ASCII"
744 PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
745 {
746   PetscMPIInt       rank;
747   PetscErrorCode    ierr;
748   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
749   const char        *name;
750 
751   PetscFunctionBegin;
752   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
753   ierr         = PetscViewerCreate(PETSC_COMM_SELF,outviewer);CHKERRQ(ierr);
754   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
755   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
756   ovascii->fd  = vascii->fd;
757   ovascii->tab = vascii->tab;
758 
759   vascii->sviewer = *outviewer;
760 
761   (*outviewer)->format  = viewer->format;
762 
763   ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr);
764   ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr);
765 
766   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
767   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
768   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
769   if (rank) (*outviewer)->ops->flush = 0;
770   else      (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
771   PetscFunctionReturn(0);
772 }
773 
774 #undef __FUNCT__
775 #define __FUNCT__ "PetscViewerRestoreSingleton_ASCII"
776 PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
777 {
778   PetscErrorCode    ierr;
779   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data;
780   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
781 
782   PetscFunctionBegin;
783   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
784   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
785 
786   ascii->sviewer             = 0;
787   vascii->fd                 = PETSC_STDOUT;
788   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
789   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
790   ierr                       = PetscViewerFlush(viewer);CHKERRQ(ierr);
791   PetscFunctionReturn(0);
792 }
793 
794 #undef __FUNCT__
795 #define __FUNCT__ "PetscViewerGetSubcomm_ASCII"
796 PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
797 {
798   PetscErrorCode    ierr;
799   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
800   const char        *name;
801 
802   PetscFunctionBegin;
803   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
804   /* Note that we need to open vascii->filename for the subcomm:
805      we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
806      Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
807      will return the current viewer, having increfed it.
808    */
809   ierr = PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);CHKERRQ(ierr);
810   if (*outviewer == viewer) PetscFunctionReturn(0);
811   ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
812 
813   ovascii->tab    = vascii->tab;
814   vascii->sviewer = *outviewer;
815 
816   (*outviewer)->format  = viewer->format;
817 
818   ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr);
819   ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr);
820 
821   ((PetscViewer_ASCII*)((*outviewer)->data))->subviewer = viewer;
822 
823   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
824   PetscFunctionReturn(0);
825 }
826 
827 #undef __FUNCT__
828 #define __FUNCT__ "PetscViewerRestoreSubcomm_ASCII"
829 PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
830 {
831   PetscErrorCode    ierr;
832   PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data;
833   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
834 
835   PetscFunctionBegin;
836   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
837   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");
838 
839   ascii->sviewer             = 0;
840   oascii->fd                 = PETSC_STDOUT;
841   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
842 
843   ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
844   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
845   PetscFunctionReturn(0);
846 }
847 
848 #undef __FUNCT__
849 #define __FUNCT__ "PetscViewerView_ASCII"
850 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
851 {
852   PetscErrorCode    ierr;
853   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
854 
855   PetscFunctionBegin;
856   if (ascii->filename) {
857     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
858   }
859   PetscFunctionReturn(0);
860 }
861 
862 #undef __FUNCT__
863 #define __FUNCT__ "PetscViewerCreate_ASCII"
864 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
865 {
866   PetscViewer_ASCII *vascii;
867   PetscErrorCode    ierr;
868 
869   PetscFunctionBegin;
870   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
871   viewer->data = (void*)vascii;
872 
873   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
874   viewer->ops->flush            = PetscViewerFlush_ASCII;
875   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
876   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
877   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
878   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;
879   viewer->ops->view             = PetscViewerView_ASCII;
880   viewer->ops->read             = PetscViewerASCIIRead;
881 
882   /* defaults to stdout unless set with PetscViewerFileSetName() */
883   vascii->fd        = PETSC_STDOUT;
884   vascii->mode      = FILE_MODE_WRITE;
885   vascii->bviewer   = 0;
886   vascii->subviewer = 0;
887   vascii->sviewer   = 0;
888   vascii->tab       = 0;
889   vascii->tab_store = 0;
890   vascii->filename  = 0;
891   vascii->closefile = PETSC_TRUE;
892 
893   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
894   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
895   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
896   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
897   PetscFunctionReturn(0);
898 }
899 
900 
901 #undef __FUNCT__
902 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf"
903 /*@C
904     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
905     several processors.  Output of the first processor is followed by that of the
906     second, etc.
907 
908     Not Collective, must call collective PetscViewerFlush() to get the results out
909 
910     Input Parameters:
911 +   viewer - the ASCII PetscViewer
912 -   format - the usual printf() format string
913 
914     Level: intermediate
915 
916     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
917 
918     Fortran Note:
919       Can only print a single character* string
920 
921 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
922           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
923           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
924 
925 @*/
926 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
927 {
928   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
929   PetscErrorCode    ierr;
930   PetscMPIInt       rank,size;
931   PetscInt          tab = vascii->tab;
932   MPI_Comm          comm;
933   FILE              *fp;
934   PetscBool         iascii;
935   int               err;
936 
937   PetscFunctionBegin;
938   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
939   PetscValidCharPointer(format,2);
940   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
941   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
942   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr);
943   if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
944   if (!viewer->ops->flush) PetscFunctionReturn(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
945 
946   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
947   fp   = vascii->fd;
948   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
949 
950   /* First processor prints immediately to fp */
951   if (!rank) {
952     va_list Argp;
953 
954     while (tab--) {
955       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
956     }
957 
958     va_start(Argp,format);
959     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
960     err  = fflush(fp);
961     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
962     if (petsc_history) {
963       va_start(Argp,format);
964       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
965       err  = fflush(petsc_history);
966       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
967     }
968     va_end(Argp);
969   } else { /* other processors add to local queue */
970     char        *string;
971     va_list     Argp;
972     size_t      fullLength;
973     PrintfQueue next;
974 
975     ierr = PetscNew(&next);CHKERRQ(ierr);
976     if (petsc_printfqueue) {
977       petsc_printfqueue->next = next;
978       petsc_printfqueue       = next;
979     } else {
980       petsc_printfqueuebase = petsc_printfqueue = next;
981     }
982     petsc_printfqueuelength++;
983     next->size = QUEUESTRINGSIZE;
984     ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
985     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
986     string     = next->string;
987     tab       *= 2;
988     while (tab--) {
989       *string++ = ' ';
990     }
991     va_start(Argp,format);
992     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
993     va_end(Argp);
994   }
995   PetscFunctionReturn(0);
996 }
997 
998 #undef __FUNCT__
999 #define __FUNCT__ "PetscViewerASCIIRead"
1000 /*@C
1001    PetscViewerASCIIRead - Reads from am ASCII file
1002 
1003    Collective on MPI_Comm
1004 
1005    Input Parameters:
1006 +  viewer - the ascii viewer
1007 .  data - location to write the data
1008 .  count - number of items of data to read
1009 -  datatype - type of data to read
1010 
1011    Level: beginner
1012 
1013    Concepts: ascii files
1014 
1015 .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
1016           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1017           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1018 @*/
1019 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt count,PetscDataType dtype)
1020 {
1021   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1022   FILE              *fd = vascii->fd;
1023   PetscInt           i;
1024 
1025   PetscFunctionBegin;
1026   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1027   for (i=0; i<count; i++) {
1028     if (dtype == PETSC_CHAR)         fscanf(fd, "%c",  &(((char*)data)[i]));
1029     else if (dtype == PETSC_STRING)  fscanf(fd, "%s",  &(((char*)data)[i]));
1030 #if PETSC_USE_64BIT_INDICES
1031 #if (PETSC_SIZEOF_LONG_LONG == 8)
1032     else if (dtype == PETSC_INT)     fscanf(fd, "%ld",  &(((PetscInt*)data)[i]));
1033 #else
1034     else if (dtype == PETSC_INT)     fscanf(fd, "%lld",  &(((PetscInt*)data)[i]));
1035 #endif
1036 #else
1037     else if (dtype == PETSC_INT)     fscanf(fd, "%d",  &(((PetscInt*)data)[i]));
1038 #endif
1039     else if (dtype == PETSC_ENUM)    fscanf(fd, "%d",  &(((int*)data)[i]));
1040     else if (dtype == PETSC_FLOAT)   fscanf(fd, "%f",  &(((float*)data)[i]));
1041     else if (dtype == PETSC_DOUBLE)  fscanf(fd, "%lg", &(((double*)data)[i]));
1042     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type not supported in PetscViewerASCIIRead()", dtype);}
1043   }
1044   PetscFunctionReturn(0);
1045 }
1046 
1047