PrintfScanf.st
author Claus Gittinger <cg@exept.de>
Tue, 27 Jul 2004 10:28:19 +0200
changeset 1463 abe8e819ea92
child 1464 10af50b07968
permissions -rw-r--r--
initial checkin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1463
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     1
"{ Package: 'stx:libbasic2' }"
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     2
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     3
Object subclass:#PrintfScanf
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
	instanceVariableNames:''
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
	classVariableNames:''
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	poolDictionaries:''
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	category:'System-Support'
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
!PrintfScanf class methodsFor:'documentation'!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
examples
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
"
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    14
    self new printf:'%#x %#X %03o%*.*s' arguments: #(16rABCD 16rEF 5 9 5 ''ghijklmn'') 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    15
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    16
    self new printf:'%- 10.4s%.2e' arguments: (Array with: 'abcdefghijkl' with: Float pi)  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    17
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
    self new printf:'%8.3f' arguments: (Array with: 200 sqrt negated)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    20
    self new printf:'%c' arguments: #(16r41)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    21
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    22
    self new sscanf:'%f%2s%s%s%s' string: '237.0 this is a test' 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    23
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    24
    self new sscanf:'%d%f%s' string: '25 54.32e-01 monday'
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    25
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    26
    self new sscanf:'%f%*f %8[A-F0-9]%c%d 0x%x%f' string: '12.45 1048.73 AE40Z527 0x75BCD15 34'
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    27
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    28
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    29
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    30
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    31
    '%#x %#X %03o%*.*s' printf: #(16rABCD 16rEF 5 9 5 ''ghijklmn'') 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    32
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    33
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    34
    '%- 10.4s%.2e' printf: (Array with: 'abcdefghijkl' with: Float pi)  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    35
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    36
    '%8.3f' printf: (Array with: 200 sqrt negated)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    37
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    38
    '%c' printf: #(16r41)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    39
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    40
    '%f%2s%s%s%s' sscanf: '237.0 this is a test' 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    41
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    42
    '%d%f%s' sscanf: '25 54.32e-01 monday'
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    43
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    44
    '%f%*f %8[A-F0-9]%c%d 0x%x%f' sscanf: '12.45 1048.73 AE40Z527 0x75BCD15 34'
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    45
"
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    46
! !
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    47
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    48
!PrintfScanf methodsFor:'printing'!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    49
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
printArgFrom:inStream to:outStream arguments:argStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
    "Interpret the required number of arguments from <argStream>
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
     according to the formatting information in <inStream>.  Place
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
     the interpretation on <outStream>.  The interpretation is C
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
     printf(3) style, as described in the UTek manual page for
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
     printf(3).  <inStream> is assumed to be positioned just past
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
     $%, and a complete control string is assumed available.     
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
     Return when the conversion control string is consumed.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
     Leave <inStream> pointing past the last character in the conversion control string.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
     This code assumes that <inStream> is formatted according to
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
     specification, and error checking is minimal.  Unexpected
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
     results will be obtained by illegal control strings, or when
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
     argument types do not match conversion codes, but it probably
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
     won't dump core, like C does in such cases!!!!"    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    67
    | ljust plus pound width precision pad char arg argString sci |
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    69
    ljust := plus := pound := false.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
    width := 0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    71
    precision := SmallInteger maxVal.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    72
    pad := $ .
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
    char := inStream peek.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    74
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    75
    char == $% ifTrue:[ 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
        ^ outStream nextPut: inStream next
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    77
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
    char == $- ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
        ljust := true.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
        inStream next.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
        char := inStream peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
    char == $  ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
        outStream space.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
        inStream next.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
        char := inStream peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
    char == $+ ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
        plus := true.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
        inStream next. 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
        char := inStream peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    97
    char == $# ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
        pound := true.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    99
        inStream next.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
        char := inStream peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
    char == $* ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
        width := argStream next.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
        inStream next.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
        char := inStream peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
    char isDigit ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
        char == $0 ifTrue: [pad _ $0].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
        width := Integer readFrom: inStream.  
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
        char := inStream peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   113
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
    char == $. ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
        inStream next.  char _ inStream peek.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
        char == $*
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   118
                    ifTrue: [precision _ argStream next.  inStream next.  char _ inStream peek]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   119
                    ifFalse: [precision _ Integer readFrom: inStream.  char _ inStream peek]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   120
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
    char == $l ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   123
        "Ignore long specifier."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   124
        inStream next.  char _ inStream peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   125
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   126
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
    ('feg' includes: char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   128
            arg _ argStream next asFloat.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   129
            precision _ precision min: 6.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   130
            argString _ WriteStream on: String new.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   131
            char == $g ifTrue:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   132
                    [self absPrintFloat:arg on: argString digits: precision + 1].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
            char == $f ifTrue:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   134
                    [self absDecimalPrintFloat:arg on: argString digits: precision + arg abs log + 1].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   135
            char == $e ifTrue:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   136
                    [self absScientificPrintFloat:arg on: argString digits: precision + 1].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   137
            argString _ argString contents.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   138
            arg < 0
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   139
                    ifTrue: [argString _ '-', argString]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   140
                    ifFalse: [plus ifTrue: [argString _ '+', argString]].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   141
            (precision = 0 and: [pound not]) ifTrue:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   142
                    [(argString includes: $e)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   143
                            ifTrue: ["self halt"]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   144
                            ifFalse:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   145
                                    [argString _ arg truncated printString]].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   146
            pound ifTrue:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   147
                    [(argString includes: $e)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   148
                            ifTrue: ["self halt"]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   149
                            ifFalse:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   150
                                    [precision - (argString size - (argString indexOf: $.)) timesRepeat:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   151
                                            [argString _ argString, '0']]].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   152
            ljust ifTrue: [outStream nextPutAll: argString].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   153
            width - argString size timesRepeat: [outStream space].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   154
            ljust ifFalse: [outStream nextPutAll: argString].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   155
            ^inStream next
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   156
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   157
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   158
    char == $c ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   159
        arg _ String with: argStream next asCharacter
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   160
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   161
        
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   162
    char == $s ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   163
        "Assume the arg is a String or Symbol."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   164
        arg _ argStream next asString
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   165
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   166
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   167
    char == $d ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   168
        arg _ argStream next asInteger printString.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   169
        plus ifTrue: [arg _ '+', arg]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   170
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   171
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   172
    char == $u ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   173
        arg _ argStream next asInteger abs printString
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   174
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   175
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   176
    char == $o ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   177
        arg _ argStream next asInteger abs printStringRadix: 8.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   178
            pound ifTrue: [arg _ '0', arg]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   179
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   180
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   181
    ('xX' includes: char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   182
        arg _ argStream next asInteger abs printStringRadix: 16.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   183
        pound ifTrue: [arg _ '0x', arg]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   184
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   185
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   186
    char == $x ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   187
        1 to: arg size do: [:i |
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   188
                    ('ABCDEF' includes: (arg at: i)) ifTrue:
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   189
                            [arg at: i put: ((arg at: i) asciiValue + 16r20) asCharacter]]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   190
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   191
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   192
    precision _ precision min: arg size.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   193
    ljust ifTrue: [outStream nextPutAll: (arg copyFrom: 1 to: precision)].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   194
    width - precision timesRepeat: [outStream nextPut: pad].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   195
    ljust ifFalse: [outStream nextPutAll: (arg copyFrom: 1 to: precision)].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   196
    ^ inStream next
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   197
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   198
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   199
printf:aString arguments:args 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   200
    "Format and print the receiver with <args> formatted in C style, 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   201
     as described in the UTek manual page for printf(3)."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   202
    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   203
    |aStream|
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   204
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   205
    aStream := WriteStream on:String new.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   206
    self 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   207
        printf:aString
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   208
        on:aStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   209
        arguments:args.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   210
    ^ aStream contents
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   211
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   212
    "
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   213
     self new printf:'%d %x' arguments:#(1234 45054) 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   214
    "
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   215
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   216
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   217
printf:aFormatString on:outStream arguments: args
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   218
    "Format and print aFormatString on <outStream> with <args>
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   219
     formatted in C style, as described in the UTek manual page for
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   220
     printf(3).  This method is designed for producing output
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   221
     suitable for a machine."     
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   222
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   223
    | argStream inStream char |
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   224
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   225
    argStream := ReadStream on: args.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   226
    inStream := ReadStream on: aFormatString.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   227
    [inStream atEnd] whileFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   228
        (char := inStream next) == $% ifFalse: [
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   229
            outStream nextPut: char
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   230
        ] ifTrue: [
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   231
            self printArgFrom:inStream to:outStream arguments:argStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   232
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   233
    ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   234
! !
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   235
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   236
!PrintfScanf methodsFor:'queries'!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   237
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   238
absDecimalPrintFloat:aFloat on:aStream digits:digits 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   239
    "Place a string representation of the receiver on <aStream> using <digits> significant digits, using decimal notation."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   240
    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   241
    |exp x fuzz i|
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   242
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   243
    "x is myself normalized to (1.0, 10.0), exp is my exponent"
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   244
    exp := aFloat abs < 1.0 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   245
                (10.0 / aFloat abs) log floor negated
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   246
            ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   247
                aFloat abs log floor
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   248
            ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   249
    x := aFloat abs / (10.0 raisedTo:exp).
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   250
    fuzz := 10.0 raisedTo:1 - digits.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   251
    x := 0.5 * fuzz + x.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   252
    x >= 10.0 ifTrue:[ 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   253
        "check if rounding has unnormalized x" 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   254
        x := x / 10.0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   255
        exp := exp + 1
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   256
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   257
    exp < 0 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   258
        1 to:1 - exp do:[:j | 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   259
            aStream nextPut:('0.000000000000' at:j)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   260
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   261
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   262
    [ x >= fuzz ] whileTrue:[ 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   263
        "use fuzz to track significance" 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   264
        i := x truncated.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   265
        aStream nextPut:(48 + i) asCharacter.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   266
        x := (x - i) * 10.0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   267
        fuzz := fuzz * 10.0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   268
        exp := exp - 1.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   269
        exp = -1 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   270
            aStream nextPut:$.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   271
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   272
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   273
    [ exp >= -1 ] whileTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   274
        aStream nextPut:$0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   275
        exp := exp - 1.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   276
        exp = -1 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   277
            aStream nextPut:$.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   278
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   279
    ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   280
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   281
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   282
absPrintFloat:aFloat on:aStream digits:digits 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   283
    "Place a string representation of the receiver on <aStream> using <digits> significant digits."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   284
    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   285
    (aFloat < 1.0e6 and:[ aFloat > 1.0e-4 ]) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   286
        self 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   287
            absDecimalPrintFloat:aFloat
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   288
            on:aStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   289
            digits:digits
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   290
    ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   291
        aFloat 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   292
            absScientificPrintFloat:aFloat
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   293
            on:aStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   294
            digits:digits
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   295
    ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   296
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   297
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   298
absScientificPrintFloat:aFloat on:aStream digits:digits 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   299
    "Place a string representation of the receiver on <aStream> using <digits> significant digits, using scientific notation."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   300
    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   301
    |exp fuzz x q i|
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   302
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   303
    "x is myself normalized to [1.0, 10.0), exp is my exponent"
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   304
    exp := aFloat abs < 1.0 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   305
                (10.0 / aFloat abs) log floor negated
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   306
            ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   307
                aFloat abs log floor
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   308
            ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   309
    x := aFloat abs / (10.0 raisedTo:exp).
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   310
    fuzz := 10.0 raisedTo:1 - digits.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   311
    x := 0.5 * fuzz + x.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   312
    x >= 10.0 ifTrue:[ "check if rounding has unnormalized x" 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   313
        x := x / 10.0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   314
        exp := exp + 1
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   315
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   316
    q := exp.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   317
    exp := 0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   318
    [ x >= fuzz ] whileTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   319
        "use fuzz to track significance" 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   320
        i := x truncated.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   321
        aStream nextPut:(48 + i) asCharacter.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   322
        x := (x - i) * 10.0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   323
        fuzz := fuzz * 10.0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   324
        exp := exp - 1.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   325
        exp = -1 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   326
            aStream nextPut:$.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   327
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   328
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   329
    [ exp >= -1 ] whileTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   330
        aStream nextPut:$0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   331
        exp := exp - 1.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   332
        exp = -1 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   333
            aStream nextPut:$.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   334
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   335
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   336
    aStream nextPut:$e.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   337
    q printOn:aStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   338
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   339
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   340
formatArgCountFor:aFormatString
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   341
    "Return the number of arguments required/produced,
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   342
     if the argument is interpreted as a printf/scanf format control string."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   343
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   344
    |nonConsecutive count|
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   345
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   346
    nonConsecutive := true.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   347
    count := 0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   348
    aFormatString do:[:c |
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   349
        c == $% ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   350
            nonConsecutive ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   351
                count := count + 1. 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   352
                nonConsecutive := false
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   353
            ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   354
                count := count - 1. 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   355
                nonConsecutive := true
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   356
            ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   357
        ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   358
            nonConsecutive := true
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   359
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   360
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   361
    ^ count
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   362
! !
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   363
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   364
!PrintfScanf methodsFor:'scanning'!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   365
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   366
scanArgFrom:dataStream to:collection format:format 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   367
    "Add to <collection> an object who's representation is found
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   368
     in <dataStream> interpreted according to the conversion
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   369
     control string in the Stream <format>.  <format> is assumed to
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   370
     be positioned just past a $%, and a complete control string is
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   371
     assumed available.    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   372
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   373
     Return when the conversion control string is consumed.  Leave
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   374
     <format> pointing past the last character in the conversion
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   375
     control string, leave <dataStream> pointing past any width
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   376
     specified in <format>, or at the first character that doesn't
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   377
     make sense for the <format>."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   378
    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   379
    |final width char pos data scanset exclusive return last|
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   380
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   381
    final := [:retval | 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   382
            collection add:retval.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   383
            data == dataStream ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   384
                dataStream position:dataStream position + data position
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   385
            ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   386
            ^ self
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   387
        ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   388
    width := 0.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   389
    char := format peek.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   390
    char == $% ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   391
        ^ dataStream peekFor:char
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   392
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   393
    char == $* ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   394
        format next.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   395
        char := format peek.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   396
        final := [:retval | 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   397
                data == dataStream ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   398
                    dataStream position:dataStream position + data position
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   399
                ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   400
                ^ self
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   401
            ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   402
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   403
    char isDigit ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   404
        width := Integer readFrom:format.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   405
        char := format peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   406
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   407
    ('slhduoxfeg' includes:char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   408
        dataStream skipSeparators
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   409
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   410
    width = 0 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   411
        data := dataStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   412
    ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   413
        pos := dataStream position.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   414
        data := ReadStream on:(dataStream next:width).
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   415
        dataStream position:pos
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   416
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   417
    char == $s ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   418
        final value:(data upToSeparator)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   419
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   420
    char == $c ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   421
        width = 0 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   422
            final value:(String with:data next)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   423
        ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   424
            final value:data contents
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   425
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   426
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   427
    char == $[ ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   428
        "What a mess!!!!" 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   429
        return := WriteStream on:(String new:8).
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   430
        scanset := IdentitySet new.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   431
        format next.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   432
        width = 0 ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   433
            width := SmallInteger maxVal
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   434
        ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   435
        exclusive := format peekFor:$^.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   436
        [
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   437
            last := char.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   438
            char := format next.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   439
            char == $]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   440
        ] whileFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   441
            char == $- ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   442
                scanset add:char
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   443
            ] ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   444
                (last to:format next) do:[:c | 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   445
                    scanset add:c
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   446
                ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   447
            ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   448
        ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   449
        [
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   450
            data atEnd not and:[ (scanset includes:data peek) xor:exclusive ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   451
        ] whileTrue:[ return nextPut:data next ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   452
        final value:return contents
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   453
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   454
    ('lh' includes:char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   455
        format next.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   456
        char := format peek
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   457
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   458
    ('DUdu' includes:char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   459
        final value:(Integer readFrom:data)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   460
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   461
    ('FEGfeg' includes:char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   462
        final value:(Float readFrom:data)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   463
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   464
    ('Oo' includes:char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   465
        final value:(Integer readFrom:data radix:8)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   466
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   467
    ('Xx' includes:char) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   468
        final value:(Integer readFrom:data radix:16)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   469
    ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   470
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   471
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   472
scanf:formatString fromStream:dataStream 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   473
    "Return a Collection of objects found in the Character Stream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   474
     <dataStream> as interpreted according to the receiver.  The
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   475
     receiver is assumed to be a conversion control string as
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   476
     specified in the UTek manual page for scanf(3)."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   477
    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   478
    |results format char|
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   479
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   480
    results := OrderedCollection new.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   481
    format := ReadStream on:formatString.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   482
    [ format atEnd ] whileFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   483
        char := format next.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   484
        (char == Character space or:[ char == Character tab ]) ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   485
            dataStream skipSeparators.
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   486
            format skipSeparators
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   487
        ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   488
        char == $% ifTrue:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   489
            self 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   490
                scanArgFrom:dataStream
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   491
                to:results
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   492
                format:format
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   493
        ] ifFalse:[
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   494
            dataStream peekFor:char
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   495
        ]
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   496
    ].
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   497
    ^ results
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   498
!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   499
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   500
sscanf:formatString fromString:aString 
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   501
    "Return a Collection of objects found in <string> as
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   502
     interpreted according to the receiver.  The receiver is
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   503
     assumed to be a conversion control string as specified in the
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   504
     UTek manual page for scanf(3)."
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   505
    
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   506
    ^ self scanf:formatString fromStream:(ReadStream on:aString)
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   507
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   508
    "
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   509
     self new sscanf:'%d %x' fromString:'1234 affe'
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   510
    "
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   511
! !
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   512
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   513
!PrintfScanf class methodsFor:'documentation'!
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   514
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   515
version
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   516
    ^ '$Header: /cvs/stx/stx/libbasic2/PrintfScanf.st,v 1.1 2004-07-27 08:28:19 cg Exp $'
abe8e819ea92 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   517
! !