Actual source code: filev.c
1: #define PETSC_DLL
3: #include src/sys/viewer/impls/ascii/asciiimpl.h
4: #include "petscfix.h"
5: #include <stdarg.h>
7: /* ----------------------------------------------------------------------*/
10: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
11: {
12: PetscMPIInt rank;
13: PetscErrorCode ierr;
14: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
15: PetscViewerLink *vlink;
16: PetscTruth flg;
19: if (vascii->sviewer) {
20: SETERRQ(PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
21: }
22: MPI_Comm_rank(viewer->comm,&rank);
23: if (!rank && vascii->fd != stderr && vascii->fd != stdout) {
24: if (vascii->fd) fclose(vascii->fd);
25: if (vascii->storecompressed) {
26: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
27: FILE *fp;
28: PetscStrcpy(par,"gzip ");
29: PetscStrcat(par,vascii->filename);
30: #if defined(PETSC_HAVE_POPEN)
31: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
32: if (fgets(buf,1024,fp)) {
33: SETERRQ2(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
34: }
35: PetscPClose(PETSC_COMM_SELF,fp);
36: #else
37: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
38: #endif
39: }
40: }
41: PetscStrfree(vascii->filename);
42: PetscFree(vascii);
44: /* remove the viewer from the list in the MPI Communicator */
45: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
46: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
47: }
49: MPI_Attr_get(viewer->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
50: if (flg) {
51: if (vlink && vlink->viewer == viewer) {
52: MPI_Attr_put(viewer->comm,Petsc_Viewer_keyval,vlink->next);
53: PetscFree(vlink);
54: } else {
55: while (vlink && vlink->next) {
56: if (vlink->next->viewer == viewer) {
57: PetscViewerLink *nv = vlink->next;
58: vlink->next = vlink->next->next;
59: PetscFree(nv);
60: }
61: vlink = vlink->next;
62: }
63: }
64: }
65: return(0);
66: }
70: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
71: {
72: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
73: PetscErrorCode ierr;
75: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
76: return(0);
77: }
81: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
82: {
83: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
86: fflush(vascii->fd);
87: return(0);
88: }
92: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
93: {
94: PetscMPIInt rank;
95: PetscErrorCode ierr;
96: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
99: MPI_Comm_rank(viewer->comm,&rank);
100: if (!rank) {
101: fflush(vascii->fd);
102: }
104: /*
105: Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
106: */
107: PetscSynchronizedFlush(viewer->comm);
108: return(0);
109: }
113: /*@C
114: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
116: Not Collective
118: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
119: - fd - file pointer
121: Level: intermediate
123: Fortran Note:
124: This routine is not supported in Fortran.
126: Concepts: PetscViewer^file pointer
127: Concepts: file pointer^getting from PetscViewer
129: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
130: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
131: @*/
132: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
133: {
134: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
137: *fd = vascii->fd;
138: return(0);
139: }
141: /*@C
142: PetscViewerFileSetMode - Sets the mode in which to open the file.
144: Not Collective
146: + viewer - viewer context, obtained from PetscViewerCreate()
147: - mode - The file mode
149: Level: intermediate
151: Fortran Note:
152: This routine is not supported in Fortran.
154: .keywords: Viewer, file, get, pointer
156: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
157: @*/
162: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
163: {
164: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
167: vascii->mode = mode;
168: return(0);
169: }
172: /*
173: If petsc_history is on, then all Petsc*Printf() results are saved
174: if the appropriate (usually .petschistory) file.
175: */
180: /*@
181: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
183: Not Collective, but only first processor in set has any effect
185: Input Parameters:
186: + viewer - optained with PetscViewerASCIIOpen()
187: - tabs - number of tabs
189: Level: developer
191: Fortran Note:
192: This routine is not supported in Fortran.
194: Concepts: PetscViewerASCII^formating
195: Concepts: tab^setting
197: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
198: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
199: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
200: @*/
201: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
202: {
203: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
204: PetscTruth iascii;
205: PetscErrorCode ierr;
209: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
210: if (iascii) {
211: ascii->tab = tabs;
212: }
213: return(0);
214: }
218: /*@
219: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
220: lines are tabbed.
222: Not Collective, but only first processor in set has any effect
224: Input Parameters:
225: . viewer - optained with PetscViewerASCIIOpen()
227: Level: developer
229: Fortran Note:
230: This routine is not supported in Fortran.
232: Concepts: PetscViewerASCII^formating
233: Concepts: tab^setting
235: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
236: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
237: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
238: @*/
239: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPushTab(PetscViewer viewer)
240: {
241: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
242: PetscTruth iascii;
243: PetscErrorCode ierr;
247: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
248: if (iascii) {
249: ascii->tab++;
250: }
251: return(0);
252: }
256: /*@
257: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
258: lines are tabbed.
260: Not Collective, but only first processor in set has any effect
262: Input Parameters:
263: . viewer - optained with PetscViewerASCIIOpen()
265: Level: developer
267: Fortran Note:
268: This routine is not supported in Fortran.
270: Concepts: PetscViewerASCII^formating
271: Concepts: tab^setting
273: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
274: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
275: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
276: @*/
277: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPopTab(PetscViewer viewer)
278: {
279: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
280: PetscErrorCode ierr;
281: PetscTruth iascii;
285: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
286: if (iascii) {
287: if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
288: ascii->tab--;
289: }
290: return(0);
291: }
295: /*@
296: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
298: Not Collective, but only first processor in set has any effect
300: Input Parameters:
301: + viewer - optained with PetscViewerASCIIOpen()
302: - flg - PETSC_YES or PETSC_NO
304: Level: developer
306: Fortran Note:
307: This routine is not supported in Fortran.
309: Concepts: PetscViewerASCII^formating
310: Concepts: tab^setting
312: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
313: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
314: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
315: @*/
316: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
317: {
318: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
319: PetscTruth iascii;
320: PetscErrorCode ierr;
324: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
325: if (iascii) {
326: if (flg) {
327: ascii->tab = ascii->tab_store;
328: } else {
329: ascii->tab_store = ascii->tab;
330: ascii->tab = 0;
331: }
332: }
333: return(0);
334: }
336: /* ----------------------------------------------------------------------- */
338: #include src/sys/fileio/mprint.h
342: /*@C
343: PetscViewerASCIIPrintf - Prints to a file, only from the first
344: processor in the PetscViewer
346: Not Collective, but only first processor in set has any effect
348: Input Parameters:
349: + viewer - optained with PetscViewerASCIIOpen()
350: - format - the usual printf() format string
352: Level: developer
354: Fortran Note:
355: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
356: That is, you can only pass a single character string from Fortran.
358: Concepts: PetscViewerASCII^printing
359: Concepts: printing^to file
360: Concepts: printf
362: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
363: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
364: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
365: @*/
366: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
367: {
368: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
369: PetscMPIInt rank;
370: PetscInt tab;
371: PetscErrorCode ierr;
372: FILE *fd = ascii->fd;
373: PetscTruth iascii;
378: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
379: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
381: MPI_Comm_rank(viewer->comm,&rank);
382: if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
383: if (!rank) {
384: va_list Argp;
385: if (ascii->bviewer) {
386: queuefile = fd;
387: }
389: tab = ascii->tab;
390: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
392: va_start(Argp,format);
393: PetscVFPrintf(fd,format,Argp);
394: fflush(fd);
395: if (petsc_history) {
396: tab = ascii->tab;
397: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
398: PetscVFPrintf(petsc_history,format,Argp);
399: fflush(petsc_history);
400: }
401: va_end(Argp);
402: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
403: va_list Argp;
404: char *string;
406: PrintfQueue next;
407: PetscNew(struct _PrintfQueue,&next);
408: if (queue) {queue->next = next; queue = next;}
409: else {queuebase = queue = next;}
410: queuelength++;
411: string = next->string;
412: PetscMemzero(string,QUEUESTRINGSIZE);
413: tab = 2*ascii->tab;
414: while (tab--) {*string++ = ' ';}
415: va_start(Argp,format);
416: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
417: va_end(Argp);
418: }
419: return(0);
420: }
424: /*@C
425: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
427: Collective on PetscViewer
429: Input Parameters:
430: + viewer - the PetscViewer; either ASCII or binary
431: - name - the name of the file it should use
433: Level: advanced
435: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
436: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
438: @*/
439: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileSetName(PetscViewer viewer,const char name[])
440: {
441: PetscErrorCode ierr,(*f)(PetscViewer,const char[]);
446: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
447: if (f) {
448: (*f)(viewer,name);
449: }
450: return(0);
451: }
455: /*@C
456: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
458: Not Collective
460: Input Parameter:
461: . viewer - the PetscViewer; either ASCII or binary
463: Output Parameter:
464: . name - the name of the file it is using
466: Level: advanced
468: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
470: @*/
471: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileGetName(PetscViewer viewer,char **name)
472: {
473: PetscErrorCode ierr,(*f)(PetscViewer,char **);
477: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
478: if (f) {
479: (*f)(viewer,name);
480: }
481: return(0);
482: }
487: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
488: {
489: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
492: *name = vascii->filename;
493: return(0);
494: }
501: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
502: {
503: PetscErrorCode ierr;
504: size_t len;
505: char fname[PETSC_MAX_PATH_LEN],*gz;
506: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
507: PetscTruth isstderr,isstdout;
508: PetscMPIInt rank;
511: if (!name) return(0);
512: PetscStrallocpy(name,&vascii->filename);
514: /* Is this file to be compressed */
515: vascii->storecompressed = PETSC_FALSE;
516: PetscStrstr(vascii->filename,".gz",&gz);
517: if (gz) {
518: PetscStrlen(gz,&len);
519: if (len == 3) {
520: *gz = 0;
521: vascii->storecompressed = PETSC_TRUE;
522: }
523: }
524: MPI_Comm_rank(viewer->comm,&rank);
525: if (!rank) {
526: PetscStrcmp(name,"stderr",&isstderr);
527: PetscStrcmp(name,"stdout",&isstdout);
528: /* empty filename means stdout */
529: if (name[0] == 0) isstdout = PETSC_TRUE;
530: if (isstderr) vascii->fd = stderr;
531: else if (isstdout) vascii->fd = stdout;
532: else {
535: PetscFixFilename(name,fname);
536: switch(vascii->mode) {
537: case FILE_MODE_READ:
538: vascii->fd = fopen(fname,"r");
539: break;
540: case FILE_MODE_WRITE:
541: vascii->fd = fopen(fname,"w");
542: break;
543: case FILE_MODE_APPEND:
544: vascii->fd = fopen(fname,"a");
545: break;
546: case FILE_MODE_UPDATE:
547: vascii->fd = fopen(fname,"r+");
548: if (!vascii->fd) {
549: vascii->fd = fopen(fname,"w+");
550: }
551: break;
552: case FILE_MODE_APPEND_UPDATE:
553: /* I really want a file which is opened at the end for updating,
554: not a+, which opens at the beginning, but makes writes at the end.
555: */
556: vascii->fd = fopen(fname,"r+");
557: if (!vascii->fd) {
558: vascii->fd = fopen(fname,"w+");
559: } else {
560: fseek(vascii->fd, 0, SEEK_END);
561: }
562: break;
563: default:
564: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
565: }
566: if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
567: }
568: }
569: #if defined(PETSC_USE_LOG)
570: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
571: #endif
572: return(0);
573: }
578: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
579: {
580: PetscMPIInt rank;
581: PetscErrorCode ierr;
582: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
583: const char *name;
586: if (vascii->sviewer) {
587: SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
588: }
589: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
590: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
591: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
592: ovascii->fd = vascii->fd;
593: ovascii->tab = vascii->tab;
595: vascii->sviewer = *outviewer;
597: (*outviewer)->format = viewer->format;
598: (*outviewer)->iformat = viewer->iformat;
600: PetscObjectGetName((PetscObject)viewer,&name);
601: PetscObjectSetName((PetscObject)(*outviewer),name);
603: MPI_Comm_rank(viewer->comm,&rank);
604: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
605: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
606: if (rank) {
607: (*outviewer)->ops->flush = 0;
608: } else {
609: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
610: }
611: return(0);
612: }
616: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
617: {
618: PetscErrorCode ierr;
619: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
620: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
623: if (!ascii->sviewer) {
624: SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
625: }
626: if (ascii->sviewer != *outviewer) {
627: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
628: }
630: ascii->sviewer = 0;
631: vascii->fd = stdout;
632: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
633: PetscViewerDestroy(*outviewer);
634: PetscViewerFlush(viewer);
635: return(0);
636: }
641: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_ASCII(PetscViewer viewer)
642: {
643: PetscViewer_ASCII *vascii;
644: PetscErrorCode ierr;
647: PetscNew(PetscViewer_ASCII,&vascii);
648: viewer->data = (void*)vascii;
650: viewer->ops->destroy = PetscViewerDestroy_ASCII;
651: viewer->ops->flush = PetscViewerFlush_ASCII;
652: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
653: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
655: /* defaults to stdout unless set with PetscViewerFileSetName() */
656: vascii->fd = stdout;
657: vascii->mode = FILE_MODE_WRITE;
658: vascii->bviewer = 0;
659: vascii->sviewer = 0;
660: viewer->format = PETSC_VIEWER_ASCII_DEFAULT;
661: viewer->iformat = 0;
662: vascii->tab = 0;
663: vascii->tab_store = 0;
664: vascii->filename = 0;
666: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
667: PetscViewerFileSetName_ASCII);
668: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
669: PetscViewerFileGetName_ASCII);
670: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
671: PetscViewerFileSetMode_ASCII);
673: return(0);
674: }
680: /*@C
681: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
682: several processors. Output of the first processor is followed by that of the
683: second, etc.
685: Not Collective, must call collective PetscViewerFlush() to get the results out
687: Input Parameters:
688: + viewer - the ASCII PetscViewer
689: - format - the usual printf() format string
691: Level: intermediate
693: Fortran Note:
694: Can only print a single character* string
696: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
697: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
698: PetscViewerASCIIPrintf()
700: @*/
701: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
702: {
703: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
704: PetscErrorCode ierr;
705: PetscMPIInt rank;
706: PetscInt tab = vascii->tab;
707: MPI_Comm comm;
708: FILE *fp;
709: PetscTruth iascii;
714: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
715: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
717: comm = viewer->comm;
718: fp = vascii->fd;
719: MPI_Comm_rank(comm,&rank);
720: if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
721:
723: /* First processor prints immediately to fp */
724: if (!rank) {
725: va_list Argp;
727: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
729: va_start(Argp,format);
730: PetscVFPrintf(fp,format,Argp);
731: fflush(fp);
732: queuefile = fp;
733: if (petsc_history) {
734: PetscVFPrintf(petsc_history,format,Argp);
735: fflush(petsc_history);
736: }
737: va_end(Argp);
738: } else { /* other processors add to local queue */
739: char *string;
740: va_list Argp;
741: PrintfQueue next;
743: PetscNew(struct _PrintfQueue,&next);
744: if (queue) {queue->next = next; queue = next;}
745: else {queuebase = queue = next;}
746: queuelength++;
747: string = next->string;
748: PetscMemzero(string,QUEUESTRINGSIZE);
749: tab *= 2;
750: while (tab--) {*string++ = ' ';}
751: va_start(Argp,format);
752: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
753: va_end(Argp);
754: }
755: return(0);
756: }