/*****************************************************************************\
*                           Systems Research Group                            *
*******************************************************************************


                     #######   ##        ########  #######
                     ########  ##        ########  ########
                     ##    ##  ##           ##     ##    ##
                     #######   ##           ##     #######
                     ##    ##  ##           ##     ##    ##
                     ##    ##  ##           ##     ##    ##
                     ########  ########  ########  ########
                     #######   ########  ########  #######


********************************************************************************
*    I. D. Wilson           Last Modified   -   IDW   -   01/09/84             *
\******************************************************************************/



SECTION "BLIB"



GET "LIBHDR"



LET packstring( v, s )  =  VALOF
$(
    LET n     =  v!0 & #XFF
    LET size  =  n/bytesperword

    FOR  i = 0    TO  n                        DO  s % i  :=  v!i
    FOR  i = n+1  TO  (size+1)*bytesperword-1  DO  s % i  :=  0

    RESULTIS size
$)



AND unpackstring( s, v )  BE
    FOR  i = s % 0  TO  0  BY -1  DO  v!i  :=  s % i



AND readn()  =  VALOF
$(
    LET sum       =  0
    LET negative  =  FALSE
    LET ch        =  rdch()

    UNTIL  '0' <= ch <= '9'  DO
    $(
        SWITCHON  ch  INTO
        $(
            CASE '*S'  :
            CASE '*T'  :
            CASE '*N'  :  //  Layout character.  Skip this, and try to find
                          //  the next one.

                          ENDCASE


            CASE '+'   :  //  Positive sign.  Meaningless, so ignore it.

                          ENDCASE


            CASE '-'   :  //  Negative sign.  Set the "negative" flag.

                         negative  :=  TRUE
                         ENDCASE


            DEFAULT   :  //  Not the sort of character we were expecting,
                         //  so return with zero result.

                         unrdch()

                         RESULTIS  0
        $)

        ch  :=  rdch()
    $)

    //  Now read the rest of the number.

    WHILE  '0' <= ch <= '9'  DO
    $(
        sum  :=  sum * 10  +  ch  -  '0'
        ch   :=  rdch()
    $)

    unrdch()

    RESULTIS  negative  ->  -sum, sum
$)



AND newline()  BE  wrch( '*N' )



AND writed( n, d )  BE
$(
    LET t  =  VEC 10
    LET i  =  0
    LET k  =  -n

    IF n < 0  THEN  d, k  :=  d-1, n

    t!i, k, i  :=  -(k REM 10), k/10, i+1   REPEATUNTIL k = 0

    FOR  j = i+1  TO  d  DO  wrch( '*S' )

    IF n < 0  THEN  wrch ( '-' )

    FOR  j = i-1  TO  0  BY  -1  DO  wrch( t!j + '0' )
$)



AND writen( n )  BE  writed( n, 0 )



AND writehex( n, d )  BE
$(
    IF  d > 1  THEN  writehex( n >> 4, d-1 )

    wrch( (n & #B1111)!TABLE  '0','1','2','3','4','5','6','7',
                              '8','9','A','B','C','D','E','F' )
$)



AND writeoct( n, d )  BE
$(
    IF d > 1  THEN  writeoct( n >> 3, d-1 )

    wrch( (n & #B111) + '0' )
$)



AND writes( s )  BE  FOR  i = 1  TO  s % 0  DO  wrch( s % i )



AND writef( format, a, b, c, d, e, f, g, h, i, j, k )  BE
$(
    LET t  =  @a

    FOR  p = 1  TO  format % 0  DO
    $(
        LET k  =  format % p

        TEST k = '%'  THEN
        $(
            LET f     =  0
            LET n     =  0
            LET type  =  0

            p     :=  p + 1
            type  :=  capitalch( format % p )

            SWITCHON type INTO
            $(
                CASE '$' :  t  :=  t + 1    ;  ENDCASE

                CASE 'S' :  f  :=  writes   ;  GOTO l
                CASE 'C' :  f  :=  wrch     ;  GOTO l
                CASE 'O' :  f  :=  writeoct ;  GOTO m
                CASE 'X' :  f  :=  writehex ;  GOTO m
                CASE 'I' :  f  :=  writed   ;  GOTO m
                CASE 'N' :  f  :=  writen   ;  GOTO l

                DEFAULT  :  wrch( type )    ;  ENDCASE


                m:  p  :=  p + 1
                    n  :=  format % p
                    n  :=  '0' <= n <= '9'  ->   n - '0',  10 + n - 'A'

                l:  f( !t, n )
                
                    t  :=  t + 1
            $)
        $)
        ELSE wrch( k )
    $)
$)



AND capitalch( ch )  =  'a' <= ch <= 'z'  ->  ch - 'a' + 'A',  ch


