xref: /petsc/src/sys/fileio/mprint.c (revision 7889ec69ae0e44a97e08bf1c73874b7ce2f33c45)
1e5c89e4eSSatish Balay /*
2e5c89e4eSSatish Balay       Utilites routines to add simple ASCII IO capability.
3e5c89e4eSSatish Balay */
4c6db04a5SJed Brown #include <../src/sys/fileio/mprint.h>
579c0e996SJed Brown #include <errno.h>
6e5c89e4eSSatish Balay /*
7e5c89e4eSSatish Balay    If petsc_history is on, then all Petsc*Printf() results are saved
8e5c89e4eSSatish Balay    if the appropriate (usually .petschistory) file.
9e5c89e4eSSatish Balay */
10e5c89e4eSSatish Balay extern FILE *petsc_history;
11e5c89e4eSSatish Balay /*
12e5c89e4eSSatish Balay      Allows one to overwrite where standard out is sent. For example
135106ddf5SBarry Smith      PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out
14e5c89e4eSSatish Balay      writes to go to terminal XX; assuming you have write permission there
15e5c89e4eSSatish Balay */
16e5c89e4eSSatish Balay FILE *PETSC_STDOUT = 0;
17ae9b4142SLisandro Dalcin /*
18ae9b4142SLisandro Dalcin      Allows one to overwrite where standard error is sent. For example
19ae9b4142SLisandro Dalcin      PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error
20ae9b4142SLisandro Dalcin      writes to go to terminal XX; assuming you have write permission there
21ae9b4142SLisandro Dalcin */
22ae9b4142SLisandro Dalcin FILE *PETSC_STDERR = 0;
23b13499bfSbcordonn 
24354e5084SJose Roman /*
25354e5084SJose Roman      Return the maximum expected new size of the format
26354e5084SJose Roman */
27354e5084SJose Roman #define PETSC_MAX_LENGTH_FORMAT(l) (l+l/8)
28354e5084SJose Roman 
29e5c89e4eSSatish Balay #undef __FUNCT__
30e5c89e4eSSatish Balay #define __FUNCT__ "PetscFormatConvert"
31c9a19010SBarry Smith /*@C
32c9a19010SBarry Smith      PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string
33c9a19010SBarry Smith 
34c9a19010SBarry Smith    Input Parameters:
35c9a19010SBarry Smith +   format - the PETSc format string
36c9a19010SBarry Smith .   newformat - the location to put the standard C format string values
37c9a19010SBarry Smith -   size - the length of newformat
38c9a19010SBarry Smith 
39eed5747fSBarry Smith     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
40c9a19010SBarry Smith 
41c9a19010SBarry Smith  Level: developer
42c9a19010SBarry Smith 
43c9a19010SBarry Smith @*/
447087cfbeSBarry Smith PetscErrorCode  PetscFormatConvert(const char *format,char *newformat,size_t size)
45e5c89e4eSSatish Balay {
46e5c89e4eSSatish Balay   PetscInt i = 0,j = 0;
47e5c89e4eSSatish Balay 
48eed5747fSBarry Smith   PetscFunctionBegin;
497bc47156SJose Roman   while (format[i] && j < (PetscInt)size-1) {
502a1ad9caSBarry Smith     if (format[i] == '%' && format[i+1] == '%') {
512a1ad9caSBarry Smith       newformat[j++] = format[i++];
522a1ad9caSBarry Smith       newformat[j++] = format[i++];
532a1ad9caSBarry Smith     } else if (format[i] == '%') {
548627564fSBarry Smith       if (format[i+1] == 'g') {
558627564fSBarry Smith         newformat[j++] = '[';
568627564fSBarry Smith         newformat[j++] = '|';
578627564fSBarry Smith       }
587bc47156SJose Roman       /* Find the letter */
597bc47156SJose Roman       for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i];
607bc47156SJose Roman       switch (format[i]) {
617bc47156SJose Roman       case 'D':
626de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
63e5c89e4eSSatish Balay         newformat[j++] = 'd';
64e5c89e4eSSatish Balay #else
65e5c89e4eSSatish Balay         newformat[j++] = 'l';
66e5c89e4eSSatish Balay         newformat[j++] = 'l';
67e5c89e4eSSatish Balay         newformat[j++] = 'd';
68e5c89e4eSSatish Balay #endif
697bc47156SJose Roman         break;
708627564fSBarry Smith       case 'g':
718627564fSBarry Smith         newformat[j++] = format[i];
728627564fSBarry Smith         if (format[i-1] == '%') {
738627564fSBarry Smith           newformat[j++] = '|';
748627564fSBarry Smith           newformat[j++] = ']';
758627564fSBarry Smith         }
768627564fSBarry Smith         break;
777bc47156SJose Roman       case 'G':
78145505e7SDominic Meiser         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double");
797bc47156SJose Roman         break;
80121a09c4SJose Roman       case 'F':
81145505e7SDominic Meiser         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%F format is no longer supported, use %%f and cast the argument to double");
82121a09c4SJose Roman         break;
837bc47156SJose Roman       default:
847bc47156SJose Roman         newformat[j++] = format[i];
857bc47156SJose Roman         break;
867bc47156SJose Roman       }
877bc47156SJose Roman       i++;
88a297a907SKarl Rupp     } else newformat[j++] = format[i++];
89e5c89e4eSSatish Balay   }
90e5c89e4eSSatish Balay   newformat[j] = 0;
91eed5747fSBarry Smith   PetscFunctionReturn(0);
92e5c89e4eSSatish Balay }
93e5c89e4eSSatish Balay 
94e5c89e4eSSatish Balay #undef __FUNCT__
95e5c89e4eSSatish Balay #define __FUNCT__ "PetscVSNPrintf"
96c9a19010SBarry Smith /*@C
97c9a19010SBarry Smith      PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the
98c9a19010SBarry Smith        function arguments into a string using the format statement.
99c9a19010SBarry Smith 
100c9a19010SBarry Smith    Input Parameters:
101c9a19010SBarry Smith +   str - location to put result
102c9a19010SBarry Smith .   len - the amount of space in str
103c9a19010SBarry Smith +   format - the PETSc format string
104c9a19010SBarry Smith -   fullLength - the amount of space in str actually used.
105c9a19010SBarry Smith 
106eed5747fSBarry Smith     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
107eed5747fSBarry Smith       a recursion will occur and possible crash.
108c9a19010SBarry Smith 
109c9a19010SBarry Smith  Level: developer
110c9a19010SBarry Smith 
111c9a19010SBarry Smith @*/
1127087cfbeSBarry Smith PetscErrorCode  PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp)
113e5c89e4eSSatish Balay {
114e2135aedSMatthew Knepley   char           *newformat;
115e2135aedSMatthew Knepley   char           formatbuf[8*1024];
1161a96acb8SJed Brown   size_t         oldLength,length;
1171a15ef5dSMatthew Knepley   PetscErrorCode ierr;
118e5c89e4eSSatish Balay 
119eed5747fSBarry Smith   PetscFunctionBegin;
120e2135aedSMatthew Knepley   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
121e2135aedSMatthew Knepley   if (oldLength < 8*1024) {
122e2135aedSMatthew Knepley     newformat = formatbuf;
123354e5084SJose Roman     oldLength = 8*1024-1;
124e2135aedSMatthew Knepley   } else {
125354e5084SJose Roman     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
126785e854fSJed Brown     ierr      = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr);
127e2135aedSMatthew Knepley   }
128e298bee8SBarry Smith   ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr);
1291a15ef5dSMatthew Knepley   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
1302d609e63SMatthew Knepley #if 0
131a297a907SKarl Rupp   if (length > len) newformat[len] = '\0';
1322d609e63SMatthew Knepley #endif
1335a058713SBarry Smith #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
134748e1b9dSBarry Smith   (void) vsnprintf(str,len,newformat,(char*)Argp);
13589b07760SSatish Balay #elif defined(PETSC_HAVE_VSNPRINTF)
136748e1b9dSBarry Smith   (void) vsnprintf(str,len,newformat,Argp);
137141c0d65SSatish Balay #elif defined(PETSC_HAVE__VSNPRINTF)
138748e1b9dSBarry Smith   (void) _vsnprintf(str,len,newformat,Argp);
139e5c89e4eSSatish Balay #else
14089b07760SSatish Balay #error "vsnprintf not found"
141e5c89e4eSSatish Balay #endif
142e2135aedSMatthew Knepley   if (oldLength >= 8*1024) {
143e2135aedSMatthew Knepley     ierr = PetscFree(newformat);CHKERRQ(ierr);
144e2135aedSMatthew Knepley   }
1458627564fSBarry Smith   {
1468627564fSBarry Smith     PetscBool foundedot;
1478627564fSBarry Smith     size_t cnt = 0,ncnt = 0,leng;
1488627564fSBarry Smith     ierr = PetscStrlen(str,&leng);CHKERRQ(ierr);
14917ca8410SBarry Smith     if (leng > 4) {
1508627564fSBarry Smith       for (cnt=0; cnt<leng-4; cnt++) {
1518627564fSBarry Smith         if (str[cnt] == '[' && str[cnt+1] == '|'){
1528627564fSBarry Smith            cnt++; cnt++;
1538627564fSBarry Smith            foundedot = PETSC_FALSE;
1548627564fSBarry Smith            for (; cnt<leng-1; cnt++) {
1558627564fSBarry Smith              if (str[cnt] == '|' && str[cnt+1] == ']'){
1568627564fSBarry Smith                cnt++;
1578627564fSBarry Smith                if (!foundedot) str[ncnt++] = '.';
1588627564fSBarry Smith                ncnt--;
1598627564fSBarry Smith                break;
1608627564fSBarry Smith              } else {
1618627564fSBarry Smith                if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE;
1628627564fSBarry Smith                str[ncnt++] = str[cnt];
1638627564fSBarry Smith              }
1648627564fSBarry Smith            }
1658627564fSBarry Smith         } else {
1668627564fSBarry Smith           str[ncnt] = str[cnt];
1678627564fSBarry Smith         }
1688627564fSBarry Smith         ncnt++;
1698627564fSBarry Smith       }
1708627564fSBarry Smith       while (cnt < leng) {
1718627564fSBarry Smith         str[ncnt] = str[cnt]; ncnt++; cnt++;
1728627564fSBarry Smith       }
1738627564fSBarry Smith       str[ncnt] = 0;
1748627564fSBarry Smith     }
1758627564fSBarry Smith   }
176748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
177e51f71cfSBarry Smith   /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */
178748e1b9dSBarry Smith   {
179748e1b9dSBarry Smith     size_t cnt = 0,ncnt = 0,leng;
180748e1b9dSBarry Smith     ierr = PetscStrlen(str,&leng);CHKERRQ(ierr);
181748e1b9dSBarry Smith     if (leng > 5) {
182748e1b9dSBarry Smith       for (cnt=0; cnt<leng-4; cnt++) {
183e51f71cfSBarry Smith         if (str[cnt] == 'e' && (str[cnt+1] == '-' || str[cnt+1] == '+') && str[cnt+2] == '0'  && str[cnt+3] >= '0' && str[cnt+3] <= '9' && str[cnt+4] >= '0' && str[cnt+4] <= '9') {
184748e1b9dSBarry Smith           str[ncnt] = str[cnt]; ncnt++; cnt++;
185e51f71cfSBarry Smith           str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++;
186e51f71cfSBarry Smith           str[ncnt] = str[cnt];
187748e1b9dSBarry Smith         } else {
188748e1b9dSBarry Smith           str[ncnt] = str[cnt];
189748e1b9dSBarry Smith         }
190748e1b9dSBarry Smith         ncnt++;
191748e1b9dSBarry Smith       }
192748e1b9dSBarry Smith       while (cnt < leng) {
193748e1b9dSBarry Smith         str[ncnt] = str[cnt]; ncnt++; cnt++;
194748e1b9dSBarry Smith       }
195748e1b9dSBarry Smith       str[ncnt] = 0;
196748e1b9dSBarry Smith     }
197748e1b9dSBarry Smith   }
198748e1b9dSBarry Smith #endif
199748e1b9dSBarry Smith   if (fullLength) {
200748e1b9dSBarry Smith     ierr = PetscStrlen(str,fullLength);CHKERRQ(ierr);
201748e1b9dSBarry Smith   }
202eed5747fSBarry Smith   PetscFunctionReturn(0);
203e5c89e4eSSatish Balay }
204e5c89e4eSSatish Balay 
205e5c89e4eSSatish Balay #undef __FUNCT__
206c9a19010SBarry Smith #define __FUNCT__ "PetscVFPrintfDefault"
207c9a19010SBarry Smith /*@C
208c9a19010SBarry Smith      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
209e5c89e4eSSatish Balay         can be replaced with something that does not simply write to a file.
210e5c89e4eSSatish Balay 
211c9a19010SBarry Smith       To use, write your own function for example,
212c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
213c9a19010SBarry Smith ${
214c9a19010SBarry Smith $  PetscErrorCode ierr;
215c9a19010SBarry Smith $
216c9a19010SBarry Smith $  PetscFunctionBegin;
217c9a19010SBarry Smith $   if (fd != stdout && fd != stderr) {  handle regular files
218c9a19010SBarry Smith $      ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr);
219c9a19010SBarry Smith $  } else {
220c9a19010SBarry Smith $     char   buff[BIG];
221c9a19010SBarry Smith $     size_t length;
222c9a19010SBarry Smith $     ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr);
223c9a19010SBarry Smith $     now send buff to whatever stream or whatever you want
224c9a19010SBarry Smith $ }
225c9a19010SBarry Smith $ PetscFunctionReturn(0);
226c9a19010SBarry Smith $}
227c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
228c9a19010SBarry Smith $    PetscVFPrintf = mypetscvfprintf;
229c9a19010SBarry Smith 
230c9a19010SBarry Smith       Notes: For error messages this may be called by any process, for regular standard out it is
231e5c89e4eSSatish Balay           called only by process 0 of a given communicator
232e5c89e4eSSatish Balay 
233eed5747fSBarry Smith       Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur
234eed5747fSBarry Smith                        and a crash
235c9a19010SBarry Smith 
236c9a19010SBarry Smith   Level:  developer
237c9a19010SBarry Smith 
238c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf()
239c9a19010SBarry Smith 
240c9a19010SBarry Smith @*/
2417087cfbeSBarry Smith PetscErrorCode  PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
242e5c89e4eSSatish Balay {
243748e1b9dSBarry Smith   char           str[8*1024];
244eed5747fSBarry Smith   PetscErrorCode ierr;
2451179db26SBarry Smith 
246eed5747fSBarry Smith   PetscFunctionBegin;
247748e1b9dSBarry Smith   ierr = PetscVSNPrintf(str,sizeof(str),format,NULL,Argp);CHKERRQ(ierr);
248748e1b9dSBarry Smith   fprintf(fd,"%s",str);CHKERRQ(ierr);
2495a058713SBarry Smith   fflush(fd);
250eed5747fSBarry Smith   PetscFunctionReturn(0);
251e5c89e4eSSatish Balay }
252e5c89e4eSSatish Balay 
2535b5bc046SBarry Smith #undef __FUNCT__
2545b5bc046SBarry Smith #define __FUNCT__ "PetscSNPrintf"
2555b5bc046SBarry Smith /*@C
2565b5bc046SBarry Smith     PetscSNPrintf - Prints to a string of given length
2575b5bc046SBarry Smith 
2585b5bc046SBarry Smith     Not Collective
2595b5bc046SBarry Smith 
2605b5bc046SBarry Smith     Input Parameters:
2615b5bc046SBarry Smith +   str - the string to print to
2625b5bc046SBarry Smith .   len - the length of str
2635b5bc046SBarry Smith .   format - the usual printf() format string
2645b5bc046SBarry Smith -   any arguments
2655b5bc046SBarry Smith 
2665b5bc046SBarry Smith    Level: intermediate
2675b5bc046SBarry Smith 
2685b5bc046SBarry Smith .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
2695b5bc046SBarry Smith           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
2705b5bc046SBarry Smith @*/
2717087cfbeSBarry Smith PetscErrorCode  PetscSNPrintf(char *str,size_t len,const char format[],...)
2725b5bc046SBarry Smith {
2735b5bc046SBarry Smith   PetscErrorCode ierr;
274c9a19010SBarry Smith   size_t         fullLength;
2755b5bc046SBarry Smith   va_list        Argp;
2765b5bc046SBarry Smith 
2775b5bc046SBarry Smith   PetscFunctionBegin;
2785b5bc046SBarry Smith   va_start(Argp,format);
2792d609e63SMatthew Knepley   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
2805b5bc046SBarry Smith   PetscFunctionReturn(0);
2815b5bc046SBarry Smith }
2825b5bc046SBarry Smith 
283257d2499SJed Brown #undef __FUNCT__
284257d2499SJed Brown #define __FUNCT__ "PetscSNPrintfCount"
285257d2499SJed Brown /*@C
286257d2499SJed Brown     PetscSNPrintfCount - Prints to a string of given length, returns count
287257d2499SJed Brown 
288257d2499SJed Brown     Not Collective
289257d2499SJed Brown 
290257d2499SJed Brown     Input Parameters:
291257d2499SJed Brown +   str - the string to print to
292257d2499SJed Brown .   len - the length of str
293257d2499SJed Brown .   format - the usual printf() format string
294257d2499SJed Brown .   countused - number of characters used
295257d2499SJed Brown -   any arguments
296257d2499SJed Brown 
297257d2499SJed Brown    Level: intermediate
298257d2499SJed Brown 
299257d2499SJed Brown .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
300257d2499SJed Brown           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf()
301257d2499SJed Brown @*/
302257d2499SJed Brown PetscErrorCode  PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...)
303257d2499SJed Brown {
304257d2499SJed Brown   PetscErrorCode ierr;
305257d2499SJed Brown   va_list        Argp;
306257d2499SJed Brown 
307257d2499SJed Brown   PetscFunctionBegin;
308257d2499SJed Brown   va_start(Argp,countused);
309257d2499SJed Brown   ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr);
310257d2499SJed Brown   PetscFunctionReturn(0);
311257d2499SJed Brown }
312257d2499SJed Brown 
313e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */
314e5c89e4eSSatish Balay 
315d30b0576SJed Brown PrintfQueue petsc_printfqueue       = 0,petsc_printfqueuebase = 0;
316d30b0576SJed Brown int         petsc_printfqueuelength = 0;
317e5c89e4eSSatish Balay 
318e5c89e4eSSatish Balay #undef __FUNCT__
319e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedPrintf"
320e5c89e4eSSatish Balay /*@C
321e5c89e4eSSatish Balay     PetscSynchronizedPrintf - Prints synchronized output from several processors.
322e5c89e4eSSatish Balay     Output of the first processor is followed by that of the second, etc.
323e5c89e4eSSatish Balay 
324e5c89e4eSSatish Balay     Not Collective
325e5c89e4eSSatish Balay 
326e5c89e4eSSatish Balay     Input Parameters:
327e5c89e4eSSatish Balay +   comm - the communicator
328e5c89e4eSSatish Balay -   format - the usual printf() format string
329e5c89e4eSSatish Balay 
330e5c89e4eSSatish Balay    Level: intermediate
331e5c89e4eSSatish Balay 
332e5c89e4eSSatish Balay     Notes:
333*7889ec69SBarry Smith     REQUIRES a call to PetscSynchronizedFlush() by all the processes after the completion of the calls to PetscSynchronizedPrintf() for the information
334e5c89e4eSSatish Balay     from all the processors to be printed.
335e5c89e4eSSatish Balay 
336e5c89e4eSSatish Balay     Fortran Note:
337d60d70ccSBarry Smith     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
338e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
339e5c89e4eSSatish Balay 
340e5c89e4eSSatish Balay .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
341e5c89e4eSSatish Balay           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
342e5c89e4eSSatish Balay @*/
3437087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
344e5c89e4eSSatish Balay {
345e5c89e4eSSatish Balay   PetscErrorCode ierr;
346e5c89e4eSSatish Balay   PetscMPIInt    rank;
347e5c89e4eSSatish Balay 
348e5c89e4eSSatish Balay   PetscFunctionBegin;
3496180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
350e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
351e5c89e4eSSatish Balay 
352e5c89e4eSSatish Balay   /* First processor prints immediately to stdout */
353e5c89e4eSSatish Balay   if (!rank) {
354e5c89e4eSSatish Balay     va_list Argp;
355e5c89e4eSSatish Balay     va_start(Argp,format);
3561179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
357e5c89e4eSSatish Balay     if (petsc_history) {
358cdc7d174SSatish Balay       va_start(Argp,format);
3591179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
360e5c89e4eSSatish Balay     }
361e5c89e4eSSatish Balay     va_end(Argp);
362e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
363e5c89e4eSSatish Balay     va_list     Argp;
364e5c89e4eSSatish Balay     PrintfQueue next;
365c9a19010SBarry Smith     size_t      fullLength = 8191;
366e5c89e4eSSatish Balay 
367b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
368a297a907SKarl Rupp     if (petsc_printfqueue) {
369a297a907SKarl Rupp       petsc_printfqueue->next = next;
370a297a907SKarl Rupp       petsc_printfqueue       = next;
371a297a907SKarl Rupp       petsc_printfqueue->next = 0;
372a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
373d30b0576SJed Brown     petsc_printfqueuelength++;
3742d609e63SMatthew Knepley     next->size = -1;
3759ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
3762d609e63SMatthew Knepley       next->size = fullLength+1;
377a297a907SKarl Rupp 
378785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
379e5c89e4eSSatish Balay       va_start(Argp,format);
3802d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
3812d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
382e5c89e4eSSatish Balay       va_end(Argp);
383e5c89e4eSSatish Balay     }
3842d609e63SMatthew Knepley   }
385e5c89e4eSSatish Balay   PetscFunctionReturn(0);
386e5c89e4eSSatish Balay }
387e5c89e4eSSatish Balay 
388e5c89e4eSSatish Balay #undef __FUNCT__
389e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFPrintf"
390e5c89e4eSSatish Balay /*@C
391e5c89e4eSSatish Balay     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
392e5c89e4eSSatish Balay     several processors.  Output of the first processor is followed by that of the
393e5c89e4eSSatish Balay     second, etc.
394e5c89e4eSSatish Balay 
395e5c89e4eSSatish Balay     Not Collective
396e5c89e4eSSatish Balay 
397e5c89e4eSSatish Balay     Input Parameters:
398e5c89e4eSSatish Balay +   comm - the communicator
399e5c89e4eSSatish Balay .   fd - the file pointer
400e5c89e4eSSatish Balay -   format - the usual printf() format string
401e5c89e4eSSatish Balay 
402e5c89e4eSSatish Balay     Level: intermediate
403e5c89e4eSSatish Balay 
404e5c89e4eSSatish Balay     Notes:
405e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
406e5c89e4eSSatish Balay     from all the processors to be printed.
407e5c89e4eSSatish Balay 
408e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
409e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
410e5c89e4eSSatish Balay 
411e5c89e4eSSatish Balay @*/
4127087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...)
413e5c89e4eSSatish Balay {
414e5c89e4eSSatish Balay   PetscErrorCode ierr;
415e5c89e4eSSatish Balay   PetscMPIInt    rank;
416e5c89e4eSSatish Balay 
417e5c89e4eSSatish Balay   PetscFunctionBegin;
4186180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
419e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
420e5c89e4eSSatish Balay 
421e5c89e4eSSatish Balay   /* First processor prints immediately to fp */
422e5c89e4eSSatish Balay   if (!rank) {
423e5c89e4eSSatish Balay     va_list Argp;
424e5c89e4eSSatish Balay     va_start(Argp,format);
4251179db26SBarry Smith     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
426cdc7d174SSatish Balay     if (petsc_history && (fp !=petsc_history)) {
427cdc7d174SSatish Balay       va_start(Argp,format);
4281179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
429e5c89e4eSSatish Balay     }
430e5c89e4eSSatish Balay     va_end(Argp);
431e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
432e5c89e4eSSatish Balay     va_list     Argp;
433e5c89e4eSSatish Balay     PrintfQueue next;
434c9a19010SBarry Smith     size_t      fullLength = 8191;
435b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
436a297a907SKarl Rupp     if (petsc_printfqueue) {
437a297a907SKarl Rupp       petsc_printfqueue->next = next;
438a297a907SKarl Rupp       petsc_printfqueue       = next;
439a297a907SKarl Rupp       petsc_printfqueue->next = 0;
440a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
441d30b0576SJed Brown     petsc_printfqueuelength++;
4422d609e63SMatthew Knepley     next->size = -1;
4439ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
4442d609e63SMatthew Knepley       next->size = fullLength+1;
445785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
446e5c89e4eSSatish Balay       va_start(Argp,format);
4472d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
4482d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
449e5c89e4eSSatish Balay       va_end(Argp);
450e5c89e4eSSatish Balay     }
4512d609e63SMatthew Knepley   }
452e5c89e4eSSatish Balay   PetscFunctionReturn(0);
453e5c89e4eSSatish Balay }
454e5c89e4eSSatish Balay 
455e5c89e4eSSatish Balay #undef __FUNCT__
456e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFlush"
4570ec8b6e3SBarry Smith /*@C
458e5c89e4eSSatish Balay     PetscSynchronizedFlush - Flushes to the screen output from all processors
459*7889ec69SBarry Smith     involved in previous PetscSynchronizedPrintf()/PetscSynchronizedFPrintf() calls.
460e5c89e4eSSatish Balay 
461e5c89e4eSSatish Balay     Collective on MPI_Comm
462e5c89e4eSSatish Balay 
463e5c89e4eSSatish Balay     Input Parameters:
4640ec8b6e3SBarry Smith +   comm - the communicator
4650ec8b6e3SBarry Smith -   fd - the file pointer (valid on process 0 of the communicator)
466e5c89e4eSSatish Balay 
467e5c89e4eSSatish Balay     Level: intermediate
468e5c89e4eSSatish Balay 
469e5c89e4eSSatish Balay     Notes:
470*7889ec69SBarry Smith     If PetscSynchronizedPrintf() and/or PetscSynchronizedFPrintf() are called with
471*7889ec69SBarry Smith     different MPI communicators there must be an intervening call to PetscSynchronizedFlush() between the calls with different MPI communicators.
472e5c89e4eSSatish Balay 
473e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
474e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf()
4750087d953SMatthew G. Knepley @*/
4760ec8b6e3SBarry Smith PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm,FILE *fd)
477e5c89e4eSSatish Balay {
478e5c89e4eSSatish Balay   PetscErrorCode ierr;
47929a5cbdcSMatthew G. Knepley   PetscMPIInt    rank,size,tag,i,j,n = 0,dummy = 0;
4802d609e63SMatthew Knepley   char          *message;
481e5c89e4eSSatish Balay   MPI_Status     status;
482e5c89e4eSSatish Balay 
483e5c89e4eSSatish Balay   PetscFunctionBegin;
484e5c89e4eSSatish Balay   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
485e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
486e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
487e5c89e4eSSatish Balay 
488e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
489e5c89e4eSSatish Balay   if (!rank) {
4900ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
491e5c89e4eSSatish Balay     for (i=1; i<size; i++) {
4929f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
4939f73f8ecSBarry Smith       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
494e5c89e4eSSatish Balay       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
495e5c89e4eSSatish Balay       for (j=0; j<n; j++) {
49629a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
4972d609e63SMatthew Knepley 
4982d609e63SMatthew Knepley         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
499785e854fSJed Brown         ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
5002d609e63SMatthew Knepley         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
5013bf036e2SBarry Smith         ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
5022d609e63SMatthew Knepley         ierr = PetscFree(message);CHKERRQ(ierr);
503e5c89e4eSSatish Balay       }
504e5c89e4eSSatish Balay     }
505e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
506d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase,previous;
507e5c89e4eSSatish Balay 
508b3ef9d35SBarry Smith     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
509d30b0576SJed Brown     ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
510d30b0576SJed Brown     for (i=0; i<petsc_printfqueuelength; i++) {
5112d609e63SMatthew Knepley       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
5122d609e63SMatthew Knepley       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
513e5c89e4eSSatish Balay       previous = next;
514e5c89e4eSSatish Balay       next     = next->next;
5152d609e63SMatthew Knepley       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
516e5c89e4eSSatish Balay       ierr     = PetscFree(previous);CHKERRQ(ierr);
517e5c89e4eSSatish Balay     }
518d30b0576SJed Brown     petsc_printfqueue       = 0;
519d30b0576SJed Brown     petsc_printfqueuelength = 0;
520e5c89e4eSSatish Balay   }
521e5c89e4eSSatish Balay   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
522e5c89e4eSSatish Balay   PetscFunctionReturn(0);
523e5c89e4eSSatish Balay }
524e5c89e4eSSatish Balay 
525e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
526e5c89e4eSSatish Balay 
527e5c89e4eSSatish Balay #undef __FUNCT__
528e5c89e4eSSatish Balay #define __FUNCT__ "PetscFPrintf"
529e5c89e4eSSatish Balay /*@C
530e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
531e5c89e4eSSatish Balay     processor in the communicator.
532e5c89e4eSSatish Balay 
533e5c89e4eSSatish Balay     Not Collective
534e5c89e4eSSatish Balay 
535e5c89e4eSSatish Balay     Input Parameters:
536e5c89e4eSSatish Balay +   comm - the communicator
537e5c89e4eSSatish Balay .   fd - the file pointer
538e5c89e4eSSatish Balay -   format - the usual printf() format string
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay     Level: intermediate
541e5c89e4eSSatish Balay 
542e5c89e4eSSatish Balay     Fortran Note:
543e5c89e4eSSatish Balay     This routine is not supported in Fortran.
544e5c89e4eSSatish Balay 
545e5c89e4eSSatish Balay    Concepts: printing^in parallel
546e5c89e4eSSatish Balay    Concepts: printf^in parallel
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
549e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
550e5c89e4eSSatish Balay @*/
5517087cfbeSBarry Smith PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
552e5c89e4eSSatish Balay {
553e5c89e4eSSatish Balay   PetscErrorCode ierr;
554e5c89e4eSSatish Balay   PetscMPIInt    rank;
555e5c89e4eSSatish Balay 
556e5c89e4eSSatish Balay   PetscFunctionBegin;
5576180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
558e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
559e5c89e4eSSatish Balay   if (!rank) {
560e5c89e4eSSatish Balay     va_list Argp;
561e5c89e4eSSatish Balay     va_start(Argp,format);
5621179db26SBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
563cdc7d174SSatish Balay     if (petsc_history && (fd !=petsc_history)) {
564cdc7d174SSatish Balay       va_start(Argp,format);
5651179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
566e5c89e4eSSatish Balay     }
567e5c89e4eSSatish Balay     va_end(Argp);
568e5c89e4eSSatish Balay   }
569e5c89e4eSSatish Balay   PetscFunctionReturn(0);
570e5c89e4eSSatish Balay }
571e5c89e4eSSatish Balay 
572e5c89e4eSSatish Balay #undef __FUNCT__
573e5c89e4eSSatish Balay #define __FUNCT__ "PetscPrintf"
574e5c89e4eSSatish Balay /*@C
575e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
576eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
577e5c89e4eSSatish Balay 
578e5c89e4eSSatish Balay     Not Collective
579e5c89e4eSSatish Balay 
580e5c89e4eSSatish Balay     Input Parameters:
581e5c89e4eSSatish Balay +   comm - the communicator
582e5c89e4eSSatish Balay -   format - the usual printf() format string
583e5c89e4eSSatish Balay 
584e5c89e4eSSatish Balay    Level: intermediate
585e5c89e4eSSatish Balay 
586e5c89e4eSSatish Balay     Fortran Note:
587d60d70ccSBarry Smith     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
588e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
589e5c89e4eSSatish Balay 
590e5c89e4eSSatish Balay    Concepts: printing^in parallel
591e5c89e4eSSatish Balay    Concepts: printf^in parallel
592e5c89e4eSSatish Balay 
593e5c89e4eSSatish Balay .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
594e5c89e4eSSatish Balay @*/
5957087cfbeSBarry Smith PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
596e5c89e4eSSatish Balay {
597e5c89e4eSSatish Balay   PetscErrorCode ierr;
598e5c89e4eSSatish Balay   PetscMPIInt    rank;
599e5c89e4eSSatish Balay 
600e5c89e4eSSatish Balay   PetscFunctionBegin;
6016180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
602e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
603e5c89e4eSSatish Balay   if (!rank) {
604e5c89e4eSSatish Balay     va_list Argp;
605e5c89e4eSSatish Balay     va_start(Argp,format);
606eed5747fSBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
607e5c89e4eSSatish Balay     if (petsc_history) {
608cdc7d174SSatish Balay       va_start(Argp,format);
609eed5747fSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
610e5c89e4eSSatish Balay     }
611e5c89e4eSSatish Balay     va_end(Argp);
612e5c89e4eSSatish Balay   }
613e5c89e4eSSatish Balay   PetscFunctionReturn(0);
614e5c89e4eSSatish Balay }
615e5c89e4eSSatish Balay 
616e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
617e5c89e4eSSatish Balay #undef __FUNCT__
618e5c89e4eSSatish Balay #define __FUNCT__ "PetscHelpPrintfDefault"
619c9a19010SBarry Smith /*@C
620c9a19010SBarry Smith      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
621c9a19010SBarry Smith         replacinng it  with something that does not simply write to a stdout.
622c9a19010SBarry Smith 
623c9a19010SBarry Smith       To use, write your own function for example,
624c9a19010SBarry Smith $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
625c9a19010SBarry Smith ${
626c9a19010SBarry Smith $ PetscFunctionReturn(0);
627c9a19010SBarry Smith $}
628c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
629c9a19010SBarry Smith $    PetscHelpPrintf = mypetschelpprintf;
630c9a19010SBarry Smith 
631c9a19010SBarry Smith   Note: the default routine used is called PetscHelpPrintfDefault().
632c9a19010SBarry Smith 
633c9a19010SBarry Smith   Level:  developer
634c9a19010SBarry Smith 
635c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
636c9a19010SBarry Smith @*/
6377087cfbeSBarry Smith PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
638e5c89e4eSSatish Balay {
639e5c89e4eSSatish Balay   PetscErrorCode ierr;
640e5c89e4eSSatish Balay   PetscMPIInt    rank;
641e5c89e4eSSatish Balay 
642e5c89e4eSSatish Balay   PetscFunctionBegin;
6436180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
644e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
645e5c89e4eSSatish Balay   if (!rank) {
646e5c89e4eSSatish Balay     va_list Argp;
647e5c89e4eSSatish Balay     va_start(Argp,format);
6481179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
649e5c89e4eSSatish Balay     if (petsc_history) {
650cdc7d174SSatish Balay       va_start(Argp,format);
6511179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
652e5c89e4eSSatish Balay     }
653e5c89e4eSSatish Balay     va_end(Argp);
654e5c89e4eSSatish Balay   }
655e5c89e4eSSatish Balay   PetscFunctionReturn(0);
656e5c89e4eSSatish Balay }
657e5c89e4eSSatish Balay 
658e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
659e5c89e4eSSatish Balay 
660e5c89e4eSSatish Balay 
661e5c89e4eSSatish Balay #undef __FUNCT__
662e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFGets"
663e5c89e4eSSatish Balay /*@C
664e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
665e5c89e4eSSatish Balay 
666e5c89e4eSSatish Balay     Collective on MPI_Comm
667e5c89e4eSSatish Balay 
668e5c89e4eSSatish Balay     Input Parameters:
669e5c89e4eSSatish Balay +   comm - the communicator
670e5c89e4eSSatish Balay .   fd - the file pointer
671e5c89e4eSSatish Balay -   len - the length of the output buffer
672e5c89e4eSSatish Balay 
673e5c89e4eSSatish Balay     Output Parameter:
674e31d4fa4SJed Brown .   string - the line read from the file, at end of file string[0] == 0
675e5c89e4eSSatish Balay 
676e5c89e4eSSatish Balay     Level: intermediate
677e5c89e4eSSatish Balay 
678e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
679e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
680e5c89e4eSSatish Balay 
681e5c89e4eSSatish Balay @*/
6827087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[])
683e5c89e4eSSatish Balay {
684e5c89e4eSSatish Balay   PetscErrorCode ierr;
685e5c89e4eSSatish Balay   PetscMPIInt    rank;
686e5c89e4eSSatish Balay 
687e5c89e4eSSatish Balay   PetscFunctionBegin;
688e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
689e5c89e4eSSatish Balay 
690e5c89e4eSSatish Balay   if (!rank) {
691047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
692047b9c12SMatthew G Knepley 
693047b9c12SMatthew G Knepley     if (!ptr) {
694e31d4fa4SJed Brown       string[0] = 0;
695e31d4fa4SJed Brown       if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
696047b9c12SMatthew G Knepley     }
697e5c89e4eSSatish Balay   }
698e5c89e4eSSatish Balay   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
699e5c89e4eSSatish Balay   PetscFunctionReturn(0);
700e5c89e4eSSatish Balay }
701238ccf28SShri Abhyankar 
702f1d7fe2eSBarry Smith #if defined(PETSC_HAVE_CLOSURES)
703f1d7fe2eSBarry Smith int (^SwiftClosure)(const char*) = 0;
704f1d7fe2eSBarry Smith 
705f1d7fe2eSBarry Smith #undef __FUNCT__
706f1d7fe2eSBarry Smith #define __FUNCT__ "PetscVFPrintfToString"
707f1d7fe2eSBarry Smith PetscErrorCode  PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp)
708f1d7fe2eSBarry Smith {
709f1d7fe2eSBarry Smith   PetscErrorCode ierr;
710f1d7fe2eSBarry Smith 
711f1d7fe2eSBarry Smith   PetscFunctionBegin;
712f1d7fe2eSBarry Smith   if (fd != stdout && fd != stderr) { /* handle regular files */
713f1d7fe2eSBarry Smith     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
714f1d7fe2eSBarry Smith   } else {
715f1d7fe2eSBarry Smith     size_t len=8*1024,length;
716f1d7fe2eSBarry Smith     char   buf[len];
717f1d7fe2eSBarry Smith 
718f1d7fe2eSBarry Smith     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
719f1d7fe2eSBarry Smith     ierr = SwiftClosure(buf);CHKERRQ(ierr);
720f1d7fe2eSBarry Smith   }
721f1d7fe2eSBarry Smith   PetscFunctionReturn(0);
722f1d7fe2eSBarry Smith }
723f1d7fe2eSBarry Smith 
724f1d7fe2eSBarry Smith /*
725f1d7fe2eSBarry Smith    Provide a Swift function that processes all the PETSc calls to PetscVFPrintf()
726f1d7fe2eSBarry Smith */
727f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*))
728f1d7fe2eSBarry Smith {
729f1d7fe2eSBarry Smith   PetscVFPrintf = PetscVFPrintfToString;
730f1d7fe2eSBarry Smith   SwiftClosure  = closure;
731f1d7fe2eSBarry Smith   return 0;
732f1d7fe2eSBarry Smith }
733f1d7fe2eSBarry Smith #endif
734f1d7fe2eSBarry Smith 
735238ccf28SShri Abhyankar #if defined(PETSC_HAVE_MATLAB_ENGINE)
736c6db04a5SJed Brown #include <mex.h>
737238ccf28SShri Abhyankar #undef __FUNCT__
738238ccf28SShri Abhyankar #define __FUNCT__ "PetscVFPrintf_Matlab"
7397087cfbeSBarry Smith PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
740238ccf28SShri Abhyankar {
741238ccf28SShri Abhyankar   PetscErrorCode ierr;
742238ccf28SShri Abhyankar 
743238ccf28SShri Abhyankar   PetscFunctionBegin;
744238ccf28SShri Abhyankar   if (fd != stdout && fd != stderr) { /* handle regular files */
745238ccf28SShri Abhyankar     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
746238ccf28SShri Abhyankar   } else {
747238ccf28SShri Abhyankar     size_t len=8*1024,length;
748238ccf28SShri Abhyankar     char   buf[len];
749238ccf28SShri Abhyankar 
750238ccf28SShri Abhyankar     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
751df413903SBarry Smith     mexPrintf("%s",buf);
752238ccf28SShri Abhyankar   }
753238ccf28SShri Abhyankar   PetscFunctionReturn(0);
754238ccf28SShri Abhyankar }
755238ccf28SShri Abhyankar #endif
7566fc7ef2bSBarry Smith 
7576fc7ef2bSBarry Smith #undef __FUNCT__
7588c74ee41SBarry Smith #define __FUNCT__ "PetscFormatStrip"
7598c74ee41SBarry Smith /*@C
7608c74ee41SBarry Smith      PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations
7618c74ee41SBarry Smith 
7628c74ee41SBarry Smith    Input Parameters:
7638c74ee41SBarry Smith .   format - the PETSc format string
7648c74ee41SBarry Smith 
7658c74ee41SBarry Smith  Level: developer
7668c74ee41SBarry Smith 
7678c74ee41SBarry Smith @*/
7688c74ee41SBarry Smith PetscErrorCode  PetscFormatStrip(char *format)
7698c74ee41SBarry Smith {
7708c74ee41SBarry Smith   size_t loc1 = 0, loc2 = 0;
7718c74ee41SBarry Smith 
7728c74ee41SBarry Smith   PetscFunctionBegin;
7738c74ee41SBarry Smith   while (format[loc2]) {
7748c74ee41SBarry Smith     if (format[loc2] == '%') {
7758c74ee41SBarry Smith       format[loc1++] = format[loc2++];
7768c74ee41SBarry Smith       while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++;
7778c74ee41SBarry Smith     }
7788c74ee41SBarry Smith     format[loc1++] = format[loc2++];
7798c74ee41SBarry Smith   }
7808c74ee41SBarry Smith   PetscFunctionReturn(0);
7818c74ee41SBarry Smith }
7828c74ee41SBarry Smith 
783