Annotation of researchv10no/cmd/cfront/libC/ooiostream/intin.c, revision 1.1.1.1

1.1       root        1: /*ident        "@(#)ctrans:lib/stream/intin.c  1.1.1.1" */
                      2: /**************************************************************************
                      3:                        Copyright (c) 1984 AT&T
                      4:                          All Rights Reserved   
                      5: 
                      6:        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
                      7:        
                      8:        The copyright notice above does not evidence any        
                      9:        actual or intended publication of such source code.
                     10: 
                     11: intin.c: Input conversions of numbers
                     12: 
                     13: *****************************************************************************/
                     14: 
                     15: 
                     16: #include <ctype.h>
                     17: #include <iostream.h>
                     18: 
                     19: /****************
                     20:  * 
                     21:  *     This file contains the extraction operations for integer input. 
                     22:  *     It suffers from several flaws that ought to be fixed. 
                     23:  *
                     24:  *     All other versions depend on the extractor for longs to
                     25:  *     do the real work.  This is OK when int==long but on a machine
                     26:  *     where int!=long there will be a large performance penalty.
                     27:  *
                     28:  *     Overflow detection is limited to cases where the long is
                     29:  *     shortened and changes its value.  This misses a lot of cases.
                     30:  *
                     31:  ***************/
                     32: 
                     33: 
                     34: #define ISTREAM istream
                     35: 
                     36: static const int a10 = 'a'-10;
                     37: static const int A10 = 'A'-10;
                     38: 
                     39: istream& ISTREAM::operator>>(long& i)
                     40: {
                     41:        // This code ignores overflows.  This ought to be fixed
                     42:        // in some future version.
                     43: 
                     44:        if ( !ipfx() ) return *this ;
                     45: 
                     46:        register int    c;
                     47:        register int    base    ;
                     48: 
                     49:        switch ( flags()&(ios::dec|ios::hex|ios::oct) ) {
                     50:                case ios::hex : base = 16 ; break ;
                     51:                case ios::oct : base = 8 ; break ;
                     52:                case ios::dec : base = 10 ; break ;
                     53:                default :               base = 0 ; break ;
                     54:                }
                     55: 
                     56:        register streambuf *nbp = bp;   // put bp in a reg for efficiency
                     57:        register int    x       = 0 ;   // how many chars are processed 
                     58:        register int    neg     = 0;    // set to '-' for negative number
                     59: 
                     60:        switch (c = nbp->sgetc()) {
                     61:        case '-':
                     62:                neg = 1 ;
                     63:                c = nbp->snextc(); ++x ;
                     64:                break;
                     65:        case '+':
                     66:                c = nbp->snextc(); ++x ;
                     67:                break;
                     68:        case EOF:
                     69:                setstate(failbit|eofbit) ;
                     70:                break ;
                     71:        }
                     72: 
                     73:        if ( base==0 && c=='0' ) {
                     74:                c = nbp->snextc() ; ++x ;
                     75: 
                     76:                if ( c=='x' || c=='X' ) {
                     77:                        base = 16 ;
                     78:                        c = nbp->snextc() ; ++x ;
                     79:                        }
                     80:                else {
                     81:                        base = 8 ;
                     82:                }
                     83:        } else if ( base==0 ) base = 10 ;
                     84: 
                     85:        // for efficiency we have similar loops
                     86:        // Note that when we reach this point c has already been set to
                     87:        // the first char of the string to be converted. 
                     88: 
                     89:        if ( base==10 ) {
                     90:                register long ii = 0;
                     91:                for( ; isdigit(c) ; c=nbp->snextc(),++x ) {
                     92:                        
                     93:                        /* accumulate as negative to avoid problems
                     94:                         * with biggest negative integer on
                     95:                         * 2's complement machines
                     96:                         */
                     97:                        ii = ii*10-(c-'0');
                     98:                }
                     99:                i = neg ? ii : -ii;
                    100:        } else if ( base < 10 ) {
                    101:                register unsigned long ii = 0;
                    102:                for( ; isdigit(c)  ; c=nbp->snextc(),++x ) {
                    103:                        /* accumulate as unsigned */
                    104:                        register int diff = c-'0' ;
                    105:                        if ( diff >= base ) break ;
                    106:                        ii = ii*base+diff ;
                    107:                }
                    108:                i = neg ? -(long)ii : (long)ii;
                    109:        } else if ( base>10 ) { /* hex like base */
                    110:                register unsigned long ii = 0;
                    111:                /* accumulate as unsigned */
                    112:                for( ; isxdigit(c) ; c=nbp->snextc(),++x ) {
                    113:                        register int diff ;
                    114:                        if ( isdigit(c) )       diff = (c-'0');
                    115:                        else if ( isupper(c) )  diff = (c-A10);
                    116:                        else                    diff = (c-a10);
                    117:                        if ( diff >= base ) break ;
                    118:                        ii = ii*base+diff ;
                    119:                }
                    120:                i = neg ? -(long)ii : (long)ii;
                    121:        }
                    122:        
                    123: 
                    124:        if (x == 0 ) setstate(failbit) ;
                    125:                                // Correct treatment of this case
                    126:                                // (i.e. no correct digits) 
                    127:                                // is unclear. Making it an error
                    128:                                // avoids certain infinite loops.
                    129:                        
                    130:        return *this;
                    131: }
                    132: 
                    133: istream& ISTREAM::operator>>(int& i)
                    134: {
                    135:        long l;
                    136:        
                    137:        if ( !ipfx() ) return *this ;
                    138: 
                    139:        *this>>l ;
                    140:        if ( good() ) {
                    141:                i = (int)l ;
                    142:                if  ( i != l ) {
                    143:                        // overflow
                    144:                        setstate(failbit) ;
                    145:                        }
                    146:                } 
                    147:        return *this;
                    148: }
                    149: 
                    150: istream& ISTREAM::operator>>(short& i)
                    151: {
                    152:        long l;
                    153: 
                    154:        if (!ipfx() ) return *this ;
                    155: 
                    156:        *this>>l ;
                    157:        if ( good() ) {
                    158:                i = (short)l ;
                    159:                if  ( i != l ) {
                    160:                        // overflow
                    161:                        setstate(failbit) ;
                    162:                        }
                    163:                } 
                    164: 
                    165:        return *this;
                    166: }
                    167: 
                    168: 
                    169: // The following routines deal with unsigned by reading a long and
                    170: // copying.  This is certainly safe for "shorts", but is
                    171: // slightly problematic for ints and longs.  It works on "common"
                    172: // machines.
                    173: 
                    174: 
                    175: istream& ISTREAM::operator>>(unsigned short& u)
                    176: {
                    177:        long l ;
                    178:        *this >> l ;
                    179:        if ( good() ) {
                    180:                u = (unsigned short)l ;
                    181:                if  ( u != l ) {
                    182:                        // overflow
                    183:                        setstate(failbit) ;
                    184:                        }
                    185:                } 
                    186:        return *this ;
                    187:        } 
                    188: 
                    189: istream& ISTREAM::operator>>(unsigned int& u)
                    190: {
                    191:        long l ;
                    192:        *this >> l ;
                    193:        if ( good() ) {
                    194:                u = (unsigned int)l ;
                    195:                if  ( u != l ) {
                    196:                        // overflow
                    197:                        setstate(failbit) ;
                    198:                        }
                    199:                } 
                    200:        return *this ;
                    201:        } 
                    202: 
                    203: istream& ISTREAM::operator>>(unsigned long& u)
                    204: {
                    205:        long l ;
                    206:        *this >> l ;
                    207:        if ( good() ) {
                    208:                u = (unsigned long)l ;
                    209:                if  ( u != l ) {
                    210:                        // overflow
                    211:                        setstate(failbit) ;
                    212:                        }
                    213:                } 
                    214:        return *this ;
                    215:        } 
                    216: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.