xref: /petsc/src/sys/fileio/mprint.c (revision f1d7fe2e0bf28e5e9858f1200f2475c38bc31760)
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] == '%') {
547bc47156SJose Roman       /* Find the letter */
557bc47156SJose Roman       for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i];
567bc47156SJose Roman       switch (format[i]) {
577bc47156SJose Roman       case 'D':
586de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
59e5c89e4eSSatish Balay         newformat[j++] = 'd';
60e5c89e4eSSatish Balay #else
61e5c89e4eSSatish Balay         newformat[j++] = 'l';
62e5c89e4eSSatish Balay         newformat[j++] = 'l';
63e5c89e4eSSatish Balay         newformat[j++] = 'd';
64e5c89e4eSSatish Balay #endif
657bc47156SJose Roman         break;
667bc47156SJose Roman       case 'G':
67145505e7SDominic Meiser         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%G format is no longer supported, use %%g and cast the argument to double");
687bc47156SJose Roman         break;
69121a09c4SJose Roman       case 'F':
70145505e7SDominic Meiser         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%%F format is no longer supported, use %%f and cast the argument to double");
71121a09c4SJose Roman         break;
727bc47156SJose Roman       default:
737bc47156SJose Roman         newformat[j++] = format[i];
747bc47156SJose Roman         break;
757bc47156SJose Roman       }
767bc47156SJose Roman       i++;
77a297a907SKarl Rupp     } else newformat[j++] = format[i++];
78e5c89e4eSSatish Balay   }
79e5c89e4eSSatish Balay   newformat[j] = 0;
80eed5747fSBarry Smith   PetscFunctionReturn(0);
81e5c89e4eSSatish Balay }
82e5c89e4eSSatish Balay 
83e5c89e4eSSatish Balay #undef __FUNCT__
84e5c89e4eSSatish Balay #define __FUNCT__ "PetscVSNPrintf"
85c9a19010SBarry Smith /*@C
86c9a19010SBarry Smith      PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the
87c9a19010SBarry Smith        function arguments into a string using the format statement.
88c9a19010SBarry Smith 
89c9a19010SBarry Smith    Input Parameters:
90c9a19010SBarry Smith +   str - location to put result
91c9a19010SBarry Smith .   len - the amount of space in str
92c9a19010SBarry Smith +   format - the PETSc format string
93c9a19010SBarry Smith -   fullLength - the amount of space in str actually used.
94c9a19010SBarry Smith 
95eed5747fSBarry 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
96eed5747fSBarry Smith       a recursion will occur and possible crash.
97c9a19010SBarry Smith 
98c9a19010SBarry Smith  Level: developer
99c9a19010SBarry Smith 
100c9a19010SBarry Smith @*/
1017087cfbeSBarry Smith PetscErrorCode  PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp)
102e5c89e4eSSatish Balay {
103e2135aedSMatthew Knepley   char           *newformat;
104e2135aedSMatthew Knepley   char           formatbuf[8*1024];
1051a96acb8SJed Brown   size_t         oldLength,length;
1061a96acb8SJed Brown   int            fullLengthInt;
1071a15ef5dSMatthew Knepley   PetscErrorCode ierr;
108e5c89e4eSSatish Balay 
109eed5747fSBarry Smith   PetscFunctionBegin;
110e2135aedSMatthew Knepley   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
111e2135aedSMatthew Knepley   if (oldLength < 8*1024) {
112e2135aedSMatthew Knepley     newformat = formatbuf;
113354e5084SJose Roman     oldLength = 8*1024-1;
114e2135aedSMatthew Knepley   } else {
115354e5084SJose Roman     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
116785e854fSJed Brown     ierr      = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr);
117e2135aedSMatthew Knepley   }
118354e5084SJose Roman   PetscFormatConvert(format,newformat,oldLength);
1191a15ef5dSMatthew Knepley   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
1202d609e63SMatthew Knepley #if 0
121a297a907SKarl Rupp   if (length > len) newformat[len] = '\0';
1222d609e63SMatthew Knepley #endif
1235a058713SBarry Smith #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
12442c7c0bfSJed Brown   fullLengthInt = vsnprintf(str,len,newformat,(char*)Argp);
12589b07760SSatish Balay #elif defined(PETSC_HAVE_VSNPRINTF)
12642c7c0bfSJed Brown   fullLengthInt = vsnprintf(str,len,newformat,Argp);
127141c0d65SSatish Balay #elif defined(PETSC_HAVE__VSNPRINTF)
12842c7c0bfSJed Brown   fullLengthInt = _vsnprintf(str,len,newformat,Argp);
129e5c89e4eSSatish Balay #else
13089b07760SSatish Balay #error "vsnprintf not found"
131e5c89e4eSSatish Balay #endif
13242c7c0bfSJed Brown   if (fullLengthInt < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"vsnprintf() failed");
1338c74ee41SBarry Smith   if (fullLength) *fullLength = (size_t)fullLengthInt;
134e2135aedSMatthew Knepley   if (oldLength >= 8*1024) {
135e2135aedSMatthew Knepley     ierr = PetscFree(newformat);CHKERRQ(ierr);
136e2135aedSMatthew Knepley   }
137eed5747fSBarry Smith   PetscFunctionReturn(0);
138e5c89e4eSSatish Balay }
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay #undef __FUNCT__
141c9a19010SBarry Smith #define __FUNCT__ "PetscVFPrintfDefault"
142c9a19010SBarry Smith /*@C
143c9a19010SBarry Smith      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
144e5c89e4eSSatish Balay         can be replaced with something that does not simply write to a file.
145e5c89e4eSSatish Balay 
146c9a19010SBarry Smith       To use, write your own function for example,
147c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
148c9a19010SBarry Smith ${
149c9a19010SBarry Smith $  PetscErrorCode ierr;
150c9a19010SBarry Smith $
151c9a19010SBarry Smith $  PetscFunctionBegin;
152c9a19010SBarry Smith $   if (fd != stdout && fd != stderr) {  handle regular files
153c9a19010SBarry Smith $      ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr);
154c9a19010SBarry Smith $  } else {
155c9a19010SBarry Smith $     char   buff[BIG];
156c9a19010SBarry Smith $     size_t length;
157c9a19010SBarry Smith $     ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr);
158c9a19010SBarry Smith $     now send buff to whatever stream or whatever you want
159c9a19010SBarry Smith $ }
160c9a19010SBarry Smith $ PetscFunctionReturn(0);
161c9a19010SBarry Smith $}
162c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
163c9a19010SBarry Smith $    PetscVFPrintf = mypetscvfprintf;
164c9a19010SBarry Smith 
165c9a19010SBarry Smith       Notes: For error messages this may be called by any process, for regular standard out it is
166e5c89e4eSSatish Balay           called only by process 0 of a given communicator
167e5c89e4eSSatish Balay 
168eed5747fSBarry Smith       Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur
169eed5747fSBarry Smith                        and a crash
170c9a19010SBarry Smith 
171c9a19010SBarry Smith   Level:  developer
172c9a19010SBarry Smith 
173c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf()
174c9a19010SBarry Smith 
175c9a19010SBarry Smith @*/
1767087cfbeSBarry Smith PetscErrorCode  PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
177e5c89e4eSSatish Balay {
178e2135aedSMatthew Knepley   char           *newformat;
179e2135aedSMatthew Knepley   char           formatbuf[8*1024];
180e2135aedSMatthew Knepley   size_t         oldLength;
181eed5747fSBarry Smith   PetscErrorCode ierr;
1821179db26SBarry Smith 
183eed5747fSBarry Smith   PetscFunctionBegin;
184eed5747fSBarry Smith   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
185e2135aedSMatthew Knepley   if (oldLength < 8*1024) {
186e2135aedSMatthew Knepley     newformat = formatbuf;
187354e5084SJose Roman     oldLength = 8*1024-1;
188e2135aedSMatthew Knepley   } else {
189354e5084SJose Roman     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
190785e854fSJed Brown     ierr      = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr);
191e2135aedSMatthew Knepley   }
192eed5747fSBarry Smith   ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr);
193d8c6e182Sbcordonn 
1945a058713SBarry Smith #if defined(PETSC_HAVE_VFPRINTF_CHAR)
195e5c89e4eSSatish Balay   vfprintf(fd,newformat,(char*)Argp);
196e5c89e4eSSatish Balay #else
197e5c89e4eSSatish Balay   vfprintf(fd,newformat,Argp);
198e5c89e4eSSatish Balay #endif
1995a058713SBarry Smith   fflush(fd);
200e2135aedSMatthew Knepley   if (oldLength >= 8*1024) {
201eed5747fSBarry Smith     ierr = PetscFree(newformat);CHKERRQ(ierr);
202e2135aedSMatthew Knepley   }
203eed5747fSBarry Smith   PetscFunctionReturn(0);
204e5c89e4eSSatish Balay }
205e5c89e4eSSatish Balay 
2065b5bc046SBarry Smith #undef __FUNCT__
2075b5bc046SBarry Smith #define __FUNCT__ "PetscSNPrintf"
2085b5bc046SBarry Smith /*@C
2095b5bc046SBarry Smith     PetscSNPrintf - Prints to a string of given length
2105b5bc046SBarry Smith 
2115b5bc046SBarry Smith     Not Collective
2125b5bc046SBarry Smith 
2135b5bc046SBarry Smith     Input Parameters:
2145b5bc046SBarry Smith +   str - the string to print to
2155b5bc046SBarry Smith .   len - the length of str
2165b5bc046SBarry Smith .   format - the usual printf() format string
2175b5bc046SBarry Smith -   any arguments
2185b5bc046SBarry Smith 
2195b5bc046SBarry Smith    Level: intermediate
2205b5bc046SBarry Smith 
2215b5bc046SBarry Smith .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
2225b5bc046SBarry Smith           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
2235b5bc046SBarry Smith @*/
2247087cfbeSBarry Smith PetscErrorCode  PetscSNPrintf(char *str,size_t len,const char format[],...)
2255b5bc046SBarry Smith {
2265b5bc046SBarry Smith   PetscErrorCode ierr;
227c9a19010SBarry Smith   size_t         fullLength;
2285b5bc046SBarry Smith   va_list        Argp;
2295b5bc046SBarry Smith 
2305b5bc046SBarry Smith   PetscFunctionBegin;
2315b5bc046SBarry Smith   va_start(Argp,format);
2322d609e63SMatthew Knepley   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
2335b5bc046SBarry Smith   PetscFunctionReturn(0);
2345b5bc046SBarry Smith }
2355b5bc046SBarry Smith 
236257d2499SJed Brown #undef __FUNCT__
237257d2499SJed Brown #define __FUNCT__ "PetscSNPrintfCount"
238257d2499SJed Brown /*@C
239257d2499SJed Brown     PetscSNPrintfCount - Prints to a string of given length, returns count
240257d2499SJed Brown 
241257d2499SJed Brown     Not Collective
242257d2499SJed Brown 
243257d2499SJed Brown     Input Parameters:
244257d2499SJed Brown +   str - the string to print to
245257d2499SJed Brown .   len - the length of str
246257d2499SJed Brown .   format - the usual printf() format string
247257d2499SJed Brown .   countused - number of characters used
248257d2499SJed Brown -   any arguments
249257d2499SJed Brown 
250257d2499SJed Brown    Level: intermediate
251257d2499SJed Brown 
252257d2499SJed Brown .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
253257d2499SJed Brown           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf()
254257d2499SJed Brown @*/
255257d2499SJed Brown PetscErrorCode  PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...)
256257d2499SJed Brown {
257257d2499SJed Brown   PetscErrorCode ierr;
258257d2499SJed Brown   va_list        Argp;
259257d2499SJed Brown 
260257d2499SJed Brown   PetscFunctionBegin;
261257d2499SJed Brown   va_start(Argp,countused);
262257d2499SJed Brown   ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr);
263257d2499SJed Brown   PetscFunctionReturn(0);
264257d2499SJed Brown }
265257d2499SJed Brown 
266e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */
267e5c89e4eSSatish Balay 
268d30b0576SJed Brown PrintfQueue petsc_printfqueue       = 0,petsc_printfqueuebase = 0;
269d30b0576SJed Brown int         petsc_printfqueuelength = 0;
270e5c89e4eSSatish Balay 
271e5c89e4eSSatish Balay #undef __FUNCT__
272e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedPrintf"
273e5c89e4eSSatish Balay /*@C
274e5c89e4eSSatish Balay     PetscSynchronizedPrintf - Prints synchronized output from several processors.
275e5c89e4eSSatish Balay     Output of the first processor is followed by that of the second, etc.
276e5c89e4eSSatish Balay 
277e5c89e4eSSatish Balay     Not Collective
278e5c89e4eSSatish Balay 
279e5c89e4eSSatish Balay     Input Parameters:
280e5c89e4eSSatish Balay +   comm - the communicator
281e5c89e4eSSatish Balay -   format - the usual printf() format string
282e5c89e4eSSatish Balay 
283e5c89e4eSSatish Balay    Level: intermediate
284e5c89e4eSSatish Balay 
285e5c89e4eSSatish Balay     Notes:
286e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
287e5c89e4eSSatish Balay     from all the processors to be printed.
288e5c89e4eSSatish Balay 
289e5c89e4eSSatish Balay     Fortran Note:
290d60d70ccSBarry Smith     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
291e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
292e5c89e4eSSatish Balay 
293e5c89e4eSSatish Balay .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
294e5c89e4eSSatish Balay           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
295e5c89e4eSSatish Balay @*/
2967087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
297e5c89e4eSSatish Balay {
298e5c89e4eSSatish Balay   PetscErrorCode ierr;
299e5c89e4eSSatish Balay   PetscMPIInt    rank;
300e5c89e4eSSatish Balay 
301e5c89e4eSSatish Balay   PetscFunctionBegin;
3026180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
303e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
304e5c89e4eSSatish Balay 
305e5c89e4eSSatish Balay   /* First processor prints immediately to stdout */
306e5c89e4eSSatish Balay   if (!rank) {
307e5c89e4eSSatish Balay     va_list Argp;
308e5c89e4eSSatish Balay     va_start(Argp,format);
3091179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
310e5c89e4eSSatish Balay     if (petsc_history) {
311cdc7d174SSatish Balay       va_start(Argp,format);
3121179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
313e5c89e4eSSatish Balay     }
314e5c89e4eSSatish Balay     va_end(Argp);
315e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
316e5c89e4eSSatish Balay     va_list     Argp;
317e5c89e4eSSatish Balay     PrintfQueue next;
318c9a19010SBarry Smith     size_t      fullLength = 8191;
319e5c89e4eSSatish Balay 
320b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
321a297a907SKarl Rupp     if (petsc_printfqueue) {
322a297a907SKarl Rupp       petsc_printfqueue->next = next;
323a297a907SKarl Rupp       petsc_printfqueue       = next;
324a297a907SKarl Rupp       petsc_printfqueue->next = 0;
325a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
326d30b0576SJed Brown     petsc_printfqueuelength++;
3272d609e63SMatthew Knepley     next->size = -1;
3289ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
3292d609e63SMatthew Knepley       next->size = fullLength+1;
330a297a907SKarl Rupp 
331785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
332e5c89e4eSSatish Balay       va_start(Argp,format);
3332d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
3342d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
335e5c89e4eSSatish Balay       va_end(Argp);
336e5c89e4eSSatish Balay     }
3372d609e63SMatthew Knepley   }
338e5c89e4eSSatish Balay   PetscFunctionReturn(0);
339e5c89e4eSSatish Balay }
340e5c89e4eSSatish Balay 
341e5c89e4eSSatish Balay #undef __FUNCT__
342e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFPrintf"
343e5c89e4eSSatish Balay /*@C
344e5c89e4eSSatish Balay     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
345e5c89e4eSSatish Balay     several processors.  Output of the first processor is followed by that of the
346e5c89e4eSSatish Balay     second, etc.
347e5c89e4eSSatish Balay 
348e5c89e4eSSatish Balay     Not Collective
349e5c89e4eSSatish Balay 
350e5c89e4eSSatish Balay     Input Parameters:
351e5c89e4eSSatish Balay +   comm - the communicator
352e5c89e4eSSatish Balay .   fd - the file pointer
353e5c89e4eSSatish Balay -   format - the usual printf() format string
354e5c89e4eSSatish Balay 
355e5c89e4eSSatish Balay     Level: intermediate
356e5c89e4eSSatish Balay 
357e5c89e4eSSatish Balay     Notes:
358e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
359e5c89e4eSSatish Balay     from all the processors to be printed.
360e5c89e4eSSatish Balay 
361e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
362e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
363e5c89e4eSSatish Balay 
364e5c89e4eSSatish Balay @*/
3657087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...)
366e5c89e4eSSatish Balay {
367e5c89e4eSSatish Balay   PetscErrorCode ierr;
368e5c89e4eSSatish Balay   PetscMPIInt    rank;
369e5c89e4eSSatish Balay 
370e5c89e4eSSatish Balay   PetscFunctionBegin;
3716180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
372e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
373e5c89e4eSSatish Balay 
374e5c89e4eSSatish Balay   /* First processor prints immediately to fp */
375e5c89e4eSSatish Balay   if (!rank) {
376e5c89e4eSSatish Balay     va_list Argp;
377e5c89e4eSSatish Balay     va_start(Argp,format);
3781179db26SBarry Smith     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
379cdc7d174SSatish Balay     if (petsc_history && (fp !=petsc_history)) {
380cdc7d174SSatish Balay       va_start(Argp,format);
3811179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
382e5c89e4eSSatish Balay     }
383e5c89e4eSSatish Balay     va_end(Argp);
384e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
385e5c89e4eSSatish Balay     va_list     Argp;
386e5c89e4eSSatish Balay     PrintfQueue next;
387c9a19010SBarry Smith     size_t      fullLength = 8191;
388b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
389a297a907SKarl Rupp     if (petsc_printfqueue) {
390a297a907SKarl Rupp       petsc_printfqueue->next = next;
391a297a907SKarl Rupp       petsc_printfqueue       = next;
392a297a907SKarl Rupp       petsc_printfqueue->next = 0;
393a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
394d30b0576SJed Brown     petsc_printfqueuelength++;
3952d609e63SMatthew Knepley     next->size = -1;
3969ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
3972d609e63SMatthew Knepley       next->size = fullLength+1;
398785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
399e5c89e4eSSatish Balay       va_start(Argp,format);
4002d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
4012d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
402e5c89e4eSSatish Balay       va_end(Argp);
403e5c89e4eSSatish Balay     }
4042d609e63SMatthew Knepley   }
405e5c89e4eSSatish Balay   PetscFunctionReturn(0);
406e5c89e4eSSatish Balay }
407e5c89e4eSSatish Balay 
408e5c89e4eSSatish Balay #undef __FUNCT__
409e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFlush"
4100ec8b6e3SBarry Smith /*@C
411e5c89e4eSSatish Balay     PetscSynchronizedFlush - Flushes to the screen output from all processors
412e5c89e4eSSatish Balay     involved in previous PetscSynchronizedPrintf() calls.
413e5c89e4eSSatish Balay 
414e5c89e4eSSatish Balay     Collective on MPI_Comm
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay     Input Parameters:
4170ec8b6e3SBarry Smith +   comm - the communicator
4180ec8b6e3SBarry Smith -   fd - the file pointer (valid on process 0 of the communicator)
419e5c89e4eSSatish Balay 
420e5c89e4eSSatish Balay     Level: intermediate
421e5c89e4eSSatish Balay 
422e5c89e4eSSatish Balay     Notes:
423e5c89e4eSSatish Balay     Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with
424e5c89e4eSSatish Balay     different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush().
425e5c89e4eSSatish Balay 
426e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
427e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf()
4280ec8b6e3SBarry Smith C@*/
4290ec8b6e3SBarry Smith PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm,FILE *fd)
430e5c89e4eSSatish Balay {
431e5c89e4eSSatish Balay   PetscErrorCode ierr;
43229a5cbdcSMatthew G. Knepley   PetscMPIInt    rank,size,tag,i,j,n = 0,dummy = 0;
4332d609e63SMatthew Knepley   char          *message;
434e5c89e4eSSatish Balay   MPI_Status     status;
435e5c89e4eSSatish Balay 
436e5c89e4eSSatish Balay   PetscFunctionBegin;
437e5c89e4eSSatish Balay   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
438e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
439e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
440e5c89e4eSSatish Balay 
441e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
442e5c89e4eSSatish Balay   if (!rank) {
4430ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
444e5c89e4eSSatish Balay     for (i=1; i<size; i++) {
4459f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
4469f73f8ecSBarry Smith       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
447e5c89e4eSSatish Balay       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
448e5c89e4eSSatish Balay       for (j=0; j<n; j++) {
44929a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
4502d609e63SMatthew Knepley 
4512d609e63SMatthew Knepley         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
452785e854fSJed Brown         ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
4532d609e63SMatthew Knepley         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
4543bf036e2SBarry Smith         ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
4552d609e63SMatthew Knepley         ierr = PetscFree(message);CHKERRQ(ierr);
456e5c89e4eSSatish Balay       }
457e5c89e4eSSatish Balay     }
458e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
459d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase,previous;
460e5c89e4eSSatish Balay 
461b3ef9d35SBarry Smith     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
462d30b0576SJed Brown     ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
463d30b0576SJed Brown     for (i=0; i<petsc_printfqueuelength; i++) {
4642d609e63SMatthew Knepley       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
4652d609e63SMatthew Knepley       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
466e5c89e4eSSatish Balay       previous = next;
467e5c89e4eSSatish Balay       next     = next->next;
4682d609e63SMatthew Knepley       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
469e5c89e4eSSatish Balay       ierr     = PetscFree(previous);CHKERRQ(ierr);
470e5c89e4eSSatish Balay     }
471d30b0576SJed Brown     petsc_printfqueue       = 0;
472d30b0576SJed Brown     petsc_printfqueuelength = 0;
473e5c89e4eSSatish Balay   }
474e5c89e4eSSatish Balay   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
475e5c89e4eSSatish Balay   PetscFunctionReturn(0);
476e5c89e4eSSatish Balay }
477e5c89e4eSSatish Balay 
478e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
479e5c89e4eSSatish Balay 
480e5c89e4eSSatish Balay #undef __FUNCT__
481e5c89e4eSSatish Balay #define __FUNCT__ "PetscFPrintf"
482e5c89e4eSSatish Balay /*@C
483e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
484e5c89e4eSSatish Balay     processor in the communicator.
485e5c89e4eSSatish Balay 
486e5c89e4eSSatish Balay     Not Collective
487e5c89e4eSSatish Balay 
488e5c89e4eSSatish Balay     Input Parameters:
489e5c89e4eSSatish Balay +   comm - the communicator
490e5c89e4eSSatish Balay .   fd - the file pointer
491e5c89e4eSSatish Balay -   format - the usual printf() format string
492e5c89e4eSSatish Balay 
493e5c89e4eSSatish Balay     Level: intermediate
494e5c89e4eSSatish Balay 
495e5c89e4eSSatish Balay     Fortran Note:
496e5c89e4eSSatish Balay     This routine is not supported in Fortran.
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay    Concepts: printing^in parallel
499e5c89e4eSSatish Balay    Concepts: printf^in parallel
500e5c89e4eSSatish Balay 
501e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
502e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
503e5c89e4eSSatish Balay @*/
5047087cfbeSBarry Smith PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
505e5c89e4eSSatish Balay {
506e5c89e4eSSatish Balay   PetscErrorCode ierr;
507e5c89e4eSSatish Balay   PetscMPIInt    rank;
508e5c89e4eSSatish Balay 
509e5c89e4eSSatish Balay   PetscFunctionBegin;
5106180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
511e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
512e5c89e4eSSatish Balay   if (!rank) {
513e5c89e4eSSatish Balay     va_list Argp;
514e5c89e4eSSatish Balay     va_start(Argp,format);
5151179db26SBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
516cdc7d174SSatish Balay     if (petsc_history && (fd !=petsc_history)) {
517cdc7d174SSatish Balay       va_start(Argp,format);
5181179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
519e5c89e4eSSatish Balay     }
520e5c89e4eSSatish Balay     va_end(Argp);
521e5c89e4eSSatish Balay   }
522e5c89e4eSSatish Balay   PetscFunctionReturn(0);
523e5c89e4eSSatish Balay }
524e5c89e4eSSatish Balay 
525e5c89e4eSSatish Balay #undef __FUNCT__
526e5c89e4eSSatish Balay #define __FUNCT__ "PetscPrintf"
527e5c89e4eSSatish Balay /*@C
528e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
529eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
530e5c89e4eSSatish Balay 
531e5c89e4eSSatish Balay     Not Collective
532e5c89e4eSSatish Balay 
533e5c89e4eSSatish Balay     Input Parameters:
534e5c89e4eSSatish Balay +   comm - the communicator
535e5c89e4eSSatish Balay -   format - the usual printf() format string
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay    Level: intermediate
538e5c89e4eSSatish Balay 
539e5c89e4eSSatish Balay     Fortran Note:
540d60d70ccSBarry Smith     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
541e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
542e5c89e4eSSatish Balay 
543e5c89e4eSSatish Balay    Concepts: printing^in parallel
544e5c89e4eSSatish Balay    Concepts: printf^in parallel
545e5c89e4eSSatish Balay 
546e5c89e4eSSatish Balay .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
547e5c89e4eSSatish Balay @*/
5487087cfbeSBarry Smith PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
549e5c89e4eSSatish Balay {
550e5c89e4eSSatish Balay   PetscErrorCode ierr;
551e5c89e4eSSatish Balay   PetscMPIInt    rank;
552e5c89e4eSSatish Balay 
553e5c89e4eSSatish Balay   PetscFunctionBegin;
5546180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
555e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
556e5c89e4eSSatish Balay   if (!rank) {
557e5c89e4eSSatish Balay     va_list Argp;
558e5c89e4eSSatish Balay     va_start(Argp,format);
559eed5747fSBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
560e5c89e4eSSatish Balay     if (petsc_history) {
561cdc7d174SSatish Balay       va_start(Argp,format);
562eed5747fSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
563e5c89e4eSSatish Balay     }
564e5c89e4eSSatish Balay     va_end(Argp);
565e5c89e4eSSatish Balay   }
566e5c89e4eSSatish Balay   PetscFunctionReturn(0);
567e5c89e4eSSatish Balay }
568e5c89e4eSSatish Balay 
569e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
570e5c89e4eSSatish Balay #undef __FUNCT__
571e5c89e4eSSatish Balay #define __FUNCT__ "PetscHelpPrintfDefault"
572c9a19010SBarry Smith /*@C
573c9a19010SBarry Smith      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
574c9a19010SBarry Smith         replacinng it  with something that does not simply write to a stdout.
575c9a19010SBarry Smith 
576c9a19010SBarry Smith       To use, write your own function for example,
577c9a19010SBarry Smith $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
578c9a19010SBarry Smith ${
579c9a19010SBarry Smith $ PetscFunctionReturn(0);
580c9a19010SBarry Smith $}
581c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
582c9a19010SBarry Smith $    PetscHelpPrintf = mypetschelpprintf;
583c9a19010SBarry Smith 
584c9a19010SBarry Smith   Note: the default routine used is called PetscHelpPrintfDefault().
585c9a19010SBarry Smith 
586c9a19010SBarry Smith   Level:  developer
587c9a19010SBarry Smith 
588c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
589c9a19010SBarry Smith @*/
5907087cfbeSBarry Smith PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
591e5c89e4eSSatish Balay {
592e5c89e4eSSatish Balay   PetscErrorCode ierr;
593e5c89e4eSSatish Balay   PetscMPIInt    rank;
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay   PetscFunctionBegin;
5966180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
597e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
598e5c89e4eSSatish Balay   if (!rank) {
599e5c89e4eSSatish Balay     va_list Argp;
600e5c89e4eSSatish Balay     va_start(Argp,format);
6011179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
602e5c89e4eSSatish Balay     if (petsc_history) {
603cdc7d174SSatish Balay       va_start(Argp,format);
6041179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
605e5c89e4eSSatish Balay     }
606e5c89e4eSSatish Balay     va_end(Argp);
607e5c89e4eSSatish Balay   }
608e5c89e4eSSatish Balay   PetscFunctionReturn(0);
609e5c89e4eSSatish Balay }
610e5c89e4eSSatish Balay 
611e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
612e5c89e4eSSatish Balay 
613e5c89e4eSSatish Balay 
614e5c89e4eSSatish Balay #undef __FUNCT__
615e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFGets"
616e5c89e4eSSatish Balay /*@C
617e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
618e5c89e4eSSatish Balay 
619e5c89e4eSSatish Balay     Collective on MPI_Comm
620e5c89e4eSSatish Balay 
621e5c89e4eSSatish Balay     Input Parameters:
622e5c89e4eSSatish Balay +   comm - the communicator
623e5c89e4eSSatish Balay .   fd - the file pointer
624e5c89e4eSSatish Balay -   len - the length of the output buffer
625e5c89e4eSSatish Balay 
626e5c89e4eSSatish Balay     Output Parameter:
627e31d4fa4SJed Brown .   string - the line read from the file, at end of file string[0] == 0
628e5c89e4eSSatish Balay 
629e5c89e4eSSatish Balay     Level: intermediate
630e5c89e4eSSatish Balay 
631e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
632e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
633e5c89e4eSSatish Balay 
634e5c89e4eSSatish Balay @*/
6357087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[])
636e5c89e4eSSatish Balay {
637e5c89e4eSSatish Balay   PetscErrorCode ierr;
638e5c89e4eSSatish Balay   PetscMPIInt    rank;
639e5c89e4eSSatish Balay 
640e5c89e4eSSatish Balay   PetscFunctionBegin;
641e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
642e5c89e4eSSatish Balay 
643e5c89e4eSSatish Balay   if (!rank) {
644047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
645047b9c12SMatthew G Knepley 
646047b9c12SMatthew G Knepley     if (!ptr) {
647e31d4fa4SJed Brown       string[0] = 0;
648e31d4fa4SJed Brown       if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
649047b9c12SMatthew G Knepley     }
650e5c89e4eSSatish Balay   }
651e5c89e4eSSatish Balay   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
652e5c89e4eSSatish Balay   PetscFunctionReturn(0);
653e5c89e4eSSatish Balay }
654238ccf28SShri Abhyankar 
655*f1d7fe2eSBarry Smith #if defined(PETSC_HAVE_CLOSURES)
656*f1d7fe2eSBarry Smith int (^SwiftClosure)(const char*) = 0;
657*f1d7fe2eSBarry Smith 
658*f1d7fe2eSBarry Smith #undef __FUNCT__
659*f1d7fe2eSBarry Smith #define __FUNCT__ "PetscVFPrintfToString"
660*f1d7fe2eSBarry Smith PetscErrorCode  PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp)
661*f1d7fe2eSBarry Smith {
662*f1d7fe2eSBarry Smith   PetscErrorCode ierr;
663*f1d7fe2eSBarry Smith 
664*f1d7fe2eSBarry Smith   PetscFunctionBegin;
665*f1d7fe2eSBarry Smith   if (fd != stdout && fd != stderr) { /* handle regular files */
666*f1d7fe2eSBarry Smith     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
667*f1d7fe2eSBarry Smith   } else {
668*f1d7fe2eSBarry Smith     size_t len=8*1024,length;
669*f1d7fe2eSBarry Smith     char   buf[len];
670*f1d7fe2eSBarry Smith 
671*f1d7fe2eSBarry Smith     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
672*f1d7fe2eSBarry Smith     ierr = SwiftClosure(buf);CHKERRQ(ierr);
673*f1d7fe2eSBarry Smith   }
674*f1d7fe2eSBarry Smith   PetscFunctionReturn(0);
675*f1d7fe2eSBarry Smith }
676*f1d7fe2eSBarry Smith 
677*f1d7fe2eSBarry Smith /*
678*f1d7fe2eSBarry Smith    Provide a Swift function that processes all the PETSc calls to PetscVFPrintf()
679*f1d7fe2eSBarry Smith */
680*f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*))
681*f1d7fe2eSBarry Smith {
682*f1d7fe2eSBarry Smith   PetscVFPrintf = PetscVFPrintfToString;
683*f1d7fe2eSBarry Smith   SwiftClosure  = closure;
684*f1d7fe2eSBarry Smith   return 0;
685*f1d7fe2eSBarry Smith }
686*f1d7fe2eSBarry Smith #endif
687*f1d7fe2eSBarry Smith 
688238ccf28SShri Abhyankar #if defined(PETSC_HAVE_MATLAB_ENGINE)
689c6db04a5SJed Brown #include <mex.h>
690238ccf28SShri Abhyankar #undef __FUNCT__
691238ccf28SShri Abhyankar #define __FUNCT__ "PetscVFPrintf_Matlab"
6927087cfbeSBarry Smith PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
693238ccf28SShri Abhyankar {
694238ccf28SShri Abhyankar   PetscErrorCode ierr;
695238ccf28SShri Abhyankar 
696238ccf28SShri Abhyankar   PetscFunctionBegin;
697238ccf28SShri Abhyankar   if (fd != stdout && fd != stderr) { /* handle regular files */
698238ccf28SShri Abhyankar     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
699238ccf28SShri Abhyankar   } else {
700238ccf28SShri Abhyankar     size_t len=8*1024,length;
701238ccf28SShri Abhyankar     char   buf[len];
702238ccf28SShri Abhyankar 
703238ccf28SShri Abhyankar     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
704df413903SBarry Smith     mexPrintf("%s",buf);
705238ccf28SShri Abhyankar   }
706238ccf28SShri Abhyankar   PetscFunctionReturn(0);
707238ccf28SShri Abhyankar }
708238ccf28SShri Abhyankar #endif
7096fc7ef2bSBarry Smith 
7106fc7ef2bSBarry Smith #undef __FUNCT__
7118c74ee41SBarry Smith #define __FUNCT__ "PetscFormatStrip"
7128c74ee41SBarry Smith /*@C
7138c74ee41SBarry Smith      PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations
7148c74ee41SBarry Smith 
7158c74ee41SBarry Smith    Input Parameters:
7168c74ee41SBarry Smith .   format - the PETSc format string
7178c74ee41SBarry Smith 
7188c74ee41SBarry Smith  Level: developer
7198c74ee41SBarry Smith 
7208c74ee41SBarry Smith @*/
7218c74ee41SBarry Smith PetscErrorCode  PetscFormatStrip(char *format)
7228c74ee41SBarry Smith {
7238c74ee41SBarry Smith   size_t loc1 = 0, loc2 = 0;
7248c74ee41SBarry Smith 
7258c74ee41SBarry Smith   PetscFunctionBegin;
7268c74ee41SBarry Smith   while (format[loc2]) {
7278c74ee41SBarry Smith     if (format[loc2] == '%') {
7288c74ee41SBarry Smith       format[loc1++] = format[loc2++];
7298c74ee41SBarry Smith       while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++;
7308c74ee41SBarry Smith     }
7318c74ee41SBarry Smith     format[loc1++] = format[loc2++];
7328c74ee41SBarry Smith   }
7338c74ee41SBarry Smith   PetscFunctionReturn(0);
7348c74ee41SBarry Smith }
7358c74ee41SBarry Smith 
736