xref: /petsc/src/sys/fileio/mprint.c (revision 4827ddca42da2d0ec0d1a0d9b26e4c5ddc271c44)
1 /*
2       Utilites routines to add simple ASCII IO capability.
3 */
4 #include <../src/sys/fileio/mprint.h>
5 #include <errno.h>
6 /*
7    If petsc_history is on, then all Petsc*Printf() results are saved
8    if the appropriate (usually .petschistory) file.
9 */
10 extern FILE *petsc_history;
11 /*
12      Allows one to overwrite where standard out is sent. For example
13      PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out
14      writes to go to terminal XX; assuming you have write permission there
15 */
16 FILE *PETSC_STDOUT = 0;
17 /*
18      Allows one to overwrite where standard error is sent. For example
19      PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error
20      writes to go to terminal XX; assuming you have write permission there
21 */
22 FILE *PETSC_STDERR = 0;
23 /*
24      Used to output to Zope
25 */
26 FILE *PETSC_ZOPEFD = 0;
27 
28 #undef __FUNCT__
29 #define __FUNCT__ "PetscFormatConvert"
30 /*@C
31      PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string
32 
33    Input Parameters:
34 +   format - the PETSc format string
35 .   newformat - the location to put the standard C format string values
36 -   size - the length of newformat
37 
38     Note: this exists so we can have the same code when PetscInt is either int or long long and PetscScalar is either double or float
39 
40  Level: developer
41 
42 @*/
43 PetscErrorCode  PetscFormatConvert(const char *format,char *newformat,size_t size)
44 {
45   PetscInt i = 0,j = 0;
46 
47   while (format[i] && i < (PetscInt)size-1) {
48     if (format[i] == '%' && format[i+1] == 'D') {
49       newformat[j++] = '%';
50 #if !defined(PETSC_USE_64BIT_INDICES)
51       newformat[j++] = 'd';
52 #else
53       newformat[j++] = 'l';
54       newformat[j++] = 'l';
55       newformat[j++] = 'd';
56 #endif
57       i += 2;
58     } else if (format[i] == '%' && format[i+1] >= '1' && format[i+1] <= '9' && format[i+2] == 'D') {
59       newformat[j++] = '%';
60       newformat[j++] = format[i+1];
61 #if !defined(PETSC_USE_64BIT_INDICES)
62       newformat[j++] = 'd';
63 #else
64       newformat[j++] = 'l';
65       newformat[j++] = 'l';
66       newformat[j++] = 'd';
67 #endif
68       i += 3;
69     } else if (format[i] == '%' && format[i+1] == 'G') {
70       newformat[j++] = '%';
71 #if defined(PETSC_USE_REAL_DOUBLE) || defined(PETSC_USE_REAL_SINGLE)
72       newformat[j++] = 'g';
73 #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
74       newformat[j++] = 'L';
75       newformat[j++] = 'g';
76 #elif defined(PETSC_USE_REAL___FLOAT128)
77       newformat[j++] = 'Q';
78       newformat[j++] = 'e';
79 #endif
80       i += 2;
81     }else {
82       newformat[j++] = format[i++];
83     }
84   }
85   newformat[j] = 0;
86   return 0;
87 }
88 
89 #undef __FUNCT__
90 #define __FUNCT__ "PetscVSNPrintf"
91 /*@C
92      PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the
93        function arguments into a string using the format statement.
94 
95    Input Parameters:
96 +   str - location to put result
97 .   len - the amount of space in str
98 +   format - the PETSc format string
99 -   fullLength - the amount of space in str actually used.
100 
101     Note:  No error handling because may be called by error handler
102 
103  Level: developer
104 
105 @*/
106 PetscErrorCode  PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp)
107 {
108   /* no malloc since may be called by error handler */
109   char          *newformat;
110   char           formatbuf[8*1024];
111   size_t         oldLength,length;
112   PetscErrorCode ierr;
113 
114   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
115   if (oldLength < 8*1024) {
116     newformat = formatbuf;
117   } else {
118     ierr = PetscMalloc((oldLength+1) * sizeof(char), &newformat);CHKERRQ(ierr);
119   }
120   PetscFormatConvert(format,newformat,oldLength+1);
121   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
122 #if 0
123   if (length > len) {
124     newformat[len] = '\0';
125   }
126 #endif
127 #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
128   *fullLength = vsnprintf(str,len,newformat,(char *)Argp);
129 #elif defined(PETSC_HAVE_VSNPRINTF)
130   *fullLength = vsnprintf(str,len,newformat,Argp);
131 #elif defined(PETSC_HAVE__VSNPRINTF)
132   *fullLength = _vsnprintf(str,len,newformat,Argp);
133 #else
134 #error "vsnprintf not found"
135 #endif
136   if (oldLength >= 8*1024) {
137     ierr = PetscFree(newformat);CHKERRQ(ierr);
138   }
139   return 0;
140 }
141 
142 #undef __FUNCT__
143 #define __FUNCT__ "PetscZopeLog"
144 PetscErrorCode  PetscZopeLog(const char *format,va_list Argp)
145 {
146   /* no malloc since may be called by error handler */
147   char        newformat[8*1024];
148   char        log[8*1024];
149   char        logstart[] = " <<<log>>>";
150   size_t      len,formatlen;
151 
152   PetscFormatConvert(format,newformat,8*1024);
153   PetscStrlen(logstart, &len);
154   PetscMemcpy(log, logstart, len);
155   PetscStrlen(newformat, &formatlen);
156   PetscMemcpy(&(log[len]), newformat, formatlen);
157   if (PETSC_ZOPEFD){
158 #if defined(PETSC_HAVE_VFPRINTF_CHAR)
159     vfprintf(PETSC_ZOPEFD,log,(char *)Argp);
160 #else
161     vfprintf(PETSC_ZOPEFD,log,Argp);
162 #endif
163     fflush(PETSC_ZOPEFD);
164   }
165   return 0;
166 }
167 
168 #undef __FUNCT__
169 #define __FUNCT__ "PetscVFPrintfDefault"
170 /*@C
171      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
172         can be replaced with something that does not simply write to a file.
173 
174       To use, write your own function for example,
175 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
176 ${
177 $  PetscErrorCode ierr;
178 $
179 $  PetscFunctionBegin;
180 $   if (fd != stdout && fd != stderr) {  handle regular files
181 $      ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERR(ierr);
182 $  } else {
183 $     char   buff[BIG];
184 $     size_t length;
185 $     ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr);
186 $     now send buff to whatever stream or whatever you want
187 $ }
188 $ PetscFunctionReturn(0);
189 $}
190 then before the call to PetscInitialize() do the assignment
191 $    PetscVFPrintf = mypetscvfprintf;
192 
193       Notes: For error messages this may be called by any process, for regular standard out it is
194           called only by process 0 of a given communicator
195 
196       No error handling because may be called by error handler
197 
198   Level:  developer
199 
200 .seealso: PetscVSNPrintf(), PetscErrorPrintf()
201 
202 @*/
203 PetscErrorCode  PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
204 {
205   /* no malloc since may be called by error handler (assume no long messages in errors) */
206   char        *newformat;
207   char         formatbuf[8*1024];
208   size_t       oldLength;
209 
210   PetscStrlen(format, &oldLength);
211   if (oldLength < 8*1024) {
212     newformat = formatbuf;
213   } else {
214     (void)PetscMalloc((oldLength+1) * sizeof(char), &newformat);
215   }
216   PetscFormatConvert(format,newformat,oldLength+1);
217 
218 #if defined(PETSC_HAVE_VFPRINTF_CHAR)
219   vfprintf(fd,newformat,(char *)Argp);
220 #else
221   vfprintf(fd,newformat,Argp);
222 #endif
223   fflush(fd);
224   if (oldLength >= 8*1024) {
225     (void)PetscFree(newformat);
226   }
227   return 0;
228 }
229 
230 #undef __FUNCT__
231 #define __FUNCT__ "PetscSNPrintf"
232 /*@C
233     PetscSNPrintf - Prints to a string of given length
234 
235     Not Collective
236 
237     Input Parameters:
238 +   str - the string to print to
239 .   len - the length of str
240 .   format - the usual printf() format string
241 -   any arguments
242 
243    Level: intermediate
244 
245 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
246           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
247 @*/
248 PetscErrorCode  PetscSNPrintf(char *str,size_t len,const char format[],...)
249 {
250   PetscErrorCode ierr;
251   size_t         fullLength;
252   va_list        Argp;
253 
254   PetscFunctionBegin;
255   va_start(Argp,format);
256   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
257   PetscFunctionReturn(0);
258 }
259 
260 /* ----------------------------------------------------------------------- */
261 
262 PrintfQueue queue       = 0,queuebase = 0;
263 int         queuelength = 0;
264 FILE        *queuefile  = PETSC_NULL;
265 
266 #undef __FUNCT__
267 #define __FUNCT__ "PetscSynchronizedPrintf"
268 /*@C
269     PetscSynchronizedPrintf - Prints synchronized output from several processors.
270     Output of the first processor is followed by that of the second, etc.
271 
272     Not Collective
273 
274     Input Parameters:
275 +   comm - the communicator
276 -   format - the usual printf() format string
277 
278    Level: intermediate
279 
280     Notes:
281     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
282     from all the processors to be printed.
283 
284     Fortran Note:
285     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
286     That is, you can only pass a single character string from Fortran.
287 
288 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
289           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
290 @*/
291 PetscErrorCode  PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
292 {
293   PetscErrorCode ierr;
294   PetscMPIInt    rank;
295 
296   PetscFunctionBegin;
297   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
298 
299   /* First processor prints immediately to stdout */
300   if (!rank) {
301     va_list Argp;
302     va_start(Argp,format);
303     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
304     if (petsc_history) {
305       va_start(Argp,format);
306       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
307     }
308     va_end(Argp);
309   } else { /* other processors add to local queue */
310     va_list     Argp;
311     PrintfQueue next;
312     size_t      fullLength = 8191;
313 
314     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
315     if (queue) {queue->next = next; queue = next; queue->next = 0;}
316     else       {queuebase   = queue = next;}
317     queuelength++;
318     next->size = -1;
319     while((PetscInt)fullLength >= next->size) {
320       next->size = fullLength+1;
321       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
322       va_start(Argp,format);
323       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
324       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
325       va_end(Argp);
326     }
327   }
328 
329   PetscFunctionReturn(0);
330 }
331 
332 #undef __FUNCT__
333 #define __FUNCT__ "PetscSynchronizedFPrintf"
334 /*@C
335     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
336     several processors.  Output of the first processor is followed by that of the
337     second, etc.
338 
339     Not Collective
340 
341     Input Parameters:
342 +   comm - the communicator
343 .   fd - the file pointer
344 -   format - the usual printf() format string
345 
346     Level: intermediate
347 
348     Notes:
349     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
350     from all the processors to be printed.
351 
352 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
353           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
354 
355 @*/
356 PetscErrorCode  PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...)
357 {
358   PetscErrorCode ierr;
359   PetscMPIInt    rank;
360 
361   PetscFunctionBegin;
362   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
363 
364   /* First processor prints immediately to fp */
365   if (!rank) {
366     va_list Argp;
367     va_start(Argp,format);
368     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
369     queuefile = fp;
370     if (petsc_history && (fp !=petsc_history)) {
371       va_start(Argp,format);
372       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
373     }
374     va_end(Argp);
375   } else { /* other processors add to local queue */
376     va_list     Argp;
377     PrintfQueue next;
378     size_t      fullLength = 8191;
379     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
380     if (queue) {queue->next = next; queue = next; queue->next = 0;}
381     else       {queuebase   = queue = next;}
382     queuelength++;
383     next->size = -1;
384     while((PetscInt)fullLength >= next->size) {
385       next->size = fullLength+1;
386       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
387       va_start(Argp,format);
388       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
389       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
390       va_end(Argp);
391     }
392   }
393   PetscFunctionReturn(0);
394 }
395 
396 #undef __FUNCT__
397 #define __FUNCT__ "PetscSynchronizedFlush"
398 /*@
399     PetscSynchronizedFlush - Flushes to the screen output from all processors
400     involved in previous PetscSynchronizedPrintf() calls.
401 
402     Collective on MPI_Comm
403 
404     Input Parameters:
405 .   comm - the communicator
406 
407     Level: intermediate
408 
409     Notes:
410     Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with
411     different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush().
412 
413 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
414           PetscViewerASCIISynchronizedPrintf()
415 @*/
416 PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm)
417 {
418   PetscErrorCode ierr;
419   PetscMPIInt    rank,size,tag,i,j,n,dummy = 0;
420   char          *message;
421   MPI_Status     status;
422   FILE           *fd;
423 
424   PetscFunctionBegin;
425   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
426   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
427   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
428 
429   /* First processor waits for messages from all other processors */
430   if (!rank) {
431     if (queuefile) {
432       fd = queuefile;
433     } else {
434       fd = PETSC_STDOUT;
435     }
436     for (i=1; i<size; i++) {
437       /* to prevent a flood of messages to process zero, request each message separately */
438       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
439       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
440       for (j=0; j<n; j++) {
441         PetscMPIInt size;
442 
443         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
444         ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr);
445         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
446         ierr = PetscFPrintf(comm,fd,"%s",message);
447         ierr = PetscFree(message);CHKERRQ(ierr);
448       }
449     }
450     queuefile = PETSC_NULL;
451   } else { /* other processors send queue to processor 0 */
452     PrintfQueue next = queuebase,previous;
453 
454     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
455     ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
456     for (i=0; i<queuelength; i++) {
457       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
458       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
459       previous = next;
460       next     = next->next;
461       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
462       ierr     = PetscFree(previous);CHKERRQ(ierr);
463     }
464     queue       = 0;
465     queuelength = 0;
466   }
467   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
468   PetscFunctionReturn(0);
469 }
470 
471 /* ---------------------------------------------------------------------------------------*/
472 
473 #undef __FUNCT__
474 #define __FUNCT__ "PetscFPrintf"
475 /*@C
476     PetscFPrintf - Prints to a file, only from the first
477     processor in the communicator.
478 
479     Not Collective
480 
481     Input Parameters:
482 +   comm - the communicator
483 .   fd - the file pointer
484 -   format - the usual printf() format string
485 
486     Level: intermediate
487 
488     Fortran Note:
489     This routine is not supported in Fortran.
490 
491    Concepts: printing^in parallel
492    Concepts: printf^in parallel
493 
494 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
495           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
496 @*/
497 PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
498 {
499   PetscErrorCode ierr;
500   PetscMPIInt    rank;
501 
502   PetscFunctionBegin;
503   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
504   if (!rank) {
505     va_list Argp;
506     va_start(Argp,format);
507     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
508     if (petsc_history && (fd !=petsc_history)) {
509       va_start(Argp,format);
510       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
511       }
512     va_end(Argp);
513   }
514   PetscFunctionReturn(0);
515 }
516 
517 #undef __FUNCT__
518 #define __FUNCT__ "PetscPrintf"
519 /*@C
520     PetscPrintf - Prints to standard out, only from the first
521     processor in the communicator.
522 
523     Not Collective
524 
525     Input Parameters:
526 +   comm - the communicator
527 -   format - the usual printf() format string
528 
529    Level: intermediate
530 
531     Fortran Note:
532     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
533     That is, you can only pass a single character string from Fortran.
534 
535    Notes: The %A format specifier is special.  It assumes an argument of type PetscReal
536           and is replaced with %G unless the absolute value is < 1.e-12 when it is replaced
537           with "< 1.e-12" (1.e-6 for single precision).
538 
539    Concepts: printing^in parallel
540    Concepts: printf^in parallel
541 
542 .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
543 @*/
544 PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
545 {
546   PetscErrorCode ierr;
547   PetscMPIInt    rank;
548   size_t         len;
549   char           *nformat,*sub1,*sub2;
550   PetscReal      value;
551 
552   PetscFunctionBegin;
553   if (!comm) comm = PETSC_COMM_WORLD;
554   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
555   if (!rank) {
556     va_list Argp;
557     va_start(Argp,format);
558 
559     ierr = PetscStrstr(format,"%A",&sub1);CHKERRQ(ierr);
560     if (sub1) {
561       ierr = PetscStrstr(format,"%",&sub2);CHKERRQ(ierr);
562       if (sub1 != sub2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"%%A format must be first in format string");
563       ierr    = PetscStrlen(format,&len);CHKERRQ(ierr);
564       ierr    = PetscMalloc((len+16)*sizeof(char),&nformat);CHKERRQ(ierr);
565       ierr    = PetscStrcpy(nformat,format);CHKERRQ(ierr);
566       ierr    = PetscStrstr(nformat,"%",&sub2);CHKERRQ(ierr);
567       sub2[0] = 0;
568       value   = va_arg(Argp,double);
569 #if defined(PETSC_USE_REAL_SINGLE)
570       if (PetscAbsReal(value) < 1.e-6) {
571         ierr    = PetscStrcat(nformat,"< 1.e-6");CHKERRQ(ierr);
572 #else
573       if (PetscAbsReal(value) < 1.e-12) {
574         ierr    = PetscStrcat(nformat,"< 1.e-12");CHKERRQ(ierr);
575 #endif
576       } else {
577         ierr    = PetscStrcat(nformat,"%G");CHKERRQ(ierr);
578         va_end(Argp);
579         va_start(Argp,format);
580       }
581       ierr    = PetscStrcat(nformat,sub1+2);CHKERRQ(ierr);
582     } else {
583       nformat = (char*)format;
584     }
585     ierr = (*PetscVFPrintf)(PETSC_STDOUT,nformat,Argp);CHKERRQ(ierr);
586     if (petsc_history) {
587       va_start(Argp,format);
588       ierr = (*PetscVFPrintf)(petsc_history,nformat,Argp);CHKERRQ(ierr);
589     }
590     va_end(Argp);
591     if (sub1) {ierr = PetscFree(nformat);CHKERRQ(ierr);}
592   }
593   PetscFunctionReturn(0);
594 }
595 
596 /* ---------------------------------------------------------------------------------------*/
597 #undef __FUNCT__
598 #define __FUNCT__ "PetscHelpPrintfDefault"
599 /*@C
600      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
601         replacinng it  with something that does not simply write to a stdout.
602 
603       To use, write your own function for example,
604 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
605 ${
606 $ PetscFunctionReturn(0);
607 $}
608 then before the call to PetscInitialize() do the assignment
609 $    PetscHelpPrintf = mypetschelpprintf;
610 
611   Note: the default routine used is called PetscHelpPrintfDefault().
612 
613   Level:  developer
614 
615 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
616 @*/
617 PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
618 {
619   PetscErrorCode ierr;
620   PetscMPIInt    rank;
621 
622   PetscFunctionBegin;
623   if (!comm) comm = PETSC_COMM_WORLD;
624   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
625   if (!rank) {
626     va_list Argp;
627     va_start(Argp,format);
628     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
629     if (petsc_history) {
630       va_start(Argp,format);
631       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
632     }
633     va_end(Argp);
634   }
635   PetscFunctionReturn(0);
636 }
637 
638 /* ---------------------------------------------------------------------------------------*/
639 
640 
641 #undef __FUNCT__
642 #define __FUNCT__ "PetscSynchronizedFGets"
643 /*@C
644     PetscSynchronizedFGets - Several processors all get the same line from a file.
645 
646     Collective on MPI_Comm
647 
648     Input Parameters:
649 +   comm - the communicator
650 .   fd - the file pointer
651 -   len - the length of the output buffer
652 
653     Output Parameter:
654 .   string - the line read from the file
655 
656     Level: intermediate
657 
658 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
659           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
660 
661 @*/
662 PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[])
663 {
664   PetscErrorCode ierr;
665   PetscMPIInt    rank;
666 
667   PetscFunctionBegin;
668   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
669 
670   if (!rank) {
671     char *ptr = fgets(string, len, fp);
672 
673     if (!ptr) {
674       if (feof(fp)) {
675         len = 0;
676       } else {
677         SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
678       }
679     }
680   }
681   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
682   PetscFunctionReturn(0);
683 }
684 
685 #if defined(PETSC_HAVE_MATLAB_ENGINE)
686 #include <mex.h>
687 #undef __FUNCT__
688 #define __FUNCT__ "PetscVFPrintf_Matlab"
689 PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
690 {
691   PetscErrorCode ierr;
692 
693   PetscFunctionBegin;
694   if (fd != stdout && fd != stderr) { /* handle regular files */
695     ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERRQ(ierr);
696   } else {
697     size_t len=8*1024,length;
698     char   buf[len];
699 
700     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
701     mexPrintf("%s",buf);
702  }
703  PetscFunctionReturn(0);
704 }
705 #endif
706