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