Actual source code: filev.c
1: /* $Id: filev.c,v 1.118 2001/04/10 19:34:05 bsmith Exp $ */
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: int tab; /* how many times text is tabbed in from left */
11: int 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: /* ----------------------------------------------------------------------*/
19: #undef __FUNCT__
21: int PetscViewerDestroy_ASCII(PetscViewer viewer)
22: {
23: int rank,ierr;
24: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
27: if (vascii->sviewer) {
28: SETERRQ(1,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
29: }
30: MPI_Comm_rank(viewer->comm,&rank);
31: if (!rank && vascii->fd != stderr && vascii->fd != stdout) {
32: fclose(vascii->fd);
33: if (vascii->storecompressed) {
34: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
35: FILE *fp;
36: PetscStrcpy(par,"gzip ");
37: PetscStrcat(par,vascii->filename);
38: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
39: if (fgets(buf,1024,fp)) {
40: SETERRQ2(1,"Error from compression command %sn%s",par,buf);
41: }
42: }
43: }
44: PetscStrfree(vascii->filename);
45: PetscFree(vascii);
46: return(0);
47: }
49: #undef __FUNCT__
51: int PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
52: {
53: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
54: int ierr;
56: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
57: return(0);
58: }
60: #undef __FUNCT__
62: int PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
63: {
64: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
67: fflush(vascii->fd);
68: return(0);
69: }
71: #undef __FUNCT__
73: int PetscViewerFlush_ASCII(PetscViewer viewer)
74: {
75: int rank,ierr;
76: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
79: MPI_Comm_rank(viewer->comm,&rank);
80: if (!rank) {
81: fflush(vascii->fd);
82: }
84: /*
85: Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
86: */
87: PetscSynchronizedFlush(viewer->comm);
88: return(0);
89: }
91: #undef __FUNCT__
93: /*@C
94: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
96: Not Collective
98: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
99: - fd - file pointer
101: Level: intermediate
103: Fortran Note:
104: This routine is not supported in Fortran.
106: Concepts: PetscViewer^file pointer
107: Concepts: file pointer^getting from PetscViewer
109: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
110: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
111: @*/
112: int PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
113: {
114: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
117: *fd = vascii->fd;
118: return(0);
119: }
121: #undef __FUNCT__
123: /*@C
124: PetscViewerASCIISetMode - Sets the mode in which to open the file.
126: Not Collective
128: + viewer - viewer context, obtained from PetscViewerASCIIOpen()
129: - mode - The file mode
131: Level: intermediate
133: Fortran Note:
134: This routine is not supported in Fortran.
136: .keywords: Viewer, file, get, pointer
138: .seealso: PetscViewerASCIIOpen()
139: @*/
140: int PetscViewerASCIISetMode(PetscViewer viewer, PetscFileMode mode)
141: {
142: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
145: vascii->mode = mode;
146: return(0);
147: }
149: /*
150: If petsc_history is on, then all Petsc*Printf() results are saved
151: if the appropriate (usually .petschistory) file.
152: */
153: extern FILE *petsc_history;
155: #undef __FUNCT__
157: /*@C
158: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
160: Not Collective, but only first processor in set has any effect
162: Input Parameters:
163: + viewer - optained with PetscViewerASCIIOpen()
164: - tabs - number of tabs
166: Level: developer
168: Fortran Note:
169: This routine is not supported in Fortran.
171: Concepts: PetscViewerASCII^formating
172: Concepts: tab^setting
174: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
175: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
176: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
177: @*/
178: int PetscViewerASCIISetTab(PetscViewer viewer,int tabs)
179: {
180: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
181: PetscTruth isascii;
182: int ierr;
186: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
187: if (isascii) {
188: ascii->tab = tabs;
189: }
190: return(0);
191: }
193: #undef __FUNCT__
195: /*@C
196: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
197: lines are tabbed.
199: Not Collective, but only first processor in set has any effect
201: Input Parameters:
202: . viewer - optained with PetscViewerASCIIOpen()
204: Level: developer
206: Fortran Note:
207: This routine is not supported in Fortran.
209: Concepts: PetscViewerASCII^formating
210: Concepts: tab^setting
212: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
213: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
214: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
215: @*/
216: int PetscViewerASCIIPushTab(PetscViewer viewer)
217: {
218: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
219: PetscTruth isascii;
220: int ierr;
224: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
225: if (isascii) {
226: ascii->tab++;
227: }
228: return(0);
229: }
231: #undef __FUNCT__
233: /*@C
234: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
235: lines are tabbed.
237: Not Collective, but only first processor in set has any effect
239: Input Parameters:
240: . viewer - optained with PetscViewerASCIIOpen()
242: Level: developer
244: Fortran Note:
245: This routine is not supported in Fortran.
247: Concepts: PetscViewerASCII^formating
248: Concepts: tab^setting
250: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
251: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
252: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
253: @*/
254: int PetscViewerASCIIPopTab(PetscViewer viewer)
255: {
256: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
257: int ierr;
258: PetscTruth isascii;
262: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
263: if (isascii) {
264: if (ascii->tab <= 0) SETERRQ(1,"More tabs popped than pushed");
265: ascii->tab--;
266: }
267: return(0);
268: }
270: #undef __FUNCT__
272: /*@C
273: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
275: Not Collective, but only first processor in set has any effect
277: Input Parameters:
278: + viewer - optained with PetscViewerASCIIOpen()
279: - flg - PETSC_YES or PETSC_NO
281: Level: developer
283: Fortran Note:
284: This routine is not supported in Fortran.
286: Concepts: PetscViewerASCII^formating
287: Concepts: tab^setting
289: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
290: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
291: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
292: @*/
293: int PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
294: {
295: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
296: PetscTruth isascii;
297: int ierr;
301: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
302: if (isascii) {
303: if (flg) {
304: ascii->tab = ascii->tab_store;
305: } else {
306: ascii->tab_store = ascii->tab;
307: ascii->tab = 0;
308: }
309: }
310: return(0);
311: }
313: /* ----------------------------------------------------------------------- */
315: #include src/sys/src/fileio/mprint.h
317: #undef __FUNCT__
319: /*@C
320: PetscViewerASCIIPrintf - Prints to a file, only from the first
321: processor in the PetscViewer
323: Not Collective, but only first processor in set has any effect
325: Input Parameters:
326: + viewer - optained with PetscViewerASCIIOpen()
327: - format - the usual printf() format string
329: Level: developer
331: Fortran Note:
332: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
333: That is, you can only pass a single character string from Fortran.
335: Concepts: PetscViewerASCII^printing
336: Concepts: printing^to file
337: Concepts: printf
339: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
340: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
341: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
342: @*/
343: int PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
344: {
345: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
346: int rank,tab,ierr;
347: FILE *fd = ascii->fd;
348: PetscTruth isascii;
352: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
353: if (!isascii) SETERRQ(1,"Not ASCII PetscViewer");
355: MPI_Comm_rank(viewer->comm,&rank);
356: if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
357: if (!rank) {
358: va_list Argp;
359: if (ascii->bviewer) {
360: queuefile = fd;
361: }
363: tab = ascii->tab;
364: while (tab--) fprintf(fd," ");
366: va_start(Argp,format);
367: #if defined(PETSC_HAVE_VPRINTF_CHAR)
368: vfprintf(fd,format,(char*)Argp);
369: #else
370: vfprintf(fd,format,Argp);
371: #endif
372: fflush(fd);
373: if (petsc_history) {
374: tab = ascii->tab;
375: while (tab--) fprintf(fd," ");
376: #if defined(PETSC_HAVE_VPRINTF_CHAR)
377: vfprintf(petsc_history,format,(char *)Argp);
378: #else
379: vfprintf(petsc_history,format,Argp);
380: #endif
381: fflush(petsc_history);
382: }
383: va_end(Argp);
384: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
385: int len;
386: va_list Argp;
388: PrintfQueue next;
389: PetscNew(struct _PrintfQueue,&next);
390: if (queue) {queue->next = next; queue = next;}
391: else {queuebase = queue = next;}
392: queuelength++;
393: va_start(Argp,format);
394: #if defined(PETSC_HAVE_VPRINTF_CHAR)
395: vsprintf(next->string,format,(char *)Argp);
396: #else
397: vsprintf(next->string,format,Argp);
398: #endif
399: va_end(Argp);
400: PetscStrlen(next->string,&len);
401: if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
402: }
403: return(0);
404: }
406: #undef __FUNCT__
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: int PetscViewerSetFilename(PetscViewer viewer,const char name[])
424: {
425: int ierr,(*f)(PetscViewer,const char[]);
429: if (!name) SETERRQ(1,"You must pass in non-null string");
430: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFilename_C",(void (**)(void))&f);
431: if (f) {
432: (*f)(viewer,name);
433: }
435: return(0);
436: }
438: #undef __FUNCT__
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: int PetscViewerGetFilename(PetscViewer viewer,char **name)
457: {
458: int ierr,(*f)(PetscViewer,char **);
462: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerGetFilename_C",(void (**)(void))&f);
463: if (f) {
464: (*f)(viewer,name);
465: }
467: return(0);
468: }
470: EXTERN_C_BEGIN
471: #undef __FUNCT__
473: int PetscViewerGetFilename_ASCII(PetscViewer viewer,char **name)
474: {
475: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
478: *name = vascii->filename;
479: return(0);
480: }
481: EXTERN_C_END
483: EXTERN_C_BEGIN
484: #undef __FUNCT__
486: int PetscViewerSetFilename_ASCII(PetscViewer viewer,const char name[])
487: {
488: int ierr,len;
489: char fname[PETSC_MAX_PATH_LEN],*gz;
490: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
491: PetscTruth isstderr,isstdout;
494: if (!name) return(0);
496: PetscStrallocpy(name,&vascii->filename);
498: /* Is this file to be compressed */
499: vascii->storecompressed = PETSC_FALSE;
500: PetscStrstr(vascii->filename,".gz",&gz);
501: if (gz) {
502: PetscStrlen(gz,&len);
503: if (len == 3) {
504: *gz = 0;
505: vascii->storecompressed = PETSC_TRUE;
506: }
507: }
508: PetscStrcmp(name,"stderr",&isstderr);
509: PetscStrcmp(name,"stdout",&isstdout);
510: if (isstderr) vascii->fd = stderr;
511: else if (isstdout) vascii->fd = stdout;
512: else {
513: PetscFixFilename(name,fname);
514: switch(vascii->mode) {
515: case FILE_MODE_READ:
516: vascii->fd = fopen(fname,"r");
517: break;
518: case FILE_MODE_WRITE:
519: vascii->fd = fopen(fname,"w");
520: break;
521: case FILE_MODE_APPEND:
522: vascii->fd = fopen(fname,"a");
523: break;
524: case FILE_MODE_UPDATE:
525: vascii->fd = fopen(fname,"r+");
526: if (vascii->fd == PETSC_NULL) {
527: vascii->fd = fopen(fname,"w+");
528: }
529: break;
530: case FILE_MODE_APPEND_UPDATE:
531: /* I really want a file which is opened at the end for updating,
532: not a+, which opens at the beginning, but makes writes at the end.
533: */
534: vascii->fd = fopen(fname,"r+");
535: if (vascii->fd == PETSC_NULL) {
536: vascii->fd = fopen(fname,"w+");
537: } else {
538: ierr = fseek(vascii->fd, 0, SEEK_END);
539: }
540: break;
541: default:
542: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
543: }
545: if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
546: }
547: #if defined(PETSC_USE_LOG)
548: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
549: #endif
551: return(0);
552: }
553: EXTERN_C_END
555: #undef __FUNCT__
557: int PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
558: {
559: int rank,ierr;
560: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
561: char *name;
564: if (vascii->sviewer) {
565: SETERRQ(1,"Singleton already obtained from PetscViewer and not restored");
566: }
567: ierr = PetscViewerCreate(PETSC_COMM_SELF,outviewer);
568: ierr = PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
569: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
570: ovascii->fd = vascii->fd;
571: ovascii->tab = vascii->tab;
573: vascii->sviewer = *outviewer;
575: (*outviewer)->format = viewer->format;
576: (*outviewer)->iformat = viewer->iformat;
578: PetscObjectGetName((PetscObject)viewer,&name);
579: PetscObjectSetName((PetscObject)(*outviewer),name);
581: MPI_Comm_rank(viewer->comm,&rank);
582: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
583: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
584: if (rank) {
585: (*outviewer)->ops->flush = 0;
586: } else {
587: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
588: }
589: return(0);
590: }
592: #undef __FUNCT__
594: int PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
595: {
596: int ierr;
597: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
598: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
601: if (!ascii->sviewer) {
602: SETERRQ(1,"Singleton never obtained from PetscViewer");
603: }
604: if (ascii->sviewer != *outviewer) {
605: SETERRQ(1,"This PetscViewer did not generate singleton");
606: }
608: ascii->sviewer = 0;
609: vascii->fd = stdout;
610: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
611: ierr = PetscViewerDestroy(*outviewer);
612: PetscViewerFlush(viewer);
613: return(0);
614: }
616: EXTERN_C_BEGIN
617: #undef __FUNCT__
619: int PetscViewerCreate_ASCII(PetscViewer viewer)
620: {
621: PetscViewer_ASCII *vascii;
622: int ierr;
625: ierr = PetscNew(PetscViewer_ASCII,&vascii);
626: viewer->data = (void*)vascii;
628: viewer->ops->destroy = PetscViewerDestroy_ASCII;
629: viewer->ops->flush = PetscViewerFlush_ASCII;
630: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
631: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
633: /* defaults to stdout unless set with PetscViewerSetFilename() */
634: vascii->fd = stdout;
635: vascii->mode = FILE_MODE_WRITE;
636: vascii->bviewer = 0;
637: vascii->sviewer = 0;
638: viewer->format = PETSC_VIEWER_ASCII_DEFAULT;
639: viewer->iformat = 0;
640: vascii->tab = 0;
641: vascii->tab_store = 0;
642: vascii->filename = 0;
644: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_ASCII",
645: PetscViewerSetFilename_ASCII);
646: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerGetFilename_C","PetscViewerGetFilename_ASCII",
647: PetscViewerGetFilename_ASCII);
649: return(0);
650: }
651: EXTERN_C_END
654: #undef __FUNCT__
656: /*@C
657: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
658: several processors. Output of the first processor is followed by that of the
659: second, etc.
661: Not Collective, must call collective PetscViewerFlush() to get the results out
663: Input Parameters:
664: + viewer - the ASCII PetscViewer
665: - format - the usual printf() format string
667: Level: intermediate
669: Fortran Note:
670: Can only print a single character* string
672: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
673: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
674: PetscViewerASCIIPrintf()
676: @*/
677: int PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
678: {
679: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
680: int ierr,rank,tab = vascii->tab;
681: MPI_Comm comm;
682: FILE *fp;
683: PetscTruth isascii;
687: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
688: if (!isascii) SETERRQ(1,"Not ASCII PetscViewer");
690: comm = viewer->comm;
691: fp = vascii->fd;
692: MPI_Comm_rank(comm,&rank);
693: if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
694:
696: /* First processor prints immediately to fp */
697: if (!rank) {
698: va_list Argp;
700: while (tab--) fprintf(fp," ");
702: va_start(Argp,format);
703: #if defined(PETSC_HAVE_VPRINTF_CHAR)
704: vfprintf(fp,format,(char*)Argp);
705: #else
706: vfprintf(fp,format,Argp);
707: #endif
708: fflush(fp);
709: queuefile = fp;
710: if (petsc_history) {
711: #if defined(PETSC_HAVE_VPRINTF_CHAR)
712: vfprintf(petsc_history,format,(char *)Argp);
713: #else
714: vfprintf(petsc_history,format,Argp);
715: #endif
716: fflush(petsc_history);
717: }
718: va_end(Argp);
719: } else { /* other processors add to local queue */
720: int len;
721: char *string;
722: va_list Argp;
723: PrintfQueue next;
725: PetscNew(struct _PrintfQueue,&next);
726: if (queue) {queue->next = next; queue = next;}
727: else {queuebase = queue = next;}
728: queuelength++;
729: string = next->string;
730: while (tab--) {*string++ = ' ';}
731: va_start(Argp,format);
732: #if defined(PETSC_HAVE_VPRINTF_CHAR)
733: vsprintf(string,format,(char *)Argp);
734: #else
735: vsprintf(string,format,Argp);
736: #endif
737: va_end(Argp);
738: PetscStrlen(next->string,&len);
739: if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
740: }
741: return(0);
742: }