xref: /petsc/src/sys/fileio/mprint.c (revision 6fc7ef2bf116ea7e508976bc51f847a86697e13b)
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 /*
24b13499bfSbcordonn      Used to output to Zope
25b13499bfSbcordonn */
26b13499bfSbcordonn FILE *PETSC_ZOPEFD = 0;
27b13499bfSbcordonn 
28354e5084SJose Roman /*
29354e5084SJose Roman      Return the maximum expected new size of the format
30354e5084SJose Roman */
31354e5084SJose Roman #define PETSC_MAX_LENGTH_FORMAT(l) (l+l/8)
32354e5084SJose Roman 
33e5c89e4eSSatish Balay #undef __FUNCT__
34e5c89e4eSSatish Balay #define __FUNCT__ "PetscFormatConvert"
35c9a19010SBarry Smith /*@C
36c9a19010SBarry Smith      PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string
37c9a19010SBarry Smith 
38c9a19010SBarry Smith    Input Parameters:
39c9a19010SBarry Smith +   format - the PETSc format string
40c9a19010SBarry Smith .   newformat - the location to put the standard C format string values
41c9a19010SBarry Smith -   size - the length of newformat
42c9a19010SBarry Smith 
43eed5747fSBarry 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
44c9a19010SBarry Smith 
45c9a19010SBarry Smith  Level: developer
46c9a19010SBarry Smith 
47c9a19010SBarry Smith @*/
487087cfbeSBarry Smith PetscErrorCode  PetscFormatConvert(const char *format,char *newformat,size_t size)
49e5c89e4eSSatish Balay {
50e5c89e4eSSatish Balay   PetscInt i = 0,j = 0;
51e5c89e4eSSatish Balay 
52eed5747fSBarry Smith   PetscFunctionBegin;
537bc47156SJose Roman   while (format[i] && j < (PetscInt)size-1) {
547bc47156SJose Roman     if (format[i] == '%' && format[i+1] != '%') {
557bc47156SJose Roman       /* Find the letter */
567bc47156SJose Roman       for ( ; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i];
577bc47156SJose Roman       switch (format[i]) {
587bc47156SJose Roman       case 'D':
596de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
60e5c89e4eSSatish Balay         newformat[j++] = 'd';
61e5c89e4eSSatish Balay #else
62e5c89e4eSSatish Balay         newformat[j++] = 'l';
63e5c89e4eSSatish Balay         newformat[j++] = 'l';
64e5c89e4eSSatish Balay         newformat[j++] = 'd';
65e5c89e4eSSatish Balay #endif
667bc47156SJose Roman         break;
677bc47156SJose Roman       case 'G':
68ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_DOUBLE) || defined(PETSC_USE_REAL_SINGLE)
69a83599f4SBarry Smith         newformat[j++] = 'g';
70ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128)
71d9822059SBarry Smith         newformat[j++] = 'Q';
7257ddf7daSJose Roman         newformat[j++] = 'g';
73a83599f4SBarry Smith #endif
747bc47156SJose Roman         break;
75121a09c4SJose Roman       case 'F':
76121a09c4SJose Roman #if defined(PETSC_USE_REAL_DOUBLE) || defined(PETSC_USE_REAL_SINGLE)
77121a09c4SJose Roman         newformat[j++] = 'f';
78121a09c4SJose Roman #elif defined(PETSC_USE_REAL_LONG_DOUBLE)
79121a09c4SJose Roman         newformat[j++] = 'L';
80121a09c4SJose Roman         newformat[j++] = 'f';
81121a09c4SJose Roman #elif defined(PETSC_USE_REAL___FLOAT128)
82121a09c4SJose Roman         newformat[j++] = 'Q';
83121a09c4SJose Roman         newformat[j++] = 'f';
84121a09c4SJose Roman #endif
85121a09c4SJose Roman         break;
867bc47156SJose Roman       default:
877bc47156SJose Roman         newformat[j++] = format[i];
887bc47156SJose Roman         break;
897bc47156SJose Roman       }
907bc47156SJose Roman       i++;
91e5c89e4eSSatish Balay     } else {
92e5c89e4eSSatish Balay       newformat[j++] = format[i++];
93e5c89e4eSSatish Balay     }
94e5c89e4eSSatish Balay   }
95e5c89e4eSSatish Balay   newformat[j] = 0;
96eed5747fSBarry Smith   PetscFunctionReturn(0);
97e5c89e4eSSatish Balay }
98e5c89e4eSSatish Balay 
99e5c89e4eSSatish Balay #undef __FUNCT__
100e5c89e4eSSatish Balay #define __FUNCT__ "PetscVSNPrintf"
101c9a19010SBarry Smith /*@C
102c9a19010SBarry Smith      PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the
103c9a19010SBarry Smith        function arguments into a string using the format statement.
104c9a19010SBarry Smith 
105c9a19010SBarry Smith    Input Parameters:
106c9a19010SBarry Smith +   str - location to put result
107c9a19010SBarry Smith .   len - the amount of space in str
108c9a19010SBarry Smith +   format - the PETSc format string
109c9a19010SBarry Smith -   fullLength - the amount of space in str actually used.
110c9a19010SBarry Smith 
111eed5747fSBarry 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
112eed5747fSBarry Smith       a recursion will occur and possible crash.
113c9a19010SBarry Smith 
114c9a19010SBarry Smith  Level: developer
115c9a19010SBarry Smith 
116c9a19010SBarry Smith @*/
1177087cfbeSBarry Smith PetscErrorCode  PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp)
118e5c89e4eSSatish Balay {
119e2135aedSMatthew Knepley   char          *newformat;
120e2135aedSMatthew Knepley   char           formatbuf[8*1024];
1211a96acb8SJed Brown   size_t         oldLength,length;
1221a96acb8SJed Brown   int            fullLengthInt;
1231a15ef5dSMatthew Knepley   PetscErrorCode ierr;
124e5c89e4eSSatish Balay 
125eed5747fSBarry Smith   PetscFunctionBegin;
126e2135aedSMatthew Knepley   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
127e2135aedSMatthew Knepley   if (oldLength < 8*1024) {
128e2135aedSMatthew Knepley     newformat = formatbuf;
129354e5084SJose Roman     oldLength = 8*1024-1;
130e2135aedSMatthew Knepley   } else {
131354e5084SJose Roman     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
132354e5084SJose Roman     ierr = PetscMalloc(oldLength * sizeof(char), &newformat);CHKERRQ(ierr);
133e2135aedSMatthew Knepley   }
134354e5084SJose Roman   PetscFormatConvert(format,newformat,oldLength);
1351a15ef5dSMatthew Knepley   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
1362d609e63SMatthew Knepley #if 0
1371a15ef5dSMatthew Knepley   if (length > len) {
1381a15ef5dSMatthew Knepley     newformat[len] = '\0';
1391a15ef5dSMatthew Knepley   }
1402d609e63SMatthew Knepley #endif
1415a058713SBarry Smith #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
14242c7c0bfSJed Brown   fullLengthInt = vsnprintf(str,len,newformat,(char *)Argp);
14389b07760SSatish Balay #elif defined(PETSC_HAVE_VSNPRINTF)
14442c7c0bfSJed Brown   fullLengthInt = vsnprintf(str,len,newformat,Argp);
145141c0d65SSatish Balay #elif defined(PETSC_HAVE__VSNPRINTF)
14642c7c0bfSJed Brown   fullLengthInt = _vsnprintf(str,len,newformat,Argp);
147e5c89e4eSSatish Balay #else
14889b07760SSatish Balay #error "vsnprintf not found"
149e5c89e4eSSatish Balay #endif
15042c7c0bfSJed Brown   if (fullLengthInt < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"vsnprintf() failed");
15142c7c0bfSJed Brown   *fullLength = (size_t)fullLengthInt;
152e2135aedSMatthew Knepley   if (oldLength >= 8*1024) {
153e2135aedSMatthew Knepley     ierr = PetscFree(newformat);CHKERRQ(ierr);
154e2135aedSMatthew Knepley   }
155eed5747fSBarry Smith   PetscFunctionReturn(0);
156e5c89e4eSSatish Balay }
157e5c89e4eSSatish Balay 
158e5c89e4eSSatish Balay #undef __FUNCT__
1597ead4f01Sbcordonn #define __FUNCT__ "PetscZopeLog"
1607087cfbeSBarry Smith PetscErrorCode  PetscZopeLog(const char *format,va_list Argp)
1619c4c166aSBarry Smith {
1627ead4f01Sbcordonn   /* no malloc since may be called by error handler */
1637ead4f01Sbcordonn   char        newformat[8*1024];
1647ead4f01Sbcordonn   char        log[8*1024];
1657ead4f01Sbcordonn   char        logstart[] = " <<<log>>>";
166c9a19010SBarry Smith   size_t      len,formatlen;
1679c4c166aSBarry Smith 
1687ead4f01Sbcordonn   PetscFormatConvert(format,newformat,8*1024);
1697ead4f01Sbcordonn   PetscStrlen(logstart, &len);
1707ead4f01Sbcordonn   PetscMemcpy(log, logstart, len);
1717ead4f01Sbcordonn   PetscStrlen(newformat, &formatlen);
1727ead4f01Sbcordonn   PetscMemcpy(&(log[len]), newformat, formatlen);
1739c4c166aSBarry Smith   if (PETSC_ZOPEFD){
1745a058713SBarry Smith #if defined(PETSC_HAVE_VFPRINTF_CHAR)
1757ead4f01Sbcordonn     vfprintf(PETSC_ZOPEFD,log,(char *)Argp);
1767ead4f01Sbcordonn #else
1777ead4f01Sbcordonn     vfprintf(PETSC_ZOPEFD,log,Argp);
1787ead4f01Sbcordonn #endif
1795a058713SBarry Smith     fflush(PETSC_ZOPEFD);
1807ead4f01Sbcordonn   }
1817ead4f01Sbcordonn   return 0;
1827ead4f01Sbcordonn }
1837ead4f01Sbcordonn 
1847ead4f01Sbcordonn #undef __FUNCT__
185c9a19010SBarry Smith #define __FUNCT__ "PetscVFPrintfDefault"
186c9a19010SBarry Smith /*@C
187c9a19010SBarry Smith      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
188e5c89e4eSSatish Balay         can be replaced with something that does not simply write to a file.
189e5c89e4eSSatish Balay 
190c9a19010SBarry Smith       To use, write your own function for example,
191c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
192c9a19010SBarry Smith ${
193c9a19010SBarry Smith $  PetscErrorCode ierr;
194c9a19010SBarry Smith $
195c9a19010SBarry Smith $  PetscFunctionBegin;
196c9a19010SBarry Smith $   if (fd != stdout && fd != stderr) {  handle regular files
197c9a19010SBarry Smith $      ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERR(ierr);
198c9a19010SBarry Smith $  } else {
199c9a19010SBarry Smith $     char   buff[BIG];
200c9a19010SBarry Smith $     size_t length;
201c9a19010SBarry Smith $     ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr);
202c9a19010SBarry Smith $     now send buff to whatever stream or whatever you want
203c9a19010SBarry Smith $ }
204c9a19010SBarry Smith $ PetscFunctionReturn(0);
205c9a19010SBarry Smith $}
206c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
207c9a19010SBarry Smith $    PetscVFPrintf = mypetscvfprintf;
208c9a19010SBarry Smith 
209c9a19010SBarry Smith       Notes: For error messages this may be called by any process, for regular standard out it is
210e5c89e4eSSatish Balay           called only by process 0 of a given communicator
211e5c89e4eSSatish Balay 
212eed5747fSBarry Smith       Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur
213eed5747fSBarry Smith                        and a crash
214c9a19010SBarry Smith 
215c9a19010SBarry Smith   Level:  developer
216c9a19010SBarry Smith 
217c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf()
218c9a19010SBarry Smith 
219c9a19010SBarry Smith @*/
2207087cfbeSBarry Smith PetscErrorCode  PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
221e5c89e4eSSatish Balay {
222e2135aedSMatthew Knepley   char           *newformat;
223e2135aedSMatthew Knepley   char           formatbuf[8*1024];
224e2135aedSMatthew Knepley   size_t         oldLength;
225eed5747fSBarry Smith   PetscErrorCode ierr;
2261179db26SBarry Smith 
227eed5747fSBarry Smith   PetscFunctionBegin;
228eed5747fSBarry Smith   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
229e2135aedSMatthew Knepley   if (oldLength < 8*1024) {
230e2135aedSMatthew Knepley     newformat = formatbuf;
231354e5084SJose Roman     oldLength = 8*1024-1;
232e2135aedSMatthew Knepley   } else {
233354e5084SJose Roman     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
234eed5747fSBarry Smith     ierr = PetscMalloc(oldLength * sizeof(char), &newformat);CHKERRQ(ierr);
235e2135aedSMatthew Knepley   }
236eed5747fSBarry Smith   ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr);
237d8c6e182Sbcordonn 
2385a058713SBarry Smith #if defined(PETSC_HAVE_VFPRINTF_CHAR)
239e5c89e4eSSatish Balay   vfprintf(fd,newformat,(char *)Argp);
240e5c89e4eSSatish Balay #else
241e5c89e4eSSatish Balay   vfprintf(fd,newformat,Argp);
242e5c89e4eSSatish Balay #endif
2435a058713SBarry Smith   fflush(fd);
244e2135aedSMatthew Knepley   if (oldLength >= 8*1024) {
245eed5747fSBarry Smith     ierr = PetscFree(newformat);CHKERRQ(ierr);
246e2135aedSMatthew Knepley   }
247eed5747fSBarry Smith   PetscFunctionReturn(0);
248e5c89e4eSSatish Balay }
249e5c89e4eSSatish Balay 
2505b5bc046SBarry Smith #undef __FUNCT__
2515b5bc046SBarry Smith #define __FUNCT__ "PetscSNPrintf"
2525b5bc046SBarry Smith /*@C
2535b5bc046SBarry Smith     PetscSNPrintf - Prints to a string of given length
2545b5bc046SBarry Smith 
2555b5bc046SBarry Smith     Not Collective
2565b5bc046SBarry Smith 
2575b5bc046SBarry Smith     Input Parameters:
2585b5bc046SBarry Smith +   str - the string to print to
2595b5bc046SBarry Smith .   len - the length of str
2605b5bc046SBarry Smith .   format - the usual printf() format string
2615b5bc046SBarry Smith -   any arguments
2625b5bc046SBarry Smith 
2635b5bc046SBarry Smith    Level: intermediate
2645b5bc046SBarry Smith 
2655b5bc046SBarry Smith .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
2665b5bc046SBarry Smith           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
2675b5bc046SBarry Smith @*/
2687087cfbeSBarry Smith PetscErrorCode  PetscSNPrintf(char *str,size_t len,const char format[],...)
2695b5bc046SBarry Smith {
2705b5bc046SBarry Smith   PetscErrorCode ierr;
271c9a19010SBarry Smith   size_t         fullLength;
2725b5bc046SBarry Smith   va_list        Argp;
2735b5bc046SBarry Smith 
2745b5bc046SBarry Smith   PetscFunctionBegin;
2755b5bc046SBarry Smith   va_start(Argp,format);
2762d609e63SMatthew Knepley   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
2775b5bc046SBarry Smith   PetscFunctionReturn(0);
2785b5bc046SBarry Smith }
2795b5bc046SBarry Smith 
280257d2499SJed Brown #undef __FUNCT__
281257d2499SJed Brown #define __FUNCT__ "PetscSNPrintfCount"
282257d2499SJed Brown /*@C
283257d2499SJed Brown     PetscSNPrintfCount - Prints to a string of given length, returns count
284257d2499SJed Brown 
285257d2499SJed Brown     Not Collective
286257d2499SJed Brown 
287257d2499SJed Brown     Input Parameters:
288257d2499SJed Brown +   str - the string to print to
289257d2499SJed Brown .   len - the length of str
290257d2499SJed Brown .   format - the usual printf() format string
291257d2499SJed Brown .   countused - number of characters used
292257d2499SJed Brown -   any arguments
293257d2499SJed Brown 
294257d2499SJed Brown    Level: intermediate
295257d2499SJed Brown 
296257d2499SJed Brown .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
297257d2499SJed Brown           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf()
298257d2499SJed Brown @*/
299257d2499SJed Brown PetscErrorCode  PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...)
300257d2499SJed Brown {
301257d2499SJed Brown   PetscErrorCode ierr;
302257d2499SJed Brown   va_list        Argp;
303257d2499SJed Brown 
304257d2499SJed Brown   PetscFunctionBegin;
305257d2499SJed Brown   va_start(Argp,countused);
306257d2499SJed Brown   ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr);
307257d2499SJed Brown   PetscFunctionReturn(0);
308257d2499SJed Brown }
309257d2499SJed Brown 
310e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */
311e5c89e4eSSatish Balay 
312e5c89e4eSSatish Balay PrintfQueue queue       = 0,queuebase = 0;
313e5c89e4eSSatish Balay int         queuelength = 0;
314e5c89e4eSSatish Balay FILE        *queuefile  = PETSC_NULL;
315e5c89e4eSSatish Balay 
316e5c89e4eSSatish Balay #undef __FUNCT__
317e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedPrintf"
318e5c89e4eSSatish Balay /*@C
319e5c89e4eSSatish Balay     PetscSynchronizedPrintf - Prints synchronized output from several processors.
320e5c89e4eSSatish Balay     Output of the first processor is followed by that of the second, etc.
321e5c89e4eSSatish Balay 
322e5c89e4eSSatish Balay     Not Collective
323e5c89e4eSSatish Balay 
324e5c89e4eSSatish Balay     Input Parameters:
325e5c89e4eSSatish Balay +   comm - the communicator
326e5c89e4eSSatish Balay -   format - the usual printf() format string
327e5c89e4eSSatish Balay 
328e5c89e4eSSatish Balay    Level: intermediate
329e5c89e4eSSatish Balay 
330e5c89e4eSSatish Balay     Notes:
331e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
332e5c89e4eSSatish Balay     from all the processors to be printed.
333e5c89e4eSSatish Balay 
334e5c89e4eSSatish Balay     Fortran Note:
335d60d70ccSBarry Smith     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
336e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
337e5c89e4eSSatish Balay 
338e5c89e4eSSatish Balay .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
339e5c89e4eSSatish Balay           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
340e5c89e4eSSatish Balay @*/
3417087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
342e5c89e4eSSatish Balay {
343e5c89e4eSSatish Balay   PetscErrorCode ierr;
344e5c89e4eSSatish Balay   PetscMPIInt    rank;
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay   PetscFunctionBegin;
347e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
348e5c89e4eSSatish Balay 
349e5c89e4eSSatish Balay   /* First processor prints immediately to stdout */
350e5c89e4eSSatish Balay   if (!rank) {
351e5c89e4eSSatish Balay     va_list Argp;
352e5c89e4eSSatish Balay     va_start(Argp,format);
3531179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
354e5c89e4eSSatish Balay     if (petsc_history) {
355cdc7d174SSatish Balay       va_start(Argp,format);
3561179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
357e5c89e4eSSatish Balay     }
358e5c89e4eSSatish Balay     va_end(Argp);
359e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
360e5c89e4eSSatish Balay     va_list     Argp;
361e5c89e4eSSatish Balay     PrintfQueue next;
362c9a19010SBarry Smith     size_t      fullLength = 8191;
363e5c89e4eSSatish Balay 
364e5c89e4eSSatish Balay     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
365e5c89e4eSSatish Balay     if (queue) {queue->next = next; queue = next; queue->next = 0;}
366e5c89e4eSSatish Balay     else       {queuebase   = queue = next;}
367e5c89e4eSSatish Balay     queuelength++;
3682d609e63SMatthew Knepley     next->size = -1;
3699ad23270SJed Brown     while((PetscInt)fullLength >= next->size) {
3702d609e63SMatthew Knepley       next->size = fullLength+1;
3712d609e63SMatthew Knepley       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
372e5c89e4eSSatish Balay       va_start(Argp,format);
3732d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
3742d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
375e5c89e4eSSatish Balay       va_end(Argp);
376e5c89e4eSSatish Balay     }
3772d609e63SMatthew Knepley   }
378e5c89e4eSSatish Balay 
379e5c89e4eSSatish Balay   PetscFunctionReturn(0);
380e5c89e4eSSatish Balay }
381e5c89e4eSSatish Balay 
382e5c89e4eSSatish Balay #undef __FUNCT__
383e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFPrintf"
384e5c89e4eSSatish Balay /*@C
385e5c89e4eSSatish Balay     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
386e5c89e4eSSatish Balay     several processors.  Output of the first processor is followed by that of the
387e5c89e4eSSatish Balay     second, etc.
388e5c89e4eSSatish Balay 
389e5c89e4eSSatish Balay     Not Collective
390e5c89e4eSSatish Balay 
391e5c89e4eSSatish Balay     Input Parameters:
392e5c89e4eSSatish Balay +   comm - the communicator
393e5c89e4eSSatish Balay .   fd - the file pointer
394e5c89e4eSSatish Balay -   format - the usual printf() format string
395e5c89e4eSSatish Balay 
396e5c89e4eSSatish Balay     Level: intermediate
397e5c89e4eSSatish Balay 
398e5c89e4eSSatish Balay     Notes:
399e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
400e5c89e4eSSatish Balay     from all the processors to be printed.
401e5c89e4eSSatish Balay 
402e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
403e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
404e5c89e4eSSatish Balay 
405e5c89e4eSSatish Balay @*/
4067087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFPrintf(MPI_Comm comm,FILE* fp,const char format[],...)
407e5c89e4eSSatish Balay {
408e5c89e4eSSatish Balay   PetscErrorCode ierr;
409e5c89e4eSSatish Balay   PetscMPIInt    rank;
410e5c89e4eSSatish Balay 
411e5c89e4eSSatish Balay   PetscFunctionBegin;
412e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
413e5c89e4eSSatish Balay 
414e5c89e4eSSatish Balay   /* First processor prints immediately to fp */
415e5c89e4eSSatish Balay   if (!rank) {
416e5c89e4eSSatish Balay     va_list Argp;
417e5c89e4eSSatish Balay     va_start(Argp,format);
4181179db26SBarry Smith     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
419e5c89e4eSSatish Balay     queuefile = fp;
420cdc7d174SSatish Balay     if (petsc_history && (fp !=petsc_history)) {
421cdc7d174SSatish Balay       va_start(Argp,format);
4221179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
423e5c89e4eSSatish Balay     }
424e5c89e4eSSatish Balay     va_end(Argp);
425e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
426e5c89e4eSSatish Balay     va_list     Argp;
427e5c89e4eSSatish Balay     PrintfQueue next;
428c9a19010SBarry Smith     size_t      fullLength = 8191;
429e5c89e4eSSatish Balay     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
430e5c89e4eSSatish Balay     if (queue) {queue->next = next; queue = next; queue->next = 0;}
431e5c89e4eSSatish Balay     else       {queuebase   = queue = next;}
432e5c89e4eSSatish Balay     queuelength++;
4332d609e63SMatthew Knepley     next->size = -1;
4349ad23270SJed Brown     while((PetscInt)fullLength >= next->size) {
4352d609e63SMatthew Knepley       next->size = fullLength+1;
4362d609e63SMatthew Knepley       ierr = PetscMalloc(next->size * sizeof(char), &next->string);CHKERRQ(ierr);
437e5c89e4eSSatish Balay       va_start(Argp,format);
4382d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
4392d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
440e5c89e4eSSatish Balay       va_end(Argp);
441e5c89e4eSSatish Balay     }
4422d609e63SMatthew Knepley   }
443e5c89e4eSSatish Balay   PetscFunctionReturn(0);
444e5c89e4eSSatish Balay }
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay #undef __FUNCT__
447e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFlush"
448e30d2299SSatish Balay /*@
449e5c89e4eSSatish Balay     PetscSynchronizedFlush - Flushes to the screen output from all processors
450e5c89e4eSSatish Balay     involved in previous PetscSynchronizedPrintf() calls.
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay     Collective on MPI_Comm
453e5c89e4eSSatish Balay 
454e5c89e4eSSatish Balay     Input Parameters:
455e5c89e4eSSatish Balay .   comm - the communicator
456e5c89e4eSSatish Balay 
457e5c89e4eSSatish Balay     Level: intermediate
458e5c89e4eSSatish Balay 
459e5c89e4eSSatish Balay     Notes:
460e5c89e4eSSatish Balay     Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with
461e5c89e4eSSatish Balay     different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush().
462e5c89e4eSSatish Balay 
463e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
464e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf()
465e5c89e4eSSatish Balay @*/
4667087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm)
467e5c89e4eSSatish Balay {
468e5c89e4eSSatish Balay   PetscErrorCode ierr;
469bf3b0749SBarry Smith   PetscMPIInt    rank,size,tag,i,j,n,dummy = 0;
4702d609e63SMatthew Knepley   char          *message;
471e5c89e4eSSatish Balay   MPI_Status     status;
472e5c89e4eSSatish Balay   FILE           *fd;
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay   PetscFunctionBegin;
475e5c89e4eSSatish Balay   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
476e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
477e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
478e5c89e4eSSatish Balay 
479e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
480e5c89e4eSSatish Balay   if (!rank) {
481e5c89e4eSSatish Balay     if (queuefile) {
482e5c89e4eSSatish Balay       fd = queuefile;
483e5c89e4eSSatish Balay     } else {
484e5c89e4eSSatish Balay       fd = PETSC_STDOUT;
485e5c89e4eSSatish Balay     }
486e5c89e4eSSatish Balay     for (i=1; i<size; i++) {
4879f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
4889f73f8ecSBarry Smith       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
489e5c89e4eSSatish Balay       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
490e5c89e4eSSatish Balay       for (j=0; j<n; j++) {
4919f73f8ecSBarry Smith         PetscMPIInt size;
4922d609e63SMatthew Knepley 
4932d609e63SMatthew Knepley         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
4942d609e63SMatthew Knepley         ierr = PetscMalloc(size * sizeof(char), &message);CHKERRQ(ierr);
4952d609e63SMatthew Knepley         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
496e5c89e4eSSatish Balay         ierr = PetscFPrintf(comm,fd,"%s",message);
4972d609e63SMatthew Knepley         ierr = PetscFree(message);CHKERRQ(ierr);
498e5c89e4eSSatish Balay       }
499e5c89e4eSSatish Balay     }
500e5c89e4eSSatish Balay     queuefile = PETSC_NULL;
501e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
502e5c89e4eSSatish Balay     PrintfQueue next = queuebase,previous;
503e5c89e4eSSatish Balay 
504b3ef9d35SBarry Smith     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
505e5c89e4eSSatish Balay     ierr = MPI_Send(&queuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
506e5c89e4eSSatish Balay     for (i=0; i<queuelength; i++) {
5072d609e63SMatthew Knepley       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
5082d609e63SMatthew Knepley       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
509e5c89e4eSSatish Balay       previous = next;
510e5c89e4eSSatish Balay       next     = next->next;
5112d609e63SMatthew Knepley       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
512e5c89e4eSSatish Balay       ierr     = PetscFree(previous);CHKERRQ(ierr);
513e5c89e4eSSatish Balay     }
514e5c89e4eSSatish Balay     queue       = 0;
515e5c89e4eSSatish Balay     queuelength = 0;
516e5c89e4eSSatish Balay   }
517e5c89e4eSSatish Balay   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
518e5c89e4eSSatish Balay   PetscFunctionReturn(0);
519e5c89e4eSSatish Balay }
520e5c89e4eSSatish Balay 
521e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
522e5c89e4eSSatish Balay 
523e5c89e4eSSatish Balay #undef __FUNCT__
524e5c89e4eSSatish Balay #define __FUNCT__ "PetscFPrintf"
525e5c89e4eSSatish Balay /*@C
526e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
527e5c89e4eSSatish Balay     processor in the communicator.
528e5c89e4eSSatish Balay 
529e5c89e4eSSatish Balay     Not Collective
530e5c89e4eSSatish Balay 
531e5c89e4eSSatish Balay     Input Parameters:
532e5c89e4eSSatish Balay +   comm - the communicator
533e5c89e4eSSatish Balay .   fd - the file pointer
534e5c89e4eSSatish Balay -   format - the usual printf() format string
535e5c89e4eSSatish Balay 
536e5c89e4eSSatish Balay     Level: intermediate
537e5c89e4eSSatish Balay 
538e5c89e4eSSatish Balay     Fortran Note:
539e5c89e4eSSatish Balay     This routine is not supported in Fortran.
540e5c89e4eSSatish Balay 
541e5c89e4eSSatish Balay    Concepts: printing^in parallel
542e5c89e4eSSatish Balay    Concepts: printf^in parallel
543e5c89e4eSSatish Balay 
544e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
545e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
546e5c89e4eSSatish Balay @*/
5477087cfbeSBarry Smith PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
548e5c89e4eSSatish Balay {
549e5c89e4eSSatish Balay   PetscErrorCode ierr;
550e5c89e4eSSatish Balay   PetscMPIInt    rank;
551e5c89e4eSSatish Balay 
552e5c89e4eSSatish Balay   PetscFunctionBegin;
553e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
554e5c89e4eSSatish Balay   if (!rank) {
555e5c89e4eSSatish Balay     va_list Argp;
556e5c89e4eSSatish Balay     va_start(Argp,format);
5571179db26SBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
558cdc7d174SSatish Balay     if (petsc_history && (fd !=petsc_history)) {
559cdc7d174SSatish Balay       va_start(Argp,format);
5601179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
561e5c89e4eSSatish Balay       }
562e5c89e4eSSatish Balay     va_end(Argp);
563e5c89e4eSSatish Balay   }
564e5c89e4eSSatish Balay   PetscFunctionReturn(0);
565e5c89e4eSSatish Balay }
566e5c89e4eSSatish Balay 
567e5c89e4eSSatish Balay #undef __FUNCT__
568e5c89e4eSSatish Balay #define __FUNCT__ "PetscPrintf"
569e5c89e4eSSatish Balay /*@C
570e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
571eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
572e5c89e4eSSatish Balay 
573e5c89e4eSSatish Balay     Not Collective
574e5c89e4eSSatish Balay 
575e5c89e4eSSatish Balay     Input Parameters:
576e5c89e4eSSatish Balay +   comm - the communicator
577e5c89e4eSSatish Balay -   format - the usual printf() format string
578e5c89e4eSSatish Balay 
579e5c89e4eSSatish Balay    Level: intermediate
580e5c89e4eSSatish Balay 
581e5c89e4eSSatish Balay     Fortran Note:
582d60d70ccSBarry Smith     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
583e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
584e5c89e4eSSatish Balay 
585e5c89e4eSSatish Balay    Concepts: printing^in parallel
586e5c89e4eSSatish Balay    Concepts: printf^in parallel
587e5c89e4eSSatish Balay 
588e5c89e4eSSatish Balay .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
589e5c89e4eSSatish Balay @*/
5907087cfbeSBarry Smith PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
591e5c89e4eSSatish Balay {
592e5c89e4eSSatish Balay   PetscErrorCode ierr;
593e5c89e4eSSatish Balay   PetscMPIInt    rank;
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay   PetscFunctionBegin;
596e5c89e4eSSatish Balay   if (!comm) comm = PETSC_COMM_WORLD;
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);
601eed5747fSBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
602e5c89e4eSSatish Balay     if (petsc_history) {
603cdc7d174SSatish Balay       va_start(Argp,format);
604eed5747fSBarry 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 #undef __FUNCT__
613e5c89e4eSSatish Balay #define __FUNCT__ "PetscHelpPrintfDefault"
614c9a19010SBarry Smith /*@C
615c9a19010SBarry Smith      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
616c9a19010SBarry Smith         replacinng it  with something that does not simply write to a stdout.
617c9a19010SBarry Smith 
618c9a19010SBarry Smith       To use, write your own function for example,
619c9a19010SBarry Smith $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
620c9a19010SBarry Smith ${
621c9a19010SBarry Smith $ PetscFunctionReturn(0);
622c9a19010SBarry Smith $}
623c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
624c9a19010SBarry Smith $    PetscHelpPrintf = mypetschelpprintf;
625c9a19010SBarry Smith 
626c9a19010SBarry Smith   Note: the default routine used is called PetscHelpPrintfDefault().
627c9a19010SBarry Smith 
628c9a19010SBarry Smith   Level:  developer
629c9a19010SBarry Smith 
630c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
631c9a19010SBarry Smith @*/
6327087cfbeSBarry Smith PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
633e5c89e4eSSatish Balay {
634e5c89e4eSSatish Balay   PetscErrorCode ierr;
635e5c89e4eSSatish Balay   PetscMPIInt    rank;
636e5c89e4eSSatish Balay 
637e5c89e4eSSatish Balay   PetscFunctionBegin;
638e5c89e4eSSatish Balay   if (!comm) comm = PETSC_COMM_WORLD;
639e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
640e5c89e4eSSatish Balay   if (!rank) {
641e5c89e4eSSatish Balay     va_list Argp;
642e5c89e4eSSatish Balay     va_start(Argp,format);
6431179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
644e5c89e4eSSatish Balay     if (petsc_history) {
645cdc7d174SSatish Balay       va_start(Argp,format);
6461179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
647e5c89e4eSSatish Balay     }
648e5c89e4eSSatish Balay     va_end(Argp);
649e5c89e4eSSatish Balay   }
650e5c89e4eSSatish Balay   PetscFunctionReturn(0);
651e5c89e4eSSatish Balay }
652e5c89e4eSSatish Balay 
653e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
654e5c89e4eSSatish Balay 
655e5c89e4eSSatish Balay 
656e5c89e4eSSatish Balay #undef __FUNCT__
657e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFGets"
658e5c89e4eSSatish Balay /*@C
659e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
660e5c89e4eSSatish Balay 
661e5c89e4eSSatish Balay     Collective on MPI_Comm
662e5c89e4eSSatish Balay 
663e5c89e4eSSatish Balay     Input Parameters:
664e5c89e4eSSatish Balay +   comm - the communicator
665e5c89e4eSSatish Balay .   fd - the file pointer
666e5c89e4eSSatish Balay -   len - the length of the output buffer
667e5c89e4eSSatish Balay 
668e5c89e4eSSatish Balay     Output Parameter:
669e5c89e4eSSatish Balay .   string - the line read from the file
670e5c89e4eSSatish Balay 
671e5c89e4eSSatish Balay     Level: intermediate
672e5c89e4eSSatish Balay 
673e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
674e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
675e5c89e4eSSatish Balay 
676e5c89e4eSSatish Balay @*/
6777087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE* fp,size_t len,char string[])
678e5c89e4eSSatish Balay {
679e5c89e4eSSatish Balay   PetscErrorCode ierr;
680e5c89e4eSSatish Balay   PetscMPIInt    rank;
681e5c89e4eSSatish Balay 
682e5c89e4eSSatish Balay   PetscFunctionBegin;
683e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
684e5c89e4eSSatish Balay 
685e5c89e4eSSatish Balay   if (!rank) {
686047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
687047b9c12SMatthew G Knepley 
688047b9c12SMatthew G Knepley     if (!ptr) {
689047b9c12SMatthew G Knepley       if (feof(fp)) {
690047b9c12SMatthew G Knepley         len = 0;
6914c2b986eSBarry Smith       } else SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
692047b9c12SMatthew G Knepley     }
693e5c89e4eSSatish Balay   }
694e5c89e4eSSatish Balay   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
695e5c89e4eSSatish Balay   PetscFunctionReturn(0);
696e5c89e4eSSatish Balay }
697238ccf28SShri Abhyankar 
698238ccf28SShri Abhyankar #if defined(PETSC_HAVE_MATLAB_ENGINE)
699c6db04a5SJed Brown #include <mex.h>
700238ccf28SShri Abhyankar #undef __FUNCT__
701238ccf28SShri Abhyankar #define __FUNCT__ "PetscVFPrintf_Matlab"
7027087cfbeSBarry Smith PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
703238ccf28SShri Abhyankar {
704238ccf28SShri Abhyankar   PetscErrorCode ierr;
705238ccf28SShri Abhyankar 
706238ccf28SShri Abhyankar   PetscFunctionBegin;
707238ccf28SShri Abhyankar   if (fd != stdout && fd != stderr) { /* handle regular files */
708238ccf28SShri Abhyankar     ierr = PetscVFPrintfDefault(fd,format,Argp); CHKERRQ(ierr);
709238ccf28SShri Abhyankar   } else {
710238ccf28SShri Abhyankar     size_t len=8*1024,length;
711238ccf28SShri Abhyankar     char   buf[len];
712238ccf28SShri Abhyankar 
713238ccf28SShri Abhyankar     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
714df413903SBarry Smith     mexPrintf("%s",buf);
715238ccf28SShri Abhyankar  }
716238ccf28SShri Abhyankar  PetscFunctionReturn(0);
717238ccf28SShri Abhyankar }
718238ccf28SShri Abhyankar #endif
719*6fc7ef2bSBarry Smith 
720*6fc7ef2bSBarry Smith #undef __FUNCT__
721*6fc7ef2bSBarry Smith #define __FUNCT__ "PetscVFPrintfRegress"
722*6fc7ef2bSBarry Smith /*@C
723*6fc7ef2bSBarry Smith      PetscVFPrintfRegress -  Special version of PetscVFPrintf() to help make clean PETSc regression tests
724*6fc7ef2bSBarry Smith 
725*6fc7ef2bSBarry Smith   Level:  developer
726*6fc7ef2bSBarry Smith 
727*6fc7ef2bSBarry Smith   Developer Notes:
728*6fc7ef2bSBarry Smith        Since this routine knows exactly the data-types and formats of each of the arguments it could in theory do an appropriate
729*6fc7ef2bSBarry Smith        diff for each argument, rather than using a string diff on the entire result.
730*6fc7ef2bSBarry Smith 
731*6fc7ef2bSBarry Smith        So we should somehow loop over all the parts of the format string check that the string part matches and the arguments match
732*6fc7ef2bSBarry Smith        within a reasonable tolerance.
733*6fc7ef2bSBarry Smith 
734*6fc7ef2bSBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf()
735*6fc7ef2bSBarry Smith 
736*6fc7ef2bSBarry Smith @*/
737*6fc7ef2bSBarry Smith PetscErrorCode  PetscVFPrintfRegress(FILE *fd,const char *format,va_list Argp)
738*6fc7ef2bSBarry Smith {
739*6fc7ef2bSBarry Smith   char           *newformat;
740*6fc7ef2bSBarry Smith   char           formatbuf[8*1024];
741*6fc7ef2bSBarry Smith   size_t         oldLength;
742*6fc7ef2bSBarry Smith   PetscErrorCode ierr;
743*6fc7ef2bSBarry Smith 
744*6fc7ef2bSBarry Smith   PetscFunctionBegin;
745*6fc7ef2bSBarry Smith   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
746*6fc7ef2bSBarry Smith   if (oldLength < 8*1024) {
747*6fc7ef2bSBarry Smith     newformat = formatbuf;
748*6fc7ef2bSBarry Smith     oldLength = 8*1024-1;
749*6fc7ef2bSBarry Smith   } else {
750*6fc7ef2bSBarry Smith     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
751*6fc7ef2bSBarry Smith     ierr = PetscMalloc(oldLength * sizeof(char), &newformat);CHKERRQ(ierr);
752*6fc7ef2bSBarry Smith   }
753*6fc7ef2bSBarry Smith   ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr);
754*6fc7ef2bSBarry Smith 
755*6fc7ef2bSBarry Smith #if defined(PETSC_HAVE_VFPRINTF_CHAR)
756*6fc7ef2bSBarry Smith   vfprintf(fd,newformat,(char *)Argp);
757*6fc7ef2bSBarry Smith #else
758*6fc7ef2bSBarry Smith   vfprintf(fd,newformat,Argp);
759*6fc7ef2bSBarry Smith #endif
760*6fc7ef2bSBarry Smith   fflush(fd);
761*6fc7ef2bSBarry Smith   if (oldLength >= 8*1024) {
762*6fc7ef2bSBarry Smith     ierr = PetscFree(newformat);CHKERRQ(ierr);
763*6fc7ef2bSBarry Smith   }
764*6fc7ef2bSBarry Smith   PetscFunctionReturn(0);
765*6fc7ef2bSBarry Smith }
766