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: int PetscViewerDestroy_ASCII(PetscViewer viewer)
 20: {
 21:   int               rank,ierr;
 22:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 25:   if (vascii->sviewer) {
 26:     SETERRQ(1,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
 27:   }
 28:   MPI_Comm_rank(viewer->comm,&rank);
 29:   if (!rank && vascii->fd != stderr && vascii->fd != stdout) {
 30:     fclose(vascii->fd);
 31:     if (vascii->storecompressed) {
 32:       char par[1024],buf[1024];
 33:       FILE *fp;
 34:       PetscStrcpy(par,"gzip ");
 35:       PetscStrcat(par,vascii->filename);
 36:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
 37:       if (fgets(buf,1024,fp)) {
 38:         SETERRQ2(1,"Error from compression command %sn%s",par,buf);
 39:       }
 40:     }
 41:   }
 42:   PetscStrfree(vascii->filename);
 43:   PetscFree(vascii);
 44:   return(0);
 45: }

 47: int PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
 48: {
 49:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 50:   int               ierr;
 52:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
 53:   return(0);
 54: }

 56: int PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
 57: {
 58:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 61:   fflush(vascii->fd);
 62:   return(0);
 63: }

 65: int PetscViewerFlush_ASCII(PetscViewer viewer)
 66: {
 67:   int               rank,ierr;
 68:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 71:   MPI_Comm_rank(viewer->comm,&rank);
 72:   if (!rank) {
 73:     fflush(vascii->fd);
 74:   }

 76:   /*
 77:      Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
 78:   */
 79:   PetscSynchronizedFlush(viewer->comm);
 80:   return(0);
 81: }

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

 86:     Not Collective

 88: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
 89: -   fd - file pointer

 91:     Level: intermediate

 93:     Fortran Note:
 94:     This routine is not supported in Fortran.

 96:   Concepts: PetscViewer^file pointer
 97:   Concepts: file pointer^getting from PetscViewer

 99: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
100:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
101: @*/
102: int PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
103: {
104:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

107:   *fd = vascii->fd;
108:   return(0);
109: }

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

114:     Not Collective

116: +   viewer - viewer context, obtained from PetscViewerASCIIOpen()
117: -   mode   - The file mode

119:     Level: intermediate

121:     Fortran Note:
122:     This routine is not supported in Fortran.

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

126: .seealso: PetscViewerASCIIOpen()
127: @*/
128: int PetscViewerASCIISetMode(PetscViewer viewer, PetscFileMode mode)
129: {
130:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

133:   vascii->mode = mode;
134:   return(0);
135: }

137: /*
138:    If petsc_history is on, then all Petsc*Printf() results are saved
139:    if the appropriate (usually .petschistory) file.
140: */
141: extern FILE *petsc_history;

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

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

148:     Input Parameters:
149: +    viewer - optained with PetscViewerASCIIOpen()
150: -    tabs - number of tabs

152:     Level: developer

154:     Fortran Note:
155:     This routine is not supported in Fortran.

157:   Concepts: PetscViewerASCII^formating
158:   Concepts: tab^setting

160: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
161:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
162:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
163: @*/
164: int PetscViewerASCIISetTab(PetscViewer viewer,int tabs)
165: {
166:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
167:   PetscTruth        isascii;
168:   int               ierr;

172:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
173:   if (isascii) {
174:     ascii->tab = tabs;
175:   }
176:   return(0);
177: }

179: /*@C
180:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
181:      lines are tabbed.

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

185:     Input Parameters:
186: .    viewer - optained with PetscViewerASCIIOpen()

188:     Level: developer

190:     Fortran Note:
191:     This routine is not supported in Fortran.

193:   Concepts: PetscViewerASCII^formating
194:   Concepts: tab^setting

196: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
197:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
198:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
199: @*/
200: int PetscViewerASCIIPushTab(PetscViewer viewer)
201: {
202:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
203:   PetscTruth        isascii;
204:   int               ierr;

208:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
209:   if (isascii) {
210:     ascii->tab++;
211:   }
212:   return(0);
213: }

215: /*@C
216:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
217:      lines are tabbed.

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

221:     Input Parameters:
222: .    viewer - optained with PetscViewerASCIIOpen()

224:     Level: developer

226:     Fortran Note:
227:     This routine is not supported in Fortran.

229:   Concepts: PetscViewerASCII^formating
230:   Concepts: tab^setting

232: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
233:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
234:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
235: @*/
236: int PetscViewerASCIIPopTab(PetscViewer viewer)
237: {
238:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
239:   int               ierr;
240:   PetscTruth        isascii;

244:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
245:   if (isascii) {
246:     if (ascii->tab <= 0) SETERRQ(1,"More tabs popped than pushed");
247:     ascii->tab--;
248:   }
249:   return(0);
250: }

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

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

257:     Input Parameters:
258: +    viewer - optained with PetscViewerASCIIOpen()
259: -    flg - PETSC_YES or PETSC_NO

261:     Level: developer

263:     Fortran Note:
264:     This routine is not supported in Fortran.

266:   Concepts: PetscViewerASCII^formating
267:   Concepts: tab^setting

269: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
270:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
271:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
272: @*/
273: int PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
274: {
275:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
276:   PetscTruth        isascii;
277:   int               ierr;

281:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
282:   if (isascii) {
283:     if (flg) {
284:       ascii->tab       = ascii->tab_store;
285:     } else {
286:       ascii->tab_store = ascii->tab;
287:       ascii->tab       = 0;
288:     }
289:   }
290:   return(0);
291: }

293: /* ----------------------------------------------------------------------- */

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

297: /*@C
298:     PetscViewerASCIIPrintf - Prints to a file, only from the first
299:     processor in the PetscViewer

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

303:     Input Parameters:
304: +    viewer - optained with PetscViewerASCIIOpen()
305: -    format - the usual printf() format string 

307:     Level: developer

309:     Fortran Note:
310:     This routine is not supported in Fortran.

312:   Concepts: PetscViewerASCII^printing
313:   Concepts: printing^to file
314:   Concepts: printf

316: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
317:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
318:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
319: @*/
320: int PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
321: {
322:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
323:   int               rank,tab,ierr;
324:   FILE              *fd = ascii->fd;
325:   PetscTruth        isascii;

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

332:   MPI_Comm_rank(viewer->comm,&rank);
333:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
334:   if (!rank) {
335:     va_list Argp;
336:     if (ascii->bviewer) {
337:       queuefile = fd;
338:     }

340:     tab = ascii->tab;
341:     while (tab--) fprintf(fd,"  ");

343:     va_start(Argp,format);
344: #if defined(PETSC_HAVE_VPRINTF_CHAR)
345:     vfprintf(fd,format,(char*)Argp);
346: #else
347:     vfprintf(fd,format,Argp);
348: #endif
349:     fflush(fd);
350:     if (petsc_history) {
351:       tab = ascii->tab;
352:       while (tab--) fprintf(fd,"  ");
353: #if defined(PETSC_HAVE_VPRINTF_CHAR)
354:       vfprintf(petsc_history,format,(char *)Argp);
355: #else
356:       vfprintf(petsc_history,format,Argp);
357: #endif
358:       fflush(petsc_history);
359:     }
360:     va_end(Argp);
361:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
362:     int         len;
363:     va_list     Argp;

365:     PrintfQueue next;
366:     PetscNew(struct _PrintfQueue,&next);
367:     if (queue) {queue->next = next; queue = next;}
368:     else       {queuebase   = queue = next;}
369:     queuelength++;
370:     va_start(Argp,format);
371: #if defined(PETSC_HAVE_VPRINTF_CHAR)
372:     vsprintf(next->string,format,(char *)Argp);
373: #else
374:     vsprintf(next->string,format,Argp);
375: #endif
376:     va_end(Argp);
377:     PetscStrlen(next->string,&len);
378:     if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
379:   }
380:   return(0);
381: }

383: /*@C
384:      PetscViewerSetFilename - Sets the name of the file the PetscViewer uses.

386:     Collective on PetscViewer

388:   Input Parameters:
389: +  viewer - the PetscViewer; either ASCII or binary
390: -  name - the name of the file it should use

392:     Level: advanced

394: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
395:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

397: @*/
398: int PetscViewerSetFilename(PetscViewer viewer,const char name[])
399: {
400:   int ierr,(*f)(PetscViewer,const char[]);

404:   if (!name) SETERRQ(1,"You must pass in non-null string");
405:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFilename_C",(void (**)(void))&f);
406:   if (f) {
407:     (*f)(viewer,name);
408:   }

410:   return(0);
411: }

413: /*@C
414:      PetscViewerGetFilename - Gets the name of the file the PetscViewer uses.

416:     Not Collective

418:   Input Parameter:
419: .  viewer - the PetscViewer; either ASCII or binary

421:   Output Parameter:
422: .  name - the name of the file it is using

424:     Level: advanced

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

428: @*/
429: int PetscViewerGetFilename(PetscViewer viewer,char **name)
430: {
431:   int ierr,(*f)(PetscViewer,char **);

435:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerGetFilename_C",(void (**)(void))&f);
436:   if (f) {
437:     (*f)(viewer,name);
438:   }

440:   return(0);
441: }

443: EXTERN_C_BEGIN
444: int PetscViewerGetFilename_ASCII(PetscViewer viewer,char **name)
445: {
446:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

449:   *name = vascii->filename;
450:   return(0);
451: }
452: EXTERN_C_END

454: EXTERN_C_BEGIN
455: int PetscViewerSetFilename_ASCII(PetscViewer viewer,const char name[])
456: {
457:   int               ierr,len;
458:   char              fname[256],*gz;
459:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
460:   PetscTruth        isstderr,isstdout;

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

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

467:   /* Is this file to be compressed */
468:   vascii->storecompressed = PETSC_FALSE;
469:   PetscStrstr(vascii->filename,".gz",&gz);
470:   if (gz) {
471:     PetscStrlen(gz,&len);
472:     if (len == 3) {
473:       *gz = 0;
474:       vascii->storecompressed = PETSC_TRUE;
475:     }
476:   }
477:   PetscStrcmp(name,"stderr",&isstderr);
478:   PetscStrcmp(name,"stdout",&isstdout);
479:   if (isstderr)      vascii->fd = stderr;
480:   else if (isstdout) vascii->fd = stdout;
481:   else {
482:     PetscFixFilename(name,fname);
483:     switch(vascii->mode) {
484:     case FILE_MODE_READ:
485:       vascii->fd = fopen(fname,"r");
486:       break;
487:     case FILE_MODE_WRITE:
488:       vascii->fd = fopen(fname,"w");
489:       break;
490:     case FILE_MODE_APPEND:
491:       vascii->fd = fopen(fname,"a");
492:       break;
493:     case FILE_MODE_UPDATE:
494:       vascii->fd = fopen(fname,"r+");
495:       if (vascii->fd == PETSC_NULL) {
496:         vascii->fd = fopen(fname,"w+");
497:       }
498:       break;
499:     case FILE_MODE_APPEND_UPDATE:
500:       /* I really want a file which is opened at the end for updating,
501:          not a+, which opens at the beginning, but makes writes at the end.
502:       */
503:       vascii->fd = fopen(fname,"r+");
504:       if (vascii->fd == PETSC_NULL) {
505:         vascii->fd = fopen(fname,"w+");
506:       } else {
507:         ierr     = fseek(vascii->fd, 0, SEEK_END);
508:       }
509:       break;
510:     default:
511:       SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
512:     }

514:     if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
515:   }
516: #if defined(PETSC_USE_LOG)
517:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
518: #endif

520:   return(0);
521: }
522: EXTERN_C_END

524: int PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
525: {
526:   int               rank,ierr;
527:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
528:   char              *name;

531:   if (vascii->sviewer) {
532:     SETERRQ(1,"Singleton already obtained from PetscViewer and not restored");
533:   }
534:   ierr         = PetscViewerCreate(PETSC_COMM_SELF,outviewer);
535:   ierr         = PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
536:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
537:   ovascii->fd  = vascii->fd;
538:   ovascii->tab = vascii->tab;

540:   vascii->sviewer = *outviewer;

542:   (*outviewer)->format     = viewer->format;
543:   (*outviewer)->iformat    = viewer->iformat;

545:   PetscObjectGetName((PetscObject)viewer,&name);
546:   PetscObjectSetName((PetscObject)(*outviewer),name);

548:   MPI_Comm_rank(viewer->comm,&rank);
549:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
550:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
551:   if (rank) {
552:     (*outviewer)->ops->flush = 0;
553:   } else {
554:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
555:   }
556:   return(0);
557: }

559: int PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
560: {
561:   int               ierr;
562:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
563:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

566:   if (!ascii->sviewer) {
567:     SETERRQ(1,"Singleton never obtained from PetscViewer");
568:   }
569:   if (ascii->sviewer != *outviewer) {
570:     SETERRQ(1,"This PetscViewer did not generate singleton");
571:   }

573:   ascii->sviewer             = 0;
574:   vascii->fd                 = stdout;
575:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
576:   ierr                       = PetscViewerDestroy(*outviewer);
577:   PetscViewerFlush(viewer);
578:   return(0);
579: }

581: EXTERN_C_BEGIN
582: int PetscViewerCreate_ASCII(PetscViewer viewer)
583: {
584:   PetscViewer_ASCII *vascii;
585:   int               ierr;

588:   ierr         = PetscNew(PetscViewer_ASCII,&vascii);
589:   viewer->data = (void*)vascii;

591:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
592:   viewer->ops->flush            = PetscViewerFlush_ASCII;
593:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
594:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;

596:   /* defaults to stdout unless set with PetscViewerSetFilename() */
597:   vascii->fd             = stdout;
598:   vascii->mode           = FILE_MODE_WRITE;
599:   vascii->bviewer        = 0;
600:   vascii->sviewer        = 0;
601:   viewer->format         = PETSC_VIEWER_ASCII_DEFAULT;
602:   viewer->iformat        = 0;
603:   vascii->tab            = 0;
604:   vascii->tab_store      = 0;
605:   vascii->filename       = 0;

607:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_ASCII",
608:                                      PetscViewerSetFilename_ASCII);
609:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerGetFilename_C","PetscViewerGetFilename_ASCII",
610:                                      PetscViewerGetFilename_ASCII);

612:   return(0);
613: }
614: EXTERN_C_END


617: /*@C
618:     PetscViewerASCIISynchronizedFPrintf - Prints synchronized output to the specified file from
619:     several processors.  Output of the first processor is followed by that of the 
620:     second, etc.

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

624:     Input Parameters:
625: +   viewer - the ASCII PetscViewer
626: -   format - the usual printf() format string 

628:     Level: intermediate

630: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
631:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
632:           PetscViewerASCIIPrintf()

634: @*/
635: int PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
636: {
637:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
638:   int               ierr,rank,tab = vascii->tab;
639:   MPI_Comm          comm;
640:   FILE              *fp;
641:   PetscTruth        isascii;

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

648:   comm = viewer->comm;
649:   fp   = vascii->fd;
650:   MPI_Comm_rank(comm,&rank);
651:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
652: 

654:   /* First processor prints immediately to fp */
655:   if (!rank) {
656:     va_list Argp;

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

660:     va_start(Argp,format);
661: #if defined(PETSC_HAVE_VPRINTF_CHAR)
662:     vfprintf(fp,format,(char*)Argp);
663: #else
664:     vfprintf(fp,format,Argp);
665: #endif
666:     fflush(fp);
667:     queuefile = fp;
668:     if (petsc_history) {
669: #if defined(PETSC_HAVE_VPRINTF_CHAR)
670:       vfprintf(petsc_history,format,(char *)Argp);
671: #else
672:       vfprintf(petsc_history,format,Argp);
673: #endif
674:       fflush(petsc_history);
675:     }
676:     va_end(Argp);
677:   } else { /* other processors add to local queue */
678:     int         len;
679:     char        *string;
680:     va_list     Argp;
681:     PrintfQueue next;

683:     PetscNew(struct _PrintfQueue,&next);
684:     if (queue) {queue->next = next; queue = next;}
685:     else       {queuebase   = queue = next;}
686:     queuelength++;
687:     string = next->string;
688:     while (tab--) {*string++ = ' ';}
689:     va_start(Argp,format);
690: #if defined(PETSC_HAVE_VPRINTF_CHAR)
691:     vsprintf(string,format,(char *)Argp);
692: #else
693:     vsprintf(string,format,Argp);
694: #endif
695:     va_end(Argp);
696:     PetscStrlen(next->string,&len);
697:     if (len > QUEUESTRINGSIZE) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Formatted string longer then %d bytes",QUEUESTRINGSIZE);
698:   }
699:   return(0);
700: }