Actual source code: filev.c
1: #define PETSC_DLL
3: #include src/sys/src/viewer/viewerimpl.h
4: #include "petscfix.h"
5: #include <stdarg.h>
7: typedef struct {
8: FILE *fd;
9: PetscFileMode mode; /* The mode in which to open the file */
10: PetscInt tab; /* how many times text is tabbed in from left */
11: PetscInt tab_store; /* store tabs value while tabs are turned off */
12: PetscViewer bviewer; /* if PetscViewer is a singleton, this points to mother */
13: PetscViewer sviewer; /* if PetscViewer has a singleton, this points to singleton */
14: char *filename;
15: PetscTruth storecompressed;
16: } PetscViewer_ASCII;
18: /* ----------------------------------------------------------------------*/
21: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
22: {
23: PetscMPIInt rank;
24: PetscErrorCode ierr;
25: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
28: if (vascii->sviewer) {
29: SETERRQ(PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
30: }
31: MPI_Comm_rank(viewer->comm,&rank);
32: if (!rank && vascii->fd != stderr && vascii->fd != stdout) {
33: fclose(vascii->fd);
34: if (vascii->storecompressed) {
35: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
36: FILE *fp;
37: PetscStrcpy(par,"gzip ");
38: PetscStrcat(par,vascii->filename);
39: #if defined(PETSC_HAVE_POPEN)
40: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
41: if (fgets(buf,1024,fp)) {
42: SETERRQ2(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
43: }
44: PetscPClose(PETSC_COMM_SELF,fp);
45: #else
46: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
47: #endif
48: }
49: }
50: PetscStrfree(vascii->filename);
51: PetscFree(vascii);
52: return(0);
53: }
57: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
58: {
59: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
60: PetscErrorCode ierr;
62: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
63: return(0);
64: }
68: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
69: {
70: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
73: fflush(vascii->fd);
74: return(0);
75: }
79: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
80: {
81: PetscMPIInt rank;
82: PetscErrorCode ierr;
83: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
86: MPI_Comm_rank(viewer->comm,&rank);
87: if (!rank) {
88: fflush(vascii->fd);
89: }
91: /*
92: Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
93: */
94: PetscSynchronizedFlush(viewer->comm);
95: return(0);
96: }
100: /*@C
101: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
103: Not Collective
105: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
106: - fd - file pointer
108: Level: intermediate
110: Fortran Note:
111: This routine is not supported in Fortran.
113: Concepts: PetscViewer^file pointer
114: Concepts: file pointer^getting from PetscViewer
116: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
117: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
118: @*/
119: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
120: {
121: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
124: *fd = vascii->fd;
125: return(0);
126: }
130: /*@C
131: PetscViewerASCIISetMode - Sets the mode in which to open the file.
133: Not Collective
135: + viewer - viewer context, obtained from PetscViewerASCIIOpen()
136: - mode - The file mode
138: Level: intermediate
140: Fortran Note:
141: This routine is not supported in Fortran.
143: .keywords: Viewer, file, get, pointer
145: .seealso: PetscViewerASCIIOpen()
146: @*/
147: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISetMode(PetscViewer viewer, PetscFileMode mode)
148: {
149: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
152: vascii->mode = mode;
153: return(0);
154: }
156: /*
157: If petsc_history is on, then all Petsc*Printf() results are saved
158: if the appropriate (usually .petschistory) file.
159: */
164: /*@C
165: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
167: Not Collective, but only first processor in set has any effect
169: Input Parameters:
170: + viewer - optained with PetscViewerASCIIOpen()
171: - tabs - number of tabs
173: Level: developer
175: Fortran Note:
176: This routine is not supported in Fortran.
178: Concepts: PetscViewerASCII^formating
179: Concepts: tab^setting
181: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
182: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
183: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
184: @*/
185: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
186: {
187: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
188: PetscTruth iascii;
189: PetscErrorCode ierr;
193: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
194: if (iascii) {
195: ascii->tab = tabs;
196: }
197: return(0);
198: }
202: /*@C
203: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
204: lines are tabbed.
206: Not Collective, but only first processor in set has any effect
208: Input Parameters:
209: . viewer - optained with PetscViewerASCIIOpen()
211: Level: developer
213: Fortran Note:
214: This routine is not supported in Fortran.
216: Concepts: PetscViewerASCII^formating
217: Concepts: tab^setting
219: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
220: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
221: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
222: @*/
223: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPushTab(PetscViewer viewer)
224: {
225: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
226: PetscTruth iascii;
227: PetscErrorCode ierr;
231: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
232: if (iascii) {
233: ascii->tab++;
234: }
235: return(0);
236: }
240: /*@C
241: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
242: lines are tabbed.
244: Not Collective, but only first processor in set has any effect
246: Input Parameters:
247: . viewer - optained with PetscViewerASCIIOpen()
249: Level: developer
251: Fortran Note:
252: This routine is not supported in Fortran.
254: Concepts: PetscViewerASCII^formating
255: Concepts: tab^setting
257: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
258: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
259: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
260: @*/
261: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPopTab(PetscViewer viewer)
262: {
263: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
264: PetscErrorCode ierr;
265: PetscTruth iascii;
269: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
270: if (iascii) {
271: if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
272: ascii->tab--;
273: }
274: return(0);
275: }
279: /*@C
280: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
282: Not Collective, but only first processor in set has any effect
284: Input Parameters:
285: + viewer - optained with PetscViewerASCIIOpen()
286: - flg - PETSC_YES or PETSC_NO
288: Level: developer
290: Fortran Note:
291: This routine is not supported in Fortran.
293: Concepts: PetscViewerASCII^formating
294: Concepts: tab^setting
296: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
297: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
298: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
299: @*/
300: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
301: {
302: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
303: PetscTruth iascii;
304: PetscErrorCode ierr;
308: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
309: if (iascii) {
310: if (flg) {
311: ascii->tab = ascii->tab_store;
312: } else {
313: ascii->tab_store = ascii->tab;
314: ascii->tab = 0;
315: }
316: }
317: return(0);
318: }
320: /* ----------------------------------------------------------------------- */
322: #include src/sys/src/fileio/mprint.h
326: /*@C
327: PetscViewerASCIIPrintf - Prints to a file, only from the first
328: processor in the PetscViewer
330: Not Collective, but only first processor in set has any effect
332: Input Parameters:
333: + viewer - optained with PetscViewerASCIIOpen()
334: - format - the usual printf() format string
336: Level: developer
338: Fortran Note:
339: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
340: That is, you can only pass a single character string from Fortran.
342: Concepts: PetscViewerASCII^printing
343: Concepts: printing^to file
344: Concepts: printf
346: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
347: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
348: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
349: @*/
350: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
351: {
352: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
353: PetscMPIInt rank;
354: PetscInt tab;
355: PetscErrorCode ierr;
356: FILE *fd = ascii->fd;
357: PetscTruth iascii;
362: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
363: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
365: MPI_Comm_rank(viewer->comm,&rank);
366: if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
367: if (!rank) {
368: va_list Argp;
369: if (ascii->bviewer) {
370: queuefile = fd;
371: }
373: tab = ascii->tab;
374: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
376: va_start(Argp,format);
377: PetscVFPrintf(fd,format,Argp);
378: fflush(fd);
379: if (petsc_history) {
380: tab = ascii->tab;
381: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
382: PetscVFPrintf(petsc_history,format,Argp);
383: fflush(petsc_history);
384: }
385: va_end(Argp);
386: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
387: va_list Argp;
388: char *string;
390: PrintfQueue next;
391: PetscNew(struct _PrintfQueue,&next);
392: if (queue) {queue->next = next; queue = next;}
393: else {queuebase = queue = next;}
394: queuelength++;
395: string = next->string;
396: PetscMemzero(string,QUEUESTRINGSIZE);
397: tab = 2*ascii->tab;
398: while (tab--) {*string++ = ' ';}
399: va_start(Argp,format);
400: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
401: va_end(Argp);
402: }
403: return(0);
404: }
408: /*@C
409: PetscViewerSetFilename - Sets the name of the file the PetscViewer uses.
411: Collective on PetscViewer
413: Input Parameters:
414: + viewer - the PetscViewer; either ASCII or binary
415: - name - the name of the file it should use
417: Level: advanced
419: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
420: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
422: @*/
423: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFilename(PetscViewer viewer,const char name[])
424: {
425: PetscErrorCode ierr,(*f)(PetscViewer,const char[]);
430: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFilename_C",(void (**)(void))&f);
431: if (f) {
432: (*f)(viewer,name);
433: }
435: return(0);
436: }
440: /*@C
441: PetscViewerGetFilename - Gets the name of the file the PetscViewer uses.
443: Not Collective
445: Input Parameter:
446: . viewer - the PetscViewer; either ASCII or binary
448: Output Parameter:
449: . name - the name of the file it is using
451: Level: advanced
453: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerSetFilename()
455: @*/
456: PetscErrorCode PETSC_DLLEXPORT PetscViewerGetFilename(PetscViewer viewer,char **name)
457: {
458: PetscErrorCode ierr,(*f)(PetscViewer,char **);
462: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerGetFilename_C",(void (**)(void))&f);
463: if (f) {
464: (*f)(viewer,name);
465: }
466: return(0);
467: }
472: PetscErrorCode PETSC_DLLEXPORT PetscViewerGetFilename_ASCII(PetscViewer viewer,char **name)
473: {
474: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
477: *name = vascii->filename;
478: return(0);
479: }
485: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFilename_ASCII(PetscViewer viewer,const char name[])
486: {
487: PetscErrorCode ierr;
488: size_t len;
489: char fname[PETSC_MAX_PATH_LEN],*gz;
490: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
491: PetscTruth isstderr,isstdout;
492: PetscMPIInt rank;
495: if (!name) return(0);
497: PetscStrallocpy(name,&vascii->filename);
499: /* Is this file to be compressed */
500: vascii->storecompressed = PETSC_FALSE;
501: PetscStrstr(vascii->filename,".gz",&gz);
502: if (gz) {
503: PetscStrlen(gz,&len);
504: if (len == 3) {
505: *gz = 0;
506: vascii->storecompressed = PETSC_TRUE;
507: }
508: }
509: MPI_Comm_rank(viewer->comm,&rank);
510: if (!rank) {
511: PetscStrcmp(name,"stderr",&isstderr);
512: PetscStrcmp(name,"stdout",&isstdout);
513: if (isstderr) vascii->fd = stderr;
514: else if (isstdout) vascii->fd = stdout;
515: else {
516: PetscFixFilename(name,fname);
517: switch(vascii->mode) {
518: case FILE_MODE_READ:
519: vascii->fd = fopen(fname,"r");
520: break;
521: case FILE_MODE_WRITE:
522: vascii->fd = fopen(fname,"w");
523: break;
524: case FILE_MODE_APPEND:
525: vascii->fd = fopen(fname,"a");
526: break;
527: case FILE_MODE_UPDATE:
528: vascii->fd = fopen(fname,"r+");
529: if (!vascii->fd) {
530: vascii->fd = fopen(fname,"w+");
531: }
532: break;
533: case FILE_MODE_APPEND_UPDATE:
534: /* I really want a file which is opened at the end for updating,
535: not a+, which opens at the beginning, but makes writes at the end.
536: */
537: vascii->fd = fopen(fname,"r+");
538: if (!vascii->fd) {
539: vascii->fd = fopen(fname,"w+");
540: } else {
541: fseek(vascii->fd, 0, SEEK_END);
542: }
543: break;
544: default:
545: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
546: }
547: if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
548: }
549: }
550: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
551: return(0);
552: }
557: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
558: {
559: PetscMPIInt rank;
560: PetscErrorCode ierr;
561: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
562: const char *name;
565: if (vascii->sviewer) {
566: SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
567: }
568: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
569: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
570: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
571: ovascii->fd = vascii->fd;
572: ovascii->tab = vascii->tab;
574: vascii->sviewer = *outviewer;
576: (*outviewer)->format = viewer->format;
577: (*outviewer)->iformat = viewer->iformat;
579: PetscObjectGetName((PetscObject)viewer,&name);
580: PetscObjectSetName((PetscObject)(*outviewer),name);
582: MPI_Comm_rank(viewer->comm,&rank);
583: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
584: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
585: if (rank) {
586: (*outviewer)->ops->flush = 0;
587: } else {
588: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
589: }
590: return(0);
591: }
595: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
596: {
597: PetscErrorCode ierr;
598: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
599: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
602: if (!ascii->sviewer) {
603: SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
604: }
605: if (ascii->sviewer != *outviewer) {
606: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
607: }
609: ascii->sviewer = 0;
610: vascii->fd = stdout;
611: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
612: PetscViewerDestroy(*outviewer);
613: PetscViewerFlush(viewer);
614: return(0);
615: }
620: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_ASCII(PetscViewer viewer)
621: {
622: PetscViewer_ASCII *vascii;
623: PetscErrorCode ierr;
626: PetscNew(PetscViewer_ASCII,&vascii);
627: viewer->data = (void*)vascii;
629: viewer->ops->destroy = PetscViewerDestroy_ASCII;
630: viewer->ops->flush = PetscViewerFlush_ASCII;
631: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
632: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
634: /* defaults to stdout unless set with PetscViewerSetFilename() */
635: vascii->fd = stdout;
636: vascii->mode = FILE_MODE_WRITE;
637: vascii->bviewer = 0;
638: vascii->sviewer = 0;
639: viewer->format = PETSC_VIEWER_ASCII_DEFAULT;
640: viewer->iformat = 0;
641: vascii->tab = 0;
642: vascii->tab_store = 0;
643: vascii->filename = 0;
645: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_ASCII",
646: PetscViewerSetFilename_ASCII);
647: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerGetFilename_C","PetscViewerGetFilename_ASCII",
648: PetscViewerGetFilename_ASCII);
650: return(0);
651: }
657: /*@C
658: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
659: several processors. Output of the first processor is followed by that of the
660: second, etc.
662: Not Collective, must call collective PetscViewerFlush() to get the results out
664: Input Parameters:
665: + viewer - the ASCII PetscViewer
666: - format - the usual printf() format string
668: Level: intermediate
670: Fortran Note:
671: Can only print a single character* string
673: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
674: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
675: PetscViewerASCIIPrintf()
677: @*/
678: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
679: {
680: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
681: PetscErrorCode ierr;
682: PetscMPIInt rank;
683: PetscInt tab = vascii->tab;
684: MPI_Comm comm;
685: FILE *fp;
686: PetscTruth iascii;
691: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
692: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
694: comm = viewer->comm;
695: fp = vascii->fd;
696: MPI_Comm_rank(comm,&rank);
697: if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
698:
700: /* First processor prints immediately to fp */
701: if (!rank) {
702: va_list Argp;
704: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
706: va_start(Argp,format);
707: PetscVFPrintf(fp,format,Argp);
708: fflush(fp);
709: queuefile = fp;
710: if (petsc_history) {
711: PetscVFPrintf(petsc_history,format,Argp);
712: fflush(petsc_history);
713: }
714: va_end(Argp);
715: } else { /* other processors add to local queue */
716: char *string;
717: va_list Argp;
718: PrintfQueue next;
720: PetscNew(struct _PrintfQueue,&next);
721: if (queue) {queue->next = next; queue = next;}
722: else {queuebase = queue = next;}
723: queuelength++;
724: string = next->string;
725: PetscMemzero(string,QUEUESTRINGSIZE);
726: tab *= 2;
727: while (tab--) {*string++ = ' ';}
728: va_start(Argp,format);
729: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
730: va_end(Argp);
731: }
732: return(0);
733: }