Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/os/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package os

func Getenv(key string) string {
return ""
}
39 changes: 39 additions & 0 deletions src/os/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package os

import (
"errors"
)

var (
ErrInvalid = errors.New("invalid argument")
ErrPermission = errors.New("permission denied")
ErrClosed = errors.New("file already closed")

// Portable analogs of some common system call errors.
// Note that these are exported for use in the Filesystem interface.
ErrUnsupported = errors.New("operation not supported")
ErrNotImplemented = errors.New("operation not implemented")
ErrNotExist = errors.New("file not found")
ErrExist = errors.New("file exists")
)

func IsPermission(err error) bool {
return err == ErrPermission
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not complete (it doesn't unwrap the error) but I guess it's fine for now.

}

func NewSyscallError(syscall string, err error) error {
if err == nil {
return nil
}
return &SyscallError{syscall, err}
}

// SyscallError records an error from a specific system call.
type SyscallError struct {
Syscall string
Err error
}

func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }

func (e *SyscallError) Unwrap() error { return e.Err }
6 changes: 6 additions & 0 deletions src/os/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package os

type Signal interface {
String() string
Signal() // to distinguish from other Stringers
}
31 changes: 20 additions & 11 deletions src/os/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,7 @@
package os

import (
"errors"
)

// Portable analogs of some common system call errors.
// Note that these are exported for use in the Filesystem interface.
var (
ErrUnsupported = errors.New("operation not supported")
ErrNotImplemented = errors.New("operation not implemented")
ErrNotExist = errors.New("file not found")
ErrExist = errors.New("file exists")
"syscall"
)

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

func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
return 0, ErrNotImplemented
}

// Write writes len(b) bytes to the File. It returns the number of bytes written
// and an error, if any. Write returns a non-nil error when n != len(b).
func (f *File) Write(b []byte) (n int, err error) {
Expand Down Expand Up @@ -125,6 +120,20 @@ func (f *File) Stat() (FileInfo, error) {
return nil, &PathError{"stat", f.name, ErrNotImplemented}
}

// Sync is a stub, not yet implemented
func (f *File) Sync() error {
return ErrNotImplemented
}

func (f *File) SyscallConn() (syscall.RawConn, error) {
return nil, ErrNotImplemented
}

// Fd returns the file handle referencing the open file.
func (f *File) Fd() uintptr {
panic("unimplemented: os.file.Fd()")
}

const (
PathSeparator = '/' // OS-specific path separator
PathListSeparator = ':' // OS-specific path list separator
Expand Down Expand Up @@ -194,7 +203,7 @@ type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
Mode() FileMode // file mode bits
// ModTime() time.Time // modification time
// TODO ModTime() time.Time // modification time
IsDir() bool // abbreviation for Mode().IsDir()
Sys() interface{} // underlying data source (can return nil)
}
Expand Down
5 changes: 5 additions & 0 deletions src/os/sys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package os

func Hostname() (name string, err error) {
return "", ErrNotImplemented
}
9 changes: 9 additions & 0 deletions src/reflect/deepequal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package reflect

func DeepEqual(x, y interface{}) bool {
if x == nil || y == nil {
return x == y
}

panic("unimplemented: reflect.DeepEqual()")
}
248 changes: 248 additions & 0 deletions src/reflect/strconv.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package reflect

import (
"unicode/utf8"
)

// errSyntax indicates that a value does not have the right syntax for the target type.
var errSyntax = badSyntax{}

type badSyntax struct{}

func (badSyntax) Error() string {
return "invalid syntax"
}

func unhex(b byte) (v rune, ok bool) {
c := rune(b)
switch {
case '0' <= c && c <= '9':
return c - '0', true
case 'a' <= c && c <= 'f':
return c - 'a' + 10, true
case 'A' <= c && c <= 'F':
return c - 'A' + 10, true
}
return
}

// unquoteChar decodes the first character or byte in the escaped string
// or character literal represented by the string s.
// It returns four values:
//
// 1) value, the decoded Unicode code point or byte value;
// 2) multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation;
// 3) tail, the remainder of the string after the character; and
// 4) an error that will be nil if the character is syntactically valid.
//
// The second argument, quote, specifies the type of literal being parsed
// and therefore which escaped quote character is permitted.
// If set to a single quote, it permits the sequence \' and disallows unescaped '.
// If set to a double quote, it permits \" and disallows unescaped ".
// If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
func unquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) {
// easy cases
if len(s) == 0 {
err = errSyntax
return
}
switch c := s[0]; {
case c == quote && (quote == '\'' || quote == '"'):
err = errSyntax
return
case c >= utf8.RuneSelf:
r, size := utf8.DecodeRuneInString(s)
return r, true, s[size:], nil
case c != '\\':
return rune(s[0]), false, s[1:], nil
}

// hard case: c is backslash
if len(s) <= 1 {
err = errSyntax
return
}
c := s[1]
s = s[2:]

switch c {
case 'a':
value = '\a'
case 'b':
value = '\b'
case 'f':
value = '\f'
case 'n':
value = '\n'
case 'r':
value = '\r'
case 't':
value = '\t'
case 'v':
value = '\v'
case 'x', 'u', 'U':
n := 0
switch c {
case 'x':
n = 2
case 'u':
n = 4
case 'U':
n = 8
}
var v rune
if len(s) < n {
err = errSyntax
return
}
for j := 0; j < n; j++ {
x, ok := unhex(s[j])
if !ok {
err = errSyntax
return
}
v = v<<4 | x
}
s = s[n:]
if c == 'x' {
// single-byte string, possibly not UTF-8
value = v
break
}
if v > utf8.MaxRune {
err = errSyntax
return
}
value = v
multibyte = true
case '0', '1', '2', '3', '4', '5', '6', '7':
v := rune(c) - '0'
if len(s) < 2 {
err = errSyntax
return
}
for j := 0; j < 2; j++ { // one digit already; two more
x := rune(s[j]) - '0'
if x < 0 || x > 7 {
err = errSyntax
return
}
v = (v << 3) | x
}
s = s[2:]
if v > 255 {
err = errSyntax
return
}
value = v
case '\\':
value = '\\'
case '\'', '"':
if c != quote {
err = errSyntax
return
}
value = rune(c)
default:
err = errSyntax
return
}
tail = s
return
}

// unquote interprets s as a single-quoted, double-quoted,
// or backquoted Go string literal, returning the string value
// that s quotes. (If s is single-quoted, it would be a Go
// character literal; unquote returns the corresponding
// one-character string.)
func unquote(s string) (string, error) {
n := len(s)
if n < 2 {
return "", errSyntax
}
quote := s[0]
if quote != s[n-1] {
return "", errSyntax
}
s = s[1 : n-1]

if quote == '`' {
if contains(s, '`') {
return "", errSyntax
}
if contains(s, '\r') {
// -1 because we know there is at least one \r to remove.
buf := make([]byte, 0, len(s)-1)
for i := 0; i < len(s); i++ {
if s[i] != '\r' {
buf = append(buf, s[i])
}
}
return string(buf), nil
}
return s, nil
}
if quote != '"' && quote != '\'' {
return "", errSyntax
}
if contains(s, '\n') {
return "", errSyntax
}

// Is it trivial? Avoid allocation.
if !contains(s, '\\') && !contains(s, quote) {
switch quote {
case '"':
if utf8.ValidString(s) {
return s, nil
}
case '\'':
r, size := utf8.DecodeRuneInString(s)
if size == len(s) && (r != utf8.RuneError || size != 1) {
return s, nil
}
}
}

var runeTmp [utf8.UTFMax]byte
buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
for len(s) > 0 {
c, multibyte, ss, err := unquoteChar(s, quote)
if err != nil {
return "", err
}
s = ss
if c < utf8.RuneSelf || !multibyte {
buf = append(buf, byte(c))
} else {
n := utf8.EncodeRune(runeTmp[:], c)
buf = append(buf, runeTmp[:n]...)
}
if quote == '\'' && len(s) != 0 {
// single-quoted must be single character
return "", errSyntax
}
}
return string(buf), nil
}

// contains reports whether the string contains the byte c.
func contains(s string, c byte) bool {
return indexByteString(s, c) != -1
}

// Index finds the index of the first instance of the specified byte in the string.
// If the byte is not found, this returns -1.
func indexByteString(s string, c byte) int {
for i := 0; i < len(s); i++ {
if s[i] == c {
return i
}
}
return -1
}
Loading