Skip to content

Commit 720a54a

Browse files
author
Cornel
authored
extend stdlib to allow import of more packages (#1099)
* stdlib: extend stdlib to allow import of more packages
1 parent de45da5 commit 720a54a

File tree

16 files changed

+549
-13
lines changed

16 files changed

+549
-13
lines changed

src/os/env.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package os
2+
3+
func Getenv(key string) string {
4+
return ""
5+
}

src/os/errors.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package os
2+
3+
import (
4+
"errors"
5+
)
6+
7+
var (
8+
ErrInvalid = errors.New("invalid argument")
9+
ErrPermission = errors.New("permission denied")
10+
ErrClosed = errors.New("file already closed")
11+
12+
// Portable analogs of some common system call errors.
13+
// Note that these are exported for use in the Filesystem interface.
14+
ErrUnsupported = errors.New("operation not supported")
15+
ErrNotImplemented = errors.New("operation not implemented")
16+
ErrNotExist = errors.New("file not found")
17+
ErrExist = errors.New("file exists")
18+
)
19+
20+
func IsPermission(err error) bool {
21+
return err == ErrPermission
22+
}
23+
24+
func NewSyscallError(syscall string, err error) error {
25+
if err == nil {
26+
return nil
27+
}
28+
return &SyscallError{syscall, err}
29+
}
30+
31+
// SyscallError records an error from a specific system call.
32+
type SyscallError struct {
33+
Syscall string
34+
Err error
35+
}
36+
37+
func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }
38+
39+
func (e *SyscallError) Unwrap() error { return e.Err }

src/os/exec.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package os
2+
3+
type Signal interface {
4+
String() string
5+
Signal() // to distinguish from other Stringers
6+
}

src/os/file.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,7 @@
66
package os
77

88
import (
9-
"errors"
10-
)
11-
12-
// Portable analogs of some common system call errors.
13-
// Note that these are exported for use in the Filesystem interface.
14-
var (
15-
ErrUnsupported = errors.New("operation not supported")
16-
ErrNotImplemented = errors.New("operation not implemented")
17-
ErrNotExist = errors.New("file not found")
18-
ErrExist = errors.New("file exists")
9+
"syscall"
1910
)
2011

2112
// Mkdir creates a directory. If the operation fails, it will return an error of
@@ -91,6 +82,10 @@ func (f *File) Read(b []byte) (n int, err error) {
9182
return
9283
}
9384

85+
func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
86+
return 0, ErrNotImplemented
87+
}
88+
9489
// Write writes len(b) bytes to the File. It returns the number of bytes written
9590
// and an error, if any. Write returns a non-nil error when n != len(b).
9691
func (f *File) Write(b []byte) (n int, err error) {
@@ -125,6 +120,20 @@ func (f *File) Stat() (FileInfo, error) {
125120
return nil, &PathError{"stat", f.name, ErrNotImplemented}
126121
}
127122

123+
// Sync is a stub, not yet implemented
124+
func (f *File) Sync() error {
125+
return ErrNotImplemented
126+
}
127+
128+
func (f *File) SyscallConn() (syscall.RawConn, error) {
129+
return nil, ErrNotImplemented
130+
}
131+
132+
// Fd returns the file handle referencing the open file.
133+
func (f *File) Fd() uintptr {
134+
panic("unimplemented: os.file.Fd()")
135+
}
136+
128137
const (
129138
PathSeparator = '/' // OS-specific path separator
130139
PathListSeparator = ':' // OS-specific path list separator
@@ -194,7 +203,7 @@ type FileInfo interface {
194203
Name() string // base name of the file
195204
Size() int64 // length in bytes for regular files; system-dependent for others
196205
Mode() FileMode // file mode bits
197-
// ModTime() time.Time // modification time
206+
// TODO ModTime() time.Time // modification time
198207
IsDir() bool // abbreviation for Mode().IsDir()
199208
Sys() interface{} // underlying data source (can return nil)
200209
}

src/os/sys.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package os
2+
3+
func Hostname() (name string, err error) {
4+
return "", ErrNotImplemented
5+
}

src/reflect/deepequal.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package reflect
2+
3+
func DeepEqual(x, y interface{}) bool {
4+
if x == nil || y == nil {
5+
return x == y
6+
}
7+
8+
panic("unimplemented: reflect.DeepEqual()")
9+
}

src/reflect/strconv.go

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
// Copyright 2009 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package reflect
6+
7+
import (
8+
"unicode/utf8"
9+
)
10+
11+
// errSyntax indicates that a value does not have the right syntax for the target type.
12+
var errSyntax = badSyntax{}
13+
14+
type badSyntax struct{}
15+
16+
func (badSyntax) Error() string {
17+
return "invalid syntax"
18+
}
19+
20+
func unhex(b byte) (v rune, ok bool) {
21+
c := rune(b)
22+
switch {
23+
case '0' <= c && c <= '9':
24+
return c - '0', true
25+
case 'a' <= c && c <= 'f':
26+
return c - 'a' + 10, true
27+
case 'A' <= c && c <= 'F':
28+
return c - 'A' + 10, true
29+
}
30+
return
31+
}
32+
33+
// unquoteChar decodes the first character or byte in the escaped string
34+
// or character literal represented by the string s.
35+
// It returns four values:
36+
//
37+
// 1) value, the decoded Unicode code point or byte value;
38+
// 2) multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation;
39+
// 3) tail, the remainder of the string after the character; and
40+
// 4) an error that will be nil if the character is syntactically valid.
41+
//
42+
// The second argument, quote, specifies the type of literal being parsed
43+
// and therefore which escaped quote character is permitted.
44+
// If set to a single quote, it permits the sequence \' and disallows unescaped '.
45+
// If set to a double quote, it permits \" and disallows unescaped ".
46+
// If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
47+
func unquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) {
48+
// easy cases
49+
if len(s) == 0 {
50+
err = errSyntax
51+
return
52+
}
53+
switch c := s[0]; {
54+
case c == quote && (quote == '\'' || quote == '"'):
55+
err = errSyntax
56+
return
57+
case c >= utf8.RuneSelf:
58+
r, size := utf8.DecodeRuneInString(s)
59+
return r, true, s[size:], nil
60+
case c != '\\':
61+
return rune(s[0]), false, s[1:], nil
62+
}
63+
64+
// hard case: c is backslash
65+
if len(s) <= 1 {
66+
err = errSyntax
67+
return
68+
}
69+
c := s[1]
70+
s = s[2:]
71+
72+
switch c {
73+
case 'a':
74+
value = '\a'
75+
case 'b':
76+
value = '\b'
77+
case 'f':
78+
value = '\f'
79+
case 'n':
80+
value = '\n'
81+
case 'r':
82+
value = '\r'
83+
case 't':
84+
value = '\t'
85+
case 'v':
86+
value = '\v'
87+
case 'x', 'u', 'U':
88+
n := 0
89+
switch c {
90+
case 'x':
91+
n = 2
92+
case 'u':
93+
n = 4
94+
case 'U':
95+
n = 8
96+
}
97+
var v rune
98+
if len(s) < n {
99+
err = errSyntax
100+
return
101+
}
102+
for j := 0; j < n; j++ {
103+
x, ok := unhex(s[j])
104+
if !ok {
105+
err = errSyntax
106+
return
107+
}
108+
v = v<<4 | x
109+
}
110+
s = s[n:]
111+
if c == 'x' {
112+
// single-byte string, possibly not UTF-8
113+
value = v
114+
break
115+
}
116+
if v > utf8.MaxRune {
117+
err = errSyntax
118+
return
119+
}
120+
value = v
121+
multibyte = true
122+
case '0', '1', '2', '3', '4', '5', '6', '7':
123+
v := rune(c) - '0'
124+
if len(s) < 2 {
125+
err = errSyntax
126+
return
127+
}
128+
for j := 0; j < 2; j++ { // one digit already; two more
129+
x := rune(s[j]) - '0'
130+
if x < 0 || x > 7 {
131+
err = errSyntax
132+
return
133+
}
134+
v = (v << 3) | x
135+
}
136+
s = s[2:]
137+
if v > 255 {
138+
err = errSyntax
139+
return
140+
}
141+
value = v
142+
case '\\':
143+
value = '\\'
144+
case '\'', '"':
145+
if c != quote {
146+
err = errSyntax
147+
return
148+
}
149+
value = rune(c)
150+
default:
151+
err = errSyntax
152+
return
153+
}
154+
tail = s
155+
return
156+
}
157+
158+
// unquote interprets s as a single-quoted, double-quoted,
159+
// or backquoted Go string literal, returning the string value
160+
// that s quotes. (If s is single-quoted, it would be a Go
161+
// character literal; unquote returns the corresponding
162+
// one-character string.)
163+
func unquote(s string) (string, error) {
164+
n := len(s)
165+
if n < 2 {
166+
return "", errSyntax
167+
}
168+
quote := s[0]
169+
if quote != s[n-1] {
170+
return "", errSyntax
171+
}
172+
s = s[1 : n-1]
173+
174+
if quote == '`' {
175+
if contains(s, '`') {
176+
return "", errSyntax
177+
}
178+
if contains(s, '\r') {
179+
// -1 because we know there is at least one \r to remove.
180+
buf := make([]byte, 0, len(s)-1)
181+
for i := 0; i < len(s); i++ {
182+
if s[i] != '\r' {
183+
buf = append(buf, s[i])
184+
}
185+
}
186+
return string(buf), nil
187+
}
188+
return s, nil
189+
}
190+
if quote != '"' && quote != '\'' {
191+
return "", errSyntax
192+
}
193+
if contains(s, '\n') {
194+
return "", errSyntax
195+
}
196+
197+
// Is it trivial? Avoid allocation.
198+
if !contains(s, '\\') && !contains(s, quote) {
199+
switch quote {
200+
case '"':
201+
if utf8.ValidString(s) {
202+
return s, nil
203+
}
204+
case '\'':
205+
r, size := utf8.DecodeRuneInString(s)
206+
if size == len(s) && (r != utf8.RuneError || size != 1) {
207+
return s, nil
208+
}
209+
}
210+
}
211+
212+
var runeTmp [utf8.UTFMax]byte
213+
buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
214+
for len(s) > 0 {
215+
c, multibyte, ss, err := unquoteChar(s, quote)
216+
if err != nil {
217+
return "", err
218+
}
219+
s = ss
220+
if c < utf8.RuneSelf || !multibyte {
221+
buf = append(buf, byte(c))
222+
} else {
223+
n := utf8.EncodeRune(runeTmp[:], c)
224+
buf = append(buf, runeTmp[:n]...)
225+
}
226+
if quote == '\'' && len(s) != 0 {
227+
// single-quoted must be single character
228+
return "", errSyntax
229+
}
230+
}
231+
return string(buf), nil
232+
}
233+
234+
// contains reports whether the string contains the byte c.
235+
func contains(s string, c byte) bool {
236+
return indexByteString(s, c) != -1
237+
}
238+
239+
// Index finds the index of the first instance of the specified byte in the string.
240+
// If the byte is not found, this returns -1.
241+
func indexByteString(s string, c byte) int {
242+
for i := 0; i < len(s); i++ {
243+
if s[i] == c {
244+
return i
245+
}
246+
}
247+
return -1
248+
}

0 commit comments

Comments
 (0)