Actual source code: filev.c

 2:  #include src/sys/src/viewer/viewerimpl.h
  3: #include "petscfix.h"
  4: #include <stdarg.h>

  6: typedef struct {
  7:   FILE          *fd;
  8:   PetscFileMode mode;           /* The mode in which to open the file */
  9:   PetscInt      tab;            /* how many times text is tabbed in from left */
 10:   PetscInt      tab_store;      /* store tabs value while tabs are turned off */
 11:   PetscViewer   bviewer;        /* if PetscViewer is a singleton, this points to mother */
 12:   PetscViewer   sviewer;        /* if PetscViewer has a singleton, this points to singleton */
 13:   char          *filename;
 14:   PetscTruth    storecompressed;
 15: } PetscViewer_ASCII;

 17: /* ----------------------------------------------------------------------*/
 20: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
 21: {
 22:   PetscMPIInt       rank;
 23:   PetscErrorCode    ierr;
 24:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 27:   if (vascii->sviewer) {
 28:     SETERRQ(PETSC_ERR_ORDER,"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(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
 41:       }
 42:     }
 43:   }
 44:   PetscStrfree(vascii->filename);
 45:   PetscFree(vascii);
 46:   return(0);
 47: }

 51: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
 52: {
 53:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 54:   PetscErrorCode    ierr;
 56:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
 57:   return(0);
 58: }

 62: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
 63: {
 64:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 67:   fflush(vascii->fd);
 68:   return(0);
 69: }

 73: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
 74: {
 75:   PetscMPIInt       rank;
 76:   PetscErrorCode    ierr;
 77:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 80:   MPI_Comm_rank(viewer->comm,&rank);
 81:   if (!rank) {
 82:     fflush(vascii->fd);
 83:   }

 85:   /*
 86:      Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
 87:   */
 88:   PetscSynchronizedFlush(viewer->comm);
 89:   return(0);
 90: }

 94: /*@C
 95:     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.

 97:     Not Collective

 99: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
100: -   fd - file pointer

102:     Level: intermediate

104:     Fortran Note:
105:     This routine is not supported in Fortran.

107:   Concepts: PetscViewer^file pointer
108:   Concepts: file pointer^getting from PetscViewer

110: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
111:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
112: @*/
113: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
114: {
115:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

118:   *fd = vascii->fd;
119:   return(0);
120: }

124: /*@C
125:     PetscViewerASCIISetMode - Sets the mode in which to open the file.

127:     Not Collective

129: +   viewer - viewer context, obtained from PetscViewerASCIIOpen()
130: -   mode   - The file mode

132:     Level: intermediate

134:     Fortran Note:
135:     This routine is not supported in Fortran.

137: .keywords: Viewer, file, get, pointer

139: .seealso: PetscViewerASCIIOpen()
140: @*/
141: PetscErrorCode PetscViewerASCIISetMode(PetscViewer viewer, PetscFileMode mode)
142: {
143:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

146:   vascii->mode = mode;
147:   return(0);
148: }

150: /*
151:    If petsc_history is on, then all Petsc*Printf() results are saved
152:    if the appropriate (usually .petschistory) file.
153: */

158: /*@C
159:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

161:     Not Collective, but only first processor in set has any effect

163:     Input Parameters:
164: +    viewer - optained with PetscViewerASCIIOpen()
165: -    tabs - number of tabs

167:     Level: developer

169:     Fortran Note:
170:     This routine is not supported in Fortran.

172:   Concepts: PetscViewerASCII^formating
173:   Concepts: tab^setting

175: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
176:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
177:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
178: @*/
179: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
180: {
181:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
182:   PetscTruth        iascii;
183:   PetscErrorCode    ierr;

187:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
188:   if (iascii) {
189:     ascii->tab = tabs;
190:   }
191:   return(0);
192: }

196: /*@C
197:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
198:      lines are tabbed.

200:     Not Collective, but only first processor in set has any effect

202:     Input Parameters:
203: .    viewer - optained with PetscViewerASCIIOpen()

205:     Level: developer

207:     Fortran Note:
208:     This routine is not supported in Fortran.

210:   Concepts: PetscViewerASCII^formating
211:   Concepts: tab^setting

213: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
214:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
215:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
216: @*/
217: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
218: {
219:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
220:   PetscTruth        iascii;
221:   PetscErrorCode    ierr;

225:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
226:   if (iascii) {
227:     ascii->tab++;
228:   }
229:   return(0);
230: }

234: /*@C
235:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
236:      lines are tabbed.

238:     Not Collective, but only first processor in set has any effect

240:     Input Parameters:
241: .    viewer - optained with PetscViewerASCIIOpen()

243:     Level: developer

245:     Fortran Note:
246:     This routine is not supported in Fortran.

248:   Concepts: PetscViewerASCII^formating
249:   Concepts: tab^setting

251: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
252:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
253:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
254: @*/
255: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
256: {
257:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
258:   PetscErrorCode    ierr;
259:   PetscTruth        iascii;

263:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
264:   if (iascii) {
265:     if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
266:     ascii->tab--;
267:   }
268:   return(0);
269: }

273: /*@C
274:     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer

276:     Not Collective, but only first processor in set has any effect

278:     Input Parameters:
279: +    viewer - optained with PetscViewerASCIIOpen()
280: -    flg - PETSC_YES or PETSC_NO

282:     Level: developer

284:     Fortran Note:
285:     This routine is not supported in Fortran.

287:   Concepts: PetscViewerASCII^formating
288:   Concepts: tab^setting

290: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
291:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
292:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
293: @*/
294: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
295: {
296:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
297:   PetscTruth        iascii;
298:   PetscErrorCode    ierr;

302:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
303:   if (iascii) {
304:     if (flg) {
305:       ascii->tab       = ascii->tab_store;
306:     } else {
307:       ascii->tab_store = ascii->tab;
308:       ascii->tab       = 0;
309:     }
310:   }
311:   return(0);
312: }

314: /* ----------------------------------------------------------------------- */

316:  #include src/sys/src/fileio/mprint.h

320: /*@C
321:     PetscViewerASCIIPrintf - Prints to a file, only from the first
322:     processor in the PetscViewer

324:     Not Collective, but only first processor in set has any effect

326:     Input Parameters:
327: +    viewer - optained with PetscViewerASCIIOpen()
328: -    format - the usual printf() format string 

330:     Level: developer

332:     Fortran Note:
333:     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran. 
334:     That is, you can only pass a single character string from Fortran.

336:   Concepts: PetscViewerASCII^printing
337:   Concepts: printing^to file
338:   Concepts: printf

340: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
341:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
342:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
343: @*/
344: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
345: {
346:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
347:   PetscMPIInt       rank;
348:   PetscInt          tab;
349:   PetscErrorCode    ierr;
350:   FILE              *fd = ascii->fd;
351:   PetscTruth        iascii;

356:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
357:   if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

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

367:     tab = ascii->tab;
368:     while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}

370:     va_start(Argp,format);
371:     PetscVFPrintf(fd,format,Argp);
372:     fflush(fd);
373:     if (petsc_history) {
374:       tab = ascii->tab;
375:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
376:       PetscVFPrintf(petsc_history,format,Argp);
377:       fflush(petsc_history);
378:     }
379:     va_end(Argp);
380:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
381:     va_list     Argp;
382:     char        *string;

384:     PrintfQueue next;
385:     PetscNew(struct _PrintfQueue,&next);
386:     if (queue) {queue->next = next; queue = next;}
387:     else       {queuebase   = queue = next;}
388:     queuelength++;
389:     string = next->string;
390:     PetscMemzero(string,QUEUESTRINGSIZE);
391:     tab = ascii->tab;
392:     while (tab--) {*string++ = ' ';}
393:     va_start(Argp,format);
394:     PetscVSNPrintf(string,QUEUESTRINGSIZE-ascii->tab,format,Argp);
395:     va_end(Argp);
396:   }
397:   return(0);
398: }

402: /*@C
403:      PetscViewerSetFilename - Sets the name of the file the PetscViewer uses.

405:     Collective on PetscViewer

407:   Input Parameters:
408: +  viewer - the PetscViewer; either ASCII or binary
409: -  name - the name of the file it should use

411:     Level: advanced

413: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
414:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

416: @*/
417: PetscErrorCode PetscViewerSetFilename(PetscViewer viewer,const char name[])
418: {
419:   PetscErrorCode ierr,(*f)(PetscViewer,const char[]);

424:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFilename_C",(void (**)(void))&f);
425:   if (f) {
426:     (*f)(viewer,name);
427:   }

429:   return(0);
430: }

434: /*@C
435:      PetscViewerGetFilename - Gets the name of the file the PetscViewer uses.

437:     Not Collective

439:   Input Parameter:
440: .  viewer - the PetscViewer; either ASCII or binary

442:   Output Parameter:
443: .  name - the name of the file it is using

445:     Level: advanced

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

449: @*/
450: PetscErrorCode PetscViewerGetFilename(PetscViewer viewer,char **name)
451: {
452:   PetscErrorCode ierr,(*f)(PetscViewer,char **);

456:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerGetFilename_C",(void (**)(void))&f);
457:   if (f) {
458:     (*f)(viewer,name);
459:   }
460:   return(0);
461: }

466: PetscErrorCode PetscViewerGetFilename_ASCII(PetscViewer viewer,char **name)
467: {
468:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

471:   *name = vascii->filename;
472:   return(0);
473: }

479: PetscErrorCode PetscViewerSetFilename_ASCII(PetscViewer viewer,const char name[])
480: {
481:   PetscErrorCode    ierr;
482:   size_t            len;
483:   char              fname[PETSC_MAX_PATH_LEN],*gz;
484:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
485:   PetscTruth        isstderr,isstdout;

488:   if (!name) return(0);

490:   PetscStrallocpy(name,&vascii->filename);

492:   /* Is this file to be compressed */
493:   vascii->storecompressed = PETSC_FALSE;
494:   PetscStrstr(vascii->filename,".gz",&gz);
495:   if (gz) {
496:     PetscStrlen(gz,&len);
497:     if (len == 3) {
498:       *gz = 0;
499:       vascii->storecompressed = PETSC_TRUE;
500:     }
501:   }
502:   PetscStrcmp(name,"stderr",&isstderr);
503:   PetscStrcmp(name,"stdout",&isstdout);
504:   if (isstderr)      vascii->fd = stderr;
505:   else if (isstdout) vascii->fd = stdout;
506:   else {
507:     PetscFixFilename(name,fname);
508:     switch(vascii->mode) {
509:     case FILE_MODE_READ:
510:       vascii->fd = fopen(fname,"r");
511:       break;
512:     case FILE_MODE_WRITE:
513:       vascii->fd = fopen(fname,"w");
514:       break;
515:     case FILE_MODE_APPEND:
516:       vascii->fd = fopen(fname,"a");
517:       break;
518:     case FILE_MODE_UPDATE:
519:       vascii->fd = fopen(fname,"r+");
520:       if (!vascii->fd) {
521:         vascii->fd = fopen(fname,"w+");
522:       }
523:       break;
524:     case FILE_MODE_APPEND_UPDATE:
525:       /* I really want a file which is opened at the end for updating,
526:          not a+, which opens at the beginning, but makes writes at the end.
527:       */
528:       vascii->fd = fopen(fname,"r+");
529:       if (!vascii->fd) {
530:         vascii->fd = fopen(fname,"w+");
531:       } else {
532:         fseek(vascii->fd, 0, SEEK_END);
533:       }
534:       break;
535:     default:
536:       SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
537:     }

539:     if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
540:   }
541:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
542:   return(0);
543: }

548: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
549: {
550:   PetscMPIInt       rank;
551:   PetscErrorCode    ierr;
552:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
553:   char              *name;

556:   if (vascii->sviewer) {
557:     SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
558:   }
559:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
560:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
561:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
562:   ovascii->fd  = vascii->fd;
563:   ovascii->tab = vascii->tab;

565:   vascii->sviewer = *outviewer;

567:   (*outviewer)->format     = viewer->format;
568:   (*outviewer)->iformat    = viewer->iformat;

570:   PetscObjectGetName((PetscObject)viewer,&name);
571:   PetscObjectSetName((PetscObject)(*outviewer),name);

573:   MPI_Comm_rank(viewer->comm,&rank);
574:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
575:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
576:   if (rank) {
577:     (*outviewer)->ops->flush = 0;
578:   } else {
579:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
580:   }
581:   return(0);
582: }

586: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
587: {
588:   PetscErrorCode    ierr;
589:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
590:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

593:   if (!ascii->sviewer) {
594:     SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
595:   }
596:   if (ascii->sviewer != *outviewer) {
597:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
598:   }

600:   ascii->sviewer             = 0;
601:   vascii->fd                 = stdout;
602:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
603:   PetscViewerDestroy(*outviewer);
604:   PetscViewerFlush(viewer);
605:   return(0);
606: }

611: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
612: {
613:   PetscViewer_ASCII *vascii;
614:   PetscErrorCode    ierr;

617:   PetscNew(PetscViewer_ASCII,&vascii);
618:   viewer->data = (void*)vascii;

620:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
621:   viewer->ops->flush            = PetscViewerFlush_ASCII;
622:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
623:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;

625:   /* defaults to stdout unless set with PetscViewerSetFilename() */
626:   vascii->fd             = stdout;
627:   vascii->mode           = FILE_MODE_WRITE;
628:   vascii->bviewer        = 0;
629:   vascii->sviewer        = 0;
630:   viewer->format         = PETSC_VIEWER_ASCII_DEFAULT;
631:   viewer->iformat        = 0;
632:   vascii->tab            = 0;
633:   vascii->tab_store      = 0;
634:   vascii->filename       = 0;

636:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_ASCII",
637:                                      PetscViewerSetFilename_ASCII);
638:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerGetFilename_C","PetscViewerGetFilename_ASCII",
639:                                      PetscViewerGetFilename_ASCII);

641:   return(0);
642: }


648: /*@C
649:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
650:     several processors.  Output of the first processor is followed by that of the 
651:     second, etc.

653:     Not Collective, must call collective PetscViewerFlush() to get the results out

655:     Input Parameters:
656: +   viewer - the ASCII PetscViewer
657: -   format - the usual printf() format string 

659:     Level: intermediate

661:     Fortran Note:
662:       Can only print a single character* string

664: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
665:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
666:           PetscViewerASCIIPrintf()

668: @*/
669: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
670: {
671:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
672:   PetscErrorCode    ierr;
673:   PetscMPIInt       rank;
674:   PetscInt          tab = vascii->tab;
675:   MPI_Comm          comm;
676:   FILE              *fp;
677:   PetscTruth        iascii;

682:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
683:   if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

685:   comm = viewer->comm;
686:   fp   = vascii->fd;
687:   MPI_Comm_rank(comm,&rank);
688:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
689: 

691:   /* First processor prints immediately to fp */
692:   if (!rank) {
693:     va_list Argp;

695:     while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp,"  ");}

697:     va_start(Argp,format);
698:     PetscVFPrintf(fp,format,Argp);
699:     fflush(fp);
700:     queuefile = fp;
701:     if (petsc_history) {
702:       PetscVFPrintf(petsc_history,format,Argp);
703:       fflush(petsc_history);
704:     }
705:     va_end(Argp);
706:   } else { /* other processors add to local queue */
707:     char        *string;
708:     va_list     Argp;
709:     PrintfQueue next;

711:     PetscNew(struct _PrintfQueue,&next);
712:     if (queue) {queue->next = next; queue = next;}
713:     else       {queuebase   = queue = next;}
714:     queuelength++;
715:     string = next->string;
716:     PetscMemzero(string,QUEUESTRINGSIZE);
717:     while (tab--) {*string++ = ' ';}
718:     va_start(Argp,format);
719:     PetscVSNPrintf(string,QUEUESTRINGSIZE-vascii->tab,format,Argp);
720:     va_end(Argp);
721:   }
722:   return(0);
723: }