xref: /petsc/src/sys/fileio/mprint.c (revision 95452b02e12c0ee11232c7ff2b24b568a8e07e43)
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 
29c9a19010SBarry Smith /*@C
30c9a19010SBarry Smith      PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string
31c9a19010SBarry Smith 
32c9a19010SBarry Smith    Input Parameters:
33c9a19010SBarry Smith +   format - the PETSc format string
34c9a19010SBarry Smith .   newformat - the location to put the standard C format string values
35c9a19010SBarry Smith -   size - the length of newformat
36c9a19010SBarry Smith 
37eed5747fSBarry 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
38c9a19010SBarry Smith 
39c9a19010SBarry Smith  Level: developer
40c9a19010SBarry Smith 
41c9a19010SBarry Smith @*/
427087cfbeSBarry Smith PetscErrorCode  PetscFormatConvert(const char *format,char *newformat,size_t size)
43e5c89e4eSSatish Balay {
44e5c89e4eSSatish Balay   PetscInt i = 0,j = 0;
45e5c89e4eSSatish Balay 
46eed5747fSBarry Smith   PetscFunctionBegin;
477bc47156SJose Roman   while (format[i] && j < (PetscInt)size-1) {
482a1ad9caSBarry Smith     if (format[i] == '%' && format[i+1] == '%') {
492a1ad9caSBarry Smith       newformat[j++] = format[i++];
502a1ad9caSBarry Smith       newformat[j++] = format[i++];
512a1ad9caSBarry Smith     } else if (format[i] == '%') {
528627564fSBarry Smith       if (format[i+1] == 'g') {
538627564fSBarry Smith         newformat[j++] = '[';
548627564fSBarry Smith         newformat[j++] = '|';
558627564fSBarry Smith       }
567bc47156SJose Roman       /* Find the letter */
577bc47156SJose Roman       for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i];
587bc47156SJose Roman       switch (format[i]) {
597bc47156SJose Roman       case 'D':
606de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
61e5c89e4eSSatish Balay         newformat[j++] = 'd';
62e5c89e4eSSatish Balay #else
63e5c89e4eSSatish Balay         newformat[j++] = 'l';
64e5c89e4eSSatish Balay         newformat[j++] = 'l';
65e5c89e4eSSatish Balay         newformat[j++] = 'd';
66e5c89e4eSSatish Balay #endif
677bc47156SJose Roman         break;
688627564fSBarry Smith       case 'g':
698627564fSBarry Smith         newformat[j++] = format[i];
708627564fSBarry Smith         if (format[i-1] == '%') {
718627564fSBarry Smith           newformat[j++] = '|';
728627564fSBarry Smith           newformat[j++] = ']';
738627564fSBarry Smith         }
748627564fSBarry Smith         break;
757bc47156SJose Roman       case 'G':
76145505e7SDominic Meiser         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double");
777bc47156SJose Roman         break;
78121a09c4SJose Roman       case 'F':
79145505e7SDominic Meiser         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%F format is no longer supported, use %%f and cast the argument to double");
80121a09c4SJose Roman         break;
817bc47156SJose Roman       default:
827bc47156SJose Roman         newformat[j++] = format[i];
837bc47156SJose Roman         break;
847bc47156SJose Roman       }
857bc47156SJose Roman       i++;
86a297a907SKarl Rupp     } else newformat[j++] = format[i++];
87e5c89e4eSSatish Balay   }
88e5c89e4eSSatish Balay   newformat[j] = 0;
89eed5747fSBarry Smith   PetscFunctionReturn(0);
90e5c89e4eSSatish Balay }
91e5c89e4eSSatish Balay 
92c9a19010SBarry Smith /*@C
93c9a19010SBarry Smith      PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the
94c9a19010SBarry Smith        function arguments into a string using the format statement.
95c9a19010SBarry Smith 
96c9a19010SBarry Smith    Input Parameters:
97c9a19010SBarry Smith +   str - location to put result
98c9a19010SBarry Smith .   len - the amount of space in str
99c9a19010SBarry Smith +   format - the PETSc format string
100c9a19010SBarry Smith -   fullLength - the amount of space in str actually used.
101c9a19010SBarry Smith 
102*95452b02SPatrick Sanan     Developer Notes:
103*95452b02SPatrick Sanan     this function may be called from an error handler, if an error occurs when it is called by the error handler than likely
104eed5747fSBarry Smith       a recursion will occur and possible crash.
105c9a19010SBarry Smith 
106c9a19010SBarry Smith  Level: developer
107c9a19010SBarry Smith 
108c9a19010SBarry Smith @*/
1097087cfbeSBarry Smith PetscErrorCode  PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp)
110e5c89e4eSSatish Balay {
111e2135aedSMatthew Knepley   char           *newformat;
112e2135aedSMatthew Knepley   char           formatbuf[8*1024];
1131a96acb8SJed Brown   size_t         oldLength,length;
1141a15ef5dSMatthew Knepley   PetscErrorCode ierr;
115e5c89e4eSSatish Balay 
116eed5747fSBarry Smith   PetscFunctionBegin;
117e2135aedSMatthew Knepley   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
118e2135aedSMatthew Knepley   if (oldLength < 8*1024) {
119e2135aedSMatthew Knepley     newformat = formatbuf;
120354e5084SJose Roman     oldLength = 8*1024-1;
121e2135aedSMatthew Knepley   } else {
122354e5084SJose Roman     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
123785e854fSJed Brown     ierr      = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr);
124e2135aedSMatthew Knepley   }
125e298bee8SBarry Smith   ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr);
1261a15ef5dSMatthew Knepley   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
1272d609e63SMatthew Knepley #if 0
128a297a907SKarl Rupp   if (length > len) newformat[len] = '\0';
1292d609e63SMatthew Knepley #endif
1305a058713SBarry Smith #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
131748e1b9dSBarry Smith   (void) vsnprintf(str,len,newformat,(char*)Argp);
13289b07760SSatish Balay #elif defined(PETSC_HAVE_VSNPRINTF)
133748e1b9dSBarry Smith   (void) vsnprintf(str,len,newformat,Argp);
134141c0d65SSatish Balay #elif defined(PETSC_HAVE__VSNPRINTF)
135748e1b9dSBarry Smith   (void) _vsnprintf(str,len,newformat,Argp);
136e5c89e4eSSatish Balay #else
13789b07760SSatish Balay #error "vsnprintf not found"
138e5c89e4eSSatish Balay #endif
139e2135aedSMatthew Knepley   if (oldLength >= 8*1024) {
140e2135aedSMatthew Knepley     ierr = PetscFree(newformat);CHKERRQ(ierr);
141e2135aedSMatthew Knepley   }
1428627564fSBarry Smith   {
1438627564fSBarry Smith     PetscBool foundedot;
1448627564fSBarry Smith     size_t cnt = 0,ncnt = 0,leng;
1458627564fSBarry Smith     ierr = PetscStrlen(str,&leng);CHKERRQ(ierr);
14617ca8410SBarry Smith     if (leng > 4) {
1478627564fSBarry Smith       for (cnt=0; cnt<leng-4; cnt++) {
1488627564fSBarry Smith         if (str[cnt] == '[' && str[cnt+1] == '|'){
1498627564fSBarry Smith            cnt++; cnt++;
1508627564fSBarry Smith            foundedot = PETSC_FALSE;
1518627564fSBarry Smith            for (; cnt<leng-1; cnt++) {
1528627564fSBarry Smith              if (str[cnt] == '|' && str[cnt+1] == ']'){
1538627564fSBarry Smith                cnt++;
1548627564fSBarry Smith                if (!foundedot) str[ncnt++] = '.';
1558627564fSBarry Smith                ncnt--;
1568627564fSBarry Smith                break;
1578627564fSBarry Smith              } else {
1588627564fSBarry Smith                if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE;
1598627564fSBarry Smith                str[ncnt++] = str[cnt];
1608627564fSBarry Smith              }
1618627564fSBarry Smith            }
1628627564fSBarry Smith         } else {
1638627564fSBarry Smith           str[ncnt] = str[cnt];
1648627564fSBarry Smith         }
1658627564fSBarry Smith         ncnt++;
1668627564fSBarry Smith       }
1678627564fSBarry Smith       while (cnt < leng) {
1688627564fSBarry Smith         str[ncnt] = str[cnt]; ncnt++; cnt++;
1698627564fSBarry Smith       }
1708627564fSBarry Smith       str[ncnt] = 0;
1718627564fSBarry Smith     }
1728627564fSBarry Smith   }
173748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
174e51f71cfSBarry Smith   /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */
175748e1b9dSBarry Smith   {
176748e1b9dSBarry Smith     size_t cnt = 0,ncnt = 0,leng;
177748e1b9dSBarry Smith     ierr = PetscStrlen(str,&leng);CHKERRQ(ierr);
178748e1b9dSBarry Smith     if (leng > 5) {
179748e1b9dSBarry Smith       for (cnt=0; cnt<leng-4; cnt++) {
180e51f71cfSBarry 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') {
181748e1b9dSBarry Smith           str[ncnt] = str[cnt]; ncnt++; cnt++;
182e51f71cfSBarry Smith           str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++;
183e51f71cfSBarry Smith           str[ncnt] = str[cnt];
184748e1b9dSBarry Smith         } else {
185748e1b9dSBarry Smith           str[ncnt] = str[cnt];
186748e1b9dSBarry Smith         }
187748e1b9dSBarry Smith         ncnt++;
188748e1b9dSBarry Smith       }
189748e1b9dSBarry Smith       while (cnt < leng) {
190748e1b9dSBarry Smith         str[ncnt] = str[cnt]; ncnt++; cnt++;
191748e1b9dSBarry Smith       }
192748e1b9dSBarry Smith       str[ncnt] = 0;
193748e1b9dSBarry Smith     }
194748e1b9dSBarry Smith   }
195748e1b9dSBarry Smith #endif
196748e1b9dSBarry Smith   if (fullLength) {
197748e1b9dSBarry Smith     ierr = PetscStrlen(str,fullLength);CHKERRQ(ierr);
198748e1b9dSBarry Smith   }
199eed5747fSBarry Smith   PetscFunctionReturn(0);
200e5c89e4eSSatish Balay }
201e5c89e4eSSatish Balay 
202c9a19010SBarry Smith /*@C
203c9a19010SBarry Smith      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
204e5c89e4eSSatish Balay         can be replaced with something that does not simply write to a file.
205e5c89e4eSSatish Balay 
206c9a19010SBarry Smith       To use, write your own function for example,
207c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
208c9a19010SBarry Smith ${
209c9a19010SBarry Smith $  PetscErrorCode ierr;
210c9a19010SBarry Smith $
211c9a19010SBarry Smith $  PetscFunctionBegin;
212c9a19010SBarry Smith $   if (fd != stdout && fd != stderr) {  handle regular files
213c9a19010SBarry Smith $      ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr);
214c9a19010SBarry Smith $  } else {
215c9a19010SBarry Smith $     char   buff[BIG];
216c9a19010SBarry Smith $     size_t length;
217c9a19010SBarry Smith $     ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr);
218c9a19010SBarry Smith $     now send buff to whatever stream or whatever you want
219c9a19010SBarry Smith $ }
220c9a19010SBarry Smith $ PetscFunctionReturn(0);
221c9a19010SBarry Smith $}
222c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
223c9a19010SBarry Smith $    PetscVFPrintf = mypetscvfprintf;
224c9a19010SBarry Smith 
225*95452b02SPatrick Sanan       Notes:
226*95452b02SPatrick Sanan     For error messages this may be called by any process, for regular standard out it is
227e5c89e4eSSatish Balay           called only by process 0 of a given communicator
228e5c89e4eSSatish Balay 
229*95452b02SPatrick Sanan       Developer Notes:
230*95452b02SPatrick Sanan     this could be called by an error handler, if that happens then a recursion of the error handler may occur
231eed5747fSBarry Smith                        and a crash
232c9a19010SBarry Smith 
233c9a19010SBarry Smith   Level:  developer
234c9a19010SBarry Smith 
235c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf()
236c9a19010SBarry Smith 
237c9a19010SBarry Smith @*/
2387087cfbeSBarry Smith PetscErrorCode  PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
239e5c89e4eSSatish Balay {
240748e1b9dSBarry Smith   char           str[8*1024];
241eed5747fSBarry Smith   PetscErrorCode ierr;
2421179db26SBarry Smith 
243eed5747fSBarry Smith   PetscFunctionBegin;
244748e1b9dSBarry Smith   ierr = PetscVSNPrintf(str,sizeof(str),format,NULL,Argp);CHKERRQ(ierr);
245748e1b9dSBarry Smith   fprintf(fd,"%s",str);CHKERRQ(ierr);
2465a058713SBarry Smith   fflush(fd);
247eed5747fSBarry Smith   PetscFunctionReturn(0);
248e5c89e4eSSatish Balay }
249e5c89e4eSSatish Balay 
2505b5bc046SBarry Smith /*@C
2515b5bc046SBarry Smith     PetscSNPrintf - Prints to a string of given length
2525b5bc046SBarry Smith 
2535b5bc046SBarry Smith     Not Collective
2545b5bc046SBarry Smith 
2555b5bc046SBarry Smith     Input Parameters:
2565b5bc046SBarry Smith +   str - the string to print to
2575b5bc046SBarry Smith .   len - the length of str
2585b5bc046SBarry Smith .   format - the usual printf() format string
2595b5bc046SBarry Smith -   any arguments
2605b5bc046SBarry Smith 
2615b5bc046SBarry Smith    Level: intermediate
2625b5bc046SBarry Smith 
2635b5bc046SBarry Smith .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
2645b5bc046SBarry Smith           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
2655b5bc046SBarry Smith @*/
2667087cfbeSBarry Smith PetscErrorCode  PetscSNPrintf(char *str,size_t len,const char format[],...)
2675b5bc046SBarry Smith {
2685b5bc046SBarry Smith   PetscErrorCode ierr;
269c9a19010SBarry Smith   size_t         fullLength;
2705b5bc046SBarry Smith   va_list        Argp;
2715b5bc046SBarry Smith 
2725b5bc046SBarry Smith   PetscFunctionBegin;
2735b5bc046SBarry Smith   va_start(Argp,format);
2742d609e63SMatthew Knepley   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
2755b5bc046SBarry Smith   PetscFunctionReturn(0);
2765b5bc046SBarry Smith }
2775b5bc046SBarry Smith 
278257d2499SJed Brown /*@C
279257d2499SJed Brown     PetscSNPrintfCount - Prints to a string of given length, returns count
280257d2499SJed Brown 
281257d2499SJed Brown     Not Collective
282257d2499SJed Brown 
283257d2499SJed Brown     Input Parameters:
284257d2499SJed Brown +   str - the string to print to
285257d2499SJed Brown .   len - the length of str
286257d2499SJed Brown .   format - the usual printf() format string
287257d2499SJed Brown .   countused - number of characters used
288257d2499SJed Brown -   any arguments
289257d2499SJed Brown 
290257d2499SJed Brown    Level: intermediate
291257d2499SJed Brown 
292257d2499SJed Brown .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
293257d2499SJed Brown           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf()
294257d2499SJed Brown @*/
295257d2499SJed Brown PetscErrorCode  PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...)
296257d2499SJed Brown {
297257d2499SJed Brown   PetscErrorCode ierr;
298257d2499SJed Brown   va_list        Argp;
299257d2499SJed Brown 
300257d2499SJed Brown   PetscFunctionBegin;
301257d2499SJed Brown   va_start(Argp,countused);
302257d2499SJed Brown   ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr);
303257d2499SJed Brown   PetscFunctionReturn(0);
304257d2499SJed Brown }
305257d2499SJed Brown 
306e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */
307e5c89e4eSSatish Balay 
308d30b0576SJed Brown PrintfQueue petsc_printfqueue       = 0,petsc_printfqueuebase = 0;
309d30b0576SJed Brown int         petsc_printfqueuelength = 0;
310e5c89e4eSSatish Balay 
311e5c89e4eSSatish Balay /*@C
312e5c89e4eSSatish Balay     PetscSynchronizedPrintf - Prints synchronized output from several processors.
313e5c89e4eSSatish Balay     Output of the first processor is followed by that of the second, etc.
314e5c89e4eSSatish Balay 
315e5c89e4eSSatish Balay     Not Collective
316e5c89e4eSSatish Balay 
317e5c89e4eSSatish Balay     Input Parameters:
318e5c89e4eSSatish Balay +   comm - the communicator
319e5c89e4eSSatish Balay -   format - the usual printf() format string
320e5c89e4eSSatish Balay 
321e5c89e4eSSatish Balay    Level: intermediate
322e5c89e4eSSatish Balay 
323e5c89e4eSSatish Balay     Notes:
3247889ec69SBarry Smith     REQUIRES a call to PetscSynchronizedFlush() by all the processes after the completion of the calls to PetscSynchronizedPrintf() for the information
325e5c89e4eSSatish Balay     from all the processors to be printed.
326e5c89e4eSSatish Balay 
327e5c89e4eSSatish Balay     Fortran Note:
328d60d70ccSBarry Smith     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
329e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
330e5c89e4eSSatish Balay 
331e5c89e4eSSatish Balay .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
332e5c89e4eSSatish Balay           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
333e5c89e4eSSatish Balay @*/
3347087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
335e5c89e4eSSatish Balay {
336e5c89e4eSSatish Balay   PetscErrorCode ierr;
337e5c89e4eSSatish Balay   PetscMPIInt    rank;
338e5c89e4eSSatish Balay 
339e5c89e4eSSatish Balay   PetscFunctionBegin;
3406180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
341e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
342e5c89e4eSSatish Balay 
343e5c89e4eSSatish Balay   /* First processor prints immediately to stdout */
344e5c89e4eSSatish Balay   if (!rank) {
345e5c89e4eSSatish Balay     va_list Argp;
346e5c89e4eSSatish Balay     va_start(Argp,format);
3471179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
348e5c89e4eSSatish Balay     if (petsc_history) {
349cdc7d174SSatish Balay       va_start(Argp,format);
3501179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
351e5c89e4eSSatish Balay     }
352e5c89e4eSSatish Balay     va_end(Argp);
353e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
354e5c89e4eSSatish Balay     va_list     Argp;
355e5c89e4eSSatish Balay     PrintfQueue next;
356c9a19010SBarry Smith     size_t      fullLength = 8191;
357e5c89e4eSSatish Balay 
358b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
359a297a907SKarl Rupp     if (petsc_printfqueue) {
360a297a907SKarl Rupp       petsc_printfqueue->next = next;
361a297a907SKarl Rupp       petsc_printfqueue       = next;
362a297a907SKarl Rupp       petsc_printfqueue->next = 0;
363a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
364d30b0576SJed Brown     petsc_printfqueuelength++;
3652d609e63SMatthew Knepley     next->size = -1;
3669ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
3672d609e63SMatthew Knepley       next->size = fullLength+1;
368a297a907SKarl Rupp 
369785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
370e5c89e4eSSatish Balay       va_start(Argp,format);
3712d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
3722d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
373e5c89e4eSSatish Balay       va_end(Argp);
374e5c89e4eSSatish Balay     }
3752d609e63SMatthew Knepley   }
376e5c89e4eSSatish Balay   PetscFunctionReturn(0);
377e5c89e4eSSatish Balay }
378e5c89e4eSSatish Balay 
379e5c89e4eSSatish Balay /*@C
380e5c89e4eSSatish Balay     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
381e5c89e4eSSatish Balay     several processors.  Output of the first processor is followed by that of the
382e5c89e4eSSatish Balay     second, etc.
383e5c89e4eSSatish Balay 
384e5c89e4eSSatish Balay     Not Collective
385e5c89e4eSSatish Balay 
386e5c89e4eSSatish Balay     Input Parameters:
387e5c89e4eSSatish Balay +   comm - the communicator
388e5c89e4eSSatish Balay .   fd - the file pointer
389e5c89e4eSSatish Balay -   format - the usual printf() format string
390e5c89e4eSSatish Balay 
391e5c89e4eSSatish Balay     Level: intermediate
392e5c89e4eSSatish Balay 
393e5c89e4eSSatish Balay     Notes:
394e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
395e5c89e4eSSatish Balay     from all the processors to be printed.
396e5c89e4eSSatish Balay 
397e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
398e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
399e5c89e4eSSatish Balay 
400e5c89e4eSSatish Balay @*/
4017087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...)
402e5c89e4eSSatish Balay {
403e5c89e4eSSatish Balay   PetscErrorCode ierr;
404e5c89e4eSSatish Balay   PetscMPIInt    rank;
405e5c89e4eSSatish Balay 
406e5c89e4eSSatish Balay   PetscFunctionBegin;
4076180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
408e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
409e5c89e4eSSatish Balay 
410e5c89e4eSSatish Balay   /* First processor prints immediately to fp */
411e5c89e4eSSatish Balay   if (!rank) {
412e5c89e4eSSatish Balay     va_list Argp;
413e5c89e4eSSatish Balay     va_start(Argp,format);
4141179db26SBarry Smith     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
415cdc7d174SSatish Balay     if (petsc_history && (fp !=petsc_history)) {
416cdc7d174SSatish Balay       va_start(Argp,format);
4171179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
418e5c89e4eSSatish Balay     }
419e5c89e4eSSatish Balay     va_end(Argp);
420e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
421e5c89e4eSSatish Balay     va_list     Argp;
422e5c89e4eSSatish Balay     PrintfQueue next;
423c9a19010SBarry Smith     size_t      fullLength = 8191;
424b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
425a297a907SKarl Rupp     if (petsc_printfqueue) {
426a297a907SKarl Rupp       petsc_printfqueue->next = next;
427a297a907SKarl Rupp       petsc_printfqueue       = next;
428a297a907SKarl Rupp       petsc_printfqueue->next = 0;
429a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
430d30b0576SJed Brown     petsc_printfqueuelength++;
4312d609e63SMatthew Knepley     next->size = -1;
4329ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
4332d609e63SMatthew Knepley       next->size = fullLength+1;
434785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
435e5c89e4eSSatish Balay       va_start(Argp,format);
4362d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
4372d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
438e5c89e4eSSatish Balay       va_end(Argp);
439e5c89e4eSSatish Balay     }
4402d609e63SMatthew Knepley   }
441e5c89e4eSSatish Balay   PetscFunctionReturn(0);
442e5c89e4eSSatish Balay }
443e5c89e4eSSatish Balay 
4440ec8b6e3SBarry Smith /*@C
445e5c89e4eSSatish Balay     PetscSynchronizedFlush - Flushes to the screen output from all processors
4467889ec69SBarry Smith     involved in previous PetscSynchronizedPrintf()/PetscSynchronizedFPrintf() calls.
447e5c89e4eSSatish Balay 
448e5c89e4eSSatish Balay     Collective on MPI_Comm
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay     Input Parameters:
4510ec8b6e3SBarry Smith +   comm - the communicator
4520ec8b6e3SBarry Smith -   fd - the file pointer (valid on process 0 of the communicator)
453e5c89e4eSSatish Balay 
454e5c89e4eSSatish Balay     Level: intermediate
455e5c89e4eSSatish Balay 
456e5c89e4eSSatish Balay     Notes:
4577889ec69SBarry Smith     If PetscSynchronizedPrintf() and/or PetscSynchronizedFPrintf() are called with
4587889ec69SBarry Smith     different MPI communicators there must be an intervening call to PetscSynchronizedFlush() between the calls with different MPI communicators.
459e5c89e4eSSatish Balay 
460e50bf69fSBarry Smith     From Fortran pass PETSC_STDOUT if the flush is for standard out; otherwise pass a value obtained from PetscFOpen()
461e50bf69fSBarry Smith 
462e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
463e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf()
4640087d953SMatthew G. Knepley @*/
4650ec8b6e3SBarry Smith PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm,FILE *fd)
466e5c89e4eSSatish Balay {
467e5c89e4eSSatish Balay   PetscErrorCode ierr;
46829a5cbdcSMatthew G. Knepley   PetscMPIInt    rank,size,tag,i,j,n = 0,dummy = 0;
4692d609e63SMatthew Knepley   char          *message;
470e5c89e4eSSatish Balay   MPI_Status     status;
471e5c89e4eSSatish Balay 
472e5c89e4eSSatish Balay   PetscFunctionBegin;
473e5c89e4eSSatish Balay   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
474e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
475e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
476e5c89e4eSSatish Balay 
477e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
478e5c89e4eSSatish Balay   if (!rank) {
4790ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
480e5c89e4eSSatish Balay     for (i=1; i<size; i++) {
4819f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
4829f73f8ecSBarry Smith       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
483e5c89e4eSSatish Balay       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
484e5c89e4eSSatish Balay       for (j=0; j<n; j++) {
48529a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
4862d609e63SMatthew Knepley 
4872d609e63SMatthew Knepley         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
488785e854fSJed Brown         ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
4892d609e63SMatthew Knepley         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
4903bf036e2SBarry Smith         ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
4912d609e63SMatthew Knepley         ierr = PetscFree(message);CHKERRQ(ierr);
492e5c89e4eSSatish Balay       }
493e5c89e4eSSatish Balay     }
494e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
495d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase,previous;
496e5c89e4eSSatish Balay 
497b3ef9d35SBarry Smith     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
498d30b0576SJed Brown     ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
499d30b0576SJed Brown     for (i=0; i<petsc_printfqueuelength; i++) {
5002d609e63SMatthew Knepley       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
5012d609e63SMatthew Knepley       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
502e5c89e4eSSatish Balay       previous = next;
503e5c89e4eSSatish Balay       next     = next->next;
5042d609e63SMatthew Knepley       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
505e5c89e4eSSatish Balay       ierr     = PetscFree(previous);CHKERRQ(ierr);
506e5c89e4eSSatish Balay     }
507d30b0576SJed Brown     petsc_printfqueue       = 0;
508d30b0576SJed Brown     petsc_printfqueuelength = 0;
509e5c89e4eSSatish Balay   }
510e5c89e4eSSatish Balay   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
511e5c89e4eSSatish Balay   PetscFunctionReturn(0);
512e5c89e4eSSatish Balay }
513e5c89e4eSSatish Balay 
514e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
515e5c89e4eSSatish Balay 
516e5c89e4eSSatish Balay /*@C
517e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
518e5c89e4eSSatish Balay     processor in the communicator.
519e5c89e4eSSatish Balay 
520e5c89e4eSSatish Balay     Not Collective
521e5c89e4eSSatish Balay 
522e5c89e4eSSatish Balay     Input Parameters:
523e5c89e4eSSatish Balay +   comm - the communicator
524e5c89e4eSSatish Balay .   fd - the file pointer
525e5c89e4eSSatish Balay -   format - the usual printf() format string
526e5c89e4eSSatish Balay 
527e5c89e4eSSatish Balay     Level: intermediate
528e5c89e4eSSatish Balay 
529e5c89e4eSSatish Balay     Fortran Note:
530e5c89e4eSSatish Balay     This routine is not supported in Fortran.
531e5c89e4eSSatish Balay 
532e5c89e4eSSatish Balay    Concepts: printing^in parallel
533e5c89e4eSSatish Balay    Concepts: printf^in parallel
534e5c89e4eSSatish Balay 
535e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
536e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
537e5c89e4eSSatish Balay @*/
5387087cfbeSBarry Smith PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
539e5c89e4eSSatish Balay {
540e5c89e4eSSatish Balay   PetscErrorCode ierr;
541e5c89e4eSSatish Balay   PetscMPIInt    rank;
542e5c89e4eSSatish Balay 
543e5c89e4eSSatish Balay   PetscFunctionBegin;
5446180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
545e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
546e5c89e4eSSatish Balay   if (!rank) {
547e5c89e4eSSatish Balay     va_list Argp;
548e5c89e4eSSatish Balay     va_start(Argp,format);
5491179db26SBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
550cdc7d174SSatish Balay     if (petsc_history && (fd !=petsc_history)) {
551cdc7d174SSatish Balay       va_start(Argp,format);
5521179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
553e5c89e4eSSatish Balay     }
554e5c89e4eSSatish Balay     va_end(Argp);
555e5c89e4eSSatish Balay   }
556e5c89e4eSSatish Balay   PetscFunctionReturn(0);
557e5c89e4eSSatish Balay }
558e5c89e4eSSatish Balay 
559e5c89e4eSSatish Balay /*@C
560e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
561eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
562e5c89e4eSSatish Balay 
563e5c89e4eSSatish Balay     Not Collective
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay     Input Parameters:
566e5c89e4eSSatish Balay +   comm - the communicator
567e5c89e4eSSatish Balay -   format - the usual printf() format string
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay    Level: intermediate
570e5c89e4eSSatish Balay 
571e5c89e4eSSatish Balay     Fortran Note:
572d60d70ccSBarry Smith     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
573e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
574e5c89e4eSSatish Balay 
575e5c89e4eSSatish Balay    Concepts: printing^in parallel
576e5c89e4eSSatish Balay    Concepts: printf^in parallel
577e5c89e4eSSatish Balay 
578e5c89e4eSSatish Balay .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
579e5c89e4eSSatish Balay @*/
5807087cfbeSBarry Smith PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
581e5c89e4eSSatish Balay {
582e5c89e4eSSatish Balay   PetscErrorCode ierr;
583e5c89e4eSSatish Balay   PetscMPIInt    rank;
584e5c89e4eSSatish Balay 
585e5c89e4eSSatish Balay   PetscFunctionBegin;
5866180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
587e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
588e5c89e4eSSatish Balay   if (!rank) {
589e5c89e4eSSatish Balay     va_list Argp;
590e5c89e4eSSatish Balay     va_start(Argp,format);
591eed5747fSBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
592e5c89e4eSSatish Balay     if (petsc_history) {
593cdc7d174SSatish Balay       va_start(Argp,format);
594eed5747fSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
595e5c89e4eSSatish Balay     }
596e5c89e4eSSatish Balay     va_end(Argp);
597e5c89e4eSSatish Balay   }
598e5c89e4eSSatish Balay   PetscFunctionReturn(0);
599e5c89e4eSSatish Balay }
600e5c89e4eSSatish Balay 
601e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
602c9a19010SBarry Smith /*@C
603c9a19010SBarry Smith      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
604c9a19010SBarry Smith         replacinng it  with something that does not simply write to a stdout.
605c9a19010SBarry Smith 
606c9a19010SBarry Smith       To use, write your own function for example,
607c9a19010SBarry Smith $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
608c9a19010SBarry Smith ${
609c9a19010SBarry Smith $ PetscFunctionReturn(0);
610c9a19010SBarry Smith $}
611c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
612c9a19010SBarry Smith $    PetscHelpPrintf = mypetschelpprintf;
613c9a19010SBarry Smith 
614c9a19010SBarry Smith   Note: the default routine used is called PetscHelpPrintfDefault().
615c9a19010SBarry Smith 
616c9a19010SBarry Smith   Level:  developer
617c9a19010SBarry Smith 
618c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
619c9a19010SBarry Smith @*/
6207087cfbeSBarry Smith PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
621e5c89e4eSSatish Balay {
622e5c89e4eSSatish Balay   PetscErrorCode ierr;
623e5c89e4eSSatish Balay   PetscMPIInt    rank;
624e5c89e4eSSatish Balay 
625e5c89e4eSSatish Balay   PetscFunctionBegin;
6266180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
627e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
628e5c89e4eSSatish Balay   if (!rank) {
629e5c89e4eSSatish Balay     va_list Argp;
630e5c89e4eSSatish Balay     va_start(Argp,format);
6311179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
632e5c89e4eSSatish Balay     if (petsc_history) {
633cdc7d174SSatish Balay       va_start(Argp,format);
6341179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
635e5c89e4eSSatish Balay     }
636e5c89e4eSSatish Balay     va_end(Argp);
637e5c89e4eSSatish Balay   }
638e5c89e4eSSatish Balay   PetscFunctionReturn(0);
639e5c89e4eSSatish Balay }
640e5c89e4eSSatish Balay 
641e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
642e5c89e4eSSatish Balay 
643e5c89e4eSSatish Balay 
644e5c89e4eSSatish Balay /*@C
645e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
646e5c89e4eSSatish Balay 
647e5c89e4eSSatish Balay     Collective on MPI_Comm
648e5c89e4eSSatish Balay 
649e5c89e4eSSatish Balay     Input Parameters:
650e5c89e4eSSatish Balay +   comm - the communicator
651e5c89e4eSSatish Balay .   fd - the file pointer
652e5c89e4eSSatish Balay -   len - the length of the output buffer
653e5c89e4eSSatish Balay 
654e5c89e4eSSatish Balay     Output Parameter:
655e31d4fa4SJed Brown .   string - the line read from the file, at end of file string[0] == 0
656e5c89e4eSSatish Balay 
657e5c89e4eSSatish Balay     Level: intermediate
658e5c89e4eSSatish Balay 
659e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
660e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
661e5c89e4eSSatish Balay 
662e5c89e4eSSatish Balay @*/
6637087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[])
664e5c89e4eSSatish Balay {
665e5c89e4eSSatish Balay   PetscErrorCode ierr;
666e5c89e4eSSatish Balay   PetscMPIInt    rank;
667e5c89e4eSSatish Balay 
668e5c89e4eSSatish Balay   PetscFunctionBegin;
669e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
670e5c89e4eSSatish Balay 
671e5c89e4eSSatish Balay   if (!rank) {
672047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
673047b9c12SMatthew G Knepley 
674047b9c12SMatthew G Knepley     if (!ptr) {
675e31d4fa4SJed Brown       string[0] = 0;
676e31d4fa4SJed Brown       if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
677047b9c12SMatthew G Knepley     }
678e5c89e4eSSatish Balay   }
679e5c89e4eSSatish Balay   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
680e5c89e4eSSatish Balay   PetscFunctionReturn(0);
681e5c89e4eSSatish Balay }
682238ccf28SShri Abhyankar 
683f1d7fe2eSBarry Smith #if defined(PETSC_HAVE_CLOSURES)
684f1d7fe2eSBarry Smith int (^SwiftClosure)(const char*) = 0;
685f1d7fe2eSBarry Smith 
686f1d7fe2eSBarry Smith PetscErrorCode  PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp)
687f1d7fe2eSBarry Smith {
688f1d7fe2eSBarry Smith   PetscErrorCode ierr;
689f1d7fe2eSBarry Smith 
690f1d7fe2eSBarry Smith   PetscFunctionBegin;
691f1d7fe2eSBarry Smith   if (fd != stdout && fd != stderr) { /* handle regular files */
692f1d7fe2eSBarry Smith     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
693f1d7fe2eSBarry Smith   } else {
694f1d7fe2eSBarry Smith     size_t len=8*1024,length;
695f1d7fe2eSBarry Smith     char   buf[len];
696f1d7fe2eSBarry Smith 
697f1d7fe2eSBarry Smith     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
698f1d7fe2eSBarry Smith     ierr = SwiftClosure(buf);CHKERRQ(ierr);
699f1d7fe2eSBarry Smith   }
700f1d7fe2eSBarry Smith   PetscFunctionReturn(0);
701f1d7fe2eSBarry Smith }
702f1d7fe2eSBarry Smith 
703f1d7fe2eSBarry Smith /*
704f1d7fe2eSBarry Smith    Provide a Swift function that processes all the PETSc calls to PetscVFPrintf()
705f1d7fe2eSBarry Smith */
706f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*))
707f1d7fe2eSBarry Smith {
708f1d7fe2eSBarry Smith   PetscVFPrintf = PetscVFPrintfToString;
709f1d7fe2eSBarry Smith   SwiftClosure  = closure;
710f1d7fe2eSBarry Smith   return 0;
711f1d7fe2eSBarry Smith }
712f1d7fe2eSBarry Smith #endif
713f1d7fe2eSBarry Smith 
714238ccf28SShri Abhyankar #if defined(PETSC_HAVE_MATLAB_ENGINE)
715c6db04a5SJed Brown #include <mex.h>
7167087cfbeSBarry Smith PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
717238ccf28SShri Abhyankar {
718238ccf28SShri Abhyankar   PetscErrorCode ierr;
719238ccf28SShri Abhyankar 
720238ccf28SShri Abhyankar   PetscFunctionBegin;
721238ccf28SShri Abhyankar   if (fd != stdout && fd != stderr) { /* handle regular files */
722238ccf28SShri Abhyankar     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
723238ccf28SShri Abhyankar   } else {
724238ccf28SShri Abhyankar     size_t len=8*1024,length;
725238ccf28SShri Abhyankar     char   buf[len];
726238ccf28SShri Abhyankar 
727238ccf28SShri Abhyankar     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
728df413903SBarry Smith     mexPrintf("%s",buf);
729238ccf28SShri Abhyankar   }
730238ccf28SShri Abhyankar   PetscFunctionReturn(0);
731238ccf28SShri Abhyankar }
732238ccf28SShri Abhyankar #endif
7336fc7ef2bSBarry Smith 
7348c74ee41SBarry Smith /*@C
7358c74ee41SBarry Smith      PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations
7368c74ee41SBarry Smith 
7378c74ee41SBarry Smith    Input Parameters:
7388c74ee41SBarry Smith .   format - the PETSc format string
7398c74ee41SBarry Smith 
7408c74ee41SBarry Smith  Level: developer
7418c74ee41SBarry Smith 
7428c74ee41SBarry Smith @*/
7438c74ee41SBarry Smith PetscErrorCode  PetscFormatStrip(char *format)
7448c74ee41SBarry Smith {
7458c74ee41SBarry Smith   size_t loc1 = 0, loc2 = 0;
7468c74ee41SBarry Smith 
7478c74ee41SBarry Smith   PetscFunctionBegin;
7488c74ee41SBarry Smith   while (format[loc2]) {
7498c74ee41SBarry Smith     if (format[loc2] == '%') {
7508c74ee41SBarry Smith       format[loc1++] = format[loc2++];
7518c74ee41SBarry Smith       while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++;
7528c74ee41SBarry Smith     }
7538c74ee41SBarry Smith     format[loc1++] = format[loc2++];
7548c74ee41SBarry Smith   }
7558c74ee41SBarry Smith   PetscFunctionReturn(0);
7568c74ee41SBarry Smith }
7578c74ee41SBarry Smith 
758