From e366ec84c0bc4e846a6d6140c3267f617260e15c Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 25 Feb 2024 21:02:38 +0800 Subject: [PATCH 1/2] Gop_Env --- gsh/classfile.go | 5 +++++ gsh/env.go | 9 +++++++++ gsh/gsh_test.go | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/gsh/classfile.go b/gsh/classfile.go index eae0b60..eb96427 100644 --- a/gsh/classfile.go +++ b/gsh/classfile.go @@ -44,6 +44,11 @@ func (p *App) initApp() { p.ferr = os.Stderr } +// Gop_Env retrieves the value of the environment variable named by the key. +func (p *App) Gop_Env(key string) string { + return Sys.Getenv(key) +} + func (p *App) execWith(env []string, name string, args ...string) error { cmd := exec.Command(name, args...) cmd.Stdin = p.fin diff --git a/gsh/env.go b/gsh/env.go index 0e00cc9..16f5550 100644 --- a/gsh/env.go +++ b/gsh/env.go @@ -86,6 +86,11 @@ type OS interface { // variables are replaced by the empty string. ExpandEnv(s string) string + // Getenv retrieves the value of the environment variable named by the key. + // It returns the value, which will be empty if the variable is not present. + // To distinguish between an empty value and an unset value, use LookupEnv. + Getenv(key string) string + // Run starts the specified command and waits for it to complete. Run(c *exec.Cmd) error } @@ -102,6 +107,10 @@ func (p defaultOS) ExpandEnv(s string) string { return os.ExpandEnv(s) } +func (p defaultOS) Getenv(key string) string { + return os.Getenv(key) +} + func (p defaultOS) Run(c *exec.Cmd) error { return c.Run() } diff --git a/gsh/gsh_test.go b/gsh/gsh_test.go index 9a096ed..295c3e7 100644 --- a/gsh/gsh_test.go +++ b/gsh/gsh_test.go @@ -36,6 +36,10 @@ func (p mockOS) ExpandEnv(s string) string { }) } +func (p mockOS) Getenv(key string) string { + return Getenv(mockEnv, key) +} + func (p mockOS) Run(c *exec.Cmd) error { if mockEcho { fmt.Fprintln(c.Stdout, c.Env, c.Args) @@ -91,6 +95,7 @@ func TestOS(t *testing.T) { var sys defaultOS sys.Environ() sys.ExpandEnv("foo") + sys.Getenv("foo") sys.Run(new(exec.Cmd)) } @@ -106,6 +111,9 @@ func TestEnv(t *testing.T) { func TestExecWithEnv(t *testing.T) { var app App app.initApp() + if v := app.Gop_Env("BAR"); v != "bar" { + t.Fatal("app.Gop_Env:", v) + } capout(&app, func() { err := app.Exec__0(M{"FOO": "123"}, "./app", "$FOO") check(t, err) From bba26cc01e7de9fc9f3a83142a734b6303ae289c Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sun, 25 Feb 2024 21:18:19 +0800 Subject: [PATCH 2/2] bufiox --- bufiox/bufio.go | 21 ++++++++++++++++++--- bufiox/bufio_test.go | 27 ++++++++++++++++++++++++--- bufiox/seek.go | 18 ++++++++++++++++-- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/bufiox/bufio.go b/bufiox/bufio.go index 585e5e3..f9942bf 100644 --- a/bufiox/bufio.go +++ b/bufiox/bufio.go @@ -1,3 +1,19 @@ +/* + Copyright 2020 Qiniu Limited (qiniu.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package bufiox import ( @@ -10,13 +26,13 @@ import ( // ----------------------------------------------------------------------------- -type nilReaderImpl int +type nilReaderImpl struct{} func (p nilReaderImpl) Read(b []byte) (n int, err error) { return 0, io.EOF } -var nilReader io.Reader = nilReaderImpl(0) +var nilReader io.Reader = nilReaderImpl{} // ----------------------------------------------------------------------------- @@ -82,7 +98,6 @@ var ErrSeekUnsupported = errors.New("bufio: the underlying reader doesn't suppor // SeekCurrent means relative to the current offset, and SeekEnd means // relative to the end. Seek returns the new offset relative to the start // of the file and an error, if any. -// func Seek(b *bufio.Reader, offset int64, whence int) (int64, error) { r := getUnderlyingReader(b) if seeker, ok := r.(io.Seeker); ok { diff --git a/bufiox/bufio_test.go b/bufiox/bufio_test.go index 81b2e81..8799491 100644 --- a/bufiox/bufio_test.go +++ b/bufiox/bufio_test.go @@ -1,3 +1,19 @@ +/* + Copyright 2020 Qiniu Limited (qiniu.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package bufiox import ( @@ -13,12 +29,17 @@ import ( func TestReaderSize(t *testing.T) { b1 := NewReaderBuffer(nil) - size1 := unsafe.Sizeof(*b1) b2 := bufio.NewReader(os.Stdin) - size2 := unsafe.Sizeof(*b2) - if size1 != size2 { + _ = b2 + if unsafe.Sizeof(*b1) != unsafe.Sizeof(*b2) { t.Fatal("TestReaderSize: sizeof(bufiox.Reader) != sizeof(bufio.Reader)") } + if Buffer(b1) != nil { + t.Fatal("Buffer not nil") + } + if !IsReaderBuffer(b1) { + t.Fatal("not IsReaderBuffer?") + } b, err := ReadAll(b1) if err != nil || b != nil { t.Fatal("ReadAll failed:", err, b) diff --git a/bufiox/seek.go b/bufiox/seek.go index 3912e02..56fb8cf 100644 --- a/bufiox/seek.go +++ b/bufiox/seek.go @@ -1,3 +1,19 @@ +/* + Copyright 2020 Qiniu Limited (qiniu.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package bufiox import ( @@ -24,7 +40,6 @@ func NewReader(rd io.ReadSeeker) *Reader { // NewReaderSize returns a new Reader whose buffer has at least the specified // size. If the argument io.Reader is already a Reader with large enough size, // it returns the underlying Reader. -// func NewReaderSize(rd io.ReadSeeker, size int) *Reader { b, ok := rd.(*Reader) if ok && b.Size() >= size { @@ -39,7 +54,6 @@ func NewReaderSize(rd io.ReadSeeker, size int) *Reader { // SeekCurrent means relative to the current offset, and SeekEnd means // relative to the end. Seek returns the new offset relative to the start // of the file and an error, if any. -// func (r *Reader) Seek(offset int64, whence int) (int64, error) { return Seek(&r.Reader, offset, whence) }