summaryrefslogtreecommitdiff
path: root/src/pkg/os/env.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/os/env.go')
-rw-r--r--src/pkg/os/env.go119
1 files changed, 53 insertions, 66 deletions
diff --git a/src/pkg/os/env.go b/src/pkg/os/env.go
index bdd2ac293..3a6d79dd0 100644
--- a/src/pkg/os/env.go
+++ b/src/pkg/os/env.go
@@ -1,86 +1,73 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// Copyright 2010 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.
-// Environment variables.
+// General environment variables.
package os
-import (
- "once"
-)
-
-// ENOENV is the Error indicating that an environment variable does not exist.
-var ENOENV = NewError("no such environment variable")
-
-var env map[string]string
-
-
-func copyenv() {
- env = make(map[string]string)
- for _, s := range Envs {
- for j := 0; j < len(s); j++ {
- if s[j] == '=' {
- env[s[0:j]] = s[j+1:]
- break
- }
+// Expand replaces ${var} or $var in the string based on the mapping function.
+// Invocations of undefined variables are replaced with the empty string.
+func Expand(s string, mapping func(string) string) string {
+ buf := make([]byte, 0, 2*len(s))
+ // ${} is all ASCII, so bytes are fine for this operation.
+ i := 0
+ for j := 0; j < len(s); j++ {
+ if s[j] == '$' && j+1 < len(s) {
+ buf = append(buf, []byte(s[i:j])...)
+ name, w := getShellName(s[j+1:])
+ buf = append(buf, []byte(mapping(name))...)
+ j += w
+ i = j + 1
}
}
+ return string(buf) + s[i:]
}
-// Getenverror retrieves the value of the environment variable named by the key.
-// It returns the value and an error, if any.
-func Getenverror(key string) (value string, err Error) {
- once.Do(copyenv)
-
- if len(key) == 0 {
- return "", EINVAL
- }
- v, ok := env[key]
- if !ok {
- return "", ENOENV
- }
- return v, nil
-}
-
-// 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.
-func Getenv(key string) string {
- v, _ := Getenverror(key)
- return v
+// ShellExpand replaces ${var} or $var in the string according to the values
+// of the operating system's environment variables. References to undefined
+// variables are replaced by the empty string.
+func ShellExpand(s string) string {
+ return Expand(s, Getenv)
}
-// Setenv sets the value of the environment variable named by the key.
-// It returns an Error, if any.
-func Setenv(key, value string) Error {
- once.Do(copyenv)
-
- if len(key) == 0 {
- return EINVAL
+// isSpellSpecialVar reports whether the character identifies a special
+// shell variable such as $*.
+func isShellSpecialVar(c uint8) bool {
+ switch c {
+ case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return true
}
- env[key] = value
- return nil
+ return false
}
-// Clearenv deletes all environment variables.
-func Clearenv() {
- once.Do(copyenv) // prevent copyenv in Getenv/Setenv
- env = make(map[string]string)
+// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
+func isAlphaNum(c uint8) bool {
+ return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
}
-// Environ returns an array of strings representing the environment,
-// in the form "key=value".
-func Environ() []string {
- once.Do(copyenv)
- a := make([]string, len(env))
- i := 0
- for k, v := range env {
- // check i < len(a) for safety,
- // in case env is changing underfoot.
- if i < len(a) {
- a[i] = k + "=" + v
- i++
+// getName returns the name that begins the string and the number of bytes
+// consumed to extract it. If the name is enclosed in {}, it's part of a ${}
+// expansion and two more bytes are needed than the length of the name.
+func getShellName(s string) (string, int) {
+ switch {
+ case s[0] == '{':
+ if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
+ return s[1:2], 3
+ }
+ // Scan to closing brace
+ for i := 1; i < len(s); i++ {
+ if s[i] == '}' {
+ return s[1:i], i + 1
+ }
}
+ return "", 1 // Bad syntax; just eat the brace.
+ case isShellSpecialVar(s[0]):
+ return s[0:1], 1
+ }
+ // Scan alphanumerics.
+ var i int
+ for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
}
- return a[0:i]
+ return s[:i], i
}