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