home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 21 / IOPROG_21.ISO / SOFT / LIBMAT.ZIP / MATFILE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-16  |  25.0 KB  |  967 lines

  1. /**************************************************/
  2. /*     matfile.c source for matFile family        */
  3. /**************************************************/
  4.  
  5.  
  6. /**************************************************/
  7. /*            MatClass Source File                */
  8. /*       Copyright of C. R. Birchenhall           */
  9. /*       University of Manchester, UK.            */
  10. /*   MatClass is freeware. This file should be    */
  11. /* made freely available to users of any software */
  12. /* whose creation is wholly or partly dependent   */
  13. /*                on this file.                   */
  14. /**************************************************/
  15.  
  16. #include "matfile.hpp"
  17.  
  18. #include <stdlib.h>
  19.  
  20. outFile out( "stdout", STDOUT ), errout( "stderr", STDERR ) ;
  21. inFile  in( "stdin", STDIN ) ;
  22.  
  23. void matFileInitial( void )
  24. {
  25. } // matFileInitial
  26.  
  27. #include <string.h>
  28.  
  29. static char *fileMess[] = {
  30.    "Unknown File Error" ,
  31.    "Wrong File Type",
  32.    "Failed request for New Stream",
  33.    "File Open Failure",
  34.    "Bad File Handle",
  35.    "Read Failure",
  36.    "Write Failure",
  37.    "File Naming Error : Memory Exhausted",
  38.    "File Copy constructor not implemented",
  39.    "File Open/Closed in Close/Open Operation"
  40. } ; // fileMess
  41.  
  42. void fileError( INDEX errnum )
  43. {
  44.    fprintf( stderr,  "\n\nmatFile Error : %u %s\n\n",
  45.             errnum, fileMess[errnum] ) ;
  46.    exit(2) ;
  47. } // fileError
  48.  
  49.  
  50. /********************************************************/
  51. /*                  matFile Modules                     */
  52. /********************************************************/
  53.  
  54. matFile::matFile( void )
  55. {
  56.    fh = new fileHandle ;
  57.    fh->count = 1 ;
  58.    type  = NULLFILE ;
  59.    ok    = TRUE ;
  60. } // matFile
  61.  
  62. matFile::matFile( const matFile& mf )
  63. {
  64.    fh = mf.fh ;
  65.    if ( fh )
  66.       fh->count++ ;
  67.    type = mf.type ;
  68.    ok   = mf.ok ;
  69. } // matFile
  70.  
  71. matFile& matFile::operator = ( const matFile& mf )
  72. {
  73.    if ( fh && --fh->count )
  74.       delete fh ;
  75.    fh = mf.fh ;
  76.    if ( fh )
  77.       fh->count++ ;
  78.    type = mf.type ;
  79.    ok   = mf.ok ;
  80.    return *this ;
  81. } // matFile
  82.  
  83. matFile::~matFile( void )
  84. {
  85.    if ( !fh )
  86.       fileError( NFILE ) ;
  87.    closeFile() ;
  88.    delete fh ;
  89. } // ~matFile   
  90.  
  91. void* matFile::handle( void )
  92. {
  93.    if ( !fh )
  94.       fileError( NFILE ) ;
  95.    return fh->handle ;
  96. } // matFile handle
  97.  
  98. INDEX matFile::openFile( const charArray& newName, INDEX newType )
  99. {
  100.    char* mode;
  101.    if ( !fh )
  102.       fileError( NFILE ) ;
  103.    if ( type != NULLFILE )
  104.       fileError( FBAD ) ;
  105.    if ( fh->count > 1 )  {
  106.       --fh->count ;
  107.       fh = new fileHandle ;
  108.       fh->handle = 0 ;
  109.       fh->count = 1 ;
  110.    } // if
  111.    if ( newType == STDIN || newType == STDOUT || 
  112.         newType == STDERR ) {
  113.       type = newType ;
  114.       return OK ;
  115.    } // if
  116.    if ( newType == INPUT )
  117.       mode = "r" ;
  118.    else if ( newType == OUTPUT )
  119.       mode = "w" ;
  120.    else
  121.       fileError( FTYPE ) ;
  122.    FILE *tmp = fopen( newName.array(), mode ) ;
  123.    if ( tmp == 0 )
  124.       fileError( FOPEN ) ;
  125.    fh->handle = (void *)tmp ;
  126.    fh->name = newName ;
  127.    type = newType ;
  128.    ok = TRUE ;
  129.    return OK ;
  130. } // openFile
  131.  
  132. INDEX matFile::closeFile( void )
  133. {
  134.    if ( type == NULLFILE )
  135.       return OK ;
  136.    if ( type == STDIN || type == STDOUT || type == STDERR )
  137.       return OK ;
  138.    if ( !fh || !fh->handle )
  139.       fileError( NFILE ) ;
  140.    if ( fh->count > 1 ) {
  141.       --fh->count ;
  142.       fh = new fileHandle ;
  143.    } else 
  144.       fclose( (FILE *) fh->handle ) ;
  145.    fh->handle = 0 ;
  146.    fh->name.clear() ;   
  147.    type = NULLFILE ;
  148.    ok   = TRUE ;
  149.    return OK ;
  150. } // closeFile
  151.  
  152. INDEX matFile::eof( void )
  153. {
  154.    if ( type == NULLFILE )
  155.       return TRUE ;
  156.    if ( type == STDIN || type == STDOUT || type == STDERR )
  157.       return FALSE ; // ???
  158.    if ( !fh || !fh->handle )
  159.       fileError( NFILE ) ;
  160.    return feof( (FILE *)fh->handle ) ;
  161. } // matFile eof
  162.  
  163. /********************************************************/
  164. /*                   inFile Modules                     */
  165. /********************************************************/
  166.  
  167. int inFile::good( void )
  168. {
  169.    return ok && !eof() ;
  170. } // inFile::good
  171.  
  172. int inFile::fail( void )
  173. {
  174.    return !ok ;
  175. } // inFile::fail
  176.  
  177. int inFile::close( void )
  178. {
  179.    return closeFile() ;
  180. } // inFile::close
  181.  
  182. int inFile::open( const charArray& newName, int newType )
  183. {
  184.    if ( newType != INPUT && newType != STDIN ) 
  185.       fileError( FTYPE ) ;
  186.    return openFile( newName, newType ) ;
  187. } // inFile open
  188.  
  189. inFile::inFile( void ) : matFile()
  190. {} // inFile( void )
  191.  
  192. inFile::inFile( const charArray& newName, int newType ) : matFile()
  193. {
  194.    if ( newType != INPUT && newType != STDIN ) 
  195.       fileError( FTYPE ) ;
  196.    openFile( newName, newType ) ;
  197. } // inFile
  198.  
  199. inFile::inFile( const inFile& f ) : matFile( f )
  200. {} // inFile
  201.  
  202. inFile::~inFile( void )
  203. {} // ~inFile
  204.  
  205. inFile& inFile::getCh( char& ch )
  206. {
  207.    int chin ;
  208.    if ( type == STDIN )
  209.       chin = getchar() ;
  210.    else if ( type == INPUT )
  211.       chin = getc( (FILE *)handle() ) ;
  212.    else
  213.       fileError( FTYPE ) ;
  214.    if ( chin == EOF )
  215.       fileError( FREAD ) ;
  216.    ch = (char) chin ;
  217.    return *this ;
  218. } // get ch
  219.  
  220. inFile& inFile::get( char *label, int length )
  221. {
  222.    int i = 0 ;
  223.    int ch ;
  224.    if ( type == STDIN ) {
  225.       do {
  226.          ch = getchar() ;
  227.          if ( ch != '\n' )
  228.             *label++ = ch ;
  229.       } while ( ( ++i < length ) && ( ch != '\n' )
  230.                 && ( ch != EOF ) ) ;
  231.       *label++ = '\0' ;
  232.    } else if ( type == INPUT ) {
  233.       FILE *f = (FILE *) handle() ;
  234.       do {
  235.          ch = getc(f) ;
  236.          if ( ch != '\n' )
  237.             *label++ = ch ;
  238.       } while ( ( ++i < length ) && ( ch != '\n' )
  239.                 && ( ch != EOF ) ) ;
  240.       *label++ = '\0' ;
  241.    } else
  242.       fileError( FTYPE ) ;
  243.    return *this ;
  244. } // get label
  245.  
  246. inFile& inFile::getReal( REAL& r )
  247. {
  248.    double d ;
  249.    if ( type == STDIN )
  250.       ok = scanf( "%lf", &d ) ;
  251.    else if ( type == INPUT )
  252.       ok = fscanf( (FILE*)handle(), "%lf", &d ) ;
  253.    else
  254.       fileError( FTYPE ) ;
  255.    if ( !ok )
  256.       fileError( FREAD ) ;
  257.    r = d ;
  258.    return *this ;
  259. } // get REAL
  260.  
  261. inFile& inFile::getIndex( INDEX& i )
  262. {
  263.    if ( type == STDIN )
  264.       ok = scanf( "%u", &i )  ;
  265.    else if ( type == INPUT )
  266.       ok = fscanf( (FILE*)handle(), "%u", &i ) ;
  267.    else
  268.       fileError( FTYPE ) ;
  269.    if ( !ok )
  270.       fileError( FREAD ) ;
  271.    return *this ;
  272. } // get INDEX
  273.  
  274. inFile& inFile::getLong( LONG& i )
  275. {
  276.    if ( type == STDIN )
  277.       ok = scanf( "%lu", &i ) ;
  278.    else if ( type == INPUT )
  279.       ok = fscanf( (FILE*)handle(), "%lu", &i ) ;
  280.    else
  281.       fileError( FTYPE ) ;
  282.    if ( !ok )
  283.       fileError( FREAD ) ;
  284.    return *this ;
  285. } // get LONG
  286.  
  287. void skipline( FILE *strm, int n )
  288. {
  289.    int ch ;
  290.    do {
  291.       do {
  292.          ch = getc( strm ) ;
  293.       } while ( ch != '\n' && ch != EOF ) ;
  294.    } while ( --n && ch != EOF ) ;
  295. } // skipline
  296.  
  297. void skipchar( FILE *strm, int n )
  298. {
  299.    int ch ;
  300.    do {
  301.       ch = getc( strm ) ;
  302.    } while ( --n && ch != EOF ) ;
  303. } // skipchar
  304.  
  305. inFile& inFile::nextLine( INDEX nl )
  306. {
  307.    if ( type == STDIN )
  308.       skipline( stdin, nl ) ;
  309.    else if ( type == INPUT )
  310.       skipline( (FILE*)handle(), nl ) ;
  311.    else
  312.       fileError( FTYPE ) ;
  313.    return *this ;
  314. } // inFile::nextLine
  315.  
  316. inFile& inFile::operator() ( REAL& r )
  317. { return getReal( r ) ; }
  318.  
  319. inFile& inFile::operator() ( INDEX& i )
  320. { return getIndex( i ) ; }
  321.  
  322. inFile& inFile::operator() ( char& ch )
  323. { return getCh( ch ) ; }
  324.  
  325. inFile& inFile::operator() ( charArray& ca )
  326. { return getChar( ca ) ; }
  327.  
  328. static FILE* getMatrix( FILE *strm, matrix& x )
  329. {
  330.    INDEX ok, nr = x.nRows(), nc = x.nCols(), i, j ;
  331.    int cw = matField(), pw = matPageWidth() ;
  332.    int format = matFormat() ;
  333.    int left = 1, right ; // left and right col in current pass
  334.    int cp ; // col per page
  335.    double d ;
  336.    if ( format & ROWNUMS )
  337.       cp = ( ( pw - 8 ) / ( cw + 2 ) ) - 1 ;
  338.    else
  339.       cp = ( pw / ( cw + 2 ) ) - 1 ;
  340.    ok = TRUE ;
  341.    if ( format & STACKED ) {
  342.       while ( ok && left <= nc ) {
  343.          skipline( strm, 1 ) ;
  344.          right = ( left + cp <= nc ) ? left + cp : nc ;
  345.          if ( format & (ROWNUMS|COLNUMS) )
  346.             skipline( strm, 2 ) ;
  347.          for ( i = 1; ok && i <= nr ; i++ ) {
  348.             if ( format & ROWNUMS ) {
  349.                skipchar( strm, 8 ) ;
  350.             } // if
  351.             for ( j = left; ok && j <= right ; j++ ) {
  352.                ok = fscanf( strm, "%lf", &d ) ;
  353.                if ( ok )
  354.                   x(i,j) = d ;
  355.             } // for j
  356.             skipline( strm, 1 ) ;
  357.          } // for i
  358.          left = right + 1 ;
  359.       } // while
  360.    } else if ( format & COLMAJOR ) {
  361.       for ( j = 1; ok && j <= nc; j++ ) {
  362.          for ( i = 1; ok && i <= nr; i++ ) {
  363.             ok = fscanf( strm, "%lf", &d ) ;
  364.             if ( ok )
  365.                x(i,j) = d ;
  366.          } // for i
  367.       } // for j
  368.    } else { // ROWMAJOR
  369.       for ( i = 1; ok && i <= nr; i++ ) {
  370.          for ( j = 1; ok && j <= nc; j++ ) {
  371.             ok = fscanf( strm, "%lf", &d ) ;
  372.             if ( ok )
  373.                x(i,j) = d ;
  374.          } // for j
  375.       } // for i
  376.    } // else
  377.    if ( !ok ) {
  378.       x.errorij( i-1, j-1 ) ;
  379.       x.errorExit( "istream >> matrix", NOFIL ) ;
  380.    } // if
  381.    return strm ;
  382. } // getMatrix
  383.  
  384. inFile& matrix::get( inFile& f  )
  385. {
  386.    INDEX fType = f.fileType() ;
  387.    if ( fType == STDIN )
  388.       getMatrix( stdin, *this ) ;
  389.    else if ( fType == INPUT )
  390.       getMatrix( (FILE*)f.handle(), *this ) ;
  391.    else
  392.       fileError( FTYPE ) ;
  393.    return f ;
  394. } // get matrix
  395.  
  396. /********************************************************/
  397. /*                  outFile Modules                     */
  398. /********************************************************/
  399.  
  400. outFile& outFile::put( const char *label, INDEX w )
  401. {
  402.    if ( w == 0 )
  403.       w = matField() ;
  404.    if ( type == STDOUT )
  405.       ok = printf( "%*s", w, label ) != EOF ;
  406.    else if ( type == STDERR )
  407.       ok = fprintf( stderr, "%*s", w, label ) != EOF ;
  408.    else if ( type == OUTPUT )
  409.       ok = fprintf( (FILE*)handle(), "%*s", w, label ) != EOF ;
  410.    else
  411.       fileError( FTYPE ) ;
  412.    if ( !ok )
  413.       fileError( FWRITE ) ;
  414.    return *this ;
  415. } // outFile put label
  416.  
  417. outFile& outFile::putChar( const charArray& ca, INDEX width )
  418. { return put( ca.array(), width ) ; }
  419.  
  420. outFile& outFile::writeChar( const charArray& ca )
  421. { return write( ca.array() ) ; }
  422.  
  423. outFile& outFile::write( const char *label )
  424. {
  425.    if ( type == STDOUT )
  426.       ok = printf( "%s", label ) != EOF ;
  427.    else if ( type == STDERR )
  428.       ok = fprintf( stderr, "%s", label ) != EOF ;
  429.    else if ( type == OUTPUT )
  430.       ok = fprintf( (FILE*)handle(), "%s", label ) != EOF ;
  431.    else
  432.       fileError( FTYPE ) ;
  433.    if ( !ok )
  434.       fileError( FWRITE ) ;
  435.    return *this ;
  436. } // write label
  437.  
  438. outFile& outFile::putReal( const REAL r, INDEX w, INDEX prec )
  439. {
  440.    if ( w == 0 )
  441.       w = matField() ;
  442.    if ( prec == 0 )
  443.       prec = matPrecision() ;
  444.    if ( type == STDOUT )
  445.       ok = printf( putFormat.array(), w, prec, r ) != EOF ;
  446.    else if ( type == STDERR )
  447.       ok = fprintf( stderr, putFormat.array(), w, prec, r ) != EOF ;
  448.    else if ( type == OUTPUT )
  449.       ok = fprintf( (FILE*)handle(), putFormat.array(), w, prec, r ) != EOF ;
  450.    else
  451.       fileError( FTYPE ) ;
  452.    if ( !ok )
  453.       fileError( FWRITE ) ;
  454.    return *this ;
  455. } // outFile put REAL
  456.  
  457. outFile& outFile::putReal( const REAL r, const char *format )
  458. {
  459.    if ( type == STDOUT )
  460.       ok = printf( format, r ) != EOF ;
  461.    else if ( type == STDERR )
  462.       ok = fprintf( stderr, format, r ) != EOF ;
  463.    else if ( type == OUTPUT )
  464.       ok = fprintf( (FILE*)handle(), format, r ) != EOF ;
  465.    else
  466.       fileError( FTYPE ) ;
  467.    if ( !ok )
  468.       fileError( FWRITE ) ;
  469.    return *this ;
  470. } // outFile put REAL
  471.  
  472. outFile& outFile::writeReal( const REAL r, INDEX p )
  473. {
  474.    if ( p == 0 )
  475.       p = matPrecision() ;
  476.    if ( type == STDOUT )
  477.       ok = printf( writeFormat.array(), p, r ) != EOF ;
  478.    else if ( type == STDERR )
  479.       ok = fprintf( stderr, writeFormat.array(), p, r ) != EOF ;
  480.    else if ( type == OUTPUT )
  481.       ok = fprintf( (FILE*)handle(), writeFormat.array(), p, r ) != EOF ;
  482.    else
  483.       fileError( FTYPE ) ;
  484.    if ( !ok )
  485.       fileError( FWRITE ) ;
  486.    return *this ;
  487. } // outFile write REAL
  488.  
  489. outFile& outFile::putIndex( const INDEX i, INDEX w )
  490. {
  491.    if ( w == 0 )
  492.       w = matField() ;
  493.    if ( type == STDOUT )
  494.       ok = printf( "%*u", w, i ) != EOF ;
  495.    else if ( type == STDERR )
  496.       ok = fprintf( stderr, "%*u", w, i ) != EOF ;
  497.    else if ( type == OUTPUT )
  498.       ok = fprintf( (FILE*)handle(), "%*u", w, i ) != EOF ;
  499.    else
  500.       fileError( FTYPE ) ;
  501.    if ( !ok )
  502.       fileError( FWRITE ) ;
  503.    return *this ;
  504. } // putIndex
  505.  
  506. outFile& outFile::writeIndex( const INDEX i )
  507. {
  508.    if ( type == STDOUT )
  509.       ok = printf( "%u", i ) != EOF ;
  510.    else if ( type == STDERR )
  511.       ok = fprintf( stderr, "%u", i ) != EOF ;
  512.    else if ( type == OUTPUT )
  513.       ok = fprintf( (FILE*)handle(), "%u", i ) != EOF ;
  514.    else
  515.       fileError( FTYPE ) ;
  516.    if ( !ok )
  517.       fileError( FWRITE ) ;
  518.    return *this ;
  519. } // write INDEX
  520.  
  521. outFile& outFile::putLong( const LONG i, INDEX w )
  522. {
  523.    if ( w == 0 )
  524.       w = matField() ;
  525.    if ( type == STDOUT )
  526.       ok = printf( "%*lu", w, i ) != EOF ;
  527.    else if ( type == STDERR )
  528.       ok = fprintf( stderr, "%*lu", w, i ) != EOF ;
  529.    else if ( type == OUTPUT )
  530.       ok = fprintf( (FILE*)handle(), "%*lu", w, i ) != EOF ;
  531.    else
  532.       fileError( FTYPE ) ;
  533.    return *this ;
  534. } // put LONG
  535.  
  536. outFile& outFile::writeLong( const LONG i )
  537. {
  538.    if ( type == STDOUT )
  539.       ok = printf( "%lu", i ) != EOF ;
  540.    else if ( type == STDERR )
  541.       ok = fprintf( stderr, "%lu", i ) != EOF ;
  542.    else if ( type == OUTPUT )
  543.       ok = fprintf( (FILE*)handle(), "%lu", i ) != EOF ;
  544.    else
  545.       fileError( FTYPE ) ;
  546.    if ( !ok )
  547.       fileError( FWRITE ) ;
  548.    return *this ;
  549. } // write LONG
  550.  
  551. outFile& outFile::newLine( INDEX nl )
  552. {
  553.    for ( INDEX i = 1; i <= nl ; i++ ) {
  554.       if ( type == STDOUT )
  555.          ok = putchar( '\n' ) != EOF ;
  556.       else if ( type == STDERR )
  557.          ok = fputc( '\n', stderr ) != EOF ;
  558.       else if ( type == OUTPUT )
  559.          ok = fputc( '\n', (FILE*)handle() ) != EOF ;
  560.       else
  561.          fileError( FTYPE ) ;
  562.    } // for i
  563.    if ( !ok )
  564.       fileError( FWRITE ) ;
  565.    return *this ;
  566. } // outFile::newLine
  567.  
  568. int outFile::good( void )
  569. {
  570.    return ok ;
  571. } // outFile::good
  572.  
  573. int outFile::fail( void )
  574. {
  575.    return !ok ;
  576. } // outFile::fail
  577.  
  578. int outFile::open( const charArray& newName, int newType )
  579. {
  580.    if ( newType != STDOUT && newType != STDERR 
  581.         && newType != OUTPUT )
  582.       fileError( FTYPE ) ;
  583.    return openFile( newName, newType ) ;
  584. } // outFile::open
  585.  
  586. int outFile::close( void )
  587. {
  588.    return closeFile() ;
  589. } // outFile::close
  590.  
  591. outFile& outFile::flush( void )
  592. {
  593.    if ( type == STDOUT )
  594.       fflush( stdout ) ;
  595.    else if ( type == STDERR )
  596.       fflush( stderr ) ;
  597.    else if ( type == OUTPUT )
  598.       fflush( (FILE*) handle() ) ;
  599.    else
  600.       fileError( FTYPE ) ;
  601.    return *this ;
  602. } // outFile::flush
  603.  
  604. outFile::outFile( void ) : matFile()
  605. {
  606.    putFormat   = "%*.*g" ;
  607.    writeFormat = "%.*g" ;
  608. } // outFile( void )
  609.  
  610. outFile::outFile( const charArray& newName, int newType )
  611.      : matFile()
  612. {
  613.    open( newName, newType ) ;
  614.    putFormat = "%*.*g" ;
  615.    writeFormat = "%.*g" ;
  616. } // outFile
  617.  
  618. outFile::outFile( const outFile& f ) : matFile(f)
  619. {
  620.    putFormat = "%*.*g" ;
  621.    writeFormat = "%.*g" ;
  622. } // outFile
  623.  
  624. outFile::~outFile( void )
  625. {} // ~outFile
  626.  
  627. static FILE* putMatrix( FILE* strm, const matrix& x,
  628.                         const charArray& rFormat )
  629. {
  630.    INDEX ok, nr = x.nRows(), nc = x.nCols(), i, j, n = 0 ;
  631.    int cw = matField(), pw = matPageWidth() ;
  632.    int prec = matPrecision(), format = matFormat() ;
  633.    int left = 1, right ; // left and right col in current pass
  634.    int cp ; // col per page
  635.    if ( format & ROWNUMS )
  636.       cp = ( ( pw - 8 ) / ( cw + 2 ) ) - 1 ;
  637.    else
  638.       cp = ( pw / ( cw + 2 ) ) - 1 ;
  639.    if ( format & STACKED ) {
  640.       while ( left <= nc ) {
  641.          fputc( '\n', strm ) ;
  642.          right = ( left + cp <= nc ) ? left + cp : nc ;
  643.          if ( format & COLNUMS ) {
  644.             if ( format & ROWNUMS )
  645.                fputs( " Row |  ", strm ) ;
  646.             for ( j = left; j <= right; j++ )
  647.                fprintf( strm, " Col: %*u   ", cw - 7, j ) ;
  648.             fputc( '\n', strm ) ;
  649.             if ( format & ROWNUMS )
  650.                fputs( "------  ", strm ) ;
  651.             for ( j = left; j <= right; j++ ) {
  652.                for ( i = 1; i <= cw ; i++ )
  653.                   fputc( '-', strm  ) ;
  654.                fputs( "  ", strm ) ; ;
  655.             } // for j
  656.             fputc( '\n', strm  ) ;
  657.          } else if ( format & ROWNUMS ) {
  658.                fputs( " Row |  \n", strm ) ;
  659.                fputs( "------  \n", strm ) ;
  660.          } // else if
  661.          for ( i = 1; i <= nr ; i++ ) {
  662.             if ( format & ROWNUMS )
  663.                fprintf( strm, "%4u |  ", i ) ;
  664.             for ( j = left; j <= right ; j++ ) {
  665.                ok = fprintf( strm, rFormat.array(), cw, prec, x(i,j) )
  666.                     && fprintf( strm, "  " ) ;
  667.                if ( !ok )
  668.                   fileError( FWRITE ) ;
  669.             } // for j
  670.             fputc( '\n', strm ) ;
  671.          } // for i
  672.          left = right + 1 ;
  673.       } // while
  674.    } else {
  675.       if ( format & COLMAJOR ) {
  676.          for ( j = 1; j <= nc; j++ ) {
  677.             for ( i = 1; i <= nr; i++ ) {
  678.                ok = fprintf( strm, rFormat.array(), cw, prec, x(i,j) )
  679.                     && fprintf( strm, "  " ) ;
  680.                if ( !ok )
  681.                   fileError( FWRITE ) ;
  682.                if ( ++n >= cp ) {
  683.                   fputc( '\n', strm ) ;
  684.                   n = 0 ;
  685.                } // if
  686.             } // for i
  687.          } // for j
  688.       } else { // ROWMAJOR
  689.          for ( i = 1; i <= nr; i++ ) {
  690.             for ( j = 1; j <= nc; j++ ) {
  691.                ok = fprintf( strm, rFormat.array(), cw, prec, x(i,j) )
  692.                     && fprintf( strm, "  " ) ;
  693.                if ( !ok )
  694.                   fileError( FWRITE ) ;
  695.                if ( ++n >= cp ) {
  696.                   fputc( '\n', strm ) ;
  697.                   n = 0 ;
  698.                } // if
  699.             } // for j
  700.          } // for i
  701.       } // else COLMAJOR
  702.    } // else NOT STACKED
  703.    return strm ;
  704. } // putMatrix
  705.  
  706. charArray outFile::putForm( const charArray& newForm )
  707. {
  708.    charArray oldForm = putFormat ;
  709.    putFormat = newForm ;
  710.    return oldForm ;
  711. } // outFile::putForm
  712.  
  713. charArray outFile::writeForm( const charArray& newForm )
  714. {
  715.    charArray oldForm = writeFormat ;
  716.    writeFormat = newForm ;
  717.    return oldForm ;
  718. } // outFile::writeForm
  719.  
  720. outFile& matrix::put( outFile& f ) M_CONST
  721. {
  722.    INDEX fType = f.fileType() ;
  723.    if ( fType == STDOUT )
  724.       putMatrix( stdout, *this, f.putForm() ) ;
  725.    else if ( fType == STDERR )
  726.       putMatrix( stderr, *this, f.putForm() ) ;
  727.    else if ( fType == OUTPUT )
  728.       putMatrix( (FILE*)f.handle(), *this, f.putForm() ) ;
  729.    else
  730.       fileError( FTYPE ) ;
  731.    return f ;
  732. } // matrix::put
  733.  
  734. static FILE* getIndexArray( FILE *strm, indexArray& x)
  735. {
  736.    INDEX i, len = x.length();
  737.    int format = matFormat() ;
  738.    INDEX elem ;
  739.    INDEX ok = TRUE ;
  740.    if ( format & DISPLAY ) {
  741.       skipline(strm,3);
  742.       for ( i=1; ok && i <=len ; i++) {
  743.          skipchar(strm,6);
  744.          ok = fscanf( strm, "%u",  &elem ) ;
  745.          if ( ok )
  746.             x(i) = elem ;
  747.          skipline(strm,1);
  748.       } // for
  749.       skipline(strm,1);
  750.    } else {
  751.       for ( i= 1;  ok && i <= len ; i++) {
  752.          ok = fscanf( strm, "%u", elem ) ;
  753.          if ( ok )
  754.             x(i) = elem ;
  755.       } //for i
  756.    } // else
  757.    if ( !ok) {
  758.       x.errori(i-1);  // new function in matman.cc
  759.       x.errorExit("istream >> indexArray ", NOFIL);
  760.    } //if
  761.    return strm;
  762. } // getIndexArray
  763.  
  764. inFile& indexArray::get(inFile& f)
  765. {
  766.    INDEX fType = f.fileType() ;
  767.    if ( fType == STDIN)
  768.       getIndexArray( stdin, *this ) ;
  769.    else if ( fType == INPUT)
  770.       getIndexArray( (FILE*)f.handle(), *this ) ;
  771.    else
  772.       fileError(FTYPE);
  773.    return f;
  774. } // indexArray::get
  775.  
  776.  
  777. outFile& outFile::operator << ( const REAL r )
  778. { return writeReal( r ) ; }
  779.  
  780. outFile& outFile::operator << ( const INDEX i )
  781. { return writeIndex( i ) ; }
  782.  
  783. outFile& outFile::operator << ( const char* s )
  784. { return write( s ) ; }
  785.  
  786. outFile& outFile::operator << ( const charArray& ca )
  787. { return write( ca.array() ) ; }
  788.  
  789. outFile& outFile::operator () ( const REAL r )
  790. { return putReal( r ) ; }
  791.  
  792. outFile& outFile::operator () ( const INDEX i, INDEX width )
  793. { return putIndex( i, width ) ; }
  794.  
  795. outFile& outFile::operator () ( const REAL r, INDEX width )
  796. { return putReal( r, width ) ; }
  797.  
  798. outFile& outFile::operator () ( const REAL r, INDEX width,
  799.                                 INDEX prec )
  800. { return putReal( r, width, prec ) ; }
  801.  
  802. outFile& outFile::operator () ( const REAL r, const char * format )
  803. { return putReal( r, format ) ; }
  804.  
  805. outFile& outFile::operator () ( const INDEX i )
  806. { return putIndex( i ) ; }
  807.  
  808. outFile& outFile::operator () ( const char* s )
  809. { return put( s ) ; }
  810.  
  811. outFile& outFile::operator () ( const char* s, INDEX width )
  812. { return put( s, width ) ; }
  813.  
  814. outFile& outFile::operator () ( const charArray& ca )
  815. { return put( ca.array() ) ; }
  816.  
  817. outFile& outFile::operator () ( const charArray& ca, INDEX width )
  818. { return put( ca.array(), width ) ; }
  819.  
  820.  
  821. /************************************************************/
  822. /*                     Error Methods                        */
  823. /************************************************************/
  824.  
  825. outFile *matErrFile = &out ;
  826.  
  827. void errorFile( outFile& newErr )
  828. {
  829.    if ( newErr.fileType() != OUTPUT )
  830.       fileError( FTYPE ) ;
  831.    matErrFile = &newErr ;
  832.    return ;
  833. } // errorFile
  834.  
  835. static char *errorMessage[] = {
  836.    "Unknown Error : Library fault!",
  837.    "Not implemented",
  838.    "Non-positive dimensions",
  839.    "Non-equal dimensions",
  840.    "Non-square matrix" ,
  841.    "Bad Object List",
  842.    "Memory Exhausted",
  843.    "Index out of range",
  844.    "Unassigned variable",
  845.    "Excessive dimensions",
  846.    "Call with Null Array or Pointer",
  847.    "Null Object List",
  848.    "Zero in Division",
  849.    "Singular Matrix",
  850.    "Not a vector",
  851.    "Transcendatal Range Error",
  852.    "File I/O Error",
  853.    "Parameter out of bounds",
  854.    "No Convergence",
  855.    "Over loaded parameter",
  856.    "Bad argument for function",
  857.    "Non-positive definite matrix",
  858.    "Multiple References to object"
  859. } ; // errorMessage[]
  860.  
  861. void outFile::errorMess( char *func, char *mess )
  862. {
  863.    write("Error in ").write( func ).newLine() ;
  864.    write( mess ).newLine() ;
  865.    return ;
  866. } // outFile::errorMess
  867.  
  868. void outFile::errorExit( char *func, char *mess )
  869. {
  870.    errorMess( func, mess ) ;
  871.    exit(1) ;
  872. } // outFile::errorExit
  873.  
  874. void outFile::errorMess( char *func, matError errorNum )
  875. {
  876.    write( "matObject error no. " ) ;
  877.    writeIndex( (INDEX) errorNum ) ;
  878.    newLine() ;
  879.    errorMess( func, errorMessage[ errorNum ] ) ;
  880.    return ;
  881. } // outFile::errorMess
  882.  
  883. void outFile::errorExit( char *func, matError errorNum )
  884. {
  885.    errorMess( func, errorNum ) ;
  886.    exit(1) ;
  887. } // outFile::errorExit
  888.  
  889. void matErrNumExit( char *func, matError errorNum )
  890. {
  891.    matErrFile->errorMess( func, errorNum ) ;
  892.    exit(1) ;
  893. } // matErrNumExit errorNum
  894.  
  895. void matErrorExit( char *func, char *mess )
  896. {
  897.    matErrFile->errorMess( func, mess ) ;
  898.    exit(1) ;
  899. } // matErrorExit char*
  900.  
  901. void matErrNumMess( char *func, matError errorNum )
  902. {
  903.    matErrFile->errorMess( func, errorNum ) ;
  904. } // matErrNumExit errorNum
  905.  
  906. void matErrorMess( char *func, char *mess )
  907. {
  908.    matErrFile->errorMess( func, mess ) ;
  909. } // matErrorMess char*
  910.  
  911. void matObject::errori( INDEX i) M_CONST
  912. {
  913.    matErrFile->write( "Error in element [" ) ;
  914.    matErrFile->writeIndex(i).write("]") ;
  915.    info( *matErrFile ) ;
  916.    return;
  917. }  // matObject::errori
  918.  
  919. void matObject::errorij( INDEX i, INDEX j ) M_CONST
  920. {
  921.    matErrFile->write( "Error in element [" ).writeIndex( i ) ;
  922.    matErrFile->write( "," ).writeIndex( j ) ;
  923.    matErrFile->write( "] of following object." ).newLine() ;
  924.    info( *matErrFile ) ;
  925.    return ;
  926. } // matObject::errorij
  927.  
  928. void matObject::error( char *func, matError errorNum ) M_CONST
  929. {
  930.    matErrNumMess( func, errorNum ) ;
  931.    info( *matErrFile ) ;
  932.    matFuncList() ;
  933. } // matObject::error
  934.  
  935. void matObject::error( char *func, char *errorMess ) M_CONST
  936. {
  937.    matErrorMess( func, errorMess ) ;
  938.    info( *matErrFile ) ;
  939.    matFuncList() ;
  940. } // matObject::error
  941.  
  942. #include <stdlib.h>
  943.  
  944. static void terminate( void )
  945. {
  946.    matObjectList( *matErrFile ) ;
  947.    out.write( "\n\nMatClass Fatal Error.\n\n" ) ;
  948.    exit(1) ;
  949. } // terminate
  950.  
  951. void matObject::errorExit( char *func, matError num ) M_CONST
  952. {
  953.    error( func, num ) ;
  954.    terminate() ;
  955. } // matObject::errorExit
  956.  
  957. void matObject::errorExit( char *func, char *errorMess ) M_CONST
  958. {
  959.    error( func, errorMess ) ;
  960.    terminate() ;
  961. } // matObject::errorExit
  962.  
  963. void outFile::matVersion( void )
  964. {
  965.    write( "MatClass Version 1.0d"  ) ;
  966. } // outFile matVersion
  967.