Skip to content

Commit 5e485a9

Browse files
committed
Move I/O logic out of Misc.swift
Also remove contentious [US]{8,16,32,64,128} types Swift SVN r3169
1 parent ac5abd9 commit 5e485a9

File tree

2 files changed

+365
-1
lines changed

2 files changed

+365
-1
lines changed

stdlib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LINK_LIBS_IN_SHARED := 1
1818
SHARED_LIBRARY := 1
1919
SWIFT_SOURCES := Bool.swift FixedPoint.swift FloatingPoint.swift Misc.swift \
2020
String.swift Dictionary.swift Vector.swift Algorithm.swift \
21-
Demangle.swift \
21+
Demangle.swift OutputStream.swift \
2222
POSIX/Descriptor.swift POSIX/File.swift POSIX/Misc.swift
2323
SOURCES := swift.swift
2424
NO_BUILD_ARCHIVE := 1

stdlib/OutputStream.swift

Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
//===----------------------------------------------------------------------===//
2+
// OutputStream and Formatting logic
3+
//===----------------------------------------------------------------------===//
4+
5+
extension Int8 : FormattedPrintable {
6+
func format(kind : Char, layout : String) -> String {
7+
return Int64(this).format(kind, layout)
8+
}
9+
}
10+
11+
extension UInt8 : FormattedPrintable {
12+
func format(kind : Char, layout : String) -> String {
13+
return UInt64(this).format(kind, layout)
14+
}
15+
}
16+
17+
extension Int16 : FormattedPrintable {
18+
func format(kind : Char, layout : String) -> String {
19+
return UInt64(this).format(kind, layout)
20+
}
21+
}
22+
23+
extension UInt16 : FormattedPrintable {
24+
func format(kind : Char, layout : String) -> String {
25+
return UInt64(this).format(kind, layout)
26+
}
27+
}
28+
29+
extension Int32 : FormattedPrintable {
30+
func format(kind : Char, layout : String) -> String {
31+
return Int64(this).format(kind, layout)
32+
}
33+
}
34+
35+
extension UInt32 : FormattedPrintable {
36+
func format(kind : Char, layout : String) -> String {
37+
return UInt64(this).format(kind, layout)
38+
}
39+
}
40+
41+
extension Int64 : FormattedPrintable {
42+
func format(kind : Char, layout : String) -> String {
43+
var radix = 10
44+
if kind == 'x' { radix = 16 }
45+
else if kind == 'o' { radix = 8 }
46+
return Format(layout).printToString(String(this, radix = radix))
47+
}
48+
}
49+
50+
extension UInt64 : FormattedPrintable {
51+
func format(kind : Char, layout : String) -> String{
52+
var radix = 10
53+
if kind == 'x' { radix = 16 }
54+
else if kind == 'o' { radix = 8 }
55+
return Format(layout).printToString(String(this, radix = radix))
56+
}
57+
}
58+
59+
extension Int128 : FormattedPrintable {
60+
func format(kind : Char, layout : String) -> String {
61+
var radix = 10
62+
if kind == 'x' { radix = 16 }
63+
else if kind == 'o' { radix = 8 }
64+
return Format(layout).printToString(String(this, radix = radix))
65+
}
66+
}
67+
68+
extension UInt128 : FormattedPrintable {
69+
func format(kind : Char, layout : String) -> String {
70+
var radix = 10
71+
if kind == 'x' { radix = 16 }
72+
else if kind == 'o' { radix = 8 }
73+
return Format(layout).printToString(String(this, radix = radix))
74+
}
75+
}
76+
77+
extension Float : FormattedPrintable {
78+
func format(kind : Char, layout : String) -> String {
79+
return Format(layout).printToString(String(this))
80+
}
81+
}
82+
83+
extension Double : FormattedPrintable {
84+
func format(kind : Char, layout : String) -> String {
85+
return Format(layout).printToString(String(this))
86+
}
87+
}
88+
89+
//===----------------------------------------------------------------------===//
90+
// Formatted Printing
91+
//===----------------------------------------------------------------------===//
92+
93+
struct Format {
94+
var width : Int
95+
var isValid : Bool
96+
var leftJustify : Bool
97+
98+
constructor(layout : String) {
99+
isValid = true
100+
leftJustify = false
101+
width = 0
102+
103+
if !layout.isEmpty() {
104+
if layout[0] == '-' {
105+
leftJustify = true
106+
layout = layout.substr(1)
107+
}
108+
109+
if !layout.isEmpty() {
110+
for c in layout {
111+
if !c.isDigit() {
112+
isValid = false
113+
break
114+
}
115+
width = width * 10 + Int(UInt32(c) - UInt32('0'))
116+
}
117+
}
118+
}
119+
}
120+
121+
func printString(s : String) {
122+
123+
/* Causes problems due to <rdar://problem/11529601>
124+
if !isValid {
125+
print(s)
126+
return
127+
}
128+
*/
129+
var padding = max(width - s.size(), 0)
130+
if !leftJustify {
131+
for i in 0..padding { print(' ') }
132+
}
133+
print(s)
134+
if leftJustify {
135+
for i in 0..padding { print(' ') }
136+
}
137+
}
138+
139+
func printToString(s : String) -> String {
140+
if !isValid {
141+
return s
142+
}
143+
var r : String
144+
var padding = max(width - s.size(), 0)
145+
if !leftJustify {
146+
r = String(padding, ' ')
147+
}
148+
r = r + s
149+
if leftJustify {
150+
r = r + String(padding, ' ')
151+
}
152+
return r
153+
}
154+
155+
func replPrint() {
156+
print("valid = \(isValid), leftJustify = \(leftJustify), width=\(width)")
157+
}
158+
}
159+
160+
// Terminal input & output
161+
162+
class Console {
163+
func write(buf : UInt8[]) -> Int {
164+
var r = posix_write(1, buf.base.value, buf.length)
165+
assert(r != -1)
166+
return r
167+
}
168+
169+
func write(buf : String) -> Int {
170+
var r = posix_write(1, buf.str_value.base.value, buf.length)
171+
assert(r != -1)
172+
return r
173+
}
174+
175+
func write(c : UInt8) {
176+
var buf = new UInt8[1]
177+
buf[0] = c
178+
var r = write(buf)
179+
assert(r == 1)
180+
}
181+
}
182+
183+
class Keyboard {
184+
func read(buf : UInt8[]) -> Int {
185+
var r = posix_read(0, buf.base.value, buf.length)
186+
assert(r >= 0)
187+
return r
188+
}
189+
190+
func read() -> Int {
191+
var c = new UInt8[1]
192+
if read(c) != 1 {
193+
return -1
194+
}
195+
return Int(c[0])
196+
}
197+
}
198+
199+
extension Keyboard {
200+
func getline() -> String {
201+
return getline('\n')
202+
}
203+
204+
func getline(delim : Char) -> String {
205+
var r : String
206+
var i = read()
207+
while i != -1 {
208+
var c = Char(i)
209+
if c == delim {
210+
break
211+
}
212+
r = r + c
213+
i = read()
214+
}
215+
return r
216+
}
217+
}
218+
219+
var con : Console = new Console
220+
var kbd : Keyboard = new Keyboard
221+
222+
protocol FormattedPrintable {
223+
func format(kind : Char, layout : String) -> String
224+
}
225+
226+
func splitFormat(format : String) -> (String, String, Char, String) {
227+
var (before, afterPercent, foundPercent) = format.splitFirst('%')
228+
if !foundPercent {
229+
return (before, "", Char(0), afterPercent)
230+
}
231+
232+
var (layout, kind, after, found) = afterPercent.splitFirstIf({ $0.isAlpha() })
233+
if !found {
234+
return (before, "", Char(0), afterPercent)
235+
}
236+
237+
return (before, layout, kind, after)
238+
}
239+
240+
protocol OutputStreamable {
241+
func write(buf : UInt8[]) -> Int
242+
// FIXME: Add default implementation when language allows it:
243+
func write(buf : String) -> Int
244+
// {return write(buf.asUInt8())}
245+
}
246+
247+
// printf to an OutputStreamable
248+
// FIXME: Remove the FormattedPrintable[] overload if/when we can forward
249+
// variadic arguments.
250+
func printf(out : OutputStreamable, format : String, args : FormattedPrintable[]) {
251+
var index = 0
252+
while !format.isEmpty() {
253+
var (before, layout, kind, after) = splitFormat(format)
254+
out.write(before)
255+
if kind != Char(0) {
256+
out.write(args[index].format(kind, layout))
257+
++index
258+
}
259+
format = after
260+
}
261+
}
262+
263+
func printf(out : OutputStreamable, format : String, args : FormattedPrintable...) {
264+
printf(out, format, args)
265+
}
266+
267+
func printf(format : String, args : FormattedPrintable...) {
268+
printf(con, format, args)
269+
}
270+
271+
protocol ReplPrintable {
272+
func replPrint()
273+
}
274+
// FIXME: This function shouldn't be necessary!
275+
func replPrintSlice<T : ReplPrintable>(s : T[]) {
276+
print('[')
277+
var first = true
278+
var total = 0
279+
for i in s {
280+
if first {
281+
first = false
282+
} else {
283+
print(", ")
284+
}
285+
i.replPrint()
286+
total = total + 1
287+
if total > 50 {
288+
print(" ...]")
289+
return
290+
}
291+
}
292+
print(']')
293+
}
294+
295+
// Some very basic output functions.
296+
func print(val : Int)
297+
func print(val : UInt64)
298+
func print(val : Double)
299+
func print(val : String) {
300+
var len = val.byteLength()
301+
for var i = 0; i < len; ++i {
302+
c_putchar(Int32(val.str_value[i]))
303+
}
304+
}
305+
func print(val : Char) {
306+
var wc = UInt32(val)
307+
if wc < 0x000080 {
308+
c_putchar(Int32(wc))
309+
return
310+
} else if wc < 0x000800 {
311+
c_putchar(Int32(0xC0 | (wc >> 6)))
312+
c_putchar(Int32(0x80 | (wc & 0x03F)))
313+
return
314+
} else if wc < 0x010000 {
315+
if !(0x00D800 <= wc && wc < 0x00E000) {
316+
c_putchar(Int32(0xE0 | (wc >> 12)))
317+
c_putchar(Int32(0x80 | ((wc & 0x0FC0) >> 6)))
318+
c_putchar(Int32(0x80 | (wc & 0x003F)))
319+
return
320+
}
321+
} else if wc < 0x110000 {
322+
c_putchar(Int32(0xF0 | (wc >> 18)))
323+
c_putchar(Int32(0x80 | ((wc & 0x03F000) >> 12)))
324+
c_putchar(Int32(0x80 | ((wc & 0x000FC0) >> 6)))
325+
c_putchar(Int32(0x80 | (wc & 0x00003F)))
326+
return
327+
}
328+
print(Char(0xFFFD))
329+
}
330+
331+
func print(val : Bool) {
332+
if val {
333+
print("true")
334+
} else {
335+
print("false")
336+
}
337+
}
338+
339+
// Some derived output functions.
340+
func println(val : Bool) {
341+
print(val)
342+
print('\n')
343+
}
344+
func println(val : Int) {
345+
print(val)
346+
print('\n')
347+
}
348+
func println(val : UInt64) {
349+
print(val)
350+
print('\n')
351+
}
352+
func println(val : Double) {
353+
print(val)
354+
print('\n')
355+
}
356+
func println(val : String) {
357+
print(val)
358+
print('\n')
359+
}
360+
361+
func println(val : Char) {
362+
print(val)
363+
print('\n')
364+
}

0 commit comments

Comments
 (0)