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