diff options
author | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2011-09-13 13:13:40 +0200 |
commit | 5ff4c17907d5b19510a62e08fd8d3b11e62b431d (patch) | |
tree | c0650497e988f47be9c6f2324fa692a52dea82e1 /src/pkg/os/env.go | |
parent | 80f18fc933cf3f3e829c5455a1023d69f7b86e52 (diff) | |
download | golang-upstream/60.tar.gz |
Imported Upstream version 60upstream/60
Diffstat (limited to 'src/pkg/os/env.go')
-rw-r--r-- | src/pkg/os/env.go | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/pkg/os/env.go b/src/pkg/os/env.go new file mode 100644 index 000000000..3772c090b --- /dev/null +++ b/src/pkg/os/env.go @@ -0,0 +1,75 @@ +// 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. + +// General environment variables. + +package os + +func setenv_c(k, v string) + +// 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:] +} + +// 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) +} + +// 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 + } + return false +} + +// 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' +} + +// 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 s[:i], i +} |