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