xref: /petsc/src/sys/fileio/mprint.c (revision e50bf69f477f28ccc72e51fa782d363e35a4cda3)
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:
3337889ec69SBarry 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
4597889ec69SBarry 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:
4707889ec69SBarry Smith     If PetscSynchronizedPrintf() and/or PetscSynchronizedFPrintf() are called with
4717889ec69SBarry Smith     different MPI communicators there must be an intervening call to PetscSynchronizedFlush() between the calls with different MPI communicators.
472e5c89e4eSSatish Balay 
473*e50bf69fSBarry Smith     From Fortran pass PETSC_STDOUT if the flush is for standard out; otherwise pass a value obtained from PetscFOpen()
474*e50bf69fSBarry Smith 
475e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
476e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf()
4770087d953SMatthew G. Knepley @*/
4780ec8b6e3SBarry Smith PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm,FILE *fd)
479e5c89e4eSSatish Balay {
480e5c89e4eSSatish Balay   PetscErrorCode ierr;
48129a5cbdcSMatthew G. Knepley   PetscMPIInt    rank,size,tag,i,j,n = 0,dummy = 0;
4822d609e63SMatthew Knepley   char          *message;
483e5c89e4eSSatish Balay   MPI_Status     status;
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay   PetscFunctionBegin;
486e5c89e4eSSatish Balay   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
487e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
488e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
489e5c89e4eSSatish Balay 
490e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
491e5c89e4eSSatish Balay   if (!rank) {
4920ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
493e5c89e4eSSatish Balay     for (i=1; i<size; i++) {
4949f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
4959f73f8ecSBarry Smith       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
496e5c89e4eSSatish Balay       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
497e5c89e4eSSatish Balay       for (j=0; j<n; j++) {
49829a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
4992d609e63SMatthew Knepley 
5002d609e63SMatthew Knepley         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
501785e854fSJed Brown         ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
5022d609e63SMatthew Knepley         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
5033bf036e2SBarry Smith         ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
5042d609e63SMatthew Knepley         ierr = PetscFree(message);CHKERRQ(ierr);
505e5c89e4eSSatish Balay       }
506e5c89e4eSSatish Balay     }
507e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
508d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase,previous;
509e5c89e4eSSatish Balay 
510b3ef9d35SBarry Smith     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
511d30b0576SJed Brown     ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
512d30b0576SJed Brown     for (i=0; i<petsc_printfqueuelength; i++) {
5132d609e63SMatthew Knepley       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
5142d609e63SMatthew Knepley       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
515e5c89e4eSSatish Balay       previous = next;
516e5c89e4eSSatish Balay       next     = next->next;
5172d609e63SMatthew Knepley       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
518e5c89e4eSSatish Balay       ierr     = PetscFree(previous);CHKERRQ(ierr);
519e5c89e4eSSatish Balay     }
520d30b0576SJed Brown     petsc_printfqueue       = 0;
521d30b0576SJed Brown     petsc_printfqueuelength = 0;
522e5c89e4eSSatish Balay   }
523e5c89e4eSSatish Balay   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
524e5c89e4eSSatish Balay   PetscFunctionReturn(0);
525e5c89e4eSSatish Balay }
526e5c89e4eSSatish Balay 
527e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
528e5c89e4eSSatish Balay 
529e5c89e4eSSatish Balay #undef __FUNCT__
530e5c89e4eSSatish Balay #define __FUNCT__ "PetscFPrintf"
531e5c89e4eSSatish Balay /*@C
532e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
533e5c89e4eSSatish Balay     processor in the communicator.
534e5c89e4eSSatish Balay 
535e5c89e4eSSatish Balay     Not Collective
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay     Input Parameters:
538e5c89e4eSSatish Balay +   comm - the communicator
539e5c89e4eSSatish Balay .   fd - the file pointer
540e5c89e4eSSatish Balay -   format - the usual printf() format string
541e5c89e4eSSatish Balay 
542e5c89e4eSSatish Balay     Level: intermediate
543e5c89e4eSSatish Balay 
544e5c89e4eSSatish Balay     Fortran Note:
545e5c89e4eSSatish Balay     This routine is not supported in Fortran.
546e5c89e4eSSatish Balay 
547e5c89e4eSSatish Balay    Concepts: printing^in parallel
548e5c89e4eSSatish Balay    Concepts: printf^in parallel
549e5c89e4eSSatish Balay 
550e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
551e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
552e5c89e4eSSatish Balay @*/
5537087cfbeSBarry Smith PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
554e5c89e4eSSatish Balay {
555e5c89e4eSSatish Balay   PetscErrorCode ierr;
556e5c89e4eSSatish Balay   PetscMPIInt    rank;
557e5c89e4eSSatish Balay 
558e5c89e4eSSatish Balay   PetscFunctionBegin;
5596180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
560e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
561e5c89e4eSSatish Balay   if (!rank) {
562e5c89e4eSSatish Balay     va_list Argp;
563e5c89e4eSSatish Balay     va_start(Argp,format);
5641179db26SBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
565cdc7d174SSatish Balay     if (petsc_history && (fd !=petsc_history)) {
566cdc7d174SSatish Balay       va_start(Argp,format);
5671179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
568e5c89e4eSSatish Balay     }
569e5c89e4eSSatish Balay     va_end(Argp);
570e5c89e4eSSatish Balay   }
571e5c89e4eSSatish Balay   PetscFunctionReturn(0);
572e5c89e4eSSatish Balay }
573e5c89e4eSSatish Balay 
574e5c89e4eSSatish Balay #undef __FUNCT__
575e5c89e4eSSatish Balay #define __FUNCT__ "PetscPrintf"
576e5c89e4eSSatish Balay /*@C
577e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
578eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
579e5c89e4eSSatish Balay 
580e5c89e4eSSatish Balay     Not Collective
581e5c89e4eSSatish Balay 
582e5c89e4eSSatish Balay     Input Parameters:
583e5c89e4eSSatish Balay +   comm - the communicator
584e5c89e4eSSatish Balay -   format - the usual printf() format string
585e5c89e4eSSatish Balay 
586e5c89e4eSSatish Balay    Level: intermediate
587e5c89e4eSSatish Balay 
588e5c89e4eSSatish Balay     Fortran Note:
589d60d70ccSBarry Smith     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
590e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
591e5c89e4eSSatish Balay 
592e5c89e4eSSatish Balay    Concepts: printing^in parallel
593e5c89e4eSSatish Balay    Concepts: printf^in parallel
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
596e5c89e4eSSatish Balay @*/
5977087cfbeSBarry Smith PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
598e5c89e4eSSatish Balay {
599e5c89e4eSSatish Balay   PetscErrorCode ierr;
600e5c89e4eSSatish Balay   PetscMPIInt    rank;
601e5c89e4eSSatish Balay 
602e5c89e4eSSatish Balay   PetscFunctionBegin;
6036180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
604e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
605e5c89e4eSSatish Balay   if (!rank) {
606e5c89e4eSSatish Balay     va_list Argp;
607e5c89e4eSSatish Balay     va_start(Argp,format);
608eed5747fSBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
609e5c89e4eSSatish Balay     if (petsc_history) {
610cdc7d174SSatish Balay       va_start(Argp,format);
611eed5747fSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
612e5c89e4eSSatish Balay     }
613e5c89e4eSSatish Balay     va_end(Argp);
614e5c89e4eSSatish Balay   }
615e5c89e4eSSatish Balay   PetscFunctionReturn(0);
616e5c89e4eSSatish Balay }
617e5c89e4eSSatish Balay 
618e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
619e5c89e4eSSatish Balay #undef __FUNCT__
620e5c89e4eSSatish Balay #define __FUNCT__ "PetscHelpPrintfDefault"
621c9a19010SBarry Smith /*@C
622c9a19010SBarry Smith      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
623c9a19010SBarry Smith         replacinng it  with something that does not simply write to a stdout.
624c9a19010SBarry Smith 
625c9a19010SBarry Smith       To use, write your own function for example,
626c9a19010SBarry Smith $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
627c9a19010SBarry Smith ${
628c9a19010SBarry Smith $ PetscFunctionReturn(0);
629c9a19010SBarry Smith $}
630c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
631c9a19010SBarry Smith $    PetscHelpPrintf = mypetschelpprintf;
632c9a19010SBarry Smith 
633c9a19010SBarry Smith   Note: the default routine used is called PetscHelpPrintfDefault().
634c9a19010SBarry Smith 
635c9a19010SBarry Smith   Level:  developer
636c9a19010SBarry Smith 
637c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
638c9a19010SBarry Smith @*/
6397087cfbeSBarry Smith PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
640e5c89e4eSSatish Balay {
641e5c89e4eSSatish Balay   PetscErrorCode ierr;
642e5c89e4eSSatish Balay   PetscMPIInt    rank;
643e5c89e4eSSatish Balay 
644e5c89e4eSSatish Balay   PetscFunctionBegin;
6456180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
646e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
647e5c89e4eSSatish Balay   if (!rank) {
648e5c89e4eSSatish Balay     va_list Argp;
649e5c89e4eSSatish Balay     va_start(Argp,format);
6501179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
651e5c89e4eSSatish Balay     if (petsc_history) {
652cdc7d174SSatish Balay       va_start(Argp,format);
6531179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
654e5c89e4eSSatish Balay     }
655e5c89e4eSSatish Balay     va_end(Argp);
656e5c89e4eSSatish Balay   }
657e5c89e4eSSatish Balay   PetscFunctionReturn(0);
658e5c89e4eSSatish Balay }
659e5c89e4eSSatish Balay 
660e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
661e5c89e4eSSatish Balay 
662e5c89e4eSSatish Balay 
663e5c89e4eSSatish Balay #undef __FUNCT__
664e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFGets"
665e5c89e4eSSatish Balay /*@C
666e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
667e5c89e4eSSatish Balay 
668e5c89e4eSSatish Balay     Collective on MPI_Comm
669e5c89e4eSSatish Balay 
670e5c89e4eSSatish Balay     Input Parameters:
671e5c89e4eSSatish Balay +   comm - the communicator
672e5c89e4eSSatish Balay .   fd - the file pointer
673e5c89e4eSSatish Balay -   len - the length of the output buffer
674e5c89e4eSSatish Balay 
675e5c89e4eSSatish Balay     Output Parameter:
676e31d4fa4SJed Brown .   string - the line read from the file, at end of file string[0] == 0
677e5c89e4eSSatish Balay 
678e5c89e4eSSatish Balay     Level: intermediate
679e5c89e4eSSatish Balay 
680e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
681e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
682e5c89e4eSSatish Balay 
683e5c89e4eSSatish Balay @*/
6847087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[])
685e5c89e4eSSatish Balay {
686e5c89e4eSSatish Balay   PetscErrorCode ierr;
687e5c89e4eSSatish Balay   PetscMPIInt    rank;
688e5c89e4eSSatish Balay 
689e5c89e4eSSatish Balay   PetscFunctionBegin;
690e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
691e5c89e4eSSatish Balay 
692e5c89e4eSSatish Balay   if (!rank) {
693047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
694047b9c12SMatthew G Knepley 
695047b9c12SMatthew G Knepley     if (!ptr) {
696e31d4fa4SJed Brown       string[0] = 0;
697e31d4fa4SJed Brown       if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
698047b9c12SMatthew G Knepley     }
699e5c89e4eSSatish Balay   }
700e5c89e4eSSatish Balay   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
701e5c89e4eSSatish Balay   PetscFunctionReturn(0);
702e5c89e4eSSatish Balay }
703238ccf28SShri Abhyankar 
704f1d7fe2eSBarry Smith #if defined(PETSC_HAVE_CLOSURES)
705f1d7fe2eSBarry Smith int (^SwiftClosure)(const char*) = 0;
706f1d7fe2eSBarry Smith 
707f1d7fe2eSBarry Smith #undef __FUNCT__
708f1d7fe2eSBarry Smith #define __FUNCT__ "PetscVFPrintfToString"
709f1d7fe2eSBarry Smith PetscErrorCode  PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp)
710f1d7fe2eSBarry Smith {
711f1d7fe2eSBarry Smith   PetscErrorCode ierr;
712f1d7fe2eSBarry Smith 
713f1d7fe2eSBarry Smith   PetscFunctionBegin;
714f1d7fe2eSBarry Smith   if (fd != stdout && fd != stderr) { /* handle regular files */
715f1d7fe2eSBarry Smith     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
716f1d7fe2eSBarry Smith   } else {
717f1d7fe2eSBarry Smith     size_t len=8*1024,length;
718f1d7fe2eSBarry Smith     char   buf[len];
719f1d7fe2eSBarry Smith 
720f1d7fe2eSBarry Smith     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
721f1d7fe2eSBarry Smith     ierr = SwiftClosure(buf);CHKERRQ(ierr);
722f1d7fe2eSBarry Smith   }
723f1d7fe2eSBarry Smith   PetscFunctionReturn(0);
724f1d7fe2eSBarry Smith }
725f1d7fe2eSBarry Smith 
726f1d7fe2eSBarry Smith /*
727f1d7fe2eSBarry Smith    Provide a Swift function that processes all the PETSc calls to PetscVFPrintf()
728f1d7fe2eSBarry Smith */
729f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*))
730f1d7fe2eSBarry Smith {
731f1d7fe2eSBarry Smith   PetscVFPrintf = PetscVFPrintfToString;
732f1d7fe2eSBarry Smith   SwiftClosure  = closure;
733f1d7fe2eSBarry Smith   return 0;
734f1d7fe2eSBarry Smith }
735f1d7fe2eSBarry Smith #endif
736f1d7fe2eSBarry Smith 
737238ccf28SShri Abhyankar #if defined(PETSC_HAVE_MATLAB_ENGINE)
738c6db04a5SJed Brown #include <mex.h>
739238ccf28SShri Abhyankar #undef __FUNCT__
740238ccf28SShri Abhyankar #define __FUNCT__ "PetscVFPrintf_Matlab"
7417087cfbeSBarry Smith PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
742238ccf28SShri Abhyankar {
743238ccf28SShri Abhyankar   PetscErrorCode ierr;
744238ccf28SShri Abhyankar 
745238ccf28SShri Abhyankar   PetscFunctionBegin;
746238ccf28SShri Abhyankar   if (fd != stdout && fd != stderr) { /* handle regular files */
747238ccf28SShri Abhyankar     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
748238ccf28SShri Abhyankar   } else {
749238ccf28SShri Abhyankar     size_t len=8*1024,length;
750238ccf28SShri Abhyankar     char   buf[len];
751238ccf28SShri Abhyankar 
752238ccf28SShri Abhyankar     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
753df413903SBarry Smith     mexPrintf("%s",buf);
754238ccf28SShri Abhyankar   }
755238ccf28SShri Abhyankar   PetscFunctionReturn(0);
756238ccf28SShri Abhyankar }
757238ccf28SShri Abhyankar #endif
7586fc7ef2bSBarry Smith 
7596fc7ef2bSBarry Smith #undef __FUNCT__
7608c74ee41SBarry Smith #define __FUNCT__ "PetscFormatStrip"
7618c74ee41SBarry Smith /*@C
7628c74ee41SBarry Smith      PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations
7638c74ee41SBarry Smith 
7648c74ee41SBarry Smith    Input Parameters:
7658c74ee41SBarry Smith .   format - the PETSc format string
7668c74ee41SBarry Smith 
7678c74ee41SBarry Smith  Level: developer
7688c74ee41SBarry Smith 
7698c74ee41SBarry Smith @*/
7708c74ee41SBarry Smith PetscErrorCode  PetscFormatStrip(char *format)
7718c74ee41SBarry Smith {
7728c74ee41SBarry Smith   size_t loc1 = 0, loc2 = 0;
7738c74ee41SBarry Smith 
7748c74ee41SBarry Smith   PetscFunctionBegin;
7758c74ee41SBarry Smith   while (format[loc2]) {
7768c74ee41SBarry Smith     if (format[loc2] == '%') {
7778c74ee41SBarry Smith       format[loc1++] = format[loc2++];
7788c74ee41SBarry Smith       while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++;
7798c74ee41SBarry Smith     }
7808c74ee41SBarry Smith     format[loc1++] = format[loc2++];
7818c74ee41SBarry Smith   }
7828c74ee41SBarry Smith   PetscFunctionReturn(0);
7838c74ee41SBarry Smith }
7848c74ee41SBarry Smith 
785