xref: /petsc/src/sys/fileio/mprint.c (revision e51f71cf5eb83487edb61dade44d075cb7e6a452)
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;
1061a15ef5dSMatthew Knepley   PetscErrorCode ierr;
107e5c89e4eSSatish Balay 
108eed5747fSBarry Smith   PetscFunctionBegin;
109e2135aedSMatthew Knepley   ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr);
110e2135aedSMatthew Knepley   if (oldLength < 8*1024) {
111e2135aedSMatthew Knepley     newformat = formatbuf;
112354e5084SJose Roman     oldLength = 8*1024-1;
113e2135aedSMatthew Knepley   } else {
114354e5084SJose Roman     oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength);
115785e854fSJed Brown     ierr      = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr);
116e2135aedSMatthew Knepley   }
117354e5084SJose Roman   PetscFormatConvert(format,newformat,oldLength);
1181a15ef5dSMatthew Knepley   ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr);
1192d609e63SMatthew Knepley #if 0
120a297a907SKarl Rupp   if (length > len) newformat[len] = '\0';
1212d609e63SMatthew Knepley #endif
1225a058713SBarry Smith #if defined(PETSC_HAVE_VSNPRINTF_CHAR)
123748e1b9dSBarry Smith   (void) vsnprintf(str,len,newformat,(char*)Argp);
12489b07760SSatish Balay #elif defined(PETSC_HAVE_VSNPRINTF)
125748e1b9dSBarry Smith   (void) vsnprintf(str,len,newformat,Argp);
126141c0d65SSatish Balay #elif defined(PETSC_HAVE__VSNPRINTF)
127748e1b9dSBarry Smith   (void) _vsnprintf(str,len,newformat,Argp);
128e5c89e4eSSatish Balay #else
12989b07760SSatish Balay #error "vsnprintf not found"
130e5c89e4eSSatish Balay #endif
131e2135aedSMatthew Knepley   if (oldLength >= 8*1024) {
132e2135aedSMatthew Knepley     ierr = PetscFree(newformat);CHKERRQ(ierr);
133e2135aedSMatthew Knepley   }
134748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
135*e51f71cfSBarry Smith   /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */
136748e1b9dSBarry Smith   {
137748e1b9dSBarry Smith     size_t cnt = 0,ncnt = 0,leng;
138748e1b9dSBarry Smith     ierr = PetscStrlen(str,&leng);CHKERRQ(ierr);
139748e1b9dSBarry Smith     if (leng > 5) {
140748e1b9dSBarry Smith       for (cnt=0; cnt<leng-4; cnt++) {
141*e51f71cfSBarry 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') {
142748e1b9dSBarry Smith           str[ncnt] = str[cnt]; ncnt++; cnt++;
143*e51f71cfSBarry Smith           str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++;
144*e51f71cfSBarry Smith           str[ncnt] = str[cnt];
145748e1b9dSBarry Smith         } else {
146748e1b9dSBarry Smith           str[ncnt] = str[cnt];
147748e1b9dSBarry Smith         }
148748e1b9dSBarry Smith         ncnt++;
149748e1b9dSBarry Smith       }
150748e1b9dSBarry Smith       while (cnt < leng) {
151748e1b9dSBarry Smith         str[ncnt] = str[cnt]; ncnt++; cnt++;
152748e1b9dSBarry Smith       }
153748e1b9dSBarry Smith       str[ncnt] = 0;
154748e1b9dSBarry Smith     }
155748e1b9dSBarry Smith   }
156748e1b9dSBarry Smith #endif
157748e1b9dSBarry Smith   if (fullLength) {
158748e1b9dSBarry Smith     ierr = PetscStrlen(str,fullLength);CHKERRQ(ierr);
159748e1b9dSBarry Smith   }
160eed5747fSBarry Smith   PetscFunctionReturn(0);
161e5c89e4eSSatish Balay }
162e5c89e4eSSatish Balay 
163e5c89e4eSSatish Balay #undef __FUNCT__
164c9a19010SBarry Smith #define __FUNCT__ "PetscVFPrintfDefault"
165c9a19010SBarry Smith /*@C
166c9a19010SBarry Smith      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
167e5c89e4eSSatish Balay         can be replaced with something that does not simply write to a file.
168e5c89e4eSSatish Balay 
169c9a19010SBarry Smith       To use, write your own function for example,
170c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
171c9a19010SBarry Smith ${
172c9a19010SBarry Smith $  PetscErrorCode ierr;
173c9a19010SBarry Smith $
174c9a19010SBarry Smith $  PetscFunctionBegin;
175c9a19010SBarry Smith $   if (fd != stdout && fd != stderr) {  handle regular files
176c9a19010SBarry Smith $      ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr);
177c9a19010SBarry Smith $  } else {
178c9a19010SBarry Smith $     char   buff[BIG];
179c9a19010SBarry Smith $     size_t length;
180c9a19010SBarry Smith $     ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr);
181c9a19010SBarry Smith $     now send buff to whatever stream or whatever you want
182c9a19010SBarry Smith $ }
183c9a19010SBarry Smith $ PetscFunctionReturn(0);
184c9a19010SBarry Smith $}
185c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
186c9a19010SBarry Smith $    PetscVFPrintf = mypetscvfprintf;
187c9a19010SBarry Smith 
188c9a19010SBarry Smith       Notes: For error messages this may be called by any process, for regular standard out it is
189e5c89e4eSSatish Balay           called only by process 0 of a given communicator
190e5c89e4eSSatish Balay 
191eed5747fSBarry Smith       Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur
192eed5747fSBarry Smith                        and a crash
193c9a19010SBarry Smith 
194c9a19010SBarry Smith   Level:  developer
195c9a19010SBarry Smith 
196c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscErrorPrintf()
197c9a19010SBarry Smith 
198c9a19010SBarry Smith @*/
1997087cfbeSBarry Smith PetscErrorCode  PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp)
200e5c89e4eSSatish Balay {
201748e1b9dSBarry Smith   char           str[8*1024];
202eed5747fSBarry Smith   PetscErrorCode ierr;
2031179db26SBarry Smith 
204eed5747fSBarry Smith   PetscFunctionBegin;
205748e1b9dSBarry Smith   ierr = PetscVSNPrintf(str,sizeof(str),format,NULL,Argp);CHKERRQ(ierr);
206748e1b9dSBarry Smith   fprintf(fd,"%s",str);CHKERRQ(ierr);
2075a058713SBarry Smith   fflush(fd);
208eed5747fSBarry Smith   PetscFunctionReturn(0);
209e5c89e4eSSatish Balay }
210e5c89e4eSSatish Balay 
2115b5bc046SBarry Smith #undef __FUNCT__
2125b5bc046SBarry Smith #define __FUNCT__ "PetscSNPrintf"
2135b5bc046SBarry Smith /*@C
2145b5bc046SBarry Smith     PetscSNPrintf - Prints to a string of given length
2155b5bc046SBarry Smith 
2165b5bc046SBarry Smith     Not Collective
2175b5bc046SBarry Smith 
2185b5bc046SBarry Smith     Input Parameters:
2195b5bc046SBarry Smith +   str - the string to print to
2205b5bc046SBarry Smith .   len - the length of str
2215b5bc046SBarry Smith .   format - the usual printf() format string
2225b5bc046SBarry Smith -   any arguments
2235b5bc046SBarry Smith 
2245b5bc046SBarry Smith    Level: intermediate
2255b5bc046SBarry Smith 
2265b5bc046SBarry Smith .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
2275b5bc046SBarry Smith           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
2285b5bc046SBarry Smith @*/
2297087cfbeSBarry Smith PetscErrorCode  PetscSNPrintf(char *str,size_t len,const char format[],...)
2305b5bc046SBarry Smith {
2315b5bc046SBarry Smith   PetscErrorCode ierr;
232c9a19010SBarry Smith   size_t         fullLength;
2335b5bc046SBarry Smith   va_list        Argp;
2345b5bc046SBarry Smith 
2355b5bc046SBarry Smith   PetscFunctionBegin;
2365b5bc046SBarry Smith   va_start(Argp,format);
2372d609e63SMatthew Knepley   ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr);
2385b5bc046SBarry Smith   PetscFunctionReturn(0);
2395b5bc046SBarry Smith }
2405b5bc046SBarry Smith 
241257d2499SJed Brown #undef __FUNCT__
242257d2499SJed Brown #define __FUNCT__ "PetscSNPrintfCount"
243257d2499SJed Brown /*@C
244257d2499SJed Brown     PetscSNPrintfCount - Prints to a string of given length, returns count
245257d2499SJed Brown 
246257d2499SJed Brown     Not Collective
247257d2499SJed Brown 
248257d2499SJed Brown     Input Parameters:
249257d2499SJed Brown +   str - the string to print to
250257d2499SJed Brown .   len - the length of str
251257d2499SJed Brown .   format - the usual printf() format string
252257d2499SJed Brown .   countused - number of characters used
253257d2499SJed Brown -   any arguments
254257d2499SJed Brown 
255257d2499SJed Brown    Level: intermediate
256257d2499SJed Brown 
257257d2499SJed Brown .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(),
258257d2499SJed Brown           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf()
259257d2499SJed Brown @*/
260257d2499SJed Brown PetscErrorCode  PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...)
261257d2499SJed Brown {
262257d2499SJed Brown   PetscErrorCode ierr;
263257d2499SJed Brown   va_list        Argp;
264257d2499SJed Brown 
265257d2499SJed Brown   PetscFunctionBegin;
266257d2499SJed Brown   va_start(Argp,countused);
267257d2499SJed Brown   ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr);
268257d2499SJed Brown   PetscFunctionReturn(0);
269257d2499SJed Brown }
270257d2499SJed Brown 
271e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */
272e5c89e4eSSatish Balay 
273d30b0576SJed Brown PrintfQueue petsc_printfqueue       = 0,petsc_printfqueuebase = 0;
274d30b0576SJed Brown int         petsc_printfqueuelength = 0;
275e5c89e4eSSatish Balay 
276e5c89e4eSSatish Balay #undef __FUNCT__
277e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedPrintf"
278e5c89e4eSSatish Balay /*@C
279e5c89e4eSSatish Balay     PetscSynchronizedPrintf - Prints synchronized output from several processors.
280e5c89e4eSSatish Balay     Output of the first processor is followed by that of the second, etc.
281e5c89e4eSSatish Balay 
282e5c89e4eSSatish Balay     Not Collective
283e5c89e4eSSatish Balay 
284e5c89e4eSSatish Balay     Input Parameters:
285e5c89e4eSSatish Balay +   comm - the communicator
286e5c89e4eSSatish Balay -   format - the usual printf() format string
287e5c89e4eSSatish Balay 
288e5c89e4eSSatish Balay    Level: intermediate
289e5c89e4eSSatish Balay 
290e5c89e4eSSatish Balay     Notes:
291e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
292e5c89e4eSSatish Balay     from all the processors to be printed.
293e5c89e4eSSatish Balay 
294e5c89e4eSSatish Balay     Fortran Note:
295d60d70ccSBarry Smith     The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
296e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
297e5c89e4eSSatish Balay 
298e5c89e4eSSatish Balay .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(),
299e5c89e4eSSatish Balay           PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
300e5c89e4eSSatish Balay @*/
3017087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...)
302e5c89e4eSSatish Balay {
303e5c89e4eSSatish Balay   PetscErrorCode ierr;
304e5c89e4eSSatish Balay   PetscMPIInt    rank;
305e5c89e4eSSatish Balay 
306e5c89e4eSSatish Balay   PetscFunctionBegin;
3076180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
308e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
309e5c89e4eSSatish Balay 
310e5c89e4eSSatish Balay   /* First processor prints immediately to stdout */
311e5c89e4eSSatish Balay   if (!rank) {
312e5c89e4eSSatish Balay     va_list Argp;
313e5c89e4eSSatish Balay     va_start(Argp,format);
3141179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
315e5c89e4eSSatish Balay     if (petsc_history) {
316cdc7d174SSatish Balay       va_start(Argp,format);
3171179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
318e5c89e4eSSatish Balay     }
319e5c89e4eSSatish Balay     va_end(Argp);
320e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
321e5c89e4eSSatish Balay     va_list     Argp;
322e5c89e4eSSatish Balay     PrintfQueue next;
323c9a19010SBarry Smith     size_t      fullLength = 8191;
324e5c89e4eSSatish Balay 
325b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
326a297a907SKarl Rupp     if (petsc_printfqueue) {
327a297a907SKarl Rupp       petsc_printfqueue->next = next;
328a297a907SKarl Rupp       petsc_printfqueue       = next;
329a297a907SKarl Rupp       petsc_printfqueue->next = 0;
330a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
331d30b0576SJed Brown     petsc_printfqueuelength++;
3322d609e63SMatthew Knepley     next->size = -1;
3339ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
3342d609e63SMatthew Knepley       next->size = fullLength+1;
335a297a907SKarl Rupp 
336785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
337e5c89e4eSSatish Balay       va_start(Argp,format);
3382d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
3392d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr);
340e5c89e4eSSatish Balay       va_end(Argp);
341e5c89e4eSSatish Balay     }
3422d609e63SMatthew Knepley   }
343e5c89e4eSSatish Balay   PetscFunctionReturn(0);
344e5c89e4eSSatish Balay }
345e5c89e4eSSatish Balay 
346e5c89e4eSSatish Balay #undef __FUNCT__
347e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFPrintf"
348e5c89e4eSSatish Balay /*@C
349e5c89e4eSSatish Balay     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
350e5c89e4eSSatish Balay     several processors.  Output of the first processor is followed by that of the
351e5c89e4eSSatish Balay     second, etc.
352e5c89e4eSSatish Balay 
353e5c89e4eSSatish Balay     Not Collective
354e5c89e4eSSatish Balay 
355e5c89e4eSSatish Balay     Input Parameters:
356e5c89e4eSSatish Balay +   comm - the communicator
357e5c89e4eSSatish Balay .   fd - the file pointer
358e5c89e4eSSatish Balay -   format - the usual printf() format string
359e5c89e4eSSatish Balay 
360e5c89e4eSSatish Balay     Level: intermediate
361e5c89e4eSSatish Balay 
362e5c89e4eSSatish Balay     Notes:
363e5c89e4eSSatish Balay     REQUIRES a intervening call to PetscSynchronizedFlush() for the information
364e5c89e4eSSatish Balay     from all the processors to be printed.
365e5c89e4eSSatish Balay 
366e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
367e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
368e5c89e4eSSatish Balay 
369e5c89e4eSSatish Balay @*/
3707087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...)
371e5c89e4eSSatish Balay {
372e5c89e4eSSatish Balay   PetscErrorCode ierr;
373e5c89e4eSSatish Balay   PetscMPIInt    rank;
374e5c89e4eSSatish Balay 
375e5c89e4eSSatish Balay   PetscFunctionBegin;
3766180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
377e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
378e5c89e4eSSatish Balay 
379e5c89e4eSSatish Balay   /* First processor prints immediately to fp */
380e5c89e4eSSatish Balay   if (!rank) {
381e5c89e4eSSatish Balay     va_list Argp;
382e5c89e4eSSatish Balay     va_start(Argp,format);
3831179db26SBarry Smith     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
384cdc7d174SSatish Balay     if (petsc_history && (fp !=petsc_history)) {
385cdc7d174SSatish Balay       va_start(Argp,format);
3861179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
387e5c89e4eSSatish Balay     }
388e5c89e4eSSatish Balay     va_end(Argp);
389e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
390e5c89e4eSSatish Balay     va_list     Argp;
391e5c89e4eSSatish Balay     PrintfQueue next;
392c9a19010SBarry Smith     size_t      fullLength = 8191;
393b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
394a297a907SKarl Rupp     if (petsc_printfqueue) {
395a297a907SKarl Rupp       petsc_printfqueue->next = next;
396a297a907SKarl Rupp       petsc_printfqueue       = next;
397a297a907SKarl Rupp       petsc_printfqueue->next = 0;
398a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
399d30b0576SJed Brown     petsc_printfqueuelength++;
4002d609e63SMatthew Knepley     next->size = -1;
4019ad23270SJed Brown     while ((PetscInt)fullLength >= next->size) {
4022d609e63SMatthew Knepley       next->size = fullLength+1;
403785e854fSJed Brown       ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
404e5c89e4eSSatish Balay       va_start(Argp,format);
4052d609e63SMatthew Knepley       ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
4062d609e63SMatthew Knepley       ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr);
407e5c89e4eSSatish Balay       va_end(Argp);
408e5c89e4eSSatish Balay     }
4092d609e63SMatthew Knepley   }
410e5c89e4eSSatish Balay   PetscFunctionReturn(0);
411e5c89e4eSSatish Balay }
412e5c89e4eSSatish Balay 
413e5c89e4eSSatish Balay #undef __FUNCT__
414e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFlush"
4150ec8b6e3SBarry Smith /*@C
416e5c89e4eSSatish Balay     PetscSynchronizedFlush - Flushes to the screen output from all processors
417e5c89e4eSSatish Balay     involved in previous PetscSynchronizedPrintf() calls.
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay     Collective on MPI_Comm
420e5c89e4eSSatish Balay 
421e5c89e4eSSatish Balay     Input Parameters:
4220ec8b6e3SBarry Smith +   comm - the communicator
4230ec8b6e3SBarry Smith -   fd - the file pointer (valid on process 0 of the communicator)
424e5c89e4eSSatish Balay 
425e5c89e4eSSatish Balay     Level: intermediate
426e5c89e4eSSatish Balay 
427e5c89e4eSSatish Balay     Notes:
428e5c89e4eSSatish Balay     Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with
429e5c89e4eSSatish Balay     different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush().
430e5c89e4eSSatish Balay 
431e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(),
432e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf()
4330087d953SMatthew G. Knepley @*/
4340ec8b6e3SBarry Smith PetscErrorCode  PetscSynchronizedFlush(MPI_Comm comm,FILE *fd)
435e5c89e4eSSatish Balay {
436e5c89e4eSSatish Balay   PetscErrorCode ierr;
43729a5cbdcSMatthew G. Knepley   PetscMPIInt    rank,size,tag,i,j,n = 0,dummy = 0;
4382d609e63SMatthew Knepley   char          *message;
439e5c89e4eSSatish Balay   MPI_Status     status;
440e5c89e4eSSatish Balay 
441e5c89e4eSSatish Balay   PetscFunctionBegin;
442e5c89e4eSSatish Balay   ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
443e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
444e5c89e4eSSatish Balay   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
447e5c89e4eSSatish Balay   if (!rank) {
4480ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
449e5c89e4eSSatish Balay     for (i=1; i<size; i++) {
4509f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
4519f73f8ecSBarry Smith       ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
452e5c89e4eSSatish Balay       ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
453e5c89e4eSSatish Balay       for (j=0; j<n; j++) {
45429a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
4552d609e63SMatthew Knepley 
4562d609e63SMatthew Knepley         ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
457785e854fSJed Brown         ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
4582d609e63SMatthew Knepley         ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
4593bf036e2SBarry Smith         ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
4602d609e63SMatthew Knepley         ierr = PetscFree(message);CHKERRQ(ierr);
461e5c89e4eSSatish Balay       }
462e5c89e4eSSatish Balay     }
463e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
464d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase,previous;
465e5c89e4eSSatish Balay 
466b3ef9d35SBarry Smith     ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
467d30b0576SJed Brown     ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
468d30b0576SJed Brown     for (i=0; i<petsc_printfqueuelength; i++) {
4692d609e63SMatthew Knepley       ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
4702d609e63SMatthew Knepley       ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
471e5c89e4eSSatish Balay       previous = next;
472e5c89e4eSSatish Balay       next     = next->next;
4732d609e63SMatthew Knepley       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
474e5c89e4eSSatish Balay       ierr     = PetscFree(previous);CHKERRQ(ierr);
475e5c89e4eSSatish Balay     }
476d30b0576SJed Brown     petsc_printfqueue       = 0;
477d30b0576SJed Brown     petsc_printfqueuelength = 0;
478e5c89e4eSSatish Balay   }
479e5c89e4eSSatish Balay   ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
480e5c89e4eSSatish Balay   PetscFunctionReturn(0);
481e5c89e4eSSatish Balay }
482e5c89e4eSSatish Balay 
483e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay #undef __FUNCT__
486e5c89e4eSSatish Balay #define __FUNCT__ "PetscFPrintf"
487e5c89e4eSSatish Balay /*@C
488e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
489e5c89e4eSSatish Balay     processor in the communicator.
490e5c89e4eSSatish Balay 
491e5c89e4eSSatish Balay     Not Collective
492e5c89e4eSSatish Balay 
493e5c89e4eSSatish Balay     Input Parameters:
494e5c89e4eSSatish Balay +   comm - the communicator
495e5c89e4eSSatish Balay .   fd - the file pointer
496e5c89e4eSSatish Balay -   format - the usual printf() format string
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay     Level: intermediate
499e5c89e4eSSatish Balay 
500e5c89e4eSSatish Balay     Fortran Note:
501e5c89e4eSSatish Balay     This routine is not supported in Fortran.
502e5c89e4eSSatish Balay 
503e5c89e4eSSatish Balay    Concepts: printing^in parallel
504e5c89e4eSSatish Balay    Concepts: printf^in parallel
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
507e5c89e4eSSatish Balay           PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush()
508e5c89e4eSSatish Balay @*/
5097087cfbeSBarry Smith PetscErrorCode  PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...)
510e5c89e4eSSatish Balay {
511e5c89e4eSSatish Balay   PetscErrorCode ierr;
512e5c89e4eSSatish Balay   PetscMPIInt    rank;
513e5c89e4eSSatish Balay 
514e5c89e4eSSatish Balay   PetscFunctionBegin;
5156180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
516e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
517e5c89e4eSSatish Balay   if (!rank) {
518e5c89e4eSSatish Balay     va_list Argp;
519e5c89e4eSSatish Balay     va_start(Argp,format);
5201179db26SBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
521cdc7d174SSatish Balay     if (petsc_history && (fd !=petsc_history)) {
522cdc7d174SSatish Balay       va_start(Argp,format);
5231179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
524e5c89e4eSSatish Balay     }
525e5c89e4eSSatish Balay     va_end(Argp);
526e5c89e4eSSatish Balay   }
527e5c89e4eSSatish Balay   PetscFunctionReturn(0);
528e5c89e4eSSatish Balay }
529e5c89e4eSSatish Balay 
530e5c89e4eSSatish Balay #undef __FUNCT__
531e5c89e4eSSatish Balay #define __FUNCT__ "PetscPrintf"
532e5c89e4eSSatish Balay /*@C
533e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
534eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
535e5c89e4eSSatish Balay 
536e5c89e4eSSatish Balay     Not Collective
537e5c89e4eSSatish Balay 
538e5c89e4eSSatish Balay     Input Parameters:
539e5c89e4eSSatish Balay +   comm - the communicator
540e5c89e4eSSatish Balay -   format - the usual printf() format string
541e5c89e4eSSatish Balay 
542e5c89e4eSSatish Balay    Level: intermediate
543e5c89e4eSSatish Balay 
544e5c89e4eSSatish Balay     Fortran Note:
545d60d70ccSBarry Smith     The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
546e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
547e5c89e4eSSatish Balay 
548e5c89e4eSSatish Balay    Concepts: printing^in parallel
549e5c89e4eSSatish Balay    Concepts: printf^in parallel
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay .seealso: PetscFPrintf(), PetscSynchronizedPrintf()
552e5c89e4eSSatish Balay @*/
5537087cfbeSBarry Smith PetscErrorCode  PetscPrintf(MPI_Comm comm,const char format[],...)
554e5c89e4eSSatish Balay {
555e5c89e4eSSatish Balay   PetscErrorCode ierr;
556e5c89e4eSSatish Balay   PetscMPIInt    rank;
557e5c89e4eSSatish Balay 
558e5c89e4eSSatish Balay   PetscFunctionBegin;
5596180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
560e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
561e5c89e4eSSatish Balay   if (!rank) {
562e5c89e4eSSatish Balay     va_list Argp;
563e5c89e4eSSatish Balay     va_start(Argp,format);
564eed5747fSBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
565e5c89e4eSSatish Balay     if (petsc_history) {
566cdc7d174SSatish Balay       va_start(Argp,format);
567eed5747fSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
568e5c89e4eSSatish Balay     }
569e5c89e4eSSatish Balay     va_end(Argp);
570e5c89e4eSSatish Balay   }
571e5c89e4eSSatish Balay   PetscFunctionReturn(0);
572e5c89e4eSSatish Balay }
573e5c89e4eSSatish Balay 
574e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
575e5c89e4eSSatish Balay #undef __FUNCT__
576e5c89e4eSSatish Balay #define __FUNCT__ "PetscHelpPrintfDefault"
577c9a19010SBarry Smith /*@C
578c9a19010SBarry Smith      PetscHelpPrintf -  All PETSc help messages are passing through this function. You can change how help messages are printed by
579c9a19010SBarry Smith         replacinng it  with something that does not simply write to a stdout.
580c9a19010SBarry Smith 
581c9a19010SBarry Smith       To use, write your own function for example,
582c9a19010SBarry Smith $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....)
583c9a19010SBarry Smith ${
584c9a19010SBarry Smith $ PetscFunctionReturn(0);
585c9a19010SBarry Smith $}
586c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
587c9a19010SBarry Smith $    PetscHelpPrintf = mypetschelpprintf;
588c9a19010SBarry Smith 
589c9a19010SBarry Smith   Note: the default routine used is called PetscHelpPrintfDefault().
590c9a19010SBarry Smith 
591c9a19010SBarry Smith   Level:  developer
592c9a19010SBarry Smith 
593c9a19010SBarry Smith .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf()
594c9a19010SBarry Smith @*/
5957087cfbeSBarry Smith PetscErrorCode  PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...)
596e5c89e4eSSatish Balay {
597e5c89e4eSSatish Balay   PetscErrorCode ierr;
598e5c89e4eSSatish Balay   PetscMPIInt    rank;
599e5c89e4eSSatish Balay 
600e5c89e4eSSatish Balay   PetscFunctionBegin;
6016180deefSBarry Smith   if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
602e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
603e5c89e4eSSatish Balay   if (!rank) {
604e5c89e4eSSatish Balay     va_list Argp;
605e5c89e4eSSatish Balay     va_start(Argp,format);
6061179db26SBarry Smith     ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr);
607e5c89e4eSSatish Balay     if (petsc_history) {
608cdc7d174SSatish Balay       va_start(Argp,format);
6091179db26SBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
610e5c89e4eSSatish Balay     }
611e5c89e4eSSatish Balay     va_end(Argp);
612e5c89e4eSSatish Balay   }
613e5c89e4eSSatish Balay   PetscFunctionReturn(0);
614e5c89e4eSSatish Balay }
615e5c89e4eSSatish Balay 
616e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
617e5c89e4eSSatish Balay 
618e5c89e4eSSatish Balay 
619e5c89e4eSSatish Balay #undef __FUNCT__
620e5c89e4eSSatish Balay #define __FUNCT__ "PetscSynchronizedFGets"
621e5c89e4eSSatish Balay /*@C
622e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
623e5c89e4eSSatish Balay 
624e5c89e4eSSatish Balay     Collective on MPI_Comm
625e5c89e4eSSatish Balay 
626e5c89e4eSSatish Balay     Input Parameters:
627e5c89e4eSSatish Balay +   comm - the communicator
628e5c89e4eSSatish Balay .   fd - the file pointer
629e5c89e4eSSatish Balay -   len - the length of the output buffer
630e5c89e4eSSatish Balay 
631e5c89e4eSSatish Balay     Output Parameter:
632e31d4fa4SJed Brown .   string - the line read from the file, at end of file string[0] == 0
633e5c89e4eSSatish Balay 
634e5c89e4eSSatish Balay     Level: intermediate
635e5c89e4eSSatish Balay 
636e5c89e4eSSatish Balay .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
637e5c89e4eSSatish Balay           PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf()
638e5c89e4eSSatish Balay 
639e5c89e4eSSatish Balay @*/
6407087cfbeSBarry Smith PetscErrorCode  PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[])
641e5c89e4eSSatish Balay {
642e5c89e4eSSatish Balay   PetscErrorCode ierr;
643e5c89e4eSSatish Balay   PetscMPIInt    rank;
644e5c89e4eSSatish Balay 
645e5c89e4eSSatish Balay   PetscFunctionBegin;
646e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
647e5c89e4eSSatish Balay 
648e5c89e4eSSatish Balay   if (!rank) {
649047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
650047b9c12SMatthew G Knepley 
651047b9c12SMatthew G Knepley     if (!ptr) {
652e31d4fa4SJed Brown       string[0] = 0;
653e31d4fa4SJed Brown       if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
654047b9c12SMatthew G Knepley     }
655e5c89e4eSSatish Balay   }
656e5c89e4eSSatish Balay   ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr);
657e5c89e4eSSatish Balay   PetscFunctionReturn(0);
658e5c89e4eSSatish Balay }
659238ccf28SShri Abhyankar 
660f1d7fe2eSBarry Smith #if defined(PETSC_HAVE_CLOSURES)
661f1d7fe2eSBarry Smith int (^SwiftClosure)(const char*) = 0;
662f1d7fe2eSBarry Smith 
663f1d7fe2eSBarry Smith #undef __FUNCT__
664f1d7fe2eSBarry Smith #define __FUNCT__ "PetscVFPrintfToString"
665f1d7fe2eSBarry Smith PetscErrorCode  PetscVFPrintfToString(FILE *fd,const char format[],va_list Argp)
666f1d7fe2eSBarry Smith {
667f1d7fe2eSBarry Smith   PetscErrorCode ierr;
668f1d7fe2eSBarry Smith 
669f1d7fe2eSBarry Smith   PetscFunctionBegin;
670f1d7fe2eSBarry Smith   if (fd != stdout && fd != stderr) { /* handle regular files */
671f1d7fe2eSBarry Smith     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
672f1d7fe2eSBarry Smith   } else {
673f1d7fe2eSBarry Smith     size_t len=8*1024,length;
674f1d7fe2eSBarry Smith     char   buf[len];
675f1d7fe2eSBarry Smith 
676f1d7fe2eSBarry Smith     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
677f1d7fe2eSBarry Smith     ierr = SwiftClosure(buf);CHKERRQ(ierr);
678f1d7fe2eSBarry Smith   }
679f1d7fe2eSBarry Smith   PetscFunctionReturn(0);
680f1d7fe2eSBarry Smith }
681f1d7fe2eSBarry Smith 
682f1d7fe2eSBarry Smith /*
683f1d7fe2eSBarry Smith    Provide a Swift function that processes all the PETSc calls to PetscVFPrintf()
684f1d7fe2eSBarry Smith */
685f1d7fe2eSBarry Smith PetscErrorCode PetscVFPrintfSetClosure(int (^closure)(const char*))
686f1d7fe2eSBarry Smith {
687f1d7fe2eSBarry Smith   PetscVFPrintf = PetscVFPrintfToString;
688f1d7fe2eSBarry Smith   SwiftClosure  = closure;
689f1d7fe2eSBarry Smith   return 0;
690f1d7fe2eSBarry Smith }
691f1d7fe2eSBarry Smith #endif
692f1d7fe2eSBarry Smith 
693238ccf28SShri Abhyankar #if defined(PETSC_HAVE_MATLAB_ENGINE)
694c6db04a5SJed Brown #include <mex.h>
695238ccf28SShri Abhyankar #undef __FUNCT__
696238ccf28SShri Abhyankar #define __FUNCT__ "PetscVFPrintf_Matlab"
6977087cfbeSBarry Smith PetscErrorCode  PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp)
698238ccf28SShri Abhyankar {
699238ccf28SShri Abhyankar   PetscErrorCode ierr;
700238ccf28SShri Abhyankar 
701238ccf28SShri Abhyankar   PetscFunctionBegin;
702238ccf28SShri Abhyankar   if (fd != stdout && fd != stderr) { /* handle regular files */
703238ccf28SShri Abhyankar     ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr);
704238ccf28SShri Abhyankar   } else {
705238ccf28SShri Abhyankar     size_t len=8*1024,length;
706238ccf28SShri Abhyankar     char   buf[len];
707238ccf28SShri Abhyankar 
708238ccf28SShri Abhyankar     ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr);
709df413903SBarry Smith     mexPrintf("%s",buf);
710238ccf28SShri Abhyankar   }
711238ccf28SShri Abhyankar   PetscFunctionReturn(0);
712238ccf28SShri Abhyankar }
713238ccf28SShri Abhyankar #endif
7146fc7ef2bSBarry Smith 
7156fc7ef2bSBarry Smith #undef __FUNCT__
7168c74ee41SBarry Smith #define __FUNCT__ "PetscFormatStrip"
7178c74ee41SBarry Smith /*@C
7188c74ee41SBarry Smith      PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations
7198c74ee41SBarry Smith 
7208c74ee41SBarry Smith    Input Parameters:
7218c74ee41SBarry Smith .   format - the PETSc format string
7228c74ee41SBarry Smith 
7238c74ee41SBarry Smith  Level: developer
7248c74ee41SBarry Smith 
7258c74ee41SBarry Smith @*/
7268c74ee41SBarry Smith PetscErrorCode  PetscFormatStrip(char *format)
7278c74ee41SBarry Smith {
7288c74ee41SBarry Smith   size_t loc1 = 0, loc2 = 0;
7298c74ee41SBarry Smith 
7308c74ee41SBarry Smith   PetscFunctionBegin;
7318c74ee41SBarry Smith   while (format[loc2]) {
7328c74ee41SBarry Smith     if (format[loc2] == '%') {
7338c74ee41SBarry Smith       format[loc1++] = format[loc2++];
7348c74ee41SBarry Smith       while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++;
7358c74ee41SBarry Smith     }
7368c74ee41SBarry Smith     format[loc1++] = format[loc2++];
7378c74ee41SBarry Smith   }
7388c74ee41SBarry Smith   PetscFunctionReturn(0);
7398c74ee41SBarry Smith }
7408c74ee41SBarry Smith 
741