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