/*@C PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can can be replaced with something that does not simply write to a file. To use, write your own function for example, $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) ${ $ PetscErrorCode ierr; $ $ PetscFunctionBegin; $ if (fd != stdout && fd != stderr) { handle regular files $ ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr); $ } else { $ char buff[BIG]; $ size_t length; $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); $ now send buff to whatever stream or whatever you want $ } $ PetscFunctionReturn(0); $} then before the call to PetscInitialize() do the assignment $ PetscVFPrintf = mypetscvfprintf; Notes: For error messages this may be called by any process, for regular standard out it is called only by process 0 of a given communicator Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur and a crash Level: developer .seealso: PetscVSNPrintf(), PetscErrorPrintf() @*/ PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) { char *newformat; char formatbuf[8*1024]; size_t oldLength; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); if (oldLength < 8*1024) { newformat = formatbuf; oldLength = 8*1024-1; } else { oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); ierr = PetscMalloc(oldLength * sizeof(char), &newformat);CHKERRQ(ierr); } ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr); #if defined(PETSC_HAVE_VFPRINTF_CHAR) vfprintf(fd,newformat,(char*)Argp); #else vfprintf(fd,newformat,Argp); #endif fflush(fd); if (oldLength >= 8*1024) { ierr = PetscFree(newformat);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@C PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the function arguments into a string using the format statement. Input Parameters: + str - location to put result . len - the amount of space in str + format - the PETSc format string - fullLength - the amount of space in str actually used. 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 a recursion will occur and possible crash. Level: developer @*/ PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) { char *newformat; char formatbuf[8*1024]; size_t oldLength,length; int fullLengthInt; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); if (oldLength < 8*1024) { newformat = formatbuf; oldLength = 8*1024-1; } else { oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); ierr = PetscMalloc(oldLength * sizeof(char), &newformat);CHKERRQ(ierr); } PetscFormatConvert(format,newformat,oldLength); ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); #if 0 if (length > len) { newformat[len] = '\0'; } #endif #if defined(PETSC_HAVE_VSNPRINTF_CHAR) fullLengthInt = vsnprintf(str,len,newformat,(char *)Argp); #elif defined(PETSC_HAVE_VSNPRINTF) fullLengthInt = vsnprintf(str,len,newformat,Argp); #elif defined(PETSC_HAVE__VSNPRINTF) fullLengthInt = _vsnprintf(str,len,newformat,Argp); #else #error "vsnprintf not found" #endif if (fullLengthInt < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"vsnprintf() failed"); if (fullLength) *fullLength = (size_t)fullLengthInt; if (oldLength >= 8*1024) { ierr = PetscFree(newformat);CHKERRQ(ierr); } PetscFunctionReturn(0); }
/*@C PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the function arguments into a string using the format statement. Input Parameters: + str - location to put result . len - the amount of space in str + format - the PETSc format string - fullLength - the amount of space in str actually used. 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 a recursion will occur and possible crash. Level: developer @*/ PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) { char *newformat; char formatbuf[8*1024]; size_t oldLength,length; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); if (oldLength < 8*1024) { newformat = formatbuf; oldLength = 8*1024-1; } else { oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); ierr = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr); } PetscFormatConvert(format,newformat,oldLength); ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); #if 0 if (length > len) newformat[len] = '\0'; #endif #if defined(PETSC_HAVE_VSNPRINTF_CHAR) (void) vsnprintf(str,len,newformat,(char*)Argp); #elif defined(PETSC_HAVE_VSNPRINTF) (void) vsnprintf(str,len,newformat,Argp); #elif defined(PETSC_HAVE__VSNPRINTF) (void) _vsnprintf(str,len,newformat,Argp); #else #error "vsnprintf not found" #endif if (oldLength >= 8*1024) { ierr = PetscFree(newformat);CHKERRQ(ierr); } { PetscBool foundedot; size_t cnt = 0,ncnt = 0,leng; ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); if (leng > 4) { for (cnt=0; cnt<leng-4; cnt++) { if (str[cnt] == '[' && str[cnt+1] == '|'){ cnt++; cnt++; foundedot = PETSC_FALSE; for (; cnt<leng-1; cnt++) { if (str[cnt] == '|' && str[cnt+1] == ']'){ cnt++; if (!foundedot) str[ncnt++] = '.'; ncnt--; break; } else { if (str[cnt] == 'e' || str[cnt] == '.') foundedot = PETSC_TRUE; str[ncnt++] = str[cnt]; } } } else { str[ncnt] = str[cnt]; } ncnt++; } while (cnt < leng) { str[ncnt] = str[cnt]; ncnt++; cnt++; } str[ncnt] = 0; } } #if defined(PETSC_HAVE_WINDOWS_H) && !defined(PETSC_HAVE__SET_OUTPUT_FORMAT) /* older Windows OS always produces e-+0np for floating point output; remove the extra 0 */ { size_t cnt = 0,ncnt = 0,leng; ierr = PetscStrlen(str,&leng);CHKERRQ(ierr); if (leng > 5) { for (cnt=0; cnt<leng-4; cnt++) { 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') { str[ncnt] = str[cnt]; ncnt++; cnt++; str[ncnt] = str[cnt]; ncnt++; cnt++; cnt++; str[ncnt] = str[cnt]; } else { str[ncnt] = str[cnt]; } ncnt++; } while (cnt < leng) { str[ncnt] = str[cnt]; ncnt++; cnt++; } str[ncnt] = 0; } } #endif if (fullLength) { ierr = PetscStrlen(str,fullLength);CHKERRQ(ierr); } PetscFunctionReturn(0); }