xref: /petsc/src/sys/fileio/mprint.c (revision cf53795e253c8c9d9d0fbcef4cffd37d916c4e81)
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 */
1095c0884eSLisandro Dalcin PETSC_INTERN 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 */
1602c9f0b5SLisandro Dalcin FILE *PETSC_STDOUT = NULL;
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 */
2202c9f0b5SLisandro Dalcin FILE *PETSC_STDERR = NULL;
23b13499bfSbcordonn 
24c9a19010SBarry Smith /*@C
25811af0c4SBarry Smith      PetscFormatConvertGetSize - Gets the length of a string needed to hold format converted with `PetscFormatConvert()`
26811af0c4SBarry Smith 
27811af0c4SBarry Smith    Deprecated
28c9a19010SBarry Smith 
29d781fa04SBarry Smith    Input Parameter:
30d781fa04SBarry Smith .   format - the PETSc format string
31c9a19010SBarry Smith 
32d781fa04SBarry Smith    Output Parameter:
33d781fa04SBarry Smith .   size - the needed length of the new format
34c9a19010SBarry Smith 
35c9a19010SBarry Smith  Level: developer
36c9a19010SBarry Smith 
37db781477SPatrick Sanan .seealso: `PetscFormatConvert()`, `PetscVSNPrintf()`, `PetscVFPrintf()`
38c9a19010SBarry Smith @*/
39d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvertGetSize(const char *format, size_t *size)
40d71ae5a4SJacob Faibussowitsch {
413ca90d2dSJacob Faibussowitsch   size_t   sz = 0;
42d781fa04SBarry Smith   PetscInt i  = 0;
43d781fa04SBarry Smith 
44d781fa04SBarry Smith   PetscFunctionBegin;
453ca90d2dSJacob Faibussowitsch   PetscValidCharPointer(format, 1);
463ca90d2dSJacob Faibussowitsch   PetscValidPointer(size, 2);
47d781fa04SBarry Smith   while (format[i]) {
483ca90d2dSJacob Faibussowitsch     if (format[i] == '%') {
493ca90d2dSJacob Faibussowitsch       if (format[i + 1] == '%') {
503ca90d2dSJacob Faibussowitsch         i += 2;
513ca90d2dSJacob Faibussowitsch         sz += 2;
523ca90d2dSJacob Faibussowitsch         continue;
533ca90d2dSJacob Faibussowitsch       }
54d781fa04SBarry Smith       /* Find the letter */
559371c9d4SSatish Balay       while (format[i] && (format[i] <= '9')) {
569371c9d4SSatish Balay         ++i;
579371c9d4SSatish Balay         ++sz;
589371c9d4SSatish Balay       }
59d781fa04SBarry Smith       switch (format[i]) {
603ca90d2dSJacob Faibussowitsch #if PetscDefined(USE_64BIT_INDICES)
61d71ae5a4SJacob Faibussowitsch       case 'D':
62d71ae5a4SJacob Faibussowitsch         sz += 2;
63d71ae5a4SJacob Faibussowitsch         break;
64d781fa04SBarry Smith #endif
65d71ae5a4SJacob Faibussowitsch       case 'g':
66d71ae5a4SJacob Faibussowitsch         sz += 4;
67d71ae5a4SJacob Faibussowitsch       default:
68d71ae5a4SJacob Faibussowitsch         break;
69d781fa04SBarry Smith       }
70d781fa04SBarry Smith     }
713ca90d2dSJacob Faibussowitsch     ++i;
723ca90d2dSJacob Faibussowitsch     ++sz;
73d781fa04SBarry Smith   }
743ca90d2dSJacob Faibussowitsch   *size = sz + 1; /* space for NULL character */
75d781fa04SBarry Smith   PetscFunctionReturn(0);
76d781fa04SBarry Smith }
77d781fa04SBarry Smith 
78d781fa04SBarry Smith /*@C
79d781fa04SBarry Smith      PetscFormatConvert - Takes a PETSc format string and converts the %D to %d for 32 bit PETSc indices and %lld for 64 bit PETSc indices. Also
80d781fa04SBarry Smith                         converts %g to [|%g|] so that PetscVSNPrintf() can easily insure all %g formatted numbers have a decimal point when printed.
81d781fa04SBarry Smith 
82811af0c4SBarry Smith    Deprecated
83811af0c4SBarry Smith 
84d781fa04SBarry Smith    Input Parameters:
85d781fa04SBarry Smith +   format - the PETSc format string
86d781fa04SBarry Smith .   newformat - the location to put the new format
87811af0c4SBarry Smith -   size - the length of newformat, you can use `PetscFormatConvertGetSize()` to compute the needed size
88d781fa04SBarry Smith 
89811af0c4SBarry Smith     Note: this exists so we can have the same code when `PetscInt` is either int or long long int
90d781fa04SBarry Smith 
91d781fa04SBarry Smith  Level: developer
92d781fa04SBarry Smith 
93db781477SPatrick Sanan .seealso: `PetscFormatConvertGetSize()`, `PetscVSNPrintf()`, `PetscVFPrintf()`
94d781fa04SBarry Smith @*/
95d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatConvert(const char *format, char *newformat)
96d71ae5a4SJacob Faibussowitsch {
97e5c89e4eSSatish Balay   PetscInt i = 0, j = 0;
98e5c89e4eSSatish Balay 
99eed5747fSBarry Smith   PetscFunctionBegin;
100d781fa04SBarry Smith   while (format[i]) {
1012a1ad9caSBarry Smith     if (format[i] == '%' && format[i + 1] == '%') {
1022a1ad9caSBarry Smith       newformat[j++] = format[i++];
1032a1ad9caSBarry Smith       newformat[j++] = format[i++];
1042a1ad9caSBarry Smith     } else if (format[i] == '%') {
1058627564fSBarry Smith       if (format[i + 1] == 'g') {
1068627564fSBarry Smith         newformat[j++] = '[';
1078627564fSBarry Smith         newformat[j++] = '|';
1088627564fSBarry Smith       }
1097bc47156SJose Roman       /* Find the letter */
1107bc47156SJose Roman       for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i];
1117bc47156SJose Roman       switch (format[i]) {
1127bc47156SJose Roman       case 'D':
1136de02169SBarry Smith #if !defined(PETSC_USE_64BIT_INDICES)
114e5c89e4eSSatish Balay         newformat[j++] = 'd';
115e5c89e4eSSatish Balay #else
116e5c89e4eSSatish Balay         newformat[j++] = 'l';
117e5c89e4eSSatish Balay         newformat[j++] = 'l';
118e5c89e4eSSatish Balay         newformat[j++] = 'd';
119e5c89e4eSSatish Balay #endif
1207bc47156SJose Roman         break;
1218627564fSBarry Smith       case 'g':
1228627564fSBarry Smith         newformat[j++] = format[i];
1238627564fSBarry Smith         if (format[i - 1] == '%') {
1248627564fSBarry Smith           newformat[j++] = '|';
1258627564fSBarry Smith           newformat[j++] = ']';
1268627564fSBarry Smith         }
1278627564fSBarry Smith         break;
128d71ae5a4SJacob Faibussowitsch       case 'G':
129d71ae5a4SJacob Faibussowitsch         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%G format is no longer supported, use %%g and cast the argument to double");
130d71ae5a4SJacob Faibussowitsch       case 'F':
131d71ae5a4SJacob Faibussowitsch         SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "%%F format is no longer supported, use %%f and cast the argument to double");
132d71ae5a4SJacob Faibussowitsch       default:
133d71ae5a4SJacob Faibussowitsch         newformat[j++] = format[i];
134d71ae5a4SJacob Faibussowitsch         break;
1357bc47156SJose Roman       }
1367bc47156SJose Roman       i++;
137a297a907SKarl Rupp     } else newformat[j++] = format[i++];
138e5c89e4eSSatish Balay   }
139e5c89e4eSSatish Balay   newformat[j] = 0;
140eed5747fSBarry Smith   PetscFunctionReturn(0);
141e5c89e4eSSatish Balay }
142e5c89e4eSSatish Balay 
14314416c0eSBarry Smith #define PETSCDEFAULTBUFFERSIZE 8 * 1024
144d781fa04SBarry Smith 
145c9a19010SBarry Smith /*@C
146c9a19010SBarry Smith      PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the
147c9a19010SBarry Smith        function arguments into a string using the format statement.
148c9a19010SBarry Smith 
149c9a19010SBarry Smith    Input Parameters:
150c9a19010SBarry Smith +   str - location to put result
151c9a19010SBarry Smith .   len - the amount of space in str
152c9a19010SBarry Smith +   format - the PETSc format string
153c9a19010SBarry Smith -   fullLength - the amount of space in str actually used.
154c9a19010SBarry Smith 
155811af0c4SBarry Smith     Developer Note:
15695452b02SPatrick Sanan     this function may be called from an error handler, if an error occurs when it is called by the error handler than likely
157eed5747fSBarry Smith       a recursion will occur and possible crash.
158c9a19010SBarry Smith 
159c9a19010SBarry Smith  Level: developer
160c9a19010SBarry Smith 
161db781477SPatrick Sanan .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`, `PetscVPrintf()`
162c9a19010SBarry Smith @*/
163d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVSNPrintf(char *str, size_t len, const char *format, size_t *fullLength, va_list Argp)
164d71ae5a4SJacob Faibussowitsch {
165d781fa04SBarry Smith   char  *newformat = NULL;
16614416c0eSBarry Smith   char   formatbuf[PETSCDEFAULTBUFFERSIZE];
167d781fa04SBarry Smith   size_t newLength;
16814416c0eSBarry Smith   int    flen;
169e5c89e4eSSatish Balay 
170eed5747fSBarry Smith   PetscFunctionBegin;
1719566063dSJacob Faibussowitsch   PetscCall(PetscFormatConvertGetSize(format, &newLength));
17294217ebdSBarry Smith   if (newLength < sizeof(formatbuf)) {
173e2135aedSMatthew Knepley     newformat = formatbuf;
17494217ebdSBarry Smith     newLength = sizeof(formatbuf) - 1;
175e2135aedSMatthew Knepley   } else {
1769566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(newLength, &newformat));
177e2135aedSMatthew Knepley   }
1789566063dSJacob Faibussowitsch   PetscCall(PetscFormatConvert(format, newformat));
1797b9a2d1bSSatish Balay #if defined(PETSC_HAVE_VSNPRINTF)
180152b30f0SSatish Balay   flen = vsnprintf(str, len, newformat, Argp);
181e5c89e4eSSatish Balay #else
18289b07760SSatish Balay   #error "vsnprintf not found"
183e5c89e4eSSatish Balay #endif
18448a46eb9SPierre Jolivet   if (newLength > sizeof(formatbuf) - 1) PetscCall(PetscFree(newformat));
1858627564fSBarry Smith   {
1868627564fSBarry Smith     PetscBool foundedot;
1878627564fSBarry Smith     size_t    cnt = 0, ncnt = 0, leng;
1889566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(str, &leng));
18917ca8410SBarry Smith     if (leng > 4) {
1908627564fSBarry Smith       for (cnt = 0; cnt < leng - 4; cnt++) {
1918627564fSBarry Smith         if (str[cnt] == '[' && str[cnt + 1] == '|') {
192c540d043SBarry Smith           flen -= 4;
1939371c9d4SSatish Balay           cnt++;
1949371c9d4SSatish Balay           cnt++;
1958627564fSBarry Smith           foundedot = PETSC_FALSE;
1968627564fSBarry Smith           for (; cnt < leng - 1; cnt++) {
1978627564fSBarry Smith             if (str[cnt] == '|' && str[cnt + 1] == ']') {
1988627564fSBarry Smith               cnt++;
1998627564fSBarry Smith               if (!foundedot) str[ncnt++] = '.';
2008627564fSBarry Smith               ncnt--;
2018627564fSBarry Smith               break;
2028627564fSBarry Smith             } else {
2038627564fSBarry Smith               if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE;
2048627564fSBarry Smith               str[ncnt++] = str[cnt];
2058627564fSBarry Smith             }
2068627564fSBarry Smith           }
2078627564fSBarry Smith         } else {
2088627564fSBarry Smith           str[ncnt] = str[cnt];
2098627564fSBarry Smith         }
2108627564fSBarry Smith         ncnt++;
2118627564fSBarry Smith       }
2128627564fSBarry Smith       while (cnt < leng) {
2139371c9d4SSatish Balay         str[ncnt] = str[cnt];
2149371c9d4SSatish Balay         ncnt++;
2159371c9d4SSatish Balay         cnt++;
2168627564fSBarry Smith       }
2178627564fSBarry Smith       str[ncnt] = 0;
2188627564fSBarry Smith     }
2198627564fSBarry Smith   }
220748e1b9dSBarry Smith #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT)
221e51f71cfSBarry Smith   /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */
222748e1b9dSBarry Smith   {
223748e1b9dSBarry Smith     size_t cnt = 0, ncnt = 0, leng;
2249566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(str, &leng));
225748e1b9dSBarry Smith     if (leng > 5) {
226748e1b9dSBarry Smith       for (cnt = 0; cnt < leng - 4; cnt++) {
227e51f71cfSBarry 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') {
2289371c9d4SSatish Balay           str[ncnt] = str[cnt];
2299371c9d4SSatish Balay           ncnt++;
2309371c9d4SSatish Balay           cnt++;
2319371c9d4SSatish Balay           str[ncnt] = str[cnt];
2329371c9d4SSatish Balay           ncnt++;
2339371c9d4SSatish Balay           cnt++;
2349371c9d4SSatish Balay           cnt++;
235e51f71cfSBarry Smith           str[ncnt] = str[cnt];
236748e1b9dSBarry Smith         } else {
237748e1b9dSBarry Smith           str[ncnt] = str[cnt];
238748e1b9dSBarry Smith         }
239748e1b9dSBarry Smith         ncnt++;
240748e1b9dSBarry Smith       }
241748e1b9dSBarry Smith       while (cnt < leng) {
2429371c9d4SSatish Balay         str[ncnt] = str[cnt];
2439371c9d4SSatish Balay         ncnt++;
2449371c9d4SSatish Balay         cnt++;
245748e1b9dSBarry Smith       }
246748e1b9dSBarry Smith       str[ncnt] = 0;
247748e1b9dSBarry Smith     }
248748e1b9dSBarry Smith   }
249748e1b9dSBarry Smith #endif
250c540d043SBarry Smith   if (fullLength) *fullLength = 1 + (size_t)flen;
251eed5747fSBarry Smith   PetscFunctionReturn(0);
252e5c89e4eSSatish Balay }
253e5c89e4eSSatish Balay 
254c9a19010SBarry Smith /*@C
255c9a19010SBarry Smith      PetscVFPrintf -  All PETSc standard out and error messages are sent through this function; so, in theory, this can
256e5c89e4eSSatish Balay         can be replaced with something that does not simply write to a file.
257e5c89e4eSSatish Balay 
258c9a19010SBarry Smith       To use, write your own function for example,
259c9a19010SBarry Smith $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp)
260c9a19010SBarry Smith ${
261c9a19010SBarry Smith $  PetscErrorCode ierr;
262c9a19010SBarry Smith $
263c9a19010SBarry Smith $  PetscFunctionBegin;
264c9a19010SBarry Smith $   if (fd != stdout && fd != stderr) {  handle regular files
2655f80ce2aSJacob Faibussowitsch $      CHKERR(PetscVFPrintfDefault(fd,format,Argp));
266c9a19010SBarry Smith $  } else {
267c9a19010SBarry Smith $     char   buff[BIG];
268c9a19010SBarry Smith $     size_t length;
2699566063dSJacob Faibussowitsch $     PetscCall(PetscVSNPrintf(buff,BIG,format,&length,Argp));
270c9a19010SBarry Smith $     now send buff to whatever stream or whatever you want
271c9a19010SBarry Smith $ }
272c9a19010SBarry Smith $ PetscFunctionReturn(0);
273c9a19010SBarry Smith $}
274c9a19010SBarry Smith then before the call to PetscInitialize() do the assignment
275c9a19010SBarry Smith $    PetscVFPrintf = mypetscvfprintf;
276c9a19010SBarry Smith 
277811af0c4SBarry Smith       Note:
27895452b02SPatrick Sanan     For error messages this may be called by any process, for regular standard out it is
279e5c89e4eSSatish Balay           called only by process 0 of a given communicator
280e5c89e4eSSatish Balay 
281811af0c4SBarry Smith       Developer Note:
28295452b02SPatrick Sanan     this could be called by an error handler, if that happens then a recursion of the error handler may occur
283eed5747fSBarry Smith                        and a crash
284c9a19010SBarry Smith 
285c9a19010SBarry Smith   Level:  developer
286c9a19010SBarry Smith 
287db781477SPatrick Sanan .seealso: `PetscVSNPrintf()`, `PetscErrorPrintf()`
288c9a19010SBarry Smith @*/
289d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp)
290d71ae5a4SJacob Faibussowitsch {
29114416c0eSBarry Smith   char   str[PETSCDEFAULTBUFFERSIZE];
29214416c0eSBarry Smith   char  *buff = str;
29314416c0eSBarry Smith   size_t fullLength;
2941531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
29514416c0eSBarry Smith   va_list Argpcopy;
2961531940fSBarry Smith #endif
2971179db26SBarry Smith 
298eed5747fSBarry Smith   PetscFunctionBegin;
2991531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
30014416c0eSBarry Smith   va_copy(Argpcopy, Argp);
3011531940fSBarry Smith #endif
3029566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, sizeof(str), format, &fullLength, Argp));
30314416c0eSBarry Smith   if (fullLength > sizeof(str)) {
3049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(fullLength, &buff));
3051531940fSBarry Smith #if defined(PETSC_HAVE_VA_COPY)
3069566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(buff, fullLength, format, NULL, Argpcopy));
3071531940fSBarry Smith #else
3081531940fSBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "C89 does not support va_copy() hence cannot print long strings with PETSc printing routines");
3091531940fSBarry Smith #endif
31014416c0eSBarry Smith   }
3112f613bf5SBarry Smith   fprintf(fd, "%s", buff);
3125a058713SBarry Smith   fflush(fd);
31348a46eb9SPierre Jolivet   if (buff != str) PetscCall(PetscFree(buff));
314eed5747fSBarry Smith   PetscFunctionReturn(0);
315e5c89e4eSSatish Balay }
316e5c89e4eSSatish Balay 
3175b5bc046SBarry Smith /*@C
3185b5bc046SBarry Smith     PetscSNPrintf - Prints to a string of given length
3195b5bc046SBarry Smith 
3205b5bc046SBarry Smith     Not Collective
3215b5bc046SBarry Smith 
3225b5bc046SBarry Smith     Input Parameters:
3235b5bc046SBarry Smith +   str - the string to print to
3245b5bc046SBarry Smith .   len - the length of str
3255b5bc046SBarry Smith .   format - the usual printf() format string
32610699b91SBarry Smith -   ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument
3275b5bc046SBarry Smith 
3285b5bc046SBarry Smith    Level: intermediate
3295b5bc046SBarry Smith 
330db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`,
331db781477SPatrick Sanan           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscVFPrintf()`
3325b5bc046SBarry Smith @*/
333d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintf(char *str, size_t len, const char format[], ...)
334d71ae5a4SJacob Faibussowitsch {
335c9a19010SBarry Smith   size_t  fullLength;
3365b5bc046SBarry Smith   va_list Argp;
3375b5bc046SBarry Smith 
3385b5bc046SBarry Smith   PetscFunctionBegin;
3395b5bc046SBarry Smith   va_start(Argp, format);
3409566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, len, format, &fullLength, Argp));
3415b5bc046SBarry Smith   PetscFunctionReturn(0);
3425b5bc046SBarry Smith }
3435b5bc046SBarry Smith 
344257d2499SJed Brown /*@C
345257d2499SJed Brown     PetscSNPrintfCount - Prints to a string of given length, returns count
346257d2499SJed Brown 
347257d2499SJed Brown     Not Collective
348257d2499SJed Brown 
349257d2499SJed Brown     Input Parameters:
350257d2499SJed Brown +   str - the string to print to
351257d2499SJed Brown .   len - the length of str
352257d2499SJed Brown .   format - the usual printf() format string
35310699b91SBarry Smith -   ... - any arguments that are to be printed, each much have an appropriate symbol in the format argument
354257d2499SJed Brown 
355cb398dd3SBarry Smith     Output Parameter:
356cb398dd3SBarry Smith .   countused - number of characters used
357cb398dd3SBarry Smith 
358257d2499SJed Brown    Level: intermediate
359257d2499SJed Brown 
360db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`, `PetscVSNPrintf()`,
361db781477SPatrick Sanan           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscSNPrintf()`, `PetscVFPrintf()`
362257d2499SJed Brown @*/
363d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSNPrintfCount(char *str, size_t len, const char format[], size_t *countused, ...)
364d71ae5a4SJacob Faibussowitsch {
365257d2499SJed Brown   va_list Argp;
366257d2499SJed Brown 
367257d2499SJed Brown   PetscFunctionBegin;
368257d2499SJed Brown   va_start(Argp, countused);
3699566063dSJacob Faibussowitsch   PetscCall(PetscVSNPrintf(str, len, format, countused, Argp));
370257d2499SJed Brown   PetscFunctionReturn(0);
371257d2499SJed Brown }
372257d2499SJed Brown 
373e5c89e4eSSatish Balay /* ----------------------------------------------------------------------- */
374e5c89e4eSSatish Balay 
37502c9f0b5SLisandro Dalcin PrintfQueue petsc_printfqueue = NULL, petsc_printfqueuebase = NULL;
376d30b0576SJed Brown int         petsc_printfqueuelength = 0;
377e5c89e4eSSatish Balay 
378e5c89e4eSSatish Balay /*@C
379e5c89e4eSSatish Balay     PetscSynchronizedPrintf - Prints synchronized output from several processors.
380e5c89e4eSSatish Balay     Output of the first processor is followed by that of the second, etc.
381e5c89e4eSSatish Balay 
382e5c89e4eSSatish Balay     Not Collective
383e5c89e4eSSatish Balay 
384e5c89e4eSSatish Balay     Input Parameters:
385e5c89e4eSSatish Balay +   comm - the communicator
386e5c89e4eSSatish Balay -   format - the usual printf() format string
387e5c89e4eSSatish Balay 
388e5c89e4eSSatish Balay    Level: intermediate
389e5c89e4eSSatish Balay 
390811af0c4SBarry Smith     Note:
391811af0c4SBarry Smith     REQUIRES a call to `PetscSynchronizedFlush()` by all the processes after the completion of the calls to `PetscSynchronizedPrintf()` for the information
392e5c89e4eSSatish Balay     from all the processors to be printed.
393e5c89e4eSSatish Balay 
394e5c89e4eSSatish Balay     Fortran Note:
395811af0c4SBarry Smith     The call sequence is `PetscSynchronizedPrintf`(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran.
396e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
397e5c89e4eSSatish Balay 
398db781477SPatrick Sanan .seealso: `PetscSynchronizedFlush()`, `PetscSynchronizedFPrintf()`, `PetscFPrintf()`,
399db781477SPatrick Sanan           `PetscPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
400e5c89e4eSSatish Balay @*/
401d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm, const char format[], ...)
402d71ae5a4SJacob Faibussowitsch {
403e5c89e4eSSatish Balay   PetscMPIInt rank;
404e5c89e4eSSatish Balay 
405e5c89e4eSSatish Balay   PetscFunctionBegin;
40608401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
4079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
408e5c89e4eSSatish Balay 
409e5c89e4eSSatish Balay   /* First processor prints immediately to stdout */
410dd400576SPatrick Sanan   if (rank == 0) {
411e5c89e4eSSatish Balay     va_list Argp;
412e5c89e4eSSatish Balay     va_start(Argp, format);
4139566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp));
414e5c89e4eSSatish Balay     if (petsc_history) {
415cdc7d174SSatish Balay       va_start(Argp, format);
4169566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
417e5c89e4eSSatish Balay     }
418e5c89e4eSSatish Balay     va_end(Argp);
419e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
420e5c89e4eSSatish Balay     va_list     Argp;
421e5c89e4eSSatish Balay     PrintfQueue next;
42214416c0eSBarry Smith     size_t      fullLength = PETSCDEFAULTBUFFERSIZE;
423e5c89e4eSSatish Balay 
4249566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
425a297a907SKarl Rupp     if (petsc_printfqueue) {
426a297a907SKarl Rupp       petsc_printfqueue->next = next;
427a297a907SKarl Rupp       petsc_printfqueue       = next;
42802c9f0b5SLisandro Dalcin       petsc_printfqueue->next = NULL;
429a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
430d30b0576SJed Brown     petsc_printfqueuelength++;
43194217ebdSBarry Smith     next->size   = 0;
43214416c0eSBarry Smith     next->string = NULL;
43394217ebdSBarry Smith     while (fullLength >= next->size) {
4342d609e63SMatthew Knepley       next->size = fullLength + 1;
4359566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
4369566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(next->size, &next->string));
437e5c89e4eSSatish Balay       va_start(Argp, format);
4389566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(next->string, next->size));
4399566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp));
440e5c89e4eSSatish Balay       va_end(Argp);
441e5c89e4eSSatish Balay     }
4422d609e63SMatthew Knepley   }
443e5c89e4eSSatish Balay   PetscFunctionReturn(0);
444e5c89e4eSSatish Balay }
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay /*@C
447e5c89e4eSSatish Balay     PetscSynchronizedFPrintf - Prints synchronized output to the specified file from
448e5c89e4eSSatish Balay     several processors.  Output of the first processor is followed by that of the
449e5c89e4eSSatish Balay     second, etc.
450e5c89e4eSSatish Balay 
451e5c89e4eSSatish Balay     Not Collective
452e5c89e4eSSatish Balay 
453e5c89e4eSSatish Balay     Input Parameters:
454e5c89e4eSSatish Balay +   comm - the communicator
455e5c89e4eSSatish Balay .   fd - the file pointer
456e5c89e4eSSatish Balay -   format - the usual printf() format string
457e5c89e4eSSatish Balay 
458e5c89e4eSSatish Balay     Level: intermediate
459e5c89e4eSSatish Balay 
460811af0c4SBarry Smith     Note:
461811af0c4SBarry Smith     REQUIRES a intervening call to `PetscSynchronizedFlush()` for the information
462e5c89e4eSSatish Balay     from all the processors to be printed.
463e5c89e4eSSatish Balay 
464db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`, `PetscFPrintf()`,
465db781477SPatrick Sanan           `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`
466e5c89e4eSSatish Balay @*/
467d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm, FILE *fp, const char format[], ...)
468d71ae5a4SJacob Faibussowitsch {
469e5c89e4eSSatish Balay   PetscMPIInt rank;
470e5c89e4eSSatish Balay 
471e5c89e4eSSatish Balay   PetscFunctionBegin;
47208401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
4739566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
474e5c89e4eSSatish Balay 
475e5c89e4eSSatish Balay   /* First processor prints immediately to fp */
476dd400576SPatrick Sanan   if (rank == 0) {
477e5c89e4eSSatish Balay     va_list Argp;
478e5c89e4eSSatish Balay     va_start(Argp, format);
4799566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp, format, Argp));
480cdc7d174SSatish Balay     if (petsc_history && (fp != petsc_history)) {
481cdc7d174SSatish Balay       va_start(Argp, format);
4829566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
483e5c89e4eSSatish Balay     }
484e5c89e4eSSatish Balay     va_end(Argp);
485e5c89e4eSSatish Balay   } else { /* other processors add to local queue */
486e5c89e4eSSatish Balay     va_list     Argp;
487e5c89e4eSSatish Balay     PrintfQueue next;
48814416c0eSBarry Smith     size_t      fullLength = PETSCDEFAULTBUFFERSIZE;
48914416c0eSBarry Smith 
4909566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
491a297a907SKarl Rupp     if (petsc_printfqueue) {
492a297a907SKarl Rupp       petsc_printfqueue->next = next;
493a297a907SKarl Rupp       petsc_printfqueue       = next;
49402c9f0b5SLisandro Dalcin       petsc_printfqueue->next = NULL;
495a297a907SKarl Rupp     } else petsc_printfqueuebase = petsc_printfqueue = next;
496d30b0576SJed Brown     petsc_printfqueuelength++;
49794217ebdSBarry Smith     next->size   = 0;
49814416c0eSBarry Smith     next->string = NULL;
49994217ebdSBarry Smith     while (fullLength >= next->size) {
5002d609e63SMatthew Knepley       next->size = fullLength + 1;
5019566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
5029566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(next->size, &next->string));
503e5c89e4eSSatish Balay       va_start(Argp, format);
5049566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(next->string, next->size));
5059566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(next->string, next->size, format, &fullLength, Argp));
506e5c89e4eSSatish Balay       va_end(Argp);
507e5c89e4eSSatish Balay     }
5082d609e63SMatthew Knepley   }
509e5c89e4eSSatish Balay   PetscFunctionReturn(0);
510e5c89e4eSSatish Balay }
511e5c89e4eSSatish Balay 
5120ec8b6e3SBarry Smith /*@C
513e5c89e4eSSatish Balay     PetscSynchronizedFlush - Flushes to the screen output from all processors
514811af0c4SBarry Smith     involved in previous `PetscSynchronizedPrintf()`/`PetscSynchronizedFPrintf()` calls.
515e5c89e4eSSatish Balay 
516d083f849SBarry Smith     Collective
517e5c89e4eSSatish Balay 
518e5c89e4eSSatish Balay     Input Parameters:
5190ec8b6e3SBarry Smith +   comm - the communicator
5200ec8b6e3SBarry Smith -   fd - the file pointer (valid on process 0 of the communicator)
521e5c89e4eSSatish Balay 
522e5c89e4eSSatish Balay     Level: intermediate
523e5c89e4eSSatish Balay 
524811af0c4SBarry Smith     Note:
525811af0c4SBarry Smith     If `PetscSynchronizedPrintf()` and/or `PetscSynchronizedFPrintf()` are called with
526811af0c4SBarry Smith     different MPI communicators there must be an intervening call to `PetscSynchronizedFlush()` between the calls with different MPI communicators.
527e5c89e4eSSatish Balay 
528811af0c4SBarry Smith     Fortran Note:
529811af0c4SBarry Smith     Pass `PETSC_STDOUT` if the flush is for standard out; otherwise pass a value obtained from `PetscFOpen()`
530e50bf69fSBarry Smith 
531db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscFPrintf()`, `PetscPrintf()`, `PetscViewerASCIIPrintf()`,
532db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`
5330087d953SMatthew G. Knepley @*/
534d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm, FILE *fd)
535d71ae5a4SJacob Faibussowitsch {
53629a5cbdcSMatthew G. Knepley   PetscMPIInt rank, size, tag, i, j, n = 0, dummy = 0;
5372d609e63SMatthew Knepley   char       *message;
538e5c89e4eSSatish Balay   MPI_Status  status;
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay   PetscFunctionBegin;
5419566063dSJacob Faibussowitsch   PetscCall(PetscCommDuplicate(comm, &comm, &tag));
5429566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
5439566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
544e5c89e4eSSatish Balay 
545e5c89e4eSSatish Balay   /* First processor waits for messages from all other processors */
546dd400576SPatrick Sanan   if (rank == 0) {
5470ec8b6e3SBarry Smith     if (!fd) fd = PETSC_STDOUT;
548e5c89e4eSSatish Balay     for (i = 1; i < size; i++) {
5499f73f8ecSBarry Smith       /* to prevent a flood of messages to process zero, request each message separately */
5509566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&dummy, 1, MPI_INT, i, tag, comm));
5519566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&n, 1, MPI_INT, i, tag, comm, &status));
552e5c89e4eSSatish Balay       for (j = 0; j < n; j++) {
55329a5cbdcSMatthew G. Knepley         PetscMPIInt size = 0;
5542d609e63SMatthew Knepley 
5559566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(&size, 1, MPI_INT, i, tag, comm, &status));
5569566063dSJacob Faibussowitsch         PetscCall(PetscMalloc1(size, &message));
5579566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(message, size, MPI_CHAR, i, tag, comm, &status));
5589566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(comm, fd, "%s", message));
5599566063dSJacob Faibussowitsch         PetscCall(PetscFree(message));
560e5c89e4eSSatish Balay       }
561e5c89e4eSSatish Balay     }
562e5c89e4eSSatish Balay   } else { /* other processors send queue to processor 0 */
563d30b0576SJed Brown     PrintfQueue next = petsc_printfqueuebase, previous;
564e5c89e4eSSatish Balay 
5659566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Recv(&dummy, 1, MPI_INT, 0, tag, comm, &status));
5669566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Send(&petsc_printfqueuelength, 1, MPI_INT, 0, tag, comm));
567d30b0576SJed Brown     for (i = 0; i < petsc_printfqueuelength; i++) {
5689566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&next->size, 1, MPI_INT, 0, tag, comm));
5699566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(next->string, next->size, MPI_CHAR, 0, tag, comm));
570e5c89e4eSSatish Balay       previous = next;
571e5c89e4eSSatish Balay       next     = next->next;
5729566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
5739566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
574e5c89e4eSSatish Balay     }
57502c9f0b5SLisandro Dalcin     petsc_printfqueue       = NULL;
576d30b0576SJed Brown     petsc_printfqueuelength = 0;
577e5c89e4eSSatish Balay   }
5789566063dSJacob Faibussowitsch   PetscCall(PetscCommDestroy(&comm));
579e5c89e4eSSatish Balay   PetscFunctionReturn(0);
580e5c89e4eSSatish Balay }
581e5c89e4eSSatish Balay 
582e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
583e5c89e4eSSatish Balay 
584e5c89e4eSSatish Balay /*@C
585e5c89e4eSSatish Balay     PetscFPrintf - Prints to a file, only from the first
586e5c89e4eSSatish Balay     processor in the communicator.
587e5c89e4eSSatish Balay 
588*cf53795eSBarry Smith     Not Collective; No Fortran Support
589e5c89e4eSSatish Balay 
590e5c89e4eSSatish Balay     Input Parameters:
591e5c89e4eSSatish Balay +   comm - the communicator
592e5c89e4eSSatish Balay .   fd - the file pointer
593e5c89e4eSSatish Balay -   format - the usual printf() format string
594e5c89e4eSSatish Balay 
595e5c89e4eSSatish Balay     Level: intermediate
596e5c89e4eSSatish Balay 
597db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
598db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`, `PetscSynchronizedFlush()`
599e5c89e4eSSatish Balay @*/
600d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFPrintf(MPI_Comm comm, FILE *fd, const char format[], ...)
601d71ae5a4SJacob Faibussowitsch {
602e5c89e4eSSatish Balay   PetscMPIInt rank;
603e5c89e4eSSatish Balay 
604e5c89e4eSSatish Balay   PetscFunctionBegin;
60508401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
6069566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
607dd400576SPatrick Sanan   if (rank == 0) {
608e5c89e4eSSatish Balay     va_list Argp;
609e5c89e4eSSatish Balay     va_start(Argp, format);
6109566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd, format, Argp));
611cdc7d174SSatish Balay     if (petsc_history && (fd != petsc_history)) {
612cdc7d174SSatish Balay       va_start(Argp, format);
6139566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
614e5c89e4eSSatish Balay     }
615e5c89e4eSSatish Balay     va_end(Argp);
616e5c89e4eSSatish Balay   }
617e5c89e4eSSatish Balay   PetscFunctionReturn(0);
618e5c89e4eSSatish Balay }
619e5c89e4eSSatish Balay 
620e5c89e4eSSatish Balay /*@C
621e5c89e4eSSatish Balay     PetscPrintf - Prints to standard out, only from the first
622eed5747fSBarry Smith     processor in the communicator. Calls from other processes are ignored.
623e5c89e4eSSatish Balay 
624e5c89e4eSSatish Balay     Not Collective
625e5c89e4eSSatish Balay 
626e5c89e4eSSatish Balay     Input Parameters:
627e5c89e4eSSatish Balay +   comm - the communicator
628e5c89e4eSSatish Balay -   format - the usual printf() format string
629e5c89e4eSSatish Balay 
630e5c89e4eSSatish Balay     Level: intermediate
631e5c89e4eSSatish Balay 
632811af0c4SBarry Smith     Note:
633811af0c4SBarry Smith     Deprecated information: `PetscPrintf()` supports some format specifiers that are unique to PETSc.
634811af0c4SBarry Smith     See the manual page for `PetscFormatConvert()` for details.
635b2706f25SRichard Tran Mills 
636e5c89e4eSSatish Balay     Fortran Note:
637811af0c4SBarry Smith     The call sequence is `PetscPrintf`(MPI_Comm, character(*), `PetscErrorCode` ierr) from Fortran.
638e5c89e4eSSatish Balay     That is, you can only pass a single character string from Fortran.
639e5c89e4eSSatish Balay 
640db781477SPatrick Sanan .seealso: `PetscFPrintf()`, `PetscSynchronizedPrintf()`, `PetscFormatConvert()`
641e5c89e4eSSatish Balay @*/
642d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscPrintf(MPI_Comm comm, const char format[], ...)
643d71ae5a4SJacob Faibussowitsch {
644e5c89e4eSSatish Balay   PetscMPIInt rank;
645e5c89e4eSSatish Balay 
646e5c89e4eSSatish Balay   PetscFunctionBegin;
64708401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
6489566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
649dd400576SPatrick Sanan   if (rank == 0) {
650e5c89e4eSSatish Balay     va_list Argp;
651e5c89e4eSSatish Balay     va_start(Argp, format);
6529566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp));
653e5c89e4eSSatish Balay     if (petsc_history) {
654cdc7d174SSatish Balay       va_start(Argp, format);
6559566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
656e5c89e4eSSatish Balay     }
657e5c89e4eSSatish Balay     va_end(Argp);
658e5c89e4eSSatish Balay   }
659e5c89e4eSSatish Balay   PetscFunctionReturn(0);
660e5c89e4eSSatish Balay }
661e5c89e4eSSatish Balay 
662d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm, const char format[], ...)
663d71ae5a4SJacob Faibussowitsch {
664e5c89e4eSSatish Balay   PetscMPIInt rank;
665e5c89e4eSSatish Balay 
666e5c89e4eSSatish Balay   PetscFunctionBegin;
66708401ef6SPierre Jolivet   PetscCheck(comm != MPI_COMM_NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Called with MPI_COMM_NULL, likely PetscObjectComm() failed");
6689566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
669dd400576SPatrick Sanan   if (rank == 0) {
670e5c89e4eSSatish Balay     va_list Argp;
671e5c89e4eSSatish Balay     va_start(Argp, format);
6729566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(PETSC_STDOUT, format, Argp));
673e5c89e4eSSatish Balay     if (petsc_history) {
674cdc7d174SSatish Balay       va_start(Argp, format);
6759566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history, format, Argp));
676e5c89e4eSSatish Balay     }
677e5c89e4eSSatish Balay     va_end(Argp);
678e5c89e4eSSatish Balay   }
679e5c89e4eSSatish Balay   PetscFunctionReturn(0);
680e5c89e4eSSatish Balay }
681e5c89e4eSSatish Balay 
682e5c89e4eSSatish Balay /* ---------------------------------------------------------------------------------------*/
683e5c89e4eSSatish Balay 
684e5c89e4eSSatish Balay /*@C
685e5c89e4eSSatish Balay     PetscSynchronizedFGets - Several processors all get the same line from a file.
686e5c89e4eSSatish Balay 
687d083f849SBarry Smith     Collective
688e5c89e4eSSatish Balay 
689e5c89e4eSSatish Balay     Input Parameters:
690e5c89e4eSSatish Balay +   comm - the communicator
691e5c89e4eSSatish Balay .   fd - the file pointer
692e5c89e4eSSatish Balay -   len - the length of the output buffer
693e5c89e4eSSatish Balay 
694e5c89e4eSSatish Balay     Output Parameter:
695e31d4fa4SJed Brown .   string - the line read from the file, at end of file string[0] == 0
696e5c89e4eSSatish Balay 
697e5c89e4eSSatish Balay     Level: intermediate
698e5c89e4eSSatish Balay 
699db781477SPatrick Sanan .seealso: `PetscSynchronizedPrintf()`, `PetscSynchronizedFlush()`,
700db781477SPatrick Sanan           `PetscFOpen()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPrintf()`
701e5c89e4eSSatish Balay @*/
702d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm, FILE *fp, size_t len, char string[])
703d71ae5a4SJacob Faibussowitsch {
704e5c89e4eSSatish Balay   PetscMPIInt rank;
705e5c89e4eSSatish Balay 
706e5c89e4eSSatish Balay   PetscFunctionBegin;
7079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm, &rank));
708e5c89e4eSSatish Balay 
709dd400576SPatrick Sanan   if (rank == 0) {
710047b9c12SMatthew G Knepley     char *ptr = fgets(string, len, fp);
711047b9c12SMatthew G Knepley 
712047b9c12SMatthew G Knepley     if (!ptr) {
713e31d4fa4SJed Brown       string[0] = 0;
71408401ef6SPierre Jolivet       PetscCheck(feof(fp), PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno);
715047b9c12SMatthew G Knepley     }
716e5c89e4eSSatish Balay   }
7179566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Bcast(string, len, MPI_BYTE, 0, comm));
718e5c89e4eSSatish Balay   PetscFunctionReturn(0);
719e5c89e4eSSatish Balay }
720238ccf28SShri Abhyankar 
7218c74ee41SBarry Smith /*@C
7228c74ee41SBarry Smith      PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations
7238c74ee41SBarry Smith 
7248c74ee41SBarry Smith    Input Parameters:
7258c74ee41SBarry Smith .   format - the PETSc format string
7268c74ee41SBarry Smith 
7278c74ee41SBarry Smith  Level: developer
7288c74ee41SBarry Smith 
7298c74ee41SBarry Smith @*/
730d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatStrip(char *format)
731d71ae5a4SJacob Faibussowitsch {
7328c74ee41SBarry Smith   size_t loc1 = 0, loc2 = 0;
7338c74ee41SBarry Smith 
7348c74ee41SBarry Smith   PetscFunctionBegin;
7358c74ee41SBarry Smith   while (format[loc2]) {
7368c74ee41SBarry Smith     if (format[loc2] == '%') {
7378c74ee41SBarry Smith       format[loc1++] = format[loc2++];
7388c74ee41SBarry Smith       while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++;
7398c74ee41SBarry Smith     }
7408c74ee41SBarry Smith     format[loc1++] = format[loc2++];
7418c74ee41SBarry Smith   }
7428c74ee41SBarry Smith   PetscFunctionReturn(0);
7438c74ee41SBarry Smith }
7448c74ee41SBarry Smith 
745d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFormatRealArray(char buf[], size_t len, const char *fmt, PetscInt n, const PetscReal x[])
746d71ae5a4SJacob Faibussowitsch {
7471b5687a1SBarry Smith   PetscInt i;
7481b5687a1SBarry Smith   size_t   left, count;
7491b5687a1SBarry Smith   char    *p;
7501b5687a1SBarry Smith 
7511b5687a1SBarry Smith   PetscFunctionBegin;
7521b5687a1SBarry Smith   for (i = 0, p = buf, left = len; i < n; i++) {
7539566063dSJacob Faibussowitsch     PetscCall(PetscSNPrintfCount(p, left, fmt, &count, (double)x[i]));
75408401ef6SPierre Jolivet     PetscCheck(count < left, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Insufficient space in buffer");
7551b5687a1SBarry Smith     left -= count;
7561b5687a1SBarry Smith     p += count - 1;
7571b5687a1SBarry Smith     *p++ = ' ';
7581b5687a1SBarry Smith   }
7591b5687a1SBarry Smith   p[i ? 0 : -1] = 0;
7601b5687a1SBarry Smith   PetscFunctionReturn(0);
7611b5687a1SBarry Smith }
762