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: /* ----------------------------------------------------------------------*/
 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 %s\n%s",par,buf);
 41:       }
 42:     }
 43:   }
 44:   PetscStrfree(vascii->filename);
 45:   PetscFree(vascii);
 46:   return(0);
 47: }

 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: }

 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: }

 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: }

 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: }

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;

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: }

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: }

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: }

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

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;

353:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
354:   if (!isascii) SETERRQ(1,"Not ASCII PetscViewer");

356:   MPI_Comm_rank(viewer->comm,&rank);
357:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
358:   if (!rank) {
359:     va_list Argp;
360:     if (ascii->bviewer) {
361:       queuefile = fd;
362:     }

364:     tab = ascii->tab;
365:     while (tab--) fprintf(fd,"  ");

367:     va_start(Argp,format);
368: #if defined(PETSC_HAVE_VPRINTF_CHAR)
369:     vfprintf(fd,format,(char*)Argp);
370: #else
371:     vfprintf(fd,format,Argp);
372: #endif
373:     fflush(fd);
374:     if (petsc_history) {
375:       tab = ascii->tab;
376:       while (tab--) fprintf(fd,"  ");
377: #if defined(PETSC_HAVE_VPRINTF_CHAR)
378:       vfprintf(petsc_history,format,(char *)Argp);
379: #else
380:       vfprintf(petsc_history,format,Argp);
381: #endif
382:       fflush(petsc_history);
383:     }
384:     va_end(Argp);
385:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
386:     int         len;
387:     va_list     Argp;

389:     PrintfQueue next;
390:     PetscNew(struct _PrintfQueue,&next);
391:     if (queue) {queue->next = next; queue = next;}
392:     else       {queuebase   = queue = next;}
393:     queuelength++;
394:     va_start(Argp,format);
395: #if defined(PETSC_HAVE_VPRINTF_CHAR)
396:     vsprintf(next->string,format,(char *)Argp);
397: #else
398:     vsprintf(next->string,format,Argp);
399: #endif
400:     va_end(Argp);
401:     PetscStrlen(next->string,&len);
402:     if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
403:   }
404:   return(0);
405: }

409: /*@C
410:      PetscViewerSetFilename - Sets the name of the file the PetscViewer uses.

412:     Collective on PetscViewer

414:   Input Parameters:
415: +  viewer - the PetscViewer; either ASCII or binary
416: -  name - the name of the file it should use

418:     Level: advanced

420: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
421:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

423: @*/
424: int PetscViewerSetFilename(PetscViewer viewer,const char name[])
425: {
426:   int ierr,(*f)(PetscViewer,const char[]);

431:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFilename_C",(void (**)(void))&f);
432:   if (f) {
433:     (*f)(viewer,name);
434:   }

436:   return(0);
437: }

441: /*@C
442:      PetscViewerGetFilename - Gets the name of the file the PetscViewer uses.

444:     Not Collective

446:   Input Parameter:
447: .  viewer - the PetscViewer; either ASCII or binary

449:   Output Parameter:
450: .  name - the name of the file it is using

452:     Level: advanced

454: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerSetFilename()

456: @*/
457: int PetscViewerGetFilename(PetscViewer viewer,char **name)
458: {
459:   int ierr,(*f)(PetscViewer,char **);

463:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerGetFilename_C",(void (**)(void))&f);
464:   if (f) {
465:     (*f)(viewer,name);
466:   }

468:   return(0);
469: }

471: EXTERN_C_BEGIN
474: int PetscViewerGetFilename_ASCII(PetscViewer viewer,char **name)
475: {
476:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

479:   *name = vascii->filename;
480:   return(0);
481: }
482: EXTERN_C_END

484: EXTERN_C_BEGIN
487: int PetscViewerSetFilename_ASCII(PetscViewer viewer,const char name[])
488: {
489:   int               ierr,len;
490:   char              fname[PETSC_MAX_PATH_LEN],*gz;
491:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
492:   PetscTruth        isstderr,isstdout;

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:   PetscStrcmp(name,"stderr",&isstderr);
510:   PetscStrcmp(name,"stdout",&isstdout);
511:   if (isstderr)      vascii->fd = stderr;
512:   else if (isstdout) vascii->fd = stdout;
513:   else {
514:     PetscFixFilename(name,fname);
515:     switch(vascii->mode) {
516:     case FILE_MODE_READ:
517:       vascii->fd = fopen(fname,"r");
518:       break;
519:     case FILE_MODE_WRITE:
520:       vascii->fd = fopen(fname,"w");
521:       break;
522:     case FILE_MODE_APPEND:
523:       vascii->fd = fopen(fname,"a");
524:       break;
525:     case FILE_MODE_UPDATE:
526:       vascii->fd = fopen(fname,"r+");
527:       if (vascii->fd == PETSC_NULL) {
528:         vascii->fd = fopen(fname,"w+");
529:       }
530:       break;
531:     case FILE_MODE_APPEND_UPDATE:
532:       /* I really want a file which is opened at the end for updating,
533:          not a+, which opens at the beginning, but makes writes at the end.
534:       */
535:       vascii->fd = fopen(fname,"r+");
536:       if (vascii->fd == PETSC_NULL) {
537:         vascii->fd = fopen(fname,"w+");
538:       } else {
539:         fseek(vascii->fd, 0, SEEK_END);
540:       }
541:       break;
542:     default:
543:       SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
544:     }

546:     if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
547:   }
548: #if defined(PETSC_USE_LOG)
549:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
550: #endif

552:   return(0);
553: }
554: EXTERN_C_END

558: int PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
559: {
560:   int               rank,ierr;
561:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
562:   char              *name;

565:   if (vascii->sviewer) {
566:     SETERRQ(1,"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: int PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
596: {
597:   int               ierr;
598:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
599:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

602:   if (!ascii->sviewer) {
603:     SETERRQ(1,"Singleton never obtained from PetscViewer");
604:   }
605:   if (ascii->sviewer != *outviewer) {
606:     SETERRQ(1,"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: }

617: EXTERN_C_BEGIN
620: int PetscViewerCreate_ASCII(PetscViewer viewer)
621: {
622:   PetscViewer_ASCII *vascii;
623:   int               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: }
652: EXTERN_C_END


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: int PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
679: {
680:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
681:   int               ierr,rank,tab = vascii->tab;
682:   MPI_Comm          comm;
683:   FILE              *fp;
684:   PetscTruth        isascii;

689:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
690:   if (!isascii) SETERRQ(1,"Not ASCII PetscViewer");

692:   comm = viewer->comm;
693:   fp   = vascii->fd;
694:   MPI_Comm_rank(comm,&rank);
695:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
696: 

698:   /* First processor prints immediately to fp */
699:   if (!rank) {
700:     va_list Argp;

702:     while (tab--) fprintf(fp,"  ");

704:     va_start(Argp,format);
705: #if defined(PETSC_HAVE_VPRINTF_CHAR)
706:     vfprintf(fp,format,(char*)Argp);
707: #else
708:     vfprintf(fp,format,Argp);
709: #endif
710:     fflush(fp);
711:     queuefile = fp;
712:     if (petsc_history) {
713: #if defined(PETSC_HAVE_VPRINTF_CHAR)
714:       vfprintf(petsc_history,format,(char *)Argp);
715: #else
716:       vfprintf(petsc_history,format,Argp);
717: #endif
718:       fflush(petsc_history);
719:     }
720:     va_end(Argp);
721:   } else { /* other processors add to local queue */
722:     int         len;
723:     char        *string;
724:     va_list     Argp;
725:     PrintfQueue next;

727:     PetscNew(struct _PrintfQueue,&next);
728:     if (queue) {queue->next = next; queue = next;}
729:     else       {queuebase   = queue = next;}
730:     queuelength++;
731:     string = next->string;
732:     while (tab--) {*string++ = ' ';}
733:     va_start(Argp,format);
734: #if defined(PETSC_HAVE_VPRINTF_CHAR)
735:     vsprintf(string,format,(char *)Argp);
736: #else
737:     vsprintf(string,format,Argp);
738: #endif
739:     va_end(Argp);
740:     PetscStrlen(next->string,&len);
741:     if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
742:   }
743:   return(0);
744: }