1 /* 2 Utilites routines to add simple ASCII IO capability. 3 */ 4 #include <../src/sys/fileio/mprint.h> 5 #include <errno.h> 6 /* 7 If petsc_history is on, then all Petsc*Printf() results are saved 8 if the appropriate (usually .petschistory) file. 9 */ 10 extern FILE *petsc_history; 11 /* 12 Allows one to overwrite where standard out is sent. For example 13 PETSC_STDOUT = fopen("/dev/ttyXX","w") will cause all standard out 14 writes to go to terminal XX; assuming you have write permission there 15 */ 16 FILE *PETSC_STDOUT = 0; 17 /* 18 Allows one to overwrite where standard error is sent. For example 19 PETSC_STDERR = fopen("/dev/ttyXX","w") will cause all standard error 20 writes to go to terminal XX; assuming you have write permission there 21 */ 22 FILE *PETSC_STDERR = 0; 23 24 /* 25 Return the maximum expected new size of the format 26 */ 27 #define PETSC_MAX_LENGTH_FORMAT(l) (l+l/8) 28 29 #undef __FUNCT__ 30 #define __FUNCT__ "PetscFormatConvert" 31 /*@C 32 PetscFormatConvert - Takes a PETSc format string and converts it to a reqular C format string 33 34 Input Parameters: 35 + format - the PETSc format string 36 . newformat - the location to put the standard C format string values 37 - size - the length of newformat 38 39 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 40 41 Level: developer 42 43 @*/ 44 PetscErrorCode PetscFormatConvert(const char *format,char *newformat,size_t size) 45 { 46 PetscInt i = 0,j = 0; 47 48 PetscFunctionBegin; 49 while (format[i] && j < (PetscInt)size-1) { 50 if (format[i] == '%' && format[i+1] != '%') { 51 /* Find the letter */ 52 for (; format[i] && format[i] <= '9'; i++) newformat[j++] = format[i]; 53 switch (format[i]) { 54 case 'D': 55 #if !defined(PETSC_USE_64BIT_INDICES) 56 newformat[j++] = 'd'; 57 #else 58 newformat[j++] = 'l'; 59 newformat[j++] = 'l'; 60 newformat[j++] = 'd'; 61 #endif 62 break; 63 case 'G': 64 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%G format is no longer supported, use %g and caste the argument to double"); 65 break; 66 case 'F': 67 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"%F format is no longer supported, use %g and caste the argument to double"); 68 break; 69 default: 70 newformat[j++] = format[i]; 71 break; 72 } 73 i++; 74 } else newformat[j++] = format[i++]; 75 } 76 newformat[j] = 0; 77 PetscFunctionReturn(0); 78 } 79 80 #undef __FUNCT__ 81 #define __FUNCT__ "PetscVSNPrintf" 82 /*@C 83 PetscVSNPrintf - The PETSc version of vsnprintf(). Converts a PETSc format string into a standard C format string and then puts all the 84 function arguments into a string using the format statement. 85 86 Input Parameters: 87 + str - location to put result 88 . len - the amount of space in str 89 + format - the PETSc format string 90 - fullLength - the amount of space in str actually used. 91 92 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 93 a recursion will occur and possible crash. 94 95 Level: developer 96 97 @*/ 98 PetscErrorCode PetscVSNPrintf(char *str,size_t len,const char *format,size_t *fullLength,va_list Argp) 99 { 100 char *newformat; 101 char formatbuf[8*1024]; 102 size_t oldLength,length; 103 int fullLengthInt; 104 PetscErrorCode ierr; 105 106 PetscFunctionBegin; 107 ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 108 if (oldLength < 8*1024) { 109 newformat = formatbuf; 110 oldLength = 8*1024-1; 111 } else { 112 oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); 113 ierr = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr); 114 } 115 PetscFormatConvert(format,newformat,oldLength); 116 ierr = PetscStrlen(newformat, &length);CHKERRQ(ierr); 117 #if 0 118 if (length > len) newformat[len] = '\0'; 119 #endif 120 #if defined(PETSC_HAVE_VSNPRINTF_CHAR) 121 fullLengthInt = vsnprintf(str,len,newformat,(char*)Argp); 122 #elif defined(PETSC_HAVE_VSNPRINTF) 123 fullLengthInt = vsnprintf(str,len,newformat,Argp); 124 #elif defined(PETSC_HAVE__VSNPRINTF) 125 fullLengthInt = _vsnprintf(str,len,newformat,Argp); 126 #else 127 #error "vsnprintf not found" 128 #endif 129 if (fullLengthInt < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"vsnprintf() failed"); 130 if (fullLength) *fullLength = (size_t)fullLengthInt; 131 if (oldLength >= 8*1024) { 132 ierr = PetscFree(newformat);CHKERRQ(ierr); 133 } 134 PetscFunctionReturn(0); 135 } 136 137 #undef __FUNCT__ 138 #define __FUNCT__ "PetscVFPrintfDefault" 139 /*@C 140 PetscVFPrintf - All PETSc standard out and error messages are sent through this function; so, in theory, this can 141 can be replaced with something that does not simply write to a file. 142 143 To use, write your own function for example, 144 $PetscErrorCode mypetscvfprintf(FILE *fd,const char format[],va_list Argp) 145 ${ 146 $ PetscErrorCode ierr; 147 $ 148 $ PetscFunctionBegin; 149 $ if (fd != stdout && fd != stderr) { handle regular files 150 $ ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERR(ierr); 151 $ } else { 152 $ char buff[BIG]; 153 $ size_t length; 154 $ ierr = PetscVSNPrintf(buff,BIG,format,&length,Argp);CHKERRQ(ierr); 155 $ now send buff to whatever stream or whatever you want 156 $ } 157 $ PetscFunctionReturn(0); 158 $} 159 then before the call to PetscInitialize() do the assignment 160 $ PetscVFPrintf = mypetscvfprintf; 161 162 Notes: For error messages this may be called by any process, for regular standard out it is 163 called only by process 0 of a given communicator 164 165 Developer Notes: this could be called by an error handler, if that happens then a recursion of the error handler may occur 166 and a crash 167 168 Level: developer 169 170 .seealso: PetscVSNPrintf(), PetscErrorPrintf() 171 172 @*/ 173 PetscErrorCode PetscVFPrintfDefault(FILE *fd,const char *format,va_list Argp) 174 { 175 char *newformat; 176 char formatbuf[8*1024]; 177 size_t oldLength; 178 PetscErrorCode ierr; 179 180 PetscFunctionBegin; 181 ierr = PetscStrlen(format, &oldLength);CHKERRQ(ierr); 182 if (oldLength < 8*1024) { 183 newformat = formatbuf; 184 oldLength = 8*1024-1; 185 } else { 186 oldLength = PETSC_MAX_LENGTH_FORMAT(oldLength); 187 ierr = PetscMalloc1(oldLength, &newformat);CHKERRQ(ierr); 188 } 189 ierr = PetscFormatConvert(format,newformat,oldLength);CHKERRQ(ierr); 190 191 #if defined(PETSC_HAVE_VFPRINTF_CHAR) 192 vfprintf(fd,newformat,(char*)Argp); 193 #else 194 vfprintf(fd,newformat,Argp); 195 #endif 196 fflush(fd); 197 if (oldLength >= 8*1024) { 198 ierr = PetscFree(newformat);CHKERRQ(ierr); 199 } 200 PetscFunctionReturn(0); 201 } 202 203 #undef __FUNCT__ 204 #define __FUNCT__ "PetscSNPrintf" 205 /*@C 206 PetscSNPrintf - Prints to a string of given length 207 208 Not Collective 209 210 Input Parameters: 211 + str - the string to print to 212 . len - the length of str 213 . format - the usual printf() format string 214 - any arguments 215 216 Level: intermediate 217 218 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 219 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 220 @*/ 221 PetscErrorCode PetscSNPrintf(char *str,size_t len,const char format[],...) 222 { 223 PetscErrorCode ierr; 224 size_t fullLength; 225 va_list Argp; 226 227 PetscFunctionBegin; 228 va_start(Argp,format); 229 ierr = PetscVSNPrintf(str,len,format,&fullLength,Argp);CHKERRQ(ierr); 230 PetscFunctionReturn(0); 231 } 232 233 #undef __FUNCT__ 234 #define __FUNCT__ "PetscSNPrintfCount" 235 /*@C 236 PetscSNPrintfCount - Prints to a string of given length, returns count 237 238 Not Collective 239 240 Input Parameters: 241 + str - the string to print to 242 . len - the length of str 243 . format - the usual printf() format string 244 . countused - number of characters used 245 - any arguments 246 247 Level: intermediate 248 249 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), PetscVSNPrintf(), 250 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf(), PetscSNPrintf() 251 @*/ 252 PetscErrorCode PetscSNPrintfCount(char *str,size_t len,const char format[],size_t *countused,...) 253 { 254 PetscErrorCode ierr; 255 va_list Argp; 256 257 PetscFunctionBegin; 258 va_start(Argp,countused); 259 ierr = PetscVSNPrintf(str,len,format,countused,Argp);CHKERRQ(ierr); 260 PetscFunctionReturn(0); 261 } 262 263 /* ----------------------------------------------------------------------- */ 264 265 PrintfQueue petsc_printfqueue = 0,petsc_printfqueuebase = 0; 266 int petsc_printfqueuelength = 0; 267 268 #undef __FUNCT__ 269 #define __FUNCT__ "PetscSynchronizedPrintf" 270 /*@C 271 PetscSynchronizedPrintf - Prints synchronized output from several processors. 272 Output of the first processor is followed by that of the second, etc. 273 274 Not Collective 275 276 Input Parameters: 277 + comm - the communicator 278 - format - the usual printf() format string 279 280 Level: intermediate 281 282 Notes: 283 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 284 from all the processors to be printed. 285 286 Fortran Note: 287 The call sequence is PetscSynchronizedPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 288 That is, you can only pass a single character string from Fortran. 289 290 .seealso: PetscSynchronizedFlush(), PetscSynchronizedFPrintf(), PetscFPrintf(), 291 PetscPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf() 292 @*/ 293 PetscErrorCode PetscSynchronizedPrintf(MPI_Comm comm,const char format[],...) 294 { 295 PetscErrorCode ierr; 296 PetscMPIInt rank; 297 298 PetscFunctionBegin; 299 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 300 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 301 302 /* First processor prints immediately to stdout */ 303 if (!rank) { 304 va_list Argp; 305 va_start(Argp,format); 306 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 307 if (petsc_history) { 308 va_start(Argp,format); 309 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 310 } 311 va_end(Argp); 312 } else { /* other processors add to local queue */ 313 va_list Argp; 314 PrintfQueue next; 315 size_t fullLength = 8191; 316 317 ierr = PetscNew(&next);CHKERRQ(ierr); 318 if (petsc_printfqueue) { 319 petsc_printfqueue->next = next; 320 petsc_printfqueue = next; 321 petsc_printfqueue->next = 0; 322 } else petsc_printfqueuebase = petsc_printfqueue = next; 323 petsc_printfqueuelength++; 324 next->size = -1; 325 while ((PetscInt)fullLength >= next->size) { 326 next->size = fullLength+1; 327 328 ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 329 va_start(Argp,format); 330 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 331 ierr = PetscVSNPrintf(next->string,next->size,format, &fullLength,Argp);CHKERRQ(ierr); 332 va_end(Argp); 333 } 334 } 335 PetscFunctionReturn(0); 336 } 337 338 #undef __FUNCT__ 339 #define __FUNCT__ "PetscSynchronizedFPrintf" 340 /*@C 341 PetscSynchronizedFPrintf - Prints synchronized output to the specified file from 342 several processors. Output of the first processor is followed by that of the 343 second, etc. 344 345 Not Collective 346 347 Input Parameters: 348 + comm - the communicator 349 . fd - the file pointer 350 - format - the usual printf() format string 351 352 Level: intermediate 353 354 Notes: 355 REQUIRES a intervening call to PetscSynchronizedFlush() for the information 356 from all the processors to be printed. 357 358 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(), 359 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 360 361 @*/ 362 PetscErrorCode PetscSynchronizedFPrintf(MPI_Comm comm,FILE *fp,const char format[],...) 363 { 364 PetscErrorCode ierr; 365 PetscMPIInt rank; 366 367 PetscFunctionBegin; 368 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 369 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 370 371 /* First processor prints immediately to fp */ 372 if (!rank) { 373 va_list Argp; 374 va_start(Argp,format); 375 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr); 376 if (petsc_history && (fp !=petsc_history)) { 377 va_start(Argp,format); 378 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 379 } 380 va_end(Argp); 381 } else { /* other processors add to local queue */ 382 va_list Argp; 383 PrintfQueue next; 384 size_t fullLength = 8191; 385 ierr = PetscNew(&next);CHKERRQ(ierr); 386 if (petsc_printfqueue) { 387 petsc_printfqueue->next = next; 388 petsc_printfqueue = next; 389 petsc_printfqueue->next = 0; 390 } else petsc_printfqueuebase = petsc_printfqueue = next; 391 petsc_printfqueuelength++; 392 next->size = -1; 393 while ((PetscInt)fullLength >= next->size) { 394 next->size = fullLength+1; 395 ierr = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr); 396 va_start(Argp,format); 397 ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr); 398 ierr = PetscVSNPrintf(next->string,next->size,format,&fullLength,Argp);CHKERRQ(ierr); 399 va_end(Argp); 400 } 401 } 402 PetscFunctionReturn(0); 403 } 404 405 #undef __FUNCT__ 406 #define __FUNCT__ "PetscSynchronizedFlush" 407 /*@C 408 PetscSynchronizedFlush - Flushes to the screen output from all processors 409 involved in previous PetscSynchronizedPrintf() calls. 410 411 Collective on MPI_Comm 412 413 Input Parameters: 414 + comm - the communicator 415 - fd - the file pointer (valid on process 0 of the communicator) 416 417 Level: intermediate 418 419 Notes: 420 Usage of PetscSynchronizedPrintf() and PetscSynchronizedFPrintf() with 421 different MPI communicators REQUIRES an intervening call to PetscSynchronizedFlush(). 422 423 .seealso: PetscSynchronizedPrintf(), PetscFPrintf(), PetscPrintf(), PetscViewerASCIIPrintf(), 424 PetscViewerASCIISynchronizedPrintf() 425 C@*/ 426 PetscErrorCode PetscSynchronizedFlush(MPI_Comm comm,FILE *fd) 427 { 428 PetscErrorCode ierr; 429 PetscMPIInt rank,size,tag,i,j,n = 0,dummy = 0; 430 char *message; 431 MPI_Status status; 432 433 PetscFunctionBegin; 434 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr); 435 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 436 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 437 438 /* First processor waits for messages from all other processors */ 439 if (!rank) { 440 if (!fd) fd = PETSC_STDOUT; 441 for (i=1; i<size; i++) { 442 /* to prevent a flood of messages to process zero, request each message separately */ 443 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr); 444 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 445 for (j=0; j<n; j++) { 446 PetscMPIInt size = 0; 447 448 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr); 449 ierr = PetscMalloc1(size, &message);CHKERRQ(ierr); 450 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr); 451 ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr); 452 ierr = PetscFree(message);CHKERRQ(ierr); 453 } 454 } 455 } else { /* other processors send queue to processor 0 */ 456 PrintfQueue next = petsc_printfqueuebase,previous; 457 458 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr); 459 ierr = MPI_Send(&petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 460 for (i=0; i<petsc_printfqueuelength; i++) { 461 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr); 462 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr); 463 previous = next; 464 next = next->next; 465 ierr = PetscFree(previous->string);CHKERRQ(ierr); 466 ierr = PetscFree(previous);CHKERRQ(ierr); 467 } 468 petsc_printfqueue = 0; 469 petsc_printfqueuelength = 0; 470 } 471 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 472 PetscFunctionReturn(0); 473 } 474 475 /* ---------------------------------------------------------------------------------------*/ 476 477 #undef __FUNCT__ 478 #define __FUNCT__ "PetscFPrintf" 479 /*@C 480 PetscFPrintf - Prints to a file, only from the first 481 processor in the communicator. 482 483 Not Collective 484 485 Input Parameters: 486 + comm - the communicator 487 . fd - the file pointer 488 - format - the usual printf() format string 489 490 Level: intermediate 491 492 Fortran Note: 493 This routine is not supported in Fortran. 494 495 Concepts: printing^in parallel 496 Concepts: printf^in parallel 497 498 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), 499 PetscViewerASCIISynchronizedPrintf(), PetscSynchronizedFlush() 500 @*/ 501 PetscErrorCode PetscFPrintf(MPI_Comm comm,FILE* fd,const char format[],...) 502 { 503 PetscErrorCode ierr; 504 PetscMPIInt rank; 505 506 PetscFunctionBegin; 507 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 508 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 509 if (!rank) { 510 va_list Argp; 511 va_start(Argp,format); 512 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr); 513 if (petsc_history && (fd !=petsc_history)) { 514 va_start(Argp,format); 515 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 516 } 517 va_end(Argp); 518 } 519 PetscFunctionReturn(0); 520 } 521 522 #undef __FUNCT__ 523 #define __FUNCT__ "PetscPrintf" 524 /*@C 525 PetscPrintf - Prints to standard out, only from the first 526 processor in the communicator. Calls from other processes are ignored. 527 528 Not Collective 529 530 Input Parameters: 531 + comm - the communicator 532 - format - the usual printf() format string 533 534 Level: intermediate 535 536 Fortran Note: 537 The call sequence is PetscPrintf(MPI_Comm, character(*), PetscErrorCode ierr) from Fortran. 538 That is, you can only pass a single character string from Fortran. 539 540 Concepts: printing^in parallel 541 Concepts: printf^in parallel 542 543 .seealso: PetscFPrintf(), PetscSynchronizedPrintf() 544 @*/ 545 PetscErrorCode PetscPrintf(MPI_Comm comm,const char format[],...) 546 { 547 PetscErrorCode ierr; 548 PetscMPIInt rank; 549 550 PetscFunctionBegin; 551 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 552 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 553 if (!rank) { 554 va_list Argp; 555 va_start(Argp,format); 556 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 557 if (petsc_history) { 558 va_start(Argp,format); 559 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 560 } 561 va_end(Argp); 562 } 563 PetscFunctionReturn(0); 564 } 565 566 /* ---------------------------------------------------------------------------------------*/ 567 #undef __FUNCT__ 568 #define __FUNCT__ "PetscHelpPrintfDefault" 569 /*@C 570 PetscHelpPrintf - All PETSc help messages are passing through this function. You can change how help messages are printed by 571 replacinng it with something that does not simply write to a stdout. 572 573 To use, write your own function for example, 574 $PetscErrorCode mypetschelpprintf(MPI_Comm comm,const char format[],....) 575 ${ 576 $ PetscFunctionReturn(0); 577 $} 578 then before the call to PetscInitialize() do the assignment 579 $ PetscHelpPrintf = mypetschelpprintf; 580 581 Note: the default routine used is called PetscHelpPrintfDefault(). 582 583 Level: developer 584 585 .seealso: PetscVSNPrintf(), PetscVFPrintf(), PetscErrorPrintf() 586 @*/ 587 PetscErrorCode PetscHelpPrintfDefault(MPI_Comm comm,const char format[],...) 588 { 589 PetscErrorCode ierr; 590 PetscMPIInt rank; 591 592 PetscFunctionBegin; 593 if (comm == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called with MPI_COMM_NULL, likely PetscObjectComm() failed"); 594 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 595 if (!rank) { 596 va_list Argp; 597 va_start(Argp,format); 598 ierr = (*PetscVFPrintf)(PETSC_STDOUT,format,Argp);CHKERRQ(ierr); 599 if (petsc_history) { 600 va_start(Argp,format); 601 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr); 602 } 603 va_end(Argp); 604 } 605 PetscFunctionReturn(0); 606 } 607 608 /* ---------------------------------------------------------------------------------------*/ 609 610 611 #undef __FUNCT__ 612 #define __FUNCT__ "PetscSynchronizedFGets" 613 /*@C 614 PetscSynchronizedFGets - Several processors all get the same line from a file. 615 616 Collective on MPI_Comm 617 618 Input Parameters: 619 + comm - the communicator 620 . fd - the file pointer 621 - len - the length of the output buffer 622 623 Output Parameter: 624 . string - the line read from the file, at end of file string[0] == 0 625 626 Level: intermediate 627 628 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 629 PetscFOpen(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPrintf() 630 631 @*/ 632 PetscErrorCode PetscSynchronizedFGets(MPI_Comm comm,FILE *fp,size_t len,char string[]) 633 { 634 PetscErrorCode ierr; 635 PetscMPIInt rank; 636 637 PetscFunctionBegin; 638 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 639 640 if (!rank) { 641 char *ptr = fgets(string, len, fp); 642 643 if (!ptr) { 644 string[0] = 0; 645 if (!feof(fp)) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Error reading from file: %d", errno); 646 } 647 } 648 ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 649 PetscFunctionReturn(0); 650 } 651 652 #if defined(PETSC_HAVE_MATLAB_ENGINE) 653 #include <mex.h> 654 #undef __FUNCT__ 655 #define __FUNCT__ "PetscVFPrintf_Matlab" 656 PetscErrorCode PetscVFPrintf_Matlab(FILE *fd,const char format[],va_list Argp) 657 { 658 PetscErrorCode ierr; 659 660 PetscFunctionBegin; 661 if (fd != stdout && fd != stderr) { /* handle regular files */ 662 ierr = PetscVFPrintfDefault(fd,format,Argp);CHKERRQ(ierr); 663 } else { 664 size_t len=8*1024,length; 665 char buf[len]; 666 667 ierr = PetscVSNPrintf(buf,len,format,&length,Argp);CHKERRQ(ierr); 668 mexPrintf("%s",buf); 669 } 670 PetscFunctionReturn(0); 671 } 672 #endif 673 674 #undef __FUNCT__ 675 #define __FUNCT__ "PetscFormatStrip" 676 /*@C 677 PetscFormatStrip - Takes a PETSc format string and removes all numerical modifiers to % operations 678 679 Input Parameters: 680 . format - the PETSc format string 681 682 Level: developer 683 684 @*/ 685 PetscErrorCode PetscFormatStrip(char *format) 686 { 687 size_t loc1 = 0, loc2 = 0; 688 689 PetscFunctionBegin; 690 while (format[loc2]) { 691 if (format[loc2] == '%') { 692 format[loc1++] = format[loc2++]; 693 while (format[loc2] && ((format[loc2] >= '0' && format[loc2] <= '9') || format[loc2] == '.')) loc2++; 694 } 695 format[loc1++] = format[loc2++]; 696 } 697 PetscFunctionReturn(0); 698 } 699 700