Date: 2021-03-03T22:25:32+00:00

Actual source code: filev.c
petsc-3.14.5 2021-03-03
Report Typos and Errors

      2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>

      4: #define QUEUESTRINGSIZE 8192

      6: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
      7: {
      8:   PetscErrorCode    ierr;
      9:   PetscMPIInt       rank;
     10:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     11:   int               err;

     14:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
     15:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
     16:   if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
     17:     if (vascii->fd && vascii->closefile) {
     18:       err = fclose(vascii->fd);
     19:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
     20:     }
     21:     if (vascii->storecompressed) {
     22:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
     23:       FILE *fp;
     24:       PetscStrncpy(par,"gzip ",sizeof(par));
     25:       PetscStrlcat(par,vascii->filename,sizeof(par));
     26: #if defined(PETSC_HAVE_POPEN)
     27:       PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
     28:       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
     29:       PetscPClose(PETSC_COMM_SELF,fp);
     30: #else
     31:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
     32: #endif
     33:     }
     34:   }
     35:   PetscFree(vascii->filename);
     36:   return(0);
     37: }

     39: /* ----------------------------------------------------------------------*/
     40: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
     41: {
     42:   PetscErrorCode    ierr;
     43:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     44:   PetscViewerLink   *vlink;
     45:   PetscBool         flg;

     48:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
     49:   PetscViewerFileClose_ASCII(viewer);
     50:   PetscFree(vascii);

     52:   /* remove the viewer from the list in the MPI Communicator */
     53:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
     54:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
     55:   }

     57:   MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
     58:   if (flg) {
     59:     if (vlink && vlink->viewer == viewer) {
     60:       if (vlink->next) {
     61:         MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
     62:       } else {
     63:         MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
     64:       }
     65:       PetscFree(vlink);
     66:     } else {
     67:       while (vlink && vlink->next) {
     68:         if (vlink->next->viewer == viewer) {
     69:           PetscViewerLink *nv = vlink->next;
     70:           vlink->next = vlink->next->next;
     71:           PetscFree(nv);
     72:         }
     73:         vlink = vlink->next;
     74:       }
     75:     }
     76:   }

     78:   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
     79:     PetscViewer aviewer;
     80:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
     81:     if (flg && aviewer == viewer) {
     82:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
     83:     }
     84:   }
     85:   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
     86:     PetscViewer aviewer;
     87:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
     88:     if (flg && aviewer == viewer) {
     89:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
     90:     }
     91:   }
     92:   return(0);
     93: }

     95: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
     96: {
     97:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     98:   PetscErrorCode    ierr;

    101:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
    102:   return(0);
    103: }

    105: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
    106: {
    107:   PetscErrorCode    ierr;
    108:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    109:   int               err;
    110:   MPI_Comm          comm;
    111:   PetscMPIInt       rank,size;
    112:   FILE              *fd = vascii->fd;

    115:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    116:   PetscObjectGetComm((PetscObject)viewer,&comm);
    117:   MPI_Comm_rank(comm,&rank);
    118:   MPI_Comm_size(comm,&size);

    120:   if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
    121:     err = fflush(vascii->fd);
    122:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
    123:   }

    125:   if (vascii->allowsynchronized) {
    126:     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
    127:     char          *message;
    128:     MPI_Status    status;

    130:     PetscCommDuplicate(comm,&comm,&tag);

    132:     /* First processor waits for messages from all other processors */
    133:     if (!rank) {
    134:       /* flush my own messages that I may have queued up */
    135:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
    136:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    137:         if (!vascii->bviewer) {
    138:           PetscFPrintf(comm,fd,"%s",next->string);
    139:         } else {
    140:           PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
    141:         }
    142:         previous = next;
    143:         next     = next->next;
    144:         PetscFree(previous->string);
    145:         PetscFree(previous);
    146:       }
    147:       vascii->petsc_printfqueue       = NULL;
    148:       vascii->petsc_printfqueuelength = 0;
    149:       for (i=1; i<size; i++) {
    150:         /* to prevent a flood of messages to process zero, request each message separately */
    151:         MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
    152:         MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
    153:         for (j=0; j<n; j++) {
    154:           PetscMPIInt size = 0;

    156:           MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
    157:           PetscMalloc1(size, &message);
    158:           MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
    159:           if (!vascii->bviewer) {
    160:             PetscFPrintf(comm,fd,"%s",message);
    161:           } else {
    162:             PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
    163:           }
    164:           PetscFree(message);
    165:         }
    166:       }
    167:     } else { /* other processors send queue to processor 0 */
    168:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;

    170:       MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
    171:       MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
    172:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    173:         MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
    174:         MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
    175:         previous = next;
    176:         next     = next->next;
    177:         PetscFree(previous->string);
    178:         PetscFree(previous);
    179:       }
    180:       vascii->petsc_printfqueue       = NULL;
    181:       vascii->petsc_printfqueuelength = 0;
    182:     }
    183:     PetscCommDestroy(&comm);
    184:   }
    185:   return(0);
    186: }

    188: /*@C
    189:     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.

    191:     Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer

    193:     Input Parameter:
    194: .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()

    196:     Output Parameter:
    197: .    fd - file pointer

    199:     Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer

    201:     Level: intermediate

    203:     Fortran Note:
    204:     This routine is not supported in Fortran.

    207: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
    208:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
    209: @*/
    210: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
    211: {
    212:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    215:   *fd = vascii->fd;
    216:   return(0);
    217: }

    219: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
    220: {
    221:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    224:   *mode = vascii->mode;
    225:   return(0);
    226: }

    228: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
    229: {
    230:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    233:   vascii->mode = mode;
    234:   return(0);
    235: }

    237: /*
    238:    If petsc_history is on, then all Petsc*Printf() results are saved
    239:    if the appropriate (usually .petschistory) file.
    240: */
    241: PETSC_INTERN FILE *petsc_history;

    243: /*@
    244:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

    246:     Not Collective, but only first processor in set has any effect

    248:     Input Parameters:
    249: +    viewer - obtained with PetscViewerASCIIOpen()
    250: -    tabs - number of tabs

    252:     Level: developer

    254:     Fortran Note:
    255:     This routine is not supported in Fortran.

    258: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
    259:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    260:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    261: @*/
    262: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
    263: {
    264:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    265:   PetscBool         iascii;
    266:   PetscErrorCode    ierr;

    270:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    271:   if (iascii) ascii->tab = tabs;
    272:   return(0);
    273: }

    275: /*@
    276:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

    278:     Not Collective, meaningful on first processor only.

    280:     Input Parameters:
    281: .    viewer - obtained with PetscViewerASCIIOpen()

    283:     Output Parameters:
    284: .    tabs - number of tabs

    286:     Level: developer

    288:     Fortran Note:
    289:     This routine is not supported in Fortran.

    292: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
    293:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    294:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    295: @*/
    296: PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
    297: {
    298:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    299:   PetscBool         iascii;
    300:   PetscErrorCode    ierr;

    304:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    305:   if (iascii && tabs) *tabs = ascii->tab;
    306:   return(0);
    307: }

    309: /*@
    310:     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing

    312:     Not Collective, but only first processor in set has any effect

    314:     Input Parameters:
    315: +    viewer - obtained with PetscViewerASCIIOpen()
    316: -    tabs - number of tabs

    318:     Level: developer

    320:     Fortran Note:
    321:     This routine is not supported in Fortran.

    324: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    325:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    326:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    327: @*/
    328: PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
    329: {
    330:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    331:   PetscBool         iascii;
    332:   PetscErrorCode    ierr;

    336:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    337:   if (iascii) ascii->tab += tabs;
    338:   return(0);
    339: }

    341: /*@
    342:     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing

    344:     Not Collective, but only first processor in set has any effect

    346:     Input Parameters:
    347: +    viewer - obtained with PetscViewerASCIIOpen()
    348: -    tabs - number of tabs

    350:     Level: developer

    352:     Fortran Note:
    353:     This routine is not supported in Fortran.

    356: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    357:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    358:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    359: @*/
    360: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
    361: {
    362:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    363:   PetscBool         iascii;
    364:   PetscErrorCode    ierr;

    368:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    369:   if (iascii) ascii->tab -= tabs;
    370:   return(0);
    371: }

    373: /*@C
    374:     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer

    376:     Collective on PetscViewer

    378:     Input Parameters:
    379: .    viewer - obtained with PetscViewerASCIIOpen()

    381:     Level: intermediate

    383:     Notes:
    384:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.

    387: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
    388:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
    389:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
    390: @*/
    391: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
    392: {
    393:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    394:   PetscBool         iascii;
    395:   PetscErrorCode    ierr;

    399:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    400:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    401:   if (iascii) ascii->allowsynchronized++;
    402:   return(0);
    403: }

    405: /*@C
    406:     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer

    408:     Collective on PetscViewer

    410:     Input Parameters:
    411: .    viewer - obtained with PetscViewerASCIIOpen()

    413:     Level: intermediate

    415:     Notes:
    416:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.

    419: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
    420:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
    421:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
    422: @*/
    423: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
    424: {
    425:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    426:   PetscBool         iascii;
    427:   PetscErrorCode    ierr;

    431:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    432:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    433:   if (iascii) {
    434:     ascii->allowsynchronized--;
    435:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
    436:   }
    437:   return(0);
    438: }

    440: /*@C
    441:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
    442:      lines are tabbed.

    444:     Not Collective, but only first processor in set has any effect

    446:     Input Parameters:
    447: .    viewer - obtained with PetscViewerASCIIOpen()

    449:     Level: developer

    451:     Fortran Note:
    452:     This routine is not supported in Fortran.

    455: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    456:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    457:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    458: @*/
    459: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
    460: {
    461:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    462:   PetscBool         iascii;
    463:   PetscErrorCode    ierr;

    467:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    468:   if (iascii) ascii->tab++;
    469:   return(0);
    470: }

    472: /*@C
    473:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
    474:      lines are tabbed.

    476:     Not Collective, but only first processor in set has any effect

    478:     Input Parameters:
    479: .    viewer - obtained with PetscViewerASCIIOpen()

    481:     Level: developer

    483:     Fortran Note:
    484:     This routine is not supported in Fortran.

    487: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    488:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    489:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    490: @*/
    491: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
    492: {
    493:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    494:   PetscErrorCode    ierr;
    495:   PetscBool         iascii;

    499:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    500:   if (iascii) {
    501:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
    502:     ascii->tab--;
    503:   }
    504:   return(0);
    505: }

    507: /*@
    508:     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer

    510:     Not Collective, but only first processor in set has any effect

    512:     Input Parameters:
    513: +    viewer - obtained with PetscViewerASCIIOpen()
    514: -    flg - PETSC_TRUE or PETSC_FALSE

    516:     Level: developer

    518:     Fortran Note:
    519:     This routine is not supported in Fortran.

    522: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    523:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
    524:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    525: @*/
    526: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
    527: {
    528:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    529:   PetscBool         iascii;
    530:   PetscErrorCode    ierr;

    534:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    535:   if (iascii) {
    536:     if (flg) ascii->tab = ascii->tab_store;
    537:     else {
    538:       ascii->tab_store = ascii->tab;
    539:       ascii->tab       = 0;
    540:     }
    541:   }
    542:   return(0);
    543: }

    545: /* ----------------------------------------------------------------------- */

    548: /*@C
    549:     PetscViewerASCIIPrintf - Prints to a file, only from the first
    550:     processor in the PetscViewer

    552:     Not Collective, but only first processor in set has any effect

    554:     Input Parameters:
    555: +    viewer - obtained with PetscViewerASCIIOpen()
    556: -    format - the usual printf() format string

    558:     Level: developer

    560:     Fortran Note:
    561:     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
    562:     That is, you can only pass a single character string from Fortran.

    564: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
    565:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
    566:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
    567: @*/
    568: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
    569: {
    570:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    571:   PetscMPIInt       rank;
    572:   PetscInt          tab,intab = ascii->tab;
    573:   PetscErrorCode    ierr;
    574:   FILE              *fd = ascii->fd;
    575:   PetscBool         iascii;
    576:   int               err;

    580:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
    582:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    583:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    584:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    585:   if (rank) return(0);

    587:   if (ascii->bviewer) { /* pass string up to parent viewer */
    588:     char        *string;
    589:     va_list     Argp;
    590:     size_t      fullLength;

    592:     PetscCalloc1(QUEUESTRINGSIZE, &string);
    593:     va_start(Argp,format);
    594:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
    595:     va_end(Argp);
    596:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
    597:     PetscFree(string);
    598:   } else { /* write directly to file */
    599:     va_list Argp;
    600:     /* flush my own messages that I may have queued up */
    601:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
    602:     PetscInt    i;
    603:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
    604:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
    605:       previous = next;
    606:       next     = next->next;
    607:       PetscFree(previous->string);
    608:       PetscFree(previous);
    609:     }
    610:     ascii->petsc_printfqueue       = NULL;
    611:     ascii->petsc_printfqueuelength = 0;
    612:     tab = intab;
    613:     while (tab--) {
    614:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
    615:     }

    617:     va_start(Argp,format);
    618:     (*PetscVFPrintf)(fd,format,Argp);
    619:     err  = fflush(fd);
    620:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    621:     if (petsc_history) {
    622:       va_start(Argp,format);
    623:       tab = intab;
    624:       while (tab--) {
    625:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
    626:       }
    627:       (*PetscVFPrintf)(petsc_history,format,Argp);
    628:       err  = fflush(petsc_history);
    629:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    630:     }
    631:     va_end(Argp);
    632:   }
    633:   return(0);
    634: }

    636: /*@C
    637:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

    639:     Collective on PetscViewer

    641:   Input Parameters:
    642: +  viewer - the PetscViewer; either ASCII or binary
    643: -  name - the name of the file it should use

    645:     Level: advanced

    647: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
    648:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

    650: @*/
    651: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
    652: {
    654:   char           filename[PETSC_MAX_PATH_LEN];

    659:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));
    660:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
    661:   return(0);
    662: }

    664: /*@C
    665:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

    667:     Not Collective

    669:   Input Parameter:
    670: .  viewer - the PetscViewer; either ASCII or binary

    672:   Output Parameter:
    673: .  name - the name of the file it is using

    675:     Level: advanced

    677: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()

    679: @*/
    680: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
    681: {

    687:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
    688:   return(0);
    689: }

    691: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
    692: {
    693:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    696:   *name = vascii->filename;
    697:   return(0);
    698: }

    700: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
    701: {
    702:   PetscErrorCode    ierr;
    703:   size_t            len;
    704:   char              fname[PETSC_MAX_PATH_LEN],*gz;
    705:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    706:   PetscBool         isstderr,isstdout;
    707:   PetscMPIInt       rank;

    710:   PetscViewerFileClose_ASCII(viewer);
    711:   if (!name) return(0);
    712:   PetscStrallocpy(name,&vascii->filename);

    714:   /* Is this file to be compressed */
    715:   vascii->storecompressed = PETSC_FALSE;

    717:   PetscStrstr(vascii->filename,".gz",&gz);
    718:   if (gz) {
    719:     PetscStrlen(gz,&len);
    720:     if (len == 3) {
    721:       if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
    722:       *gz = 0;
    723:       vascii->storecompressed = PETSC_TRUE;
    724:     }
    725:   }
    726:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    727:   if (!rank) {
    728:     PetscStrcmp(name,"stderr",&isstderr);
    729:     PetscStrcmp(name,"stdout",&isstdout);
    730:     /* empty filename means stdout */
    731:     if (name[0] == 0)  isstdout = PETSC_TRUE;
    732:     if (isstderr)      vascii->fd = PETSC_STDERR;
    733:     else if (isstdout) vascii->fd = PETSC_STDOUT;
    734:     else {

    737:       PetscFixFilename(name,fname);
    738:       switch (vascii->mode) {
    739:       case FILE_MODE_READ:
    740:         vascii->fd = fopen(fname,"r");
    741:         break;
    742:       case FILE_MODE_WRITE:
    743:         vascii->fd = fopen(fname,"w");
    744:         break;
    745:       case FILE_MODE_APPEND:
    746:         vascii->fd = fopen(fname,"a");
    747:         break;
    748:       case FILE_MODE_UPDATE:
    749:         vascii->fd = fopen(fname,"r+");
    750:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    751:         break;
    752:       case FILE_MODE_APPEND_UPDATE:
    753:         /* I really want a file which is opened at the end for updating,
    754:            not a+, which opens at the beginning, but makes writes at the end.
    755:         */
    756:         vascii->fd = fopen(fname,"r+");
    757:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    758:         else {
    759:           fseek(vascii->fd, 0, SEEK_END);
    760:         }
    761:         break;
    762:       default:
    763:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
    764:       }
    765:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
    766:     }
    767:   }
    768: #if defined(PETSC_USE_LOG)
    769:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    770: #endif
    771:   return(0);
    772: }

    774: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
    775: {
    776:   PetscErrorCode    ierr;
    777:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

    780:   PetscViewerASCIIPushSynchronized(viewer);
    781:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
    782:   /*
    783:      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
    784:      because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
    785:      (since the count never gets to zero) in some examples this displays information that otherwise would be lost

    787:      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
    788:      PCView_GASM().
    789:   */
    790:   PetscViewerASCIIPushSynchronized(viewer);
    791:   PetscViewerCreate(subcomm,outviewer);
    792:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
    793:   PetscViewerASCIIPushSynchronized(*outviewer);
    794:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
    795:   ovascii->fd  = vascii->fd;
    796:   ovascii->tab = vascii->tab;
    797:   ovascii->closefile = PETSC_FALSE;

    799:   vascii->sviewer = *outviewer;

    801:   (*outviewer)->format  = viewer->format;

    803:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
    804:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
    805:   return(0);
    806: }

    808: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
    809: {
    810:   PetscErrorCode    ierr;
    811:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

    814:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
    815:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");

    817:   PetscViewerASCIIPopSynchronized(*outviewer);
    818:   ascii->sviewer             = NULL;
    819:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
    820:   PetscViewerDestroy(outviewer);
    821:   PetscViewerASCIIPopSynchronized(viewer);
    822:   return(0);
    823: }

    825: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
    826: {
    827:   PetscErrorCode    ierr;
    828:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

    831:   if (ascii->filename) {
    832:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
    833:   }
    834:   return(0);
    835: }

    837: /*MC
    838:    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file

    841: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
    842:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
    843:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

    845:   Level: beginner

    847: M*/
    848: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
    849: {
    850:   PetscViewer_ASCII *vascii;
    851:   PetscErrorCode    ierr;

    854:   PetscNewLog(viewer,&vascii);
    855:   viewer->data = (void*)vascii;

    857:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
    858:   viewer->ops->flush            = PetscViewerFlush_ASCII;
    859:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
    860:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
    861:   viewer->ops->view             = PetscViewerView_ASCII;
    862:   viewer->ops->read             = PetscViewerASCIIRead;

    864:   /* defaults to stdout unless set with PetscViewerFileSetName() */
    865:   vascii->fd        = PETSC_STDOUT;
    866:   vascii->mode      = FILE_MODE_WRITE;
    867:   vascii->bviewer   = NULL;
    868:   vascii->subviewer = NULL;
    869:   vascii->sviewer   = NULL;
    870:   vascii->tab       = 0;
    871:   vascii->tab_store = 0;
    872:   vascii->filename  = NULL;
    873:   vascii->closefile = PETSC_TRUE;

    875:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
    876:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
    877:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
    878:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
    879:   return(0);
    880: }

    882: /*@C
    883:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
    884:     several processors.  Output of the first processor is followed by that of the
    885:     second, etc.

    887:     Not Collective, must call collective PetscViewerFlush() to get the results out

    889:     Input Parameters:
    890: +   viewer - the ASCII PetscViewer
    891: -   format - the usual printf() format string

    893:     Level: intermediate

    895:     Notes:
    896:     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
    897:     Then you can do multiple independent calls to this routine.
    898:     The actual synchronized print is then done using PetscViewerFlush().
    899:     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
    900:     to conclude the "synchronized session".
    901:     So the typical calling sequence looks like
    902: $ PetscViewerASCIIPushSynchronized(viewer);
    903: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    904: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    905: $ ...
    906: $ PetscViewerFlush(viewer);
    907: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    908: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
    909: $ ...
    910: $ PetscViewerFlush(viewer);
    911: $ PetscViewerASCIIPopSynchronized(viewer);

    913:     Fortran Note:
    914:       Can only print a single character* string

    916: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
    917:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
    918:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
    919: @*/
    920: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
    921: {
    922:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    923:   PetscErrorCode    ierr;
    924:   PetscMPIInt       rank;
    925:   PetscInt          tab = vascii->tab;
    926:   MPI_Comm          comm;
    927:   FILE              *fp;
    928:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
    929:   int               err;

    934:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    935:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    936:   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");

    938:   PetscObjectGetComm((PetscObject)viewer,&comm);
    939:   MPI_Comm_rank(comm,&rank);

    941:   if (vascii->bviewer) {
    942:     hasbviewer = PETSC_TRUE;
    943:     if (!rank) {
    944:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
    945:       PetscObjectGetComm((PetscObject)viewer,&comm);
    946:       MPI_Comm_rank(comm,&rank);
    947:     }
    948:   }

    950:   fp   = vascii->fd;

    952:   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
    953:     va_list Argp;
    954:     /* flush my own messages that I may have queued up */
    955:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
    956:     PetscInt    i;
    957:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    958:       PetscFPrintf(comm,fp,"%s",next->string);
    959:       previous = next;
    960:       next     = next->next;
    961:       PetscFree(previous->string);
    962:       PetscFree(previous);
    963:     }
    964:     vascii->petsc_printfqueue       = NULL;
    965:     vascii->petsc_printfqueuelength = 0;

    967:     while (tab--) {
    968:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
    969:     }

    971:     va_start(Argp,format);
    972:     (*PetscVFPrintf)(fp,format,Argp);
    973:     err  = fflush(fp);
    974:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    975:     if (petsc_history) {
    976:       va_start(Argp,format);
    977:       (*PetscVFPrintf)(petsc_history,format,Argp);
    978:       err  = fflush(petsc_history);
    979:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    980:     }
    981:     va_end(Argp);
    982:   } else { /* other processors add to queue */
    983:     char        *string;
    984:     va_list     Argp;
    985:     size_t      fullLength;
    986:     PrintfQueue next;

    988:     PetscNew(&next);
    989:     if (vascii->petsc_printfqueue) {
    990:       vascii->petsc_printfqueue->next = next;
    991:       vascii->petsc_printfqueue       = next;
    992:     } else {
    993:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
    994:     }
    995:     vascii->petsc_printfqueuelength++;
    996:     next->size = QUEUESTRINGSIZE;
    997:     PetscCalloc1(next->size, &next->string);
    998:     string     = next->string;
    999:     tab       *= 2;
    1000:     while (tab--) {
    1001:       *string++ = ' ';
    1002:     }
    1003:     va_start(Argp,format);
    1004:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
    1005:     va_end(Argp);
    1006:     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
    1007:       PetscFree(next->string);
    1008:       next->size = fullLength + 2*vascii->tab;
    1009:       PetscCalloc1(next->size, &next->string);
    1010:       string     = next->string;
    1011:       tab        = 2*vascii->tab;
    1012:       while (tab--) {
    1013:         *string++ = ' ';
    1014:       }
    1015:       va_start(Argp,format);
    1016:       PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
    1017:       va_end(Argp);
    1018:     }
    1019:   }
    1020:   return(0);
    1021: }

    1023: /*@C
    1024:    PetscViewerASCIIRead - Reads from a ASCII file

    1026:    Only process 0 in the PetscViewer may call this

    1028:    Input Parameters:
    1029: +  viewer - the ascii viewer
    1030: .  data - location to write the data
    1031: .  num - number of items of data to read
    1032: -  datatype - type of data to read

    1034:    Output Parameters:
    1035: .  count - number of items of data actually read, or NULL

    1037:    Level: beginner

    1039: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
    1040:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    1041:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
    1042: @*/
    1043: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
    1044: {
    1045:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    1046:   FILE              *fd = vascii->fd;
    1047:   PetscInt           i;
    1048:   int                ret = 0;
    1049:   PetscMPIInt        rank;
    1050:   PetscErrorCode     ierr;

    1054:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    1055:   if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
    1056:   for (i=0; i<num; i++) {
    1057:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
    1058:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
    1059:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
    1060:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
    1061:     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
    1062:     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
    1063:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
    1064:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
    1065: #if defined(PETSC_USE_REAL___FLOAT128)
    1066:     else if (dtype == PETSC___FLOAT128) {
    1067:       double tmp;
    1068:       ret = fscanf(fd, "%lg", &tmp);
    1069:       ((__float128*)data)[i] = tmp;
    1070:     }
    1071: #endif
    1072:     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
    1073:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
    1074:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
    1075:   }
    1076:   if (count) *count = i;
    1077:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
    1078:   return(0);
    1079: }